@aceshooting/lyra-ui 28.1.0 → 28.1.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/CHANGELOG.md +65 -0
- package/dist/components/agent-tools/commit-card/commit-card.class.d.ts +2 -2
- package/dist/components/agent-tools/commit-card/commit-card.class.js +7 -8
- package/dist/components/agent-tools/eval-dataset/eval-dataset.class.js +1 -1
- package/dist/components/agent-tools/schema-viewer/schema-viewer.class.js +1 -1
- package/dist/components/agent-tools/span-waterfall/span-waterfall.class.js +1 -1
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +4 -4
- package/dist/components/charts/chart/box-plot.class.d.ts +2 -2
- package/dist/components/charts/chart/box-plot.class.js +14 -14
- package/dist/components/charts/chart/chart.class.d.ts +2 -2
- package/dist/components/charts/chart/chart.class.js +14 -14
- package/dist/components/charts/chart/lite-chart.class.d.ts +1 -1
- package/dist/components/charts/chart/lite-chart.class.js +8 -8
- package/dist/components/conversation/message-feedback/message-feedback.class.js +2 -2
- package/dist/components/conversation/push-to-talk/push-to-talk.class.d.ts +2 -1
- package/dist/components/conversation/push-to-talk/push-to-talk.class.js +1 -1
- package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
- package/dist/components/data/data-grid/data-grid-processing.js +1 -1
- package/dist/components/data/flow-canvas/flow-canvas.class.js +1 -1
- package/dist/components/data/gauge/gauge.class.js +1 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +1 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.js +2 -2
- package/dist/components/data/heatmap/heatmap-label-cache.js +1 -0
- package/dist/components/data/heatmap/heatmap.class.d.ts +2 -2
- package/dist/components/data/heatmap/heatmap.class.js +2 -2
- package/dist/components/data/stat/stat.class.d.ts +11 -9
- package/dist/components/data/stat/stat.class.js +4 -2
- package/dist/components/data/tree/tree.class.js +1 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
- package/dist/components/forms/color-picker/color-picker.class.js +3 -3
- package/dist/components/forms/combobox/combobox.class.d.ts +2 -4
- package/dist/components/forms/combobox/combobox.class.js +1 -1
- package/dist/components/forms/emoji-picker/emoji-picker.class.js +5 -5
- package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
- package/dist/components/forms/select/select.class.js +4 -3
- package/dist/components/forms/textarea/textarea.class.js +1 -1
- package/dist/components/forms/toggle-group/toggle-group.class.js +1 -1
- package/dist/components/layout/command-palette/command-palette.styles.js +1 -1
- package/dist/components/layout/details/accordion.class.js +1 -1
- package/dist/components/layout/filter-bar/filter-bar.class.js +3 -3
- package/dist/components/layout/menu/menu.class.d.ts +1 -1
- package/dist/components/layout/menu/menu.class.js +1 -1
- package/dist/components/layout/menubar/menubar.class.js +1 -1
- package/dist/components/layout/navigation-menu-item/navigation-menu-item.class.d.ts +1 -1
- package/dist/components/layout/navigation-menu-item/navigation-menu-item.class.js +1 -1
- package/dist/components/layout/page/page.class.d.ts +1 -1
- package/dist/components/layout/page/page.class.js +1 -1
- package/dist/components/layout/responsive-panel/responsive-panel.class.js +1 -1
- package/dist/components/layout/tab-group/tab-group.class.js +1 -1
- package/dist/components/layout/widget/widget.class.js +1 -1
- package/dist/components/media/attachment-trigger/attachment-trigger.class.js +1 -1
- package/dist/components/media/file-input/file-input.class.js +1 -1
- package/dist/components/media/image-viewer/image-viewer.class.js +1 -1
- package/dist/components/media/video-playlist/video-playlist.class.js +1 -1
- package/dist/components/overlays/overlay/dropdown.class.js +1 -1
- package/dist/components/overlays/overlay/popover.class.js +1 -1
- package/dist/components/retrieval/chunk-inspector/chunk-inspector.class.d.ts +1 -1
- package/dist/components/retrieval/chunk-inspector/chunk-inspector.class.js +2 -2
- package/dist/components/retrieval/citation-badge/citation-badge.class.js +1 -1
- package/dist/components/retrieval/entity-chip/entity-chip.class.js +1 -1
- package/dist/components/retrieval/graph/graph-canvas.js +1 -1
- package/dist/components/retrieval/graph/graph.class.d.ts +1 -1
- package/dist/components/retrieval/graph/graph.class.js +1 -1
- package/dist/components/retrieval/graph-legend/graph-legend.class.js +2 -2
- package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +1 -1
- package/dist/components/retrieval/neighbor-list/neighbor-list.class.js +1 -1
- package/dist/components/retrieval/retrieval-results/retrieval-results.class.d.ts +1 -1
- package/dist/components/retrieval/retrieval-results/retrieval-results.class.js +4 -4
- package/dist/components/retrieval/source-picker/source-picker.class.d.ts +1 -1
- package/dist/components/retrieval/source-picker/source-picker.class.js +1 -1
- package/dist/components/utility/tour/tour.class.js +4 -4
- package/dist/components/viewers/email-viewer/email-viewer.class.js +1 -1
- package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +1 -1
- package/dist/internal/dev-mode-attribute-warning.development.js +1 -1
- package/dist/internal/native-modal-carrier.js +2 -2
- package/dist/internal/overlay-manager.d.ts +2 -0
- package/dist/internal/overlay-manager.js +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/llms/components/lr-color-picker.md +2 -0
- package/llms/components/lr-commit-card.md +3 -2
- package/llms/components/lr-push-to-talk.md +3 -0
- package/llms/components/lr-select.md +2 -0
- package/llms/components/lr-stat.md +4 -0
- package/llms/peers.md +1 -1
- package/llms/shared/ai-and-peers.md +44 -0
- package/llms/shared.md +44 -0
- package/package.json +5 -5
- package/registrations.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{srOnly}from"../../../internal/a11y.js";import{syncAriaDescribedByElements}from"../../../internal/aria-reflection.js";import{finiteInteger,finiteNumber,finiteRange,minMax}from"../../../internal/numbers.js";import{getScratchCtx,resolveBoundedCanvasAllocation}from"../../../internal/canvas.js";import{resolveCanvasColor}from"../../../internal/canvas-color.js";import{resolveCssTokenLength}from"../../../internal/css-token-length.js";import{ThemeWatcher}from"../../../internal/theme-watcher.js";import{activeElementIn,shadowFocusTarget}from"../../../internal/active-element.js";import{linearAlpha,linearBucket,midpointAlpha,midpointBucket,sqrtStep}from"./heatmap-scale.js";import{styles}from"./heatmap.styles.js";import{resolveRgb,formatRgb}from"./heatmap-colors.js";import{hexToRgb,resolveRgb as resolveRgb2}from"./heatmap-colors.js";import{DEFAULT_BUCKET_COUNT,MAX_HEATMAP_CELLS,MAX_HEATMAP_DECORATIONS,MAX_ACCESSIBLE_HEATMAP_CELLS,normalizeBucketCount}from"./heatmap-limits.js";import{MAX_BUCKET_COUNT,MAX_HEATMAP_CELLS as MAX_HEATMAP_CELLS2,MAX_HEATMAP_DECORATIONS as MAX_HEATMAP_DECORATIONS2,MAX_ACCESSIBLE_HEATMAP_CELLS as MAX_ACCESSIBLE_HEATMAP_CELLS2,normalizeBucketCount as normalizeBucketCount2}from"./heatmap-limits.js";import{buildCalendarGrid,parseIsoDate,quartileBucket}from"./calendar-grid.js";import{accessibleMatrixCellRect,calendarCellAt as readCalendarCell,calendarCellRect,calendarDateAt as readCalendarDate,calendarValueAt as readCalendarValue,firstInteractiveCalendarCell as findFirstInteractiveCalendarCell,firstInteractiveMatrixCell as findFirstInteractiveMatrixCell,hitTestCalendar as hitTestCalendarGrid,hitTestMatrix as hitTestMatrixGrid,matrixCellRect,nextInteractiveCalendarCell as findNextInteractiveCalendarCell,nextInteractiveMatrixCell as findNextInteractiveMatrixCell}from"./heatmap-grid-navigation.js";import{getDateTimeFormat,getNumberFormat}from"../../../internal/intl-cache.js";import{sanitizeCssColor}from"../../../internal/safe-css.js";import{literalSetConverter}from"../../../internal/converters.js";import{devWarnOnce}from"../../../internal/dev-mode-attribute-warning.js";import{escapeCsvField}from"../../utility/export-button/csv.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{LYRA_DEFAULT_heatmapCalendarCellLabel,LYRA_DEFAULT_heatmapCalendarLabel,LYRA_DEFAULT_heatmapDecorationLimit,LYRA_DEFAULT_heatmapDefaultColLabel,LYRA_DEFAULT_heatmapDefaultRowLabel,LYRA_DEFAULT_heatmapMatrixCellLabel,LYRA_DEFAULT_heatmapMatrixLabel,LYRA_DEFAULT_heatmapNoDataValue,LYRA_DEFAULT_heatmapProjectionLimit,LYRA_DEFAULT_heatmapSelectedCellLabel,LYRA_DEFAULT_heatmapSelectedCount,LYRA_DEFAULT_heatmapValueLabel}from"../../../internal/default-strings/data.generated.js";const PAD_LEFT=60,PAD_TOP=20,ROW_LABEL_INSET=4,MAX_ROW_LABEL_FRACTION=.4,MAX_COL_LABEL_HEIGHT=240,COL_LABEL_INSET=6,labelExtentConverter={fromAttribute:value=>{if(value===null)return;const trimmed=value.trim();if(trimmed.toLowerCase()==="auto")return"auto";const parsed=Number.parseFloat(trimmed);return Number.isFinite(parsed)&&parsed>=0?parsed:void 0},toAttribute:value=>value===void 0?null:String(value)},STICKY_LABELS=literalSetConverter(["none","rows","cols","both"],"none"),FALLBACK_NO_DATA_FILL="rgba(128,128,128,0.25)",FALLBACK_STICKY_LABEL_BG="#ffffff",RAMP_STEPS=7,FALLBACK_SCALE_LO="#cde2fb",FALLBACK_SCALE_HI="#0969da",FALLBACK_LABEL_FONT="10px system-ui, sans-serif",CAL_PAD_LEFT=28,CAL_WEEKDAY_LABEL_INSET=2,CAL_LABEL_H=16,CAL_CELL=11,CAL_GAP=2,DEFAULT_MATRIX_CELL_SIZE=22,MAX_MATRIX_ROW_HEIGHT=4096,DEFAULT_ACCESSIBLE_TARGET_SIZE_PX=40,FIT_MIN_CELL=4,RING_LINE_WIDTH=2,FALLBACK_FOCUS_RING_COLOR="#0969da",FALLBACK_ANNOTATION_COLOR="#cf222e",FALLBACK_SELECTED_COLOR="#1a7f37",SCOPED_COLOR=/var\(|currentcolor|light-dark\(/i,MAX_CANVAS_DIMENSION=16384,MAX_CANVAS_PIXELS=16777216,ARROW_KEYS=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"]),GRID_KEYS=new Set([...ARROW_KEYS,"Home","End"]),MS_PER_DAY=864e5,CAL_MONTH_LABEL_GAP=2;function isoDateAtOffset(firstWeekStart,dayOffset){return new Date(firstWeekStart.getTime()+dayOffset*MS_PER_DAY).toISOString().slice(0,10)}function legendStopsChanged(value,previous){if(Object.is(value,previous))return!1;if(!Array.isArray(value)||!Array.isArray(previous)||value.length!==previous.length)return!0;for(let index=0;index<value.length;index+=1){if(Object.hasOwn(value,index)!==Object.hasOwn(previous,index))return!0;const next=value[index],before=previous[index];if(!next||!before){if(!Object.is(next,before))return!0;continue}if(!Object.is(next.value,before.value)||!Object.is(next.color,before.color)||!Object.is(next.label,before.label)||!Object.is(next.partOfRamp,before.partOfRamp))return!0}return!1}const optionalCellSizeConverter={fromAttribute(value){if(value===null||value.trim()==="")return;const parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}},DEFAULT_MATRIX_DATA=Object.freeze({kind:"matrix",rowLabels:Object.freeze([]),colLabels:Object.freeze([]),values:Object.freeze([])});function normalizeCellSizeClamp(value){if(!(value==null||!Number.isFinite(value)))return finiteRange(value,FIT_MIN_CELL,FIT_MIN_CELL)}const bucketCountConverter={fromAttribute(value){return value===null?DEFAULT_BUCKET_COUNT:normalizeBucketCount(Number(value))}};function mixRgb(from,to,t){const clamped=Math.min(1,Math.max(0,t)),r=Math.round(from[0]+(to[0]-from[0])*clamped),g=Math.round(from[1]+(to[1]-from[1])*clamped),b=Math.round(from[2]+(to[2]-from[2])*clamped),a=from[3]+(to[3]-from[3])*clamped;return formatRgb([r,g,b,a])}const CALENDAR_SPACING_PROPERTIES=new Set(["cellGapX","cellGapY","cellRadius"]);class LyraHeatmap extends LyraElement{static{this.defaultStrings={...super.defaultStrings,heatmapCalendarCellLabel:LYRA_DEFAULT_heatmapCalendarCellLabel,heatmapCalendarLabel:LYRA_DEFAULT_heatmapCalendarLabel,heatmapDecorationLimit:LYRA_DEFAULT_heatmapDecorationLimit,heatmapDefaultColLabel:LYRA_DEFAULT_heatmapDefaultColLabel,heatmapDefaultRowLabel:LYRA_DEFAULT_heatmapDefaultRowLabel,heatmapMatrixCellLabel:LYRA_DEFAULT_heatmapMatrixCellLabel,heatmapMatrixLabel:LYRA_DEFAULT_heatmapMatrixLabel,heatmapNoDataValue:LYRA_DEFAULT_heatmapNoDataValue,heatmapProjectionLimit:LYRA_DEFAULT_heatmapProjectionLimit,heatmapSelectedCellLabel:LYRA_DEFAULT_heatmapSelectedCellLabel,heatmapSelectedCount:LYRA_DEFAULT_heatmapSelectedCount,heatmapValueLabel:LYRA_DEFAULT_heatmapValueLabel}}static{this.collectionSupport=collectionSupport}static{this.immutableEventDetails=Object.freeze(["lr-selection-change"])}static{this.ownedCollectionProperties=Object.freeze(["data","annotations","legendStops","colorSteps","selectedCells"])}static{this.identityCollectionObjectProperties=Object.freeze(["data"])}static{this.styles=[LyraElement.styles,styles,srOnly]}static get observedAttributes(){return[...new Set([...super.observedAttributes,"role"])]}get effectiveMode(){return this.data.kind}get stickyLabels(){return this._stickyLabels}set stickyLabels(next){const normalized=STICKY_LABELS.normalizeReflected(this,"sticky-labels",next),old=this._stickyLabels;old!==normalized&&(this._stickyLabels=normalized,this.requestUpdate("stickyLabels",old))}get effectiveStickyLabels(){return this.effectiveMode==="matrix"?this._stickyLabels:"none"}get freezesRowLabels(){const sticky=this.effectiveStickyLabels;return sticky==="rows"||sticky==="both"}get freezesColLabels(){const sticky=this.effectiveStickyLabels;return sticky==="cols"||sticky==="both"}get effectiveColLabelRotation(){if(typeof this.colLabelRotation!="number")return 0;const degrees=finiteNumber(this.colLabelRotation,0);return Math.min(90,Math.max(0,degrees))}get matrixPadLeft(){if(this.rowLabelWidth==="auto")return this.resolvedRowLabelWidth;if(typeof this.rowLabelWidth!="number")return PAD_LEFT;const resolved=finiteNumber(this.rowLabelWidth,PAD_LEFT);return resolved>=0?resolved:PAD_LEFT}get matrixGeometry(){if(this.effectiveMode==="matrix")return this.lastPaintedMatrixGeometry}set matrixGeometry(_value){}get calendarGeometry(){if(this.effectiveMode==="calendar")return this.lastPaintedCalendarGeometry}set calendarGeometry(_value){}exportData(format){if(format==="csv")return this.exportCsv();if(format!=="png"||!this.canvasHasContent||this.drawDirty||!this.canvas||this.canvas.width<=0||this.canvas.height<=0)return"";try{const rowBand=this.frozenBandCanvas("row-labels"),colBand=this.frozenBandCanvas("col-labels");if(!rowBand&&!colBand)return this.canvas.toDataURL("image/png");const composite=this.ownerDocument.createElement("canvas");composite.width=this.canvas.width,composite.height=this.canvas.height;const context=composite.getContext("2d");return context?(context.drawImage(this.canvas,0,0),rowBand&&rowBand.width>0&&rowBand.height>0&&context.drawImage(rowBand,0,0),colBand&&colBand.width>0&&colBand.height>0&&context.drawImage(colBand,0,0),composite.toDataURL("image/png")):""}catch{return""}}exportCsv(){const data=this.data;if(data.kind==="calendar"){const header2=["date","value"].map(escapeCsvField).join(","),rows2=data.days.filter(day=>!this.isNoData(day.value)).map(day=>[day.date,this.formatNumericValue(day.value)].map(escapeCsvField).join(","));return[header2,...rows2].join(`\r
|
|
1
|
+
import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{srOnly}from"../../../internal/a11y.js";import{syncAriaDescribedByElements}from"../../../internal/aria-reflection.js";import{finiteInteger,finiteNumber,finiteRange,minMax}from"../../../internal/numbers.js";import{getScratchCtx,resolveBoundedCanvasAllocation}from"../../../internal/canvas.js";import{resolveCanvasColor}from"../../../internal/canvas-color.js";import{resolveCssTokenLength}from"../../../internal/css-token-length.js";import{ThemeWatcher}from"../../../internal/theme-watcher.js";import{activeElementIn,shadowFocusTarget}from"../../../internal/active-element.js";import{linearAlpha,linearBucket,midpointAlpha,midpointBucket,sqrtStep}from"./heatmap-scale.js";import{styles}from"./heatmap.styles.js";import{resolveRgb,formatRgb}from"./heatmap-colors.js";import{hexToRgb,resolveRgb as resolveRgb2}from"./heatmap-colors.js";import{DEFAULT_BUCKET_COUNT,MAX_HEATMAP_CELLS,MAX_HEATMAP_DECORATIONS,MAX_ACCESSIBLE_HEATMAP_CELLS,normalizeBucketCount}from"./heatmap-limits.js";import{MAX_BUCKET_COUNT,MAX_HEATMAP_CELLS as MAX_HEATMAP_CELLS2,MAX_HEATMAP_DECORATIONS as MAX_HEATMAP_DECORATIONS2,MAX_ACCESSIBLE_HEATMAP_CELLS as MAX_ACCESSIBLE_HEATMAP_CELLS2,normalizeBucketCount as normalizeBucketCount2}from"./heatmap-limits.js";import{buildCalendarGrid,parseIsoDate,quartileBucket}from"./calendar-grid.js";import{accessibleMatrixCellRect,calendarCellAt as readCalendarCell,calendarCellRect,calendarDateAt as readCalendarDate,calendarValueAt as readCalendarValue,firstInteractiveCalendarCell as findFirstInteractiveCalendarCell,firstInteractiveMatrixCell as findFirstInteractiveMatrixCell,hitTestCalendar as hitTestCalendarGrid,hitTestMatrix as hitTestMatrixGrid,matrixCellRect,nextInteractiveCalendarCell as findNextInteractiveCalendarCell,nextInteractiveMatrixCell as findNextInteractiveMatrixCell}from"./heatmap-grid-navigation.js";import{getDateTimeFormat,getNumberFormat}from"../../../internal/intl-cache.js";import{sanitizeCssColor}from"../../../internal/safe-css.js";import{literalSetConverter}from"../../../internal/converters.js";import{HeatmapLabelCache}from"./heatmap-label-cache.js";import{devWarnOnce}from"../../../internal/dev-mode-attribute-warning.js";import{escapeCsvField}from"../../utility/export-button/csv.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{LYRA_DEFAULT_heatmapCalendarCellLabel,LYRA_DEFAULT_heatmapCalendarLabel,LYRA_DEFAULT_heatmapDecorationLimit,LYRA_DEFAULT_heatmapDefaultColLabel,LYRA_DEFAULT_heatmapDefaultRowLabel,LYRA_DEFAULT_heatmapMatrixCellLabel,LYRA_DEFAULT_heatmapMatrixLabel,LYRA_DEFAULT_heatmapNoDataValue,LYRA_DEFAULT_heatmapProjectionLimit,LYRA_DEFAULT_heatmapSelectedCellLabel,LYRA_DEFAULT_heatmapSelectedCount,LYRA_DEFAULT_heatmapValueLabel}from"../../../internal/default-strings/data.generated.js";const PAD_LEFT=60,PAD_TOP=20,ROW_LABEL_INSET=4,MAX_ROW_LABEL_FRACTION=.4,MAX_COL_LABEL_HEIGHT=240,COL_LABEL_INSET=6,labelExtentConverter={fromAttribute:value=>{if(value===null)return;const trimmed=value.trim();if(trimmed.toLowerCase()==="auto")return"auto";const parsed=Number.parseFloat(trimmed);return Number.isFinite(parsed)&&parsed>=0?parsed:void 0},toAttribute:value=>value===void 0?null:String(value)},STICKY_LABELS=literalSetConverter(["none","rows","cols","both"],"none"),FALLBACK_NO_DATA_FILL="rgba(128,128,128,0.25)",FALLBACK_STICKY_LABEL_BG="#ffffff",RAMP_STEPS=7,FALLBACK_SCALE_LO="#cde2fb",FALLBACK_SCALE_HI="#0969da",FALLBACK_LABEL_FONT="10px system-ui, sans-serif",CAL_PAD_LEFT=28,CAL_WEEKDAY_LABEL_INSET=2,CAL_LABEL_H=16,CAL_CELL=11,CAL_GAP=2,DEFAULT_MATRIX_CELL_SIZE=22,MAX_MATRIX_ROW_HEIGHT=4096,DEFAULT_ACCESSIBLE_TARGET_SIZE_PX=40,FIT_MIN_CELL=4,RING_LINE_WIDTH=2,FALLBACK_FOCUS_RING_COLOR="#0969da",FALLBACK_ANNOTATION_COLOR="#cf222e",FALLBACK_SELECTED_COLOR="#1a7f37",SCOPED_COLOR=/var\(|currentcolor|light-dark\(/i,MAX_CANVAS_DIMENSION=16384,MAX_CANVAS_PIXELS=16777216,ARROW_KEYS=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"]),GRID_KEYS=new Set([...ARROW_KEYS,"Home","End"]),MS_PER_DAY=864e5,CAL_MONTH_LABEL_GAP=2;function isoDateAtOffset(firstWeekStart,dayOffset){return new Date(firstWeekStart.getTime()+dayOffset*MS_PER_DAY).toISOString().slice(0,10)}function legendStopsChanged(value,previous){if(Object.is(value,previous))return!1;if(!Array.isArray(value)||!Array.isArray(previous)||value.length!==previous.length)return!0;for(let index=0;index<value.length;index+=1){if(Object.hasOwn(value,index)!==Object.hasOwn(previous,index))return!0;const next=value[index],before=previous[index];if(!next||!before){if(!Object.is(next,before))return!0;continue}if(!Object.is(next.value,before.value)||!Object.is(next.color,before.color)||!Object.is(next.label,before.label)||!Object.is(next.partOfRamp,before.partOfRamp))return!0}return!1}const optionalCellSizeConverter={fromAttribute(value){if(value===null||value.trim()==="")return;const parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}},DEFAULT_MATRIX_DATA=Object.freeze({kind:"matrix",rowLabels:Object.freeze([]),colLabels:Object.freeze([]),values:Object.freeze([])});function normalizeCellSizeClamp(value){if(!(value==null||!Number.isFinite(value)))return finiteRange(value,FIT_MIN_CELL,FIT_MIN_CELL)}const bucketCountConverter={fromAttribute(value){return value===null?DEFAULT_BUCKET_COUNT:normalizeBucketCount(Number(value))}};function mixRgb(from,to,t){const clamped=Math.min(1,Math.max(0,t)),r=Math.round(from[0]+(to[0]-from[0])*clamped),g=Math.round(from[1]+(to[1]-from[1])*clamped),b=Math.round(from[2]+(to[2]-from[2])*clamped),a=from[3]+(to[3]-from[3])*clamped;return formatRgb([r,g,b,a])}const CALENDAR_SPACING_PROPERTIES=new Set(["cellGapX","cellGapY","cellRadius"]);class LyraHeatmap extends LyraElement{static{this.defaultStrings={...super.defaultStrings,heatmapCalendarCellLabel:LYRA_DEFAULT_heatmapCalendarCellLabel,heatmapCalendarLabel:LYRA_DEFAULT_heatmapCalendarLabel,heatmapDecorationLimit:LYRA_DEFAULT_heatmapDecorationLimit,heatmapDefaultColLabel:LYRA_DEFAULT_heatmapDefaultColLabel,heatmapDefaultRowLabel:LYRA_DEFAULT_heatmapDefaultRowLabel,heatmapMatrixCellLabel:LYRA_DEFAULT_heatmapMatrixCellLabel,heatmapMatrixLabel:LYRA_DEFAULT_heatmapMatrixLabel,heatmapNoDataValue:LYRA_DEFAULT_heatmapNoDataValue,heatmapProjectionLimit:LYRA_DEFAULT_heatmapProjectionLimit,heatmapSelectedCellLabel:LYRA_DEFAULT_heatmapSelectedCellLabel,heatmapSelectedCount:LYRA_DEFAULT_heatmapSelectedCount,heatmapValueLabel:LYRA_DEFAULT_heatmapValueLabel}}static{this.collectionSupport=collectionSupport}static{this.immutableEventDetails=Object.freeze(["lr-selection-change"])}static{this.ownedCollectionProperties=Object.freeze(["data","annotations","legendStops","colorSteps","selectedCells"])}static{this.identityCollectionObjectProperties=Object.freeze(["data"])}static{this.styles=[LyraElement.styles,styles,srOnly]}static get observedAttributes(){return[...new Set([...super.observedAttributes,"role"])]}get effectiveMode(){return this.data.kind}get stickyLabels(){return this._stickyLabels}set stickyLabels(next){const normalized=STICKY_LABELS.normalizeReflected(this,"sticky-labels",next),old=this._stickyLabels;old!==normalized&&(this._stickyLabels=normalized,this.requestUpdate("stickyLabels",old))}get effectiveStickyLabels(){return this.effectiveMode==="matrix"?this._stickyLabels:"none"}get freezesRowLabels(){const sticky=this.effectiveStickyLabels;return sticky==="rows"||sticky==="both"}get freezesColLabels(){const sticky=this.effectiveStickyLabels;return sticky==="cols"||sticky==="both"}get effectiveColLabelRotation(){if(typeof this.colLabelRotation!="number")return 0;const degrees=finiteNumber(this.colLabelRotation,0);return Math.min(90,Math.max(0,degrees))}get matrixPadLeft(){if(this.rowLabelWidth==="auto")return this.resolvedRowLabelWidth;if(typeof this.rowLabelWidth!="number")return PAD_LEFT;const resolved=finiteNumber(this.rowLabelWidth,PAD_LEFT);return resolved>=0?resolved:PAD_LEFT}get matrixGeometry(){if(this.effectiveMode==="matrix")return this.lastPaintedMatrixGeometry}set matrixGeometry(_value){}get calendarGeometry(){if(this.effectiveMode==="calendar")return this.lastPaintedCalendarGeometry}set calendarGeometry(_value){}exportData(format){if(format==="csv")return this.exportCsv();if(format!=="png"||!this.canvasHasContent||this.drawDirty||!this.canvas||this.canvas.width<=0||this.canvas.height<=0)return"";try{const rowBand=this.frozenBandCanvas("row-labels"),colBand=this.frozenBandCanvas("col-labels");if(!rowBand&&!colBand)return this.canvas.toDataURL("image/png");const composite=this.ownerDocument.createElement("canvas");composite.width=this.canvas.width,composite.height=this.canvas.height;const context=composite.getContext("2d");return context?(context.drawImage(this.canvas,0,0),rowBand&&rowBand.width>0&&rowBand.height>0&&context.drawImage(rowBand,0,0),colBand&&colBand.width>0&&colBand.height>0&&context.drawImage(colBand,0,0),composite.toDataURL("image/png")):""}catch{return""}}exportCsv(){const data=this.data;if(data.kind==="calendar"){const header2=["date","value"].map(escapeCsvField).join(","),rows2=data.days.filter(day=>!this.isNoData(day.value)).map(day=>[day.date,this.formatNumericValue(day.value)].map(escapeCsvField).join(","));return[header2,...rows2].join(`\r
|
|
2
2
|
`)}const header=["row","column","value"].map(escapeCsvField).join(","),rows=[];return data.values.forEach((rowValues,rowIndex)=>{const rowLabel=data.rowLabels[rowIndex]??"";rowValues.forEach((value,colIndex)=>{if(this.isNoData(value))return;const colLabel=data.colLabels[colIndex]??"";rows.push([rowLabel,colLabel,this.formatNumericValue(value)].map(escapeCsvField).join(","))})}),[header,...rows].join(`\r
|
|
3
|
-
`)}get matrixPadTop(){if(this.colLabelHeight==="auto")return this.resolvedColLabelHeight;if(typeof this.colLabelHeight!="number")return PAD_TOP;const resolved=finiteNumber(this.colLabelHeight,PAD_TOP);return resolved>=0?resolved:PAD_TOP}measureColLabelHeight(cs){const labels=this.matrixColLabels;if(labels.length===0)return PAD_TOP;const ctx=getScratchCtx(this.ownerDocument);if(!ctx)return PAD_TOP;ctx.font=this.labelFont(cs);let widest=0;const interval=finiteInteger(this.colLabelInterval,1,1);for(let index=0;index<labels.length;index+=interval)widest=Math.max(widest,ctx.measureText(labels[index]).width);const radians=this.effectiveColLabelRotation*Math.PI/180,projected=widest*Math.sin(radians);return Math.max(PAD_TOP,Math.min(Math.ceil(projected)+COL_LABEL_INSET,MAX_COL_LABEL_HEIGHT))}measureRowLabelWidth(cs){const labels=this.matrixRowLabels;if(labels.length===0)return PAD_LEFT;const ctx=getScratchCtx(this.ownerDocument);if(!ctx)return PAD_LEFT;ctx.font=this.labelFont(cs);let widest=0;for(const label of labels)widest=Math.max(widest,ctx.measureText(label).width);const hostWidth=this.clientWidth||0,cap=hostWidth>0?hostWidth*MAX_ROW_LABEL_FRACTION:Number.POSITIVE_INFINITY;return Math.min(Math.max(PAD_LEFT,Math.ceil(widest)+ROW_LABEL_INSET*2),cap)}ellipsize(ctx,label,maxWidth){if(maxWidth<=0)return"";if(ctx.measureText(label).width<=maxWidth)return label;const characters=[...label],shortened=kept=>`${characters.slice(0,kept).join("")}…`;let fits=0,most=characters.length-1;for(;fits<most;){const kept=fits+most+1>>1;ctx.measureText(shortened(kept)).width<=maxWidth?fits=kept:most=kept-1}return fits>0||ctx.measureText("…").width<=maxWidth?shortened(fits):""}get calendarPadLeft(){const requested=this.calendarWeekdayLabelWidth;return requested==="auto"?this.resolvedCalendarWeekdayLabelWidth:requested??CAL_PAD_LEFT}measureCalendarWeekdayLabelWidth(cs,firstWeekStart){const ctx=getScratchCtx(this.ownerDocument);if(!ctx)return CAL_PAD_LEFT;ctx.font=this.labelFont(cs);let widest=0;for(const label of this.weekdayLabels(firstWeekStart))label&&(widest=Math.max(widest,ctx.measureText(label).width));const hostWidth=this.clientWidth||0,cap=hostWidth>0?Math.max(CAL_PAD_LEFT,hostWidth*MAX_ROW_LABEL_FRACTION):Number.POSITIVE_INFINITY;return Math.min(Math.max(CAL_PAD_LEFT,Math.ceil(widest)+CAL_WEEKDAY_LABEL_INSET*2),cap)}get matrixRowLabels(){return this.cachedMatrixData.rowLabels}get matrixColLabels(){return this.cachedMatrixData.colLabels}get matrixValues(){return this.cachedMatrixData.values}get calendarDays(){return this.data.kind==="calendar"?this.data.days:[]}get calendarData(){return this.data.kind==="calendar"?this.data:void 0}get cellSize(){return this._cellSize??(this.effectiveMode==="calendar"?CAL_CELL:DEFAULT_MATRIX_CELL_SIZE)}set cellSize(value){const oldValue=this._cellSize;this._cellSize=value==null?void 0:finiteRange(value,this.effectiveMode==="calendar"?CAL_CELL:DEFAULT_MATRIX_CELL_SIZE,1),this.requestUpdate("cellSize",oldValue)}get rowHeight(){return this._rowHeight}set rowHeight(value){const oldValue=this._rowHeight;this._rowHeight=value==null||!Number.isFinite(value)?void 0:finiteRange(value,1,1,MAX_MATRIX_ROW_HEIGHT),this.requestUpdate("rowHeight",oldValue)}get signedDomain(){return this.domain!==void 0||this.midpoint!==void 0}rampAlpha(value,lo,hi){const anchor=this.midpoint;return anchor===void 0?linearAlpha(value,lo,hi):midpointAlpha(value,lo,hi,anchor)}rampBucket(value,lo,hi,steps){const anchor=this.midpoint;return anchor===void 0?linearBucket(value,lo,hi,steps):midpointBucket(value,lo,hi,anchor,steps)}isNoData(value){return Number.isFinite(value)?value<0&&!this.signedDomain:!0}get maxCellSize(){return this._maxCellSize}set maxCellSize(value){const oldValue=this._maxCellSize;this._maxCellSize=normalizeCellSizeClamp(value),this.requestUpdate("maxCellSize",oldValue)}get minCellSize(){return this._minCellSize}set minCellSize(value){const oldValue=this._minCellSize;this._minCellSize=normalizeCellSizeClamp(value),this.requestUpdate("minCellSize",oldValue)}get normalizedFirstDayOfWeek(){return(finiteInteger(this.calendarData?.firstDayOfWeek??0,0)%7+7)%7}get bucketCount(){return this._bucketCount}set bucketCount(value){const oldValue=this._bucketCount;this._bucketCount=normalizeBucketCount(value),this.requestUpdate("bucketCount",oldValue)}toggleRowSelection(row){this.toggleSelectionAxis(row,!0)}toggleColumnSelection(col){this.toggleSelectionAxis(col,!1)}get calendarWeekdayLabelText(){return this.calendarData?.weekdayLabelText}get calendarWeekdayLabelWidth(){const value=this.calendarData?.weekdayLabelWidth;if(value==="auto")return value;if(typeof value!="number")return;const resolved=finiteNumber(value,CAL_PAD_LEFT);return resolved>=0?resolved:void 0}get calendarMonthLabelText(){return this.calendarData?.monthLabelText}get calendarColumnX(){return this.calendarData?.columnX}get calendarRowY(){return this.calendarData?.rowY}constructor(){super(),this.data=DEFAULT_MATRIX_DATA,this._stickyLabels="none",this.resolvedColLabelHeight=PAD_TOP,this.resolvedRowLabelWidth=PAD_LEFT,this.resolvedCalendarWeekdayLabelWidth=CAL_PAD_LEFT,this.withoutLegend=!1,this.scale="linear",this.cellGapX=1,this.cellGapY=1,this.cellRadius=0,this.colLabelInterval=1,this.fitToWidth=!1,this._bucketCount=DEFAULT_BUCKET_COUNT,this.annotations=[],this.selectedCell=null,this.multiple=!1,this.selectedCells=[],this.accessibleCells=!1,this.cachedValueRange=null,this.cachedMatrixData={rowLabels:[],colLabels:[],values:[],truncated:!1},this.cachedCalendarGrid=buildCalendarGrid(this.calendarDays),this.cachedCalendarSortedValues=[],this.cachedCalendarCellsByPos=new Map,this.cachedCalendarCellsByDate=new Map,this.cachedAnnotations=[],this.cachedLegendStops=[],this.cachedColorSteps=[],this.cachedCalendarAnnotationDates=new Set,this.cachedMatrixAnnotationPositions=new Set,this.decorationProjectionTruncated=!1,this.cachedCalendarDateByPos=[],this.cachedAccessiblePositions=[],this.cachedAccessiblePositionsByKey=new Map,this.cachedAccessiblePositionIndexByKey=new Map,this.cachedRamp=null,this.canvasHasContent=!1,this.canvasVisible=!0,this.drawDirty=!1,this.overlayRevision=0,this.hoverCell=null,this.focusedCell=null,this.liveText="",this.accessibleTargetSizePx=DEFAULT_ACCESSIBLE_TARGET_SIZE_PX,this.restoringAccessibleFocus=!1,this.accessibleFocusGeneration=0,this.announcements=new AnnouncementSinkController(this,{eager:["polite"]}),this.authorRole=null,this.authorAriaLabel=null,this.generatedAriaLabel="",this.syncingGeneratedSemantics=!1,this.hasSyncedDescribedByElements=!1,this.onDprChange=()=>{this.watchDpr(),this.requestDraw()},this.scheduleDraw=()=>{if(this.drawFrameRequest)return;const owner=this.ownerDocument.defaultView;if(!owner||!this.isConnected)return;const request={owner,handle:0};request.handle=owner.requestAnimationFrame(()=>{this.drawFrameRequest===request&&(this.drawFrameRequest=void 0,this.isConnected&&this.ownerDocument.defaultView===owner&&this.requestDraw())}),this.drawFrameRequest=request},this.selectedPositions=new Map,this.selectionAnchor=null,this.suppressSelectionClick=!1,this.onSelectionPointerDown=event=>{if(!this.multiple||event.button!==0||!event.isPrimary||this.selectionGesture)return;const pos=this.selectionPointerPosition(event);if(!pos)return;event.preventDefault(),this.suppressSelectionClick=!1,this.selectionRangeBase=void 0,this.selectionAnchor=pos,this.focusedCell=pos,this.accessibleCells?this.focusAccessibleCell(pos):this.canvas?.focus();const target=event.currentTarget;this.selectionGesture={pointerId:event.pointerId,target,start:pos,previous:pos,moved:!1,selecting:!this.selectedPositions.has(this.accessibleCellKey(pos)),cells:new Map(this.selectedPositions)};try{target.setPointerCapture(event.pointerId)}catch{}this.paintSelectionTo(pos)},this.onSelectionPointerMove=event=>{if(this.selectionGesture?.pointerId!==event.pointerId)return;const pos=this.selectionPointerPosition(event);pos&&!this.samePos(pos,this.selectionGesture.previous)&&this.paintSelectionTo(pos)},this.onSelectionPointerUp=event=>{const gesture=this.selectionGesture;if(!gesture||gesture.pointerId!==event.pointerId)return;const pos=this.selectionPointerPosition(event);pos&&this.paintSelectionTo(pos),this.cancelSelectionGesture(),this.proposeSelection(gesture.cells,"pointer"),gesture.moved||this.emitCellClick(gesture.start,"pointer",!1)},this.onSelectionPointerCancel=event=>{this.selectionGesture?.pointerId===event.pointerId&&this.cancelSelectionGesture()},this.tooltipSize={inline:0,block:0},this.onPointerMove=e=>{const next=this.hitTest(e.offsetX,e.offsetY);this.samePos(this.hoverCell,next)||(this.hoverCell=next)},this.onPointerLeave=()=>{this.hoverCell=null},this.onCanvasClick=e=>{if(this.consumeSelectionClick(e))return;const pos=this.hitTest(e.offsetX,e.offsetY);pos&&(this.focusedCell=pos,this.announce(pos),this.emitCellClick(pos))},this.onKeyDown=e=>{if(this.selectionKeyDown(e,this.focusedCell))return;const previous=this.focusedCell,edge=this.edgeCell(e);if(edge?(e.preventDefault(),this.focusedCell=edge,this.scrollCellIntoView(edge)):this.effectiveMode==="calendar"?this.onCalendarKeyDown(e):this.onMatrixKeyDown(e),(edge||ARROW_KEYS.has(e.key))&&this.focusedCell){const proposedKeys=this.extendSelection(previous,this.focusedCell,e.shiftKey);this.announce(this.focusedCell,proposedKeys?.has(this.accessibleCellKey(this.focusedCell)))}},this.canvasColorCache=new Map,this.onAccessibleCellFocus=e=>{if(this.restoringAccessibleFocus)return;const key=e.currentTarget.dataset.cellKey,pos=key?this.accessibleCellAtKey(key):null;pos&&(this.samePos(pos,this.focusedCell)||(this.selectionAnchor=pos,this.selectionRangeBase=void 0),this.focusedCell=pos,this.announce(pos))},this.onAccessibleCellClick=e=>{if(this.consumeSelectionClick(e))return;const key=e.currentTarget.dataset.cellKey,pos=key?this.accessibleCellAtKey(key):null;pos&&(this.focusedCell=pos,this.announce(pos),this.emitCellClick(pos,e.detail===0?"keyboard":"pointer"))},this.onAccessibleCellKeyDown=e=>{const key=e.currentTarget.dataset.cellKey,pos=key?this.accessibleCellAtKey(key):null;pos&&(this.selectionKeyDown(e,pos)||GRID_KEYS.has(e.key)&&(e.preventDefault(),this.focusedCell=pos,this.onKeyDown(e),this.focusAccessibleCell(this.focusedCell)))},new ThemeWatcher(this,()=>this.onThemeSignal()),this.calendarSpacingTrackingArmed=!0}requestUpdate(name,oldValue,options){this.calendarSpacingTrackingArmed&&name!==void 0&&CALENDAR_SPACING_PROPERTIES.has(name)&&(this.explicitCalendarSpacingProperties??=new Set).add(name),super.requestUpdate(name,oldValue,options)}explicitCalendarSpacing(name){if(!this.explicitCalendarSpacingProperties?.has(name))return;const value=this[name];return value??void 0}warnOnLegendRampMismatch(){const rampColors=this.cachedColorSteps.map(color=>sanitizeCssColor(color)??color);if(rampColors.length===0)return;const legendColors=this.cachedLegendStops.filter(stop=>!!stop.color&&stop.partOfRamp!==!1).map(stop=>sanitizeCssColor(stop.color??"")??stop.color??"");legendColors.length===0||legendColors.length===rampColors.length&&legendColors.every((color,index)=>color===rampColors[index])||devWarnOnce("lyra-heatmap-legend-ramp-mismatch",`<${this.localName}>: legendStops describes ${legendColors.length} colour(s) that do not match the ${rampColors.length} colorSteps the cells are painted from, so the legend may misdescribe the ramp. Supply legendStops built from the same array as colorSteps, or omit it to keep the built-in gradient key.`)}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value),!(oldValue===value||this.syncingGeneratedSemantics)&&(name==="role"&&(this.authorRole=value),name==="aria-label"&&(this.authorAriaLabel=value))}connectedCallback(){super.connectedCallback(),this.refreshAccessibleTargetSize();const owner=this.ownerDocument.defaultView,ResizeObserverCtor=owner?.ResizeObserver;if(owner&&ResizeObserverCtor){let observer;observer=new ResizeObserverCtor(()=>{!this.isConnected||this.ownerDocument.defaultView!==owner||this.resizeObserver!==observer||this.scheduleDraw()}),this.resizeObserver=observer,observer.observe(this)}const IntersectionObserverCtor=owner?.IntersectionObserver;if(this.canvasVisible=!0,owner&&IntersectionObserverCtor){let observer;observer=new IntersectionObserverCtor(entries=>{if(!this.isConnected||this.ownerDocument.defaultView!==owner||this.intersectionObserver!==observer)return;const entry=entries.find(candidate=>candidate.target===this);!entry||entry.isIntersecting===this.canvasVisible||(this.canvasVisible=entry.isIntersecting,this.canvasVisible&&this.drawDirty&&this.scheduleDraw())}),this.intersectionObserver=observer,observer.observe(this)}this.cachedRamp=null,this.paintedTheme=void 0,this.canvasColorCache.clear(),this.watchDpr()}disconnectedCallback(){super.disconnectedCallback(),this.cancelSelectionGesture(),this.selectionAnchor=null,this.selectionRangeBase=void 0,this.accessibleFocusGeneration++,this.pendingAccessibleFocus=void 0,this.pendingAccessibleFocusOrigin=void 0,this.restoringAccessibleFocus=!1,this.hoverCell=null,this.focusedCell=null,this.liveText="",this.canvasHasContent=!1,this.drawDirty=!0,this.resizeObserver?.disconnect(),this.resizeObserver=void 0,this.intersectionObserver?.disconnect(),this.intersectionObserver=void 0,this.canvasVisible=!0,this.clearDprWatcher(),this.cancelDrawFrame()}adoptedCallback(){super.adoptedCallback(),this.announcements.adopted()}watchDpr(){this.clearDprWatcher();const owner=this.ownerDocument.defaultView;if(!owner||typeof owner.matchMedia!="function")return;const query2=owner.matchMedia(`(resolution: ${owner.devicePixelRatio}dppx)`),listener=()=>{!this.isConnected||this.ownerDocument.defaultView!==owner||this.dprQuery!==query2||this.onDprChange()};this.dprQuery=query2,this.dprChangeListener=listener,query2.addEventListener("change",listener)}clearDprWatcher(){this.dprQuery&&this.dprChangeListener&&this.dprQuery.removeEventListener("change",this.dprChangeListener),this.dprQuery=void 0,this.dprChangeListener=void 0}willUpdate(changed){super.willUpdate(changed),(changed.size!==1||!changed.has("hoverCell"))&&this.overlayRevision++,(changed.has("data")||changed.has("domain")||changed.has("midpoint")||!this.hasUpdated)&&this.rebuildCanonicalMatrixData(),(changed.has("annotations")||changed.has("legendStops")||changed.has("colorSteps")||!this.hasUpdated)&&this.rebuildBoundedDecorations();const accessibleModeChanged=changed.has("accessibleCells")&&this.hasUpdated,collectionChanged=changed.has("data")||changed.has("cellInteractive"),activeRenderedControl=collectionChanged||accessibleModeChanged?shadowFocusTarget(this):null,activeAccessibleCell=activeRenderedControl?.matches('[part="cell"]')?activeRenderedControl:null,renderedAccessibleCells=activeAccessibleCell?.matches('[part="cell"]')?[...this.shadowRoot?.querySelectorAll('[part="cell"]')??[]]:[],accessibleFocusSnapshot=activeAccessibleCell?.matches('[part="cell"]')?{identity:activeAccessibleCell.dataset.cellIdentity,index:renderedAccessibleCells.indexOf(activeAccessibleCell)}:void 0;if(collectionChanged&&(this.focusedCell=null,this.hoverCell=null,this.liveText=""),changed.has("data")||changed.has("locale")||!this.hasUpdated){this.cachedCalendarGrid=buildCalendarGrid(this.calendarDays,this.normalizedFirstDayOfWeek,this.calendarMonthLabelText,this.effectiveLocale),this.cachedCalendarSortedValues=this.cachedCalendarGrid.cells.map(cell=>cell.value).filter(value=>!this.isNoData(value)).sort((a,b)=>a-b),this.cachedCalendarCellsByPos=new Map(this.cachedCalendarGrid.cells.map(cell=>[`${cell.week}:${cell.weekday}`,cell])),this.cachedCalendarCellsByDate=new Map(this.cachedCalendarGrid.cells.map(cell=>[cell.date,cell]));const{firstWeekStart,weekCount}=this.cachedCalendarGrid;this.cachedCalendarDateByPos=Array.from({length:weekCount*7},(_,index)=>isoDateAtOffset(firstWeekStart,index))}if(changed.has("colorSteps")||changed.has("withoutLegend")||!this.hasUpdated){const colorSteps=this.withoutLegend?[]:this.cachedColorSteps.map(sanitizeCssColor);colorSteps.length>=2&&colorSteps.every(color=>color!==void 0)?this.style.setProperty("--lr-heatmap-color-steps-gradient",`linear-gradient(to right, ${colorSteps.join(", ")})`):this.style.removeProperty("--lr-heatmap-color-steps-gradient")}if((changed.has("data")||changed.has("domain")||changed.has("midpoint")||!this.hasUpdated)&&(this.cachedValueRange=this.computeValueRange()),(collectionChanged||!this.hasUpdated)&&this.rebuildAccessiblePositions(),(collectionChanged||accessibleModeChanged||changed.has("multiple"))&&(this.cancelSelectionGesture(),this.selectionAnchor=null,this.selectionRangeBase=void 0,this.proposedSelectionKeys=void 0),(collectionChanged||changed.has("selectedCells")||changed.has("multiple")||!this.hasUpdated)&&(this.rebuildSelectedPositions(),changed.has("selectedCells")&&this.selectionGesture&&this.cancelSelectionGesture(),changed.has("selectedCells")&&this.selectionRangeBase&&(this.proposedSelectionKeys?.size!==this.selectedPositions.size||[...this.selectedPositions.keys()].some(key=>!this.proposedSelectionKeys?.has(key)))&&(this.selectionAnchor=this.focusedCell,this.selectionRangeBase=void 0)),accessibleFocusSnapshot){const positions=this.accessibleCellPositions(),target=(accessibleFocusSnapshot.identity==null?void 0:positions.find(pos=>this.accessibleCellIdentity(pos)===accessibleFocusSnapshot.identity))??positions[Math.min(Math.max(accessibleFocusSnapshot.index,0),positions.length-1)]??null;this.focusedCell=target,this.liveText=target?this.resolveCellText(target):"",this.pendingAccessibleFocus=target??"base",this.pendingAccessibleFocusOrigin=activeAccessibleCell??void 0,this.restoringAccessibleFocus=!0,this.accessibleFocusGeneration++}if(accessibleModeChanged){const previouslyAccessible=changed.get("accessibleCells")===!0;if(previouslyAccessible&&!this.accessibleCells&&activeAccessibleCell){const key=activeAccessibleCell.dataset.cellKey,target=key?this.accessibleCellAtKey(key):null;target&&(this.focusedCell=target,this.liveText=this.resolveCellText(target)),this.pendingAccessibleFocus="canvas",this.pendingAccessibleFocusOrigin=activeAccessibleCell,this.restoringAccessibleFocus=!0,this.accessibleFocusGeneration++}else if(!previouslyAccessible&&this.accessibleCells&&activeRenderedControl?.matches('[part="canvas"]')){const positions=this.accessibleCellPositions(),target=this.focusedCell?positions.find(pos=>this.samePos(pos,this.focusedCell))??positions[0]??null:positions[0]??null;this.focusedCell=target,this.liveText=target?this.resolveCellText(target):"",this.pendingAccessibleFocus=target??"base",this.pendingAccessibleFocusOrigin=activeRenderedControl,this.restoringAccessibleFocus=!0,this.accessibleFocusGeneration++}}const bounds=this.cachedValueRange,range=bounds?`${this.formatNumericValue(bounds[0])}–${this.formatNumericValue(bounds[1])}`:this.localize("heatmapNoDataValue"),valueLabel=this.localizedValueLabel();let label;if(this.effectiveMode==="calendar")label=this.localize("heatmapCalendarLabel",void 0,{days:this.formatCount(this.cachedCalendarGrid.cells.length),label:valueLabel,range});else{const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;label=this.localize("heatmapMatrixLabel",void 0,{rows:this.formatCount(rows),cols:this.formatCount(cols),label:valueLabel,range})}const selectedText=this.selectedCellDescription(),generatedAriaLabel=[label,selectedText,this.projectionDescription()].filter(Boolean).join(" ");this.generatedAriaLabel=generatedAriaLabel,this.syncingGeneratedSemantics=!0;try{this.authorRole===null&&this.getAttribute("role")!=="group"&&this.setAttribute("role","group"),this.authorAriaLabel===null&&this.getAttribute("aria-label")!==generatedAriaLabel&&this.setAttribute("aria-label",generatedAriaLabel)}finally{this.syncingGeneratedSemantics=!1}}rebuildBoundedDecorations(){this.cachedAnnotations=this.annotations.slice(0,MAX_HEATMAP_DECORATIONS).map(entry=>({...entry})),this.cachedLegendStops=(this.legendStops??[]).slice(0,MAX_HEATMAP_DECORATIONS).map(entry=>({...entry})),this.cachedColorSteps=(this.colorSteps??[]).slice(0,MAX_HEATMAP_DECORATIONS),this.warnOnLegendRampMismatch(),this.cachedCalendarAnnotationDates=new Set(this.cachedAnnotations.flatMap(annotation=>annotation.date==null?[]:[annotation.date])),this.cachedMatrixAnnotationPositions=new Set(this.cachedAnnotations.flatMap(annotation=>annotation.row==null||annotation.col==null?[]:[`${annotation.row}:${annotation.col}`])),this.decorationProjectionTruncated=this.annotations.length>MAX_HEATMAP_DECORATIONS||(this.legendStops?.length??0)>MAX_HEATMAP_DECORATIONS||(this.colorSteps?.length??0)>MAX_HEATMAP_DECORATIONS}get projectionTruncated(){return this.decorationProjectionTruncated||(this.effectiveMode==="calendar"?this.cachedCalendarGrid.truncated:this.cachedMatrixData.truncated)}get cellProjectionTruncated(){return this.effectiveMode==="calendar"?this.cachedCalendarGrid.truncated:this.cachedMatrixData.truncated}projectedCellCount(){return this.effectiveMode==="calendar"?this.cachedCalendarGrid.weekCount*7:this.matrixRowLabels.length*this.matrixColLabels.length}projectionDescription(){const messages=[];return this.cellProjectionTruncated&&messages.push(this.localize("heatmapProjectionLimit",void 0,{count:this.formatCount(this.projectedCellCount())})),this.decorationProjectionTruncated&&messages.push(this.localize("heatmapDecorationLimit",void 0,{count:this.formatCount(MAX_HEATMAP_DECORATIONS)})),messages.join(" ")}rebuildCanonicalMatrixData(){if(this.data.kind!=="matrix"){this.cachedMatrixData={rowLabels:[],colLabels:[],values:[],truncated:!1};return}const colCount=Math.min(this.data.colLabels.length,MAX_HEATMAP_CELLS),rowLimit=colCount===0?Math.min(this.data.rowLabels.length,MAX_HEATMAP_CELLS):Math.floor(MAX_HEATMAP_CELLS/colCount),rowCount=Math.min(this.data.rowLabels.length,rowLimit),rowLabels=this.data.rowLabels.slice(0,rowCount).map(String),colLabels=this.data.colLabels.slice(0,colCount).map(String),source=this.data,values=Array.from({length:rowCount},(_,row)=>Array.from({length:colCount},(_2,col)=>source.values[row]?.[col]??(this.signedDomain?Number.NaN:-1)));this.cachedMatrixData={rowLabels,colLabels,values,truncated:rowCount!==this.data.rowLabels.length||colCount!==this.data.colLabels.length||this.data.values.some((row,index)=>index>=rowCount||row.length>colCount)}}selectedCellDescription(){if(this.multiple){const count=this.currentSelectedPositions.size;return count?this.localize("heatmapSelectedCount",void 0,{count:this.formatCount(count)}):""}if(!this.selectedCell)return"";if(this.effectiveMode==="calendar"){if(this.selectedCell.date==null)return"";const match=this.cachedCalendarCellsByDate.get(this.selectedCell.date);return match?this.localize("heatmapSelectedCellLabel",void 0,{cell:this.calendarCellText({week:match.week,weekday:match.weekday,date:match.date})}):""}const{row,col}=this.selectedCell;return row==null||col==null||row<0||row>=this.matrixRowLabels.length||col<0||col>=this.matrixColLabels.length?"":this.localize("heatmapSelectedCellLabel",void 0,{cell:this.matrixCellText({row,col})})}computeValueRange(){const pinned=this.domain;if(pinned){const[lo,hi]=pinned;if(Number.isFinite(lo)&&Number.isFinite(hi)&&lo!==hi)return lo<hi?[lo,hi]:[hi,lo]}const source=this.effectiveMode==="calendar"?this.cachedCalendarGrid.cells.map(cell=>cell.value):this.matrixValues.flat();return minMax(source.filter(v=>!this.isNoData(v)))}localizedValueLabel(){return this.valueLabel===void 0?this.localize("heatmapValueLabel"):this.valueLabel}formatNumericValue(value){return getNumberFormat(this.effectiveLocale||void 0).format(value)}syncExternalDescription(){const describedBy=this.getAttribute("aria-describedby");if(!describedBy&&!this.hasSyncedDescribedByElements)return;const control=this.accessibleCells?this.renderRoot.querySelector('[part="cells"]'):this.canvas;this.hasSyncedDescribedByElements=syncAriaDescribedByElements(this,control??void 0,describedBy)}updated(changed){if(super.updated(changed),this.syncExternalDescription(),this.hoverCell&&this.effectiveStickyLabels!=="none"&&this.scheduleAfterUpdate(()=>this.measureTooltip(),"heatmap-tooltip-metrics"),["data","cellSize","rowHeight","cellGapX","cellGapY","cellRadius","colLabelInterval","maxCellSize","minCellSize","valueLabel","scale","domain","midpoint","fitToWidth","rowLabelWidth","colLabelHeight","colLabelRotation","bucketCount","annotations","focusedCell","colorSteps","cellColor","selectedCell","selectedCells","multiple","selectionPreview","legendStops","accessibleCells","accessibleTargetSizePx","locale","stickyLabels"].some(name=>changed.has(name))){if(changed.has("focusedCell")&&[...changed.keys()].every(key=>key==="focusedCell"||key==="liveText")&&this.repaintFocusRing(changed.get("focusedCell")))return;this.requestDraw()}const pending=this.pendingAccessibleFocus;if(pending===void 0)return;this.pendingAccessibleFocus=void 0;const origin=this.pendingAccessibleFocusOrigin;this.pendingAccessibleFocusOrigin=void 0;const generation=this.accessibleFocusGeneration;this.scheduleAfterUpdate(()=>{try{if(generation!==this.accessibleFocusGeneration||!this.isConnected)return;if(origin){const internalActive=shadowFocusTarget(this),documentActive=activeElementIn(this.ownerDocument),focusStayedAtOrigin=internalActive===origin,originWasRemovedWithoutReplacement=internalActive===null&&(documentActive===null||documentActive===this||documentActive===this.ownerDocument.body);if(!focusStayedAtOrigin&&!originWasRemovedWithoutReplacement)return}if(pending==="base"){this.shadowRoot?.querySelector('[part="base"]')?.focus();return}if(pending==="canvas"){this.shadowRoot?.querySelector('[part="canvas"]')?.focus();return}const identity=this.accessibleCellIdentity(pending);[...this.shadowRoot?.querySelectorAll('[part="cell"]')??[]].find(candidate=>candidate.dataset.cellIdentity===identity)?.focus()}finally{this.restoringAccessibleFocus=!1}},"heatmap-accessible-focus")}refreshTheme(){this.cachedRamp=null,this.refreshAccessibleTargetSize()||this.requestDraw()}themeSignature(){const cs=this.ownerDocument.defaultView?.getComputedStyle(this);return cs?[...this.scaleEndpoints(cs),this.noDataFill(cs),this.labelColor(cs),this.labelFont(cs),this.focusRingColor(cs),this.annotationColor(cs),this.selectedColor(cs),this.stickyLabelBg(cs),...this.cachedColorSteps.map(step=>this.resolveColorStep(step,""))].join("\0"):""}onThemeSignal(){const signature=this.themeSignature(),resized=this.refreshAccessibleTargetSize();signature===this.paintedTheme&&!this.cellColor||(this.paintedTheme=signature,this.cachedRamp=null,resized||this.scheduleDraw())}refreshAccessibleTargetSize(){const raw=this.ownerDocument.defaultView?.getComputedStyle(this).getPropertyValue("--lr-icon-button-size").trim()??"",resolved=resolveCssTokenLength(raw,{host:this}),next=resolved!==void 0&&Number.isFinite(resolved)&&resolved>0?resolved:DEFAULT_ACCESSIBLE_TARGET_SIZE_PX;return next===this.accessibleTargetSizePx?!1:(this.accessibleTargetSizePx=next,!0)}scaleEndpoints(cs){const lo=cs.getPropertyValue("--lr-heatmap-scale-lo").trim()||cs.getPropertyValue("--_lr-heatmap-scale-lo").trim()||FALLBACK_SCALE_LO,hi=cs.getPropertyValue("--lr-heatmap-scale-hi").trim()||cs.getPropertyValue("--_lr-heatmap-scale-hi").trim()||FALLBACK_SCALE_HI;return[lo,hi]}labelColor(cs){return cs.getPropertyValue("--lr-color-text-quiet").trim()||"#6b7280"}labelFont(cs){return cs.getPropertyValue("--lr-heatmap-label-font").trim()||cs.getPropertyValue("--_lr-heatmap-label-font").trim()||FALLBACK_LABEL_FONT}stickyLabelBg(cs){const raw=cs.getPropertyValue("--lr-heatmap-sticky-label-bg").trim()||cs.getPropertyValue("--_lr-heatmap-sticky-label-bg").trim()||FALLBACK_STICKY_LABEL_BG;return formatRgb(resolveRgb(raw,FALLBACK_STICKY_LABEL_BG,this.ownerDocument))}noDataFill(cs){return cs.getPropertyValue("--lr-heatmap-no-data-fill").trim()||cs.getPropertyValue("--_lr-heatmap-no-data-fill").trim()||FALLBACK_NO_DATA_FILL}focusRingColor(cs){return cs.getPropertyValue("--lr-heatmap-focus-ring-color").trim()||cs.getPropertyValue("--_lr-heatmap-focus-ring-color").trim()||FALLBACK_FOCUS_RING_COLOR}annotationColor(cs){return cs.getPropertyValue("--lr-heatmap-annotation-color").trim()||cs.getPropertyValue("--_lr-heatmap-annotation-color").trim()||FALLBACK_ANNOTATION_COLOR}selectedColor(cs){return cs.getPropertyValue("--lr-heatmap-selected-color").trim()||cs.getPropertyValue("--_lr-heatmap-selected-color").trim()||FALLBACK_SELECTED_COLOR}strokeCellState(ctx,x,y,size,state2,color,paintedShape){const shape=paintedShape??(this.effectiveMode==="matrix"?this.matrixCellShape(size):this.calendarCellShape(size)),width=shape?.custom?shape.w:size,height=shape?.custom?shape.h:size;shape?.custom&&(ctx.save(),ctx.beginPath(),ctx.roundRect(x,y,shape.w,shape.h,shape.radius),ctx.clip());const inset=Math.min(state2==="annotation"?.5:state2==="selected"?3.5:6.5,Math.max(.5,(Math.min(width,height)-RING_LINE_WIDTH-1)/2)),w=Math.max(1,width-inset*2),h=Math.max(1,height-inset*2);ctx.lineWidth=RING_LINE_WIDTH,ctx.strokeStyle=color,ctx.setLineDash?.(state2==="annotation"?[]:state2==="selected"?[4,2]:[1,2]),shape?.custom&&shape.radius>0?(ctx.beginPath(),ctx.roundRect(x+inset,y+inset,w,h,Math.max(0,shape.radius-inset)),ctx.stroke()):ctx.strokeRect(x+inset,y+inset,w,h),ctx.setLineDash?.([]),shape?.custom&&ctx.restore()}isSelectedPos(pos){return this.multiple?this.currentSelectedPositions.has(this.accessibleCellKey(pos)):this.selectedCell?"week"in pos?this.selectedCell.date==null?!1:this.calendarCellAt(pos).date===this.selectedCell.date:this.selectedCell.row===pos.row&&this.selectedCell.col===pos.col:!1}draw(){if(!this.canvasVisible){this.drawDirty=!0;return}this.syncDeferredFitFrame(!1),this.drawDirty=!1,this.canvasHasContent=!1,this.paintedTheme??=this.themeSignature(),this.effectiveMode==="calendar"?this.drawCalendar():this.drawMatrix()}requestDraw(){this.drawDirty=!0,this.canvasVisible?this.draw():this.syncDeferredFitFrame(!0)}syncDeferredFitFrame(deferred){const base=this.shadowRoot?.querySelector('[part="base"]');if(!base)return;let contained=!1;deferred&&this.fitToWidth&&this.clientWidth>0&&(contained=(this.effectiveMode==="calendar"?this.columnXFor(Math.max(1,this.cachedCalendarGrid.weekCount)):this.matrixPadLeft+this.matrixColLabels.length*this.matrixCellSize(this.matrixColLabels.length))<=this.clientWidth),base.toggleAttribute("data-fit-frame-contained",contained)}repaintFocusRing(previous){if(!this.canvasHasContent||!this.canvas||this.drawDirty)return!1;const current=this.focusedCell;if(this.effectiveMode==="calendar"){if(previous&&!("week"in previous)||current&&!("week"in current))return!1;this.repaintCalendarFocusCell(previous&&"week"in previous?previous:null),current&&(!previous||!this.samePos(previous,current))&&this.repaintCalendarFocusCell(current)}else{if(previous&&!("row"in previous)||current&&!("row"in current))return!1;this.repaintMatrixFocusCell(previous&&"row"in previous?previous:null),current&&(!previous||!this.samePos(previous,current))&&this.repaintMatrixFocusCell(current)}return!0}cancelDrawFrame(){const request=this.drawFrameRequest;request&&request.owner.cancelAnimationFrame(request.handle),this.drawFrameRequest=void 0}resolveColorStep(color,fallback){const safe=sanitizeCssColor(color);return safe?resolveCanvasColor(this,safe,fallback):fallback}colorRamp(bucketCount,cs){const steps=this.cachedColorSteps;if(steps&&steps.length>=2){const key2=`steps ${steps.join(" ")}`;if(this.cachedRamp?.key===key2)return this.cachedRamp;const resolved=steps.map((color,index)=>this.resolveColorStep(color,index===steps.length-1?FALLBACK_SCALE_HI:FALLBACK_SCALE_LO)),colors2=resolved.map(color=>formatRgb(resolveRgb(color,FALLBACK_SCALE_LO,this.ownerDocument))),loRgb2=resolveRgb(resolved[0],FALLBACK_SCALE_LO,this.ownerDocument),hiRgb2=resolveRgb(resolved[resolved.length-1],FALLBACK_SCALE_HI,this.ownerDocument);return this.cachedRamp={key:key2,colors:colors2,loRgb:loRgb2,hiRgb:hiRgb2},this.cachedRamp}const[scaleLo,scaleHi]=this.scaleEndpoints(cs),normalizedBucketCount=normalizeBucketCount(bucketCount),key=`${scaleLo}\0${scaleHi}\0${normalizedBucketCount}`;if(this.cachedRamp?.key===key)return this.cachedRamp;const loRgb=resolveRgb(scaleLo,FALLBACK_SCALE_LO,this.ownerDocument),hiRgb=resolveRgb(scaleHi,FALLBACK_SCALE_HI,this.ownerDocument),colors=Array.from({length:normalizedBucketCount},(_,i)=>mixRgb(loRgb,hiRgb,i/(normalizedBucketCount-1)));return this.cachedRamp={key,colors,loRgb,hiRgb},this.cachedRamp}calendarCellSize(){return this.calendarSpacing().cellSize}calendarSpacing(){const{weekCount}=this.cachedCalendarGrid,rawGapX=this.explicitCalendarSpacing("cellGapX"),rawGapY=this.explicitCalendarSpacing("cellGapY"),rawRadius=this.explicitCalendarSpacing("cellRadius"),boundGap=(raw,size2)=>raw===void 0?CAL_GAP:finiteRange(raw,CAL_GAP,0,Math.max(0,size2-1));let size;if(this.fitToWidth&&weekCount>0){const fitGap=boundGap(rawGapX,this.cellSize),hostWidth=this.clientWidth||this.calendarPadLeft+weekCount*(this.cellSize+fitGap);size=this.clampFitCellSize((hostWidth-this.calendarPadLeft)/weekCount-fitGap)}else size=this.cellSize;return this.accessibleCells&&(size=Math.max(size,this.accessibleTargetSizePx)),{cellSize:size,gapX:boundGap(rawGapX,size),gapY:boundGap(rawGapY,size),radius:rawRadius===void 0?0:finiteRange(rawRadius,0,0,size/2)}}clampFitCellSize(size){const floored=finiteRange(size,FIT_MIN_CELL,Math.max(FIT_MIN_CELL,this.minCellSize??FIT_MIN_CELL));return this.maxCellSize==null?floored:Math.min(floored,this.maxCellSize)}columnXFor(week){return this.calendarColumnPositions()[week]??this.calendarPadLeft}rowYFor(weekday){return this.calendarRowPositions()[weekday]??CAL_LABEL_H}calendarColumnPositions(){const{cellSize,gapX:gap}=this.calendarSpacing(),weekCount=this.cachedCalendarGrid.weekCount,callback=this.calendarColumnX,padLeft=this.calendarPadLeft,cached=this.cachedColumnGeometry;if(cached!==void 0&&cached.callback===callback&&cached.padLeft===padLeft&&cached.cellSize===cellSize&&cached.gap===gap&&cached.weekCount===weekCount)return cached.positions;const positions=[];for(let index=0;index<=weekCount;index++){const fallback=index===0?padLeft:positions[index-1]+cellSize+gap;let candidate=fallback;if(callback)try{const supplied=callback(index);Number.isFinite(supplied)&&supplied>=0&&(index===0||supplied>=positions[index-1]+cellSize)&&(candidate=supplied)}catch{candidate=fallback}positions.push(candidate)}return this.cachedColumnGeometry={callback,padLeft,cellSize,gap,weekCount,positions},positions}calendarRowPositions(){const{cellSize,gapY:gap}=this.calendarSpacing(),callback=this.calendarRowY,cached=this.cachedRowGeometry;if(cached!==void 0&&cached.callback===callback&&cached.cellSize===cellSize&&cached.gap===gap)return cached.positions;const positions=[];for(let index=0;index<=7;index++){const fallback=index===0?CAL_LABEL_H:positions[index-1]+cellSize+gap;let candidate=fallback;if(callback)try{const supplied=callback(index);Number.isFinite(supplied)&&supplied>=0&&(index===0||supplied>=positions[index-1]+cellSize)&&(candidate=supplied)}catch{candidate=fallback}positions.push(candidate)}return this.cachedRowGeometry={callback,cellSize,gap,positions},positions}weekdayLabels(firstWeekStart){const formatter=getDateTimeFormat(this.effectiveLocale||void 0,{weekday:"short",timeZone:"UTC"}),labels=["","","","","","",""];for(const weekday of[1,3,5]){const row=(weekday-this.normalizedFirstDayOfWeek+7)%7;labels[row]=this.calendarWeekdayLabelText?.(weekday)??formatter.format(new Date(firstWeekStart.getTime()+row*MS_PER_DAY))}return labels}paintCalendarAxisLabels(ctx,cellSize,cs,firstWeekStart,monthLabels,months=!0,weekdays=!0){if(ctx.fillStyle=this.labelColor(cs),ctx.font=this.labelFont(cs),months){const canvasRight=this.columnXFor(Math.max(1,this.cachedCalendarGrid.weekCount)),placed=[];monthLabels.forEach((month,index)=>{const label=this.ellipsize(ctx,month.label,canvasRight);if(!label)return;const width=ctx.measureText(label).width,x=Math.max(0,Math.min(this.columnXFor(month.week),canvasRight-width)),nextWeek=monthLabels[index+1]?.week??Math.max(month.week+1,this.cachedCalendarGrid.weekCount),entry={label,x,end:x+width+CAL_MONTH_LABEL_GAP,span:nextWeek-month.week};let previous=placed[placed.length-1];for(;previous&&entry.x<previous.end&&entry.span>previous.span;)placed.pop(),previous=placed[placed.length-1];previous&&entry.x<previous.end||placed.push(entry)});for(const{label,x}of placed)ctx.fillText(label,x,CAL_LABEL_H-4)}if(weekdays){const available=this.calendarPadLeft-CAL_WEEKDAY_LABEL_INSET*2;this.weekdayLabels(firstWeekStart).forEach((label,weekday)=>{const shown=label?this.ellipsize(ctx,label,available):"";shown&&ctx.fillText(shown,CAL_WEEKDAY_LABEL_INSET,this.rowYFor(weekday)+cellSize-1)})}}drawCalendar(){if(!this.canvas)return;const{weekCount,firstWeekStart,monthLabels}=this.cachedCalendarGrid,cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;this.calendarWeekdayLabelWidth==="auto"&&(this.resolvedCalendarWeekdayLabelWidth=this.measureCalendarWeekdayLabelWidth(cs,firstWeekStart));const spacing=this.calendarSpacing(),cellSize=spacing.cellSize,w=this.columnXFor(Math.max(1,weekCount)),h=this.rowYFor(7),ctx=this.sizeCanvas(this.canvas,w,h);if(!ctx)return;ctx.clearRect(0,0,w,h);const buckets=normalizeBucketCount(this.bucketCount),ramp=this.colorRamp(buckets,cs).colors,noDataFill=this.noDataFill(cs);this.canvasColorCache.clear();const bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1;for(let week=0;week<weekCount;week++)for(let weekday=0;weekday<7;weekday++){const value=this.calendarValueAt(week,weekday),x=this.columnXFor(week),y=this.rowYFor(weekday),override=this.cellColor?.(this.calendarPos(week,weekday),value);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(value))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(value,hi,ramp.length);ctx.fillStyle=step<0?noDataFill:ramp[step]}else if(this.cachedColorSteps.length>=2){const step=this.rampBucket(value,lo,hi,ramp.length);ctx.fillStyle=ramp[step]}else ctx.fillStyle=ramp[quartileBucket(value,this.cachedCalendarSortedValues,buckets)];this.fillCalendarCell(ctx,x,y,cellSize,spacing.radius)}if(this.cachedAnnotations.length)for(const ann of this.cachedAnnotations){if(ann.date==null)continue;const match=this.cachedCalendarCellsByDate.get(ann.date);if(!match)continue;const x=this.columnXFor(match.week),y=this.rowYFor(match.weekday);this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs))}for(const match of this.selectedPaintPositions())if("week"in match){const x=this.columnXFor(match.week),y=this.rowYFor(match.weekday);this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs))}if(this.focusedCell&&"week"in this.focusedCell){const{week,weekday}=this.focusedCell;if(week<weekCount&&weekday<7){const x=this.columnXFor(week),y=this.rowYFor(weekday);this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs))}}this.paintCalendarAxisLabels(ctx,cellSize,cs,firstWeekStart,monthLabels),this.canvasHasContent=!0,this.recordCalendarGeometry(spacing,weekCount)&&this.accessibleCells&&this.scheduleAfterUpdate(()=>this.requestUpdate(),"heatmap-calendar-accessible-geometry")}matrixCellSize(cols){let size;if(this.fitToWidth&&cols>0){const padLeft=this.matrixPadLeft,hostWidth=this.clientWidth||padLeft+cols*this.cellSize;size=this.clampFitCellSize((hostWidth-padLeft)/cols)}else size=this.cellSize;if(!this.accessibleCells)return size;const target=this.accessibleTargetSizePx,custom=finiteNumber(this.cellGapX,1)!==1||finiteNumber(this.cellGapY,1)!==1||finiteRange(this.cellRadius,0,0)>0,gap=this.rowHeight!==void 0?finiteRange(this.cellGapX,1,0,target):custom?Math.max(finiteRange(this.cellGapX,1,0,target),finiteRange(this.cellGapY,1,0,target)):0;return Math.max(size,target+gap)}matrixRowHeight(cellSize){if(this.rowHeight===void 0)return cellSize;const height=finiteRange(this.rowHeight,cellSize,1);if(!this.accessibleCells)return height;const target=this.accessibleTargetSizePx;return Math.max(height,target+finiteRange(this.cellGapY,1,0,target))}matrixCellShape(size,height=this.matrixRowHeight(size)){if(height===size&&finiteNumber(this.cellGapX,1)===1&&finiteNumber(this.cellGapY,1)===1&&finiteRange(this.cellRadius,0,0)===0)return{w:size-1,h:size-1,radius:0,custom:!1};const target=this.accessibleCells?this.accessibleTargetSizePx:1,w=size-finiteRange(this.cellGapX,1,0,Math.max(0,size-Math.min(size,target))),h=height-finiteRange(this.cellGapY,1,0,Math.max(0,height-Math.min(height,target))),radius=finiteRange(this.cellRadius,0,0,Math.min(w,h)/2);return{w,h,radius,custom:height!==size||w!==size-1||h!==size-1||radius!==0}}calendarCellShape(size){const radius=this.calendarSpacing().radius;return radius>0?{w:size,h:size,radius:Math.min(radius,size/2),custom:!0}:void 0}fillMatrixCell(ctx,x,y,shape){shape.radius===0?ctx.fillRect(x,y,shape.w,shape.h):(ctx.beginPath(),ctx.roundRect(x,y,shape.w,shape.h,shape.radius),ctx.fill())}paintMatrixCell(ctx,row,col,cellSize,rowHeight,shape,cs,rampData,noDataFill){const value=this.matrixValues[row]?.[col]??Number.NaN,bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1,override=this.cellColor?.({row,col},value);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(value))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(value,hi,rampData.colors.length);ctx.fillStyle=step<0?noDataFill:rampData.colors[step]}else this.cachedColorSteps.length>=2?ctx.fillStyle=rampData.colors[this.rampBucket(value,lo,hi,rampData.colors.length)]:ctx.fillStyle=mixRgb(rampData.loRgb,rampData.hiRgb,this.rampAlpha(value,lo,hi));this.fillMatrixCell(ctx,this.matrixPadLeft+col*cellSize,this.matrixPadTop+row*rowHeight,shape)}paintMatrixFocusOverlays(ctx,row,col,cellSize,rowHeight,shape,cs,state2){const x=this.matrixPadLeft+col*cellSize,y=this.matrixPadTop+row*rowHeight;state2==="annotation"&&this.cachedMatrixAnnotationPositions.has(`${row}:${col}`)&&this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs),shape),state2==="selected"&&this.isSelectedPos({row,col})&&this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs),shape),state2==="focus"&&this.focusedCell&&"row"in this.focusedCell&&this.focusedCell.row===row&&this.focusedCell.col===col&&this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs),shape)}focusRepaintBounds(ctx,x,y,cellSize,cellHeight=cellSize){const padding=RING_LINE_WIDTH+1,dpr=ctx.getTransform().a,left=Math.floor((x-padding)*dpr)/dpr,top=Math.floor((y-padding)*dpr)/dpr,right=Math.ceil((x+cellSize+padding)*dpr)/dpr,bottom=Math.ceil((y+cellHeight+padding)*dpr)/dpr;return{left,top,width:right-left,height:bottom-top,radius:Math.ceil((2*padding+1/dpr)/cellSize),rowRadius:Math.ceil((2*padding+1/dpr)/cellHeight)}}repaintMatrixFocusCell(pos){if(!pos||!this.canvas)return;const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;if(pos.row<0||pos.row>=rows||pos.col<0||pos.col>=cols)return;const cellSize=this.matrixCellSize(cols),rowHeight=this.matrixRowHeight(cellSize),shape=this.matrixCellShape(cellSize,rowHeight),x=this.matrixPadLeft+pos.col*cellSize,y=this.matrixPadTop+pos.row*rowHeight,ctx=this.canvas.getContext("2d");if(!ctx)return;const cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;const{left,top,width,height,radius,rowRadius}=this.focusRepaintBounds(ctx,x,y,cellSize,rowHeight),firstRow=Math.max(0,pos.row-rowRadius),lastRow=Math.min(rows-1,pos.row+rowRadius),firstCol=Math.max(0,pos.col-radius),lastCol=Math.min(cols-1,pos.col+radius),ramp=this.colorRamp(RAMP_STEPS,cs),noData=this.noDataFill(cs),scratch=rowHeight===cellSize?void 0:this.ownerDocument.createElement("canvas"),dpr=ctx.getTransform().a,scratchLeft=Math.floor((this.matrixPadLeft+firstCol*cellSize-RING_LINE_WIDTH-1)*dpr)/dpr,scratchTop=Math.floor((this.matrixPadTop+firstRow*rowHeight-RING_LINE_WIDTH-1)*dpr)/dpr;if(scratch){const right=Math.ceil((this.matrixPadLeft+(lastCol+1)*cellSize+RING_LINE_WIDTH+1)*dpr),bottom=Math.ceil((this.matrixPadTop+(lastRow+1)*rowHeight+RING_LINE_WIDTH+1)*dpr);scratch.width=right-Math.round(scratchLeft*dpr),scratch.height=bottom-Math.round(scratchTop*dpr)}const paintCtx=scratch?.getContext("2d")??ctx;if(scratch&&paintCtx===ctx){this.drawMatrix();return}paintCtx.save();try{scratch?paintCtx.setTransform(dpr,0,0,dpr,-scratchLeft*dpr,-scratchTop*dpr):(paintCtx.beginPath(),paintCtx.rect(left,top,width,height),paintCtx.clip(),paintCtx.clearRect(left,top,width,height));for(let row=firstRow;row<=lastRow;row++)for(let col=firstCol;col<=lastCol;col++)this.paintMatrixCell(paintCtx,row,col,cellSize,rowHeight,shape,cs,ramp,noData);for(const state2 of["annotation","selected","focus"])for(let row=firstRow;row<=lastRow;row++)for(let col=firstCol;col<=lastCol;col++)this.paintMatrixFocusOverlays(paintCtx,row,col,cellSize,rowHeight,shape,cs,state2);left<this.matrixPadLeft&&this.paintMatrixRowLabels(paintCtx,this.matrixPadLeft,this.matrixPadTop,rowHeight,cs,{top,bottom:top+height}),top<this.matrixPadTop&&this.paintMatrixColLabels(paintCtx,this.matrixPadLeft,this.matrixPadTop,cellSize,cs,{first:firstCol,last:lastCol})}finally{paintCtx.restore()}if(scratch){ctx.save();try{ctx.setTransform(1,0,0,1,0,0),ctx.clearRect(left*dpr,top*dpr,width*dpr,height*dpr),ctx.drawImage(scratch,Math.round((left-scratchLeft)*dpr),Math.round((top-scratchTop)*dpr),Math.round(width*dpr),Math.round(height*dpr),Math.round(left*dpr),Math.round(top*dpr),Math.round(width*dpr),Math.round(height*dpr))}finally{ctx.restore()}}}paintCalendarCell(ctx,week,weekday,cellSize,cs,ramp,noDataFill){const value=this.calendarValueAt(week,weekday),bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1,override=this.cellColor?.(this.calendarPos(week,weekday),value);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(value))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(value,hi,ramp.length);ctx.fillStyle=step<0?noDataFill:ramp[step]}else this.cachedColorSteps.length>=2?ctx.fillStyle=ramp[this.rampBucket(value,lo,hi,ramp.length)]:ctx.fillStyle=ramp[quartileBucket(value,this.cachedCalendarSortedValues,ramp.length)];this.fillCalendarCell(ctx,this.columnXFor(week),this.rowYFor(weekday),cellSize,this.calendarSpacing().radius)}fillCalendarCell(ctx,x,y,size,radius){radius===0?ctx.fillRect(x,y,size,size):(ctx.beginPath(),ctx.roundRect(x,y,size,size,radius),ctx.fill())}recordCalendarGeometry(spacing,weekCount){const next={padLeft:this.calendarPadLeft,padTop:CAL_LABEL_H,cellSize:spacing.cellSize,cellWidth:spacing.cellSize,cellHeight:spacing.cellSize,cellGapX:spacing.gapX,cellGapY:spacing.gapY,cellRadius:spacing.radius,weekCount,firstDayOfWeek:this.normalizedFirstDayOfWeek},previous=this.lastPaintedCalendarGeometry;if(previous&&Object.keys(next).every(key=>previous[key]===next[key]))return!1;const frozen=Object.freeze(next);return this.lastPaintedCalendarGeometry=frozen,this.emit("lr-calendar-geometry-change",frozen),!0}paintCalendarFocusOverlays(ctx,week,weekday,cellSize,cs,state2){const date=this.calendarDateAt(week,weekday),x=this.columnXFor(week),y=this.rowYFor(weekday);state2==="annotation"&&this.cachedCalendarCellsByDate.has(date)&&this.cachedCalendarAnnotationDates.has(date)&&this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs)),state2==="selected"&&(this.multiple||this.cachedCalendarCellsByDate.has(date))&&this.isSelectedPos({week,weekday,date})&&this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs)),state2==="focus"&&this.focusedCell&&"week"in this.focusedCell&&this.focusedCell.week===week&&this.focusedCell.weekday===weekday&&this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs))}repaintCalendarFocusCell(pos){if(!pos||!this.canvas)return;const{weekCount,firstWeekStart}=this.cachedCalendarGrid;if(pos.week<0||pos.week>=weekCount||pos.weekday<0||pos.weekday>=7)return;const cellSize=this.calendarCellSize(),x=this.columnXFor(pos.week),y=this.rowYFor(pos.weekday),ctx=this.canvas.getContext("2d");if(!ctx)return;const cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;const{left,top,width,height,radius}=this.focusRepaintBounds(ctx,x,y,cellSize),firstWeek=Math.max(0,pos.week-radius),lastWeek=Math.min(weekCount-1,pos.week+radius),firstDay=Math.max(0,pos.weekday-radius),lastDay=Math.min(6,pos.weekday+radius),ramp=this.colorRamp(normalizeBucketCount(this.bucketCount),cs).colors,noData=this.noDataFill(cs);ctx.save();try{ctx.beginPath(),ctx.rect(left,top,width,height),ctx.clip(),ctx.clearRect(left,top,width,height);for(let week=firstWeek;week<=lastWeek;week++)for(let day=firstDay;day<=lastDay;day++)this.paintCalendarCell(ctx,week,day,cellSize,cs,ramp,noData);for(const state2 of["annotation","selected","focus"])for(let week=firstWeek;week<=lastWeek;week++)for(let day=firstDay;day<=lastDay;day++)this.paintCalendarFocusOverlays(ctx,week,day,cellSize,cs,state2);this.paintCalendarAxisLabels(ctx,cellSize,cs,firstWeekStart,this.cachedCalendarGrid.monthLabels,top<CAL_LABEL_H,left<this.calendarPadLeft)}finally{ctx.restore()}}drawMatrix(){if(!this.canvas)return;const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length,cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;this.rowLabelWidth==="auto"&&(this.resolvedRowLabelWidth=this.measureRowLabelWidth(cs)),this.colLabelHeight==="auto"&&(this.resolvedColLabelHeight=this.measureColLabelHeight(cs));const padLeft=this.matrixPadLeft,padTop=this.matrixPadTop,cellSize=this.matrixCellSize(cols),rowHeight=this.matrixRowHeight(cellSize),shape=this.matrixCellShape(cellSize,rowHeight),dimensions=shape.custom?{cellWidth:shape.w,cellHeight:shape.h,cellRadius:shape.radius}:{},previous=this.lastPaintedMatrixGeometry,geometry=previous&&previous.padLeft===padLeft&&previous.padTop===padTop&&previous.cellSize===cellSize&&previous.rowHeight===(rowHeight===cellSize?void 0:rowHeight)&&previous.cellWidth===dimensions.cellWidth&&previous.cellHeight===dimensions.cellHeight&&previous.cellRadius===dimensions.cellRadius?previous:Object.freeze({padLeft,padTop,cellSize,...rowHeight===cellSize?{}:{rowHeight},...dimensions});this.lastPaintedMatrixGeometry=geometry;const geometryChanged=geometry!==previous;geometryChanged&&this.emit("lr-matrix-geometry-change",geometry);const w=padLeft+cols*cellSize,h=padTop+rows*rowHeight,ctx=this.sizeCanvas(this.canvas,w,h);if(!ctx)return;ctx.clearRect(0,0,w,h);const bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1,rampData=this.colorRamp(RAMP_STEPS,cs),ramp=rampData.colors,{loRgb,hiRgb}=rampData,noDataFill=this.noDataFill(cs);this.canvasColorCache.clear();for(let r=0;r<rows;r++)for(let c=0;c<cols;c++){const v=this.matrixValues[r]?.[c]??Number.NaN,x=padLeft+c*cellSize,y=padTop+r*rowHeight,override=this.cellColor?.({row:r,col:c},v);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(v))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(v,hi,ramp.length);ctx.fillStyle=step<0?noDataFill:ramp[step]}else if(this.cachedColorSteps.length>=2){const step=this.rampBucket(v,lo,hi,ramp.length);ctx.fillStyle=ramp[step]}else{const t=this.rampAlpha(v,lo,hi);ctx.fillStyle=mixRgb(loRgb,hiRgb,t)}this.fillMatrixCell(ctx,x,y,shape)}if(this.cachedAnnotations.length)for(const ann of this.cachedAnnotations){if(ann.row==null||ann.col==null||ann.row<0||ann.row>=rows||ann.col<0||ann.col>=cols)continue;const x=padLeft+ann.col*cellSize,y=padTop+ann.row*rowHeight;this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs),shape)}for(const selected of this.selectedPaintPositions()){if(!("row"in selected))continue;const{row,col}=selected;if(row>=0&&row<rows&&col>=0&&col<cols){const x=padLeft+col*cellSize,y=padTop+row*rowHeight;this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs),shape)}}if(this.focusedCell&&"row"in this.focusedCell){const{row,col}=this.focusedCell;if(row<rows&&col<cols){const x=padLeft+col*cellSize,y=padTop+row*rowHeight;this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs),shape)}}this.paintMatrixRowLabels(ctx,padLeft,padTop,rowHeight,cs),this.paintMatrixColLabels(ctx,padLeft,padTop,cellSize,cs),this.paintFrozenLabelBands(padLeft,padTop,cellSize,rowHeight,w,h,ctx.getTransform().a,cs),this.canvasHasContent=!0,geometryChanged&&this.accessibleCells&&this.scheduleAfterUpdate(()=>this.requestUpdate(),"heatmap-matrix-accessible-geometry")}paintMatrixRowLabels(ctx,padLeft,padTop,cellSize,cs,dirty){ctx.fillStyle=this.labelColor(cs),ctx.font=this.labelFont(cs);const rowLabelSpace=padLeft-ROW_LABEL_INSET*2;let first=0,last=this.matrixRowLabels.length-1;if(dirty){const{fontBoundingBoxAscent,fontBoundingBoxDescent}=ctx.measureText("M"),baseline=padTop+cellSize/2+3;first=Math.max(first,Math.floor((dirty.top-fontBoundingBoxDescent-baseline)/cellSize)),last=Math.min(last,Math.ceil((dirty.bottom+fontBoundingBoxAscent-baseline)/cellSize))}for(let r=first;r<=last;r++){const shown=this.ellipsize(ctx,this.matrixRowLabels[r],rowLabelSpace);shown&&ctx.fillText(shown,ROW_LABEL_INSET,padTop+r*cellSize+cellSize/2+3)}}paintMatrixColLabels(ctx,padLeft,padTop,cellSize,cs,columns){ctx.fillStyle=this.labelColor(cs),ctx.font=this.labelFont(cs);const colRotation=this.effectiveColLabelRotation,interval=finiteInteger(this.colLabelInterval,1,1);if(colRotation===0){const cols=this.matrixColLabels.length;this.matrixColLabels.forEach((label,c)=>{if(c%interval!==0||columns&&(c<columns.first-interval+1||c>columns.last))return;const shown=this.ellipsize(ctx,label,Math.min(interval,cols-c)*cellSize-2);shown&&ctx.fillText(shown,padLeft+c*cellSize+2,padTop-COL_LABEL_INSET)});return}const radians=colRotation*Math.PI/180,previousAlign=ctx.textAlign;ctx.textAlign="right",this.matrixColLabels.forEach((label,c)=>{c%interval===0&&(ctx.save(),ctx.translate(padLeft+c*cellSize+cellSize/2,padTop-COL_LABEL_INSET),ctx.rotate(radians),ctx.fillText(label,0,0),ctx.restore())}),ctx.textAlign=previousAlign}paintFrozenLabelBands(padLeft,padTop,cellSize,rowHeight,width,height,scale,cs){if(this.effectiveStickyLabels==="none")return;const backdrop=this.stickyLabelBg(cs),rowBand=this.frozenBandCanvas("row-labels");rowBand&&this.paintFrozenBand(rowBand,padLeft,height,scale,backdrop,bandCtx=>this.paintMatrixRowLabels(bandCtx,padLeft,padTop,rowHeight,cs));const colBand=this.frozenBandCanvas("col-labels");colBand&&this.paintFrozenBand(colBand,width,padTop,scale,backdrop,bandCtx=>this.paintMatrixColLabels(bandCtx,padLeft,padTop,cellSize,cs))}frozenBandCanvas(part){return this.shadowRoot?.querySelector(`[part="${part}"]`)??null}sizeCanvas(canvas,width,height,desiredScale=this.ownerDocument.defaultView?.devicePixelRatio){const{pixelWidth,pixelHeight,scale}=resolveBoundedCanvasAllocation({cssWidth:width,cssHeight:height,desiredScale,maxDimension:MAX_CANVAS_DIMENSION,maxPixels:MAX_CANVAS_PIXELS});canvas.width=pixelWidth,canvas.height=pixelHeight,canvas.style.width=`${width}px`,canvas.style.height=`${height}px`;const ctx=canvas.getContext("2d");return ctx?.scale(scale,scale),ctx}paintFrozenBand(canvas,width,height,scale,backdrop,paint){const ctx=this.sizeCanvas(canvas,width,height,scale);ctx&&(ctx.clearRect(0,0,width,height),ctx.fillStyle=backdrop,ctx.fillRect(0,0,width,height),paint(ctx))}hitTest(x,y){return this.effectiveMode==="calendar"?this.hitTestCalendar(x,y):this.hitTestMatrix(x,y)}matrixNavigationGeometry(rows,cols){const painted=this.lastPaintedMatrixGeometry;if(painted)return{rows,cols,padLeft:painted.padLeft,padTop:painted.padTop,cellSize:painted.cellSize,rowHeight:painted.rowHeight??painted.cellSize,cellWidth:painted.cellWidth??painted.cellSize-1,cellHeight:painted.cellHeight??painted.cellSize-1,customShape:painted.cellWidth!==void 0};const cellSize=this.matrixCellSize(cols),rowHeight=this.matrixRowHeight(cellSize),shape=this.matrixCellShape(cellSize,rowHeight);return{rows,cols,padLeft:this.matrixPadLeft,padTop:this.matrixPadTop,cellSize,rowHeight,cellWidth:shape.w,cellHeight:shape.h,customShape:shape.custom}}calendarNavigationGeometry(){const cellSize=this.calendarCellSize(),columnPositions=this.calendarColumnPositions(),rowPositions=this.calendarRowPositions();return{weekCount:this.cachedCalendarGrid.weekCount,cellSize,columnPositions,rowPositions,padLeft:this.calendarPadLeft,padTop:CAL_LABEL_H}}hitTestMatrix(x,y){const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;return rows===0||cols===0?null:hitTestMatrixGrid(x,y,this.matrixNavigationGeometry(rows,cols),pos=>this.isCellInteractive(pos))}firstInteractiveMatrixCell(rows,cols){return findFirstInteractiveMatrixCell(rows,cols,pos=>this.isCellInteractive(pos))}nextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols){return findNextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols,pos=>this.isCellInteractive(pos))}firstInteractiveCalendarCell(weekCount){return findFirstInteractiveCalendarCell(weekCount,(week,weekday)=>this.calendarPos(week,weekday),pos=>this.isCellInteractive(pos))}nextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount){return findNextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount,(nextWeek,nextWeekday)=>this.calendarPos(nextWeek,nextWeekday),pos=>this.isCellInteractive(pos))}hitTestCalendar(x,y){const weekCount=this.cachedCalendarGrid.weekCount;if(weekCount===0)return null;const columnPositions=this.calendarColumnPositions();return hitTestCalendarGrid(x,y,weekCount,columnPositions,()=>this.calendarCellSize(),()=>this.calendarRowPositions(),(week,weekday)=>this.calendarPos(week,weekday),pos=>this.isCellInteractive(pos))}calendarCellAt(pos){return readCalendarCell(pos.week,pos.weekday,this.cachedCalendarCellsByPos,this.cachedCalendarDateByPos,this.cachedCalendarGrid.firstWeekStart,this.signedDomain)}calendarValueAt(week,weekday){return readCalendarValue(week,weekday,this.cachedCalendarCellsByPos,this.signedDomain)}calendarDateAt(week,weekday){return readCalendarDate(week,weekday,this.cachedCalendarDateByPos,this.cachedCalendarGrid.firstWeekStart)}calendarPos(week,weekday){return{week,weekday,date:this.calendarDateAt(week,weekday)}}cellRect(pos){return"week"in pos?calendarCellRect(pos.week,pos.weekday,this.calendarNavigationGeometry()):matrixCellRect(pos,this.matrixNavigationGeometry(this.matrixRowLabels.length,this.matrixColLabels.length))}accessibleCellRect(pos){return"week"in pos||!this.lastPaintedMatrixGeometry?this.cellRect(pos):accessibleMatrixCellRect(pos,this.lastPaintedMatrixGeometry)}defaultCellText(pos){return"week"in pos?this.calendarCellText(pos):this.matrixCellText(pos)}matrixCellText(pos){const rowLabel=this.matrixRowLabels[pos.row]??this.localize("heatmapDefaultRowLabel",void 0,{n:this.formatCount(pos.row+1)}),colLabel=this.matrixColLabels[pos.col]??this.localize("heatmapDefaultColLabel",void 0,{n:this.formatCount(pos.col+1)}),v=this.matrixValues[pos.row]?.[pos.col],valueText=v==null||this.isNoData(v)?this.localize("heatmapNoDataValue"):this.formatNumericValue(v);return this.localize("heatmapMatrixCellLabel",void 0,{row:rowLabel,col:colLabel,value:valueText})}calendarCellText(pos){const{date,value}=this.calendarCellAt(pos),label=getDateTimeFormat(this.effectiveLocale||void 0,{month:"short",day:"numeric",timeZone:"UTC"}).format(parseIsoDate(date)),valueText=this.isNoData(value)?this.localize("heatmapNoDataValue"):this.formatNumericValue(value);return this.localize("heatmapCalendarCellLabel",void 0,{date:label,value:valueText})}valueAt(pos){return"week"in pos?this.calendarCellAt(pos).value:this.matrixValues[pos.row]?.[pos.col]??-1}resolveCellText(pos){return this.cellText?this.cellText(pos,this.valueAt(pos)):this.defaultCellText(pos)}isCellInteractive(pos){return this.cellInteractive?.(pos,this.valueAt(pos))??!0}announce(pos,isSelectedOverride){const text=this.resolveCellText(pos),announcement=isSelectedOverride??this.isSelectedPos(pos)?this.localize("heatmapSelectedCellLabel",void 0,{cell:text}):text;this.liveText=announcement,this.announcements.announcePolite(announcement)}emitCellClick(pos,source="pointer",select=!0){if(!this.isCellInteractive(pos))return;this.multiple&&select&&(this.selectionAnchor=pos,this.selectionRangeBase=void 0,this.toggleSelectionPositions([pos],source));let detail;if("week"in pos){const{date,value}=this.calendarCellAt(pos);detail={date,value}}else{const value=this.matrixValues[pos.row]?.[pos.col]??-1;detail={row:pos.row,col:pos.col,value}}this.emit("lr-cell-activate",{...detail})}get currentSelectedPositions(){return this.selectionPreview??this.selectedPositions}selectedPaintPositions(){if(this.multiple)return[...this.currentSelectedPositions.values()];const selected=this.selectedCell;if(!selected)return[];if(this.effectiveMode==="calendar"){const match=selected.date?this.cachedCalendarCellsByDate.get(selected.date):void 0;return match?[match]:[]}return selected.row!=null&&selected.col!=null?[{row:selected.row,col:selected.col}]:[]}rebuildSelectedPositions(){const positions=new Map,dates=this.effectiveMode==="calendar"?new Map(this.cachedAccessiblePositions.map(pos=>[this.accessibleCellIdentity(pos),pos])):void 0,input=Array.isArray(this.selectedCells)?this.selectedCells:[];for(const cell of input.slice(0,MAX_HEATMAP_CELLS)){if(!cell||typeof cell!="object")continue;const pos=dates?typeof cell.date=="string"?dates.get(cell.date):void 0:Number.isInteger(cell.row)&&Number.isInteger(cell.col)?this.cachedAccessiblePositionsByKey.get(`matrix-${cell.row}-${cell.col}`):void 0;pos&&positions.set(this.accessibleCellKey(pos),pos)}this.selectedPositions=positions}selectionCoordinates(pos){return"week"in pos?{row:pos.weekday,col:pos.week}:pos}proposeSelection(positions,source){if(positions.size===this.selectedPositions.size&&[...positions.keys()].every(key=>this.selectedPositions.has(key)))return;this.proposedSelectionKeys=new Set(positions.keys());const selectedCells=[...positions.values()].sort((a,b)=>{const first=this.selectionCoordinates(a),second=this.selectionCoordinates(b);return first.row-second.row||first.col-second.col}).map(pos=>"week"in pos?{date:pos.date}:{row:pos.row,col:pos.col});this.emit("lr-selection-change",{selectedCells,source})}toggleSelectionPositions(positions,source){if(!this.multiple||positions.length===0)return;const next=new Map(this.selectedPositions),remove=positions.every(pos=>next.has(this.accessibleCellKey(pos)));for(const pos of positions){const key=this.accessibleCellKey(pos);remove?next.delete(key):next.set(key,pos)}this.proposeSelection(next,source)}toggleSelectionAxis(index,row){!this.multiple||!Number.isInteger(index)||index<0||(this.cancelSelectionGesture(),this.selectionRangeBase=void 0,this.toggleSelectionPositions(this.cachedAccessiblePositions.filter(pos=>{const coordinates=this.selectionCoordinates(pos);return(row?coordinates.row:coordinates.col)===index}),row?"row":"column"))}selectionKeyDown(event,pos){if(!this.multiple)return!1;if(event.key==="Escape"&&this.selectionGesture)return event.preventDefault(),this.cancelSelectionGesture(),!0;if(event.key!==" "||!pos||!(event.shiftKey||event.ctrlKey||event.metaKey))return!1;event.preventDefault();const coordinates=this.selectionCoordinates(pos);return event.ctrlKey||event.metaKey?this.toggleColumnSelection(coordinates.col):this.toggleRowSelection(coordinates.row),!0}extendSelection(previous,next,range){if(!this.multiple)return;if(!range){this.selectionAnchor=next,this.selectionRangeBase=void 0;return}this.selectionAnchor??=previous??next,this.selectionRangeBase??=new Map(this.selectedPositions);const from=this.selectionCoordinates(this.selectionAnchor),to=this.selectionCoordinates(next),selected=new Map(this.selectionRangeBase);for(const pos of this.cachedAccessiblePositions){const{row,col}=this.selectionCoordinates(pos);row>=Math.min(from.row,to.row)&&row<=Math.max(from.row,to.row)&&col>=Math.min(from.col,to.col)&&col<=Math.max(from.col,to.col)&&selected.set(this.accessibleCellKey(pos),pos)}return this.proposeSelection(selected,"keyboard"),new Set(selected.keys())}selectionPointerPosition(event){if(!this.canvas)return null;const rect=this.canvas.getBoundingClientRect();return this.hitTest(event.clientX-rect.left,event.clientY-rect.top)}paintSelectionTo(pos){const gesture=this.selectionGesture;if(!gesture)return;this.samePos(pos,gesture.previous)||(gesture.moved=!0);const from=this.selectionCoordinates(gesture.previous),to=this.selectionCoordinates(pos),steps=Math.max(Math.abs(to.row-from.row),Math.abs(to.col-from.col),1),changed=[];for(let step=0;step<=steps;step++){const row=Math.round(from.row+(to.row-from.row)*step/steps),col=Math.round(from.col+(to.col-from.col)*step/steps),key=this.effectiveMode==="calendar"?`calendar-${col}-${row}`:`matrix-${row}-${col}`,candidate=this.cachedAccessiblePositionsByKey.get(key);candidate&&(gesture.cells.has(key)!==gesture.selecting&&changed.push(candidate),gesture.selecting?gesture.cells.set(key,candidate):gesture.cells.delete(key))}if(gesture.previous=pos,this.selectionPreview!==gesture.cells){this.selectionPreview=gesture.cells;return}this.requestUpdate(),(changed.length>16||!changed.every(cell=>this.repaintCell(cell)))&&this.requestDraw()}repaintCell(pos){return!this.canvasHasContent||!this.canvas||this.drawDirty?!1:("week"in pos?this.repaintCalendarFocusCell(pos):this.repaintMatrixFocusCell(pos),!0)}cancelSelectionGesture(){const gesture=this.selectionGesture;if(this.selectionGesture=void 0,this.selectionPreview=void 0,!!gesture){this.suppressSelectionClick=!0;try{gesture.target.hasPointerCapture(gesture.pointerId)&&gesture.target.releasePointerCapture(gesture.pointerId)}catch{}}}consumeSelectionClick(event){return!this.suppressSelectionClick||event.detail===0?!1:(this.suppressSelectionClick=!1,!0)}get gridScrollport(){return this.shadowRoot?.querySelector('[part="grid"]')??null}measureTooltip(){if(!this.gridScrollport)return;const tooltip=this.shadowRoot?.querySelector('[part="tooltip"]');if(!tooltip||tooltip.hidden)return;const view=this.ownerDocument.defaultView,gap=view?Math.abs(finiteNumber(Number.parseFloat(view.getComputedStyle(tooltip).marginBlockStart),0)):0,inline=tooltip.offsetWidth,block=tooltip.offsetHeight+gap;inline===this.tooltipSize.inline&&block===this.tooltipSize.block||(this.tooltipSize={inline,block},this.requestUpdate())}tooltipAnchor(pos){const rect=this.cellRect(pos),center=rect.x+rect.w/2,port=this.gridScrollport;if(!port)return{style:{left:`${center}px`,top:`${rect.y}px`},below:!1};const{inline,block}=this.tooltipSize,windowStart=port.scrollLeft+(this.freezesRowLabels?this.matrixPadLeft:0),windowEnd=port.scrollLeft+port.clientWidth,windowTop=port.scrollTop+(this.freezesColLabels?this.matrixPadTop:0),windowBottom=port.scrollTop+port.clientHeight,below=rect.y-block<windowTop&&rect.y+rect.h+block<=windowBottom;return{style:{left:`${Math.max(windowStart+inline/2,Math.min(center,windowEnd-inline/2))}px`,top:`${below?rect.y+rect.h:rect.y}px`},below}}scrollCellIntoView(pos){const port=this.gridScrollport;if(!port)return;const rect=this.cellRect(pos),bandInline=this.freezesRowLabels?this.matrixPadLeft:0,bandBlock=this.freezesColLabels?this.matrixPadTop:0,left=Math.min(Math.max(port.scrollLeft,rect.x+rect.w-port.clientWidth),rect.x-bandInline),top=Math.min(Math.max(port.scrollTop,rect.y+rect.h-port.clientHeight),rect.y-bandBlock);left!==port.scrollLeft&&(port.scrollLeft=left),top!==port.scrollTop&&(port.scrollTop=top)}samePos(a,b){return a===b?!0:!a||!b?!1:"week"in a&&"week"in b?a.week===b.week&&a.weekday===b.weekday:"row"in a&&"row"in b?a.row===b.row&&a.col===b.col:!1}edgeCell(e){if(e.key!=="Home"&&e.key!=="End")return null;const row=this.focusedCell&&!(e.ctrlKey||e.metaKey)?this.selectionCoordinates(this.focusedCell).row:void 0,cells=this.cachedAccessiblePositions.filter(pos=>row===void 0||this.selectionCoordinates(pos).row===row);return cells[e.key==="Home"?0:cells.length-1]??null}onMatrixKeyDown(e){const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;if(rows===0||cols===0)return;if(e.key==="Enter"||e.key===" "){e.preventDefault(),this.focusedCell&&this.emitCellClick(this.focusedCell,"keyboard");return}if(!ARROW_KEYS.has(e.key))return;if(e.preventDefault(),!this.focusedCell||!("row"in this.focusedCell)){const next2=this.firstInteractiveMatrixCell(rows,cols);if(!next2)return;this.focusedCell=next2,this.scrollCellIntoView(next2);return}const{row,col}=this.focusedCell;let dRow=0,dCol=0;e.key==="ArrowUp"?dRow=-1:e.key==="ArrowDown"?dRow=1:e.key==="ArrowLeft"?dCol=-1:e.key==="ArrowRight"&&(dCol=1);const next=this.nextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols);this.focusedCell=next,this.scrollCellIntoView(next)}onCalendarKeyDown(e){const{weekCount}=this.cachedCalendarGrid;if(weekCount===0)return;if(e.key==="Enter"||e.key===" "){e.preventDefault(),this.focusedCell&&this.emitCellClick(this.focusedCell,"keyboard");return}if(!ARROW_KEYS.has(e.key))return;if(e.preventDefault(),!this.focusedCell||!("week"in this.focusedCell)){const next2=this.firstInteractiveCalendarCell(weekCount);if(!next2)return;this.focusedCell=next2;return}const{week,weekday}=this.focusedCell;let dWeek=0,dWeekday=0;e.key==="ArrowUp"?dWeekday=-1:e.key==="ArrowDown"?dWeekday=1:e.key==="ArrowLeft"?dWeek=-1:e.key==="ArrowRight"&&(dWeek=1);const next=this.nextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount);this.focusedCell=next}resolveCellColor(value,cs){let color=this.canvasColorCache.get(value);if(color===void 0){const ctx=SCOPED_COLOR.test(value)?null:getScratchCtx(this.ownerDocument);if(ctx){ctx.fillStyle="rgb(1, 2, 3)";const rejected=ctx.fillStyle;ctx.fillStyle=value,ctx.fillStyle!==rejected&&(color=ctx.fillStyle)}color??=resolveCanvasColor(this,value,this.noDataFill(cs)),this.canvasColorCache.set(value,color)}return color}rebuildAccessiblePositions(){const positions=[];if(this.effectiveMode==="calendar"){const{weekCount}=this.cachedCalendarGrid;for(let week=0;week<weekCount;week++)for(let weekday=0;weekday<7;weekday++){const pos=this.calendarPos(week,weekday);this.isCellInteractive(pos)&&positions.push(pos)}}else for(let row=0;row<this.matrixRowLabels.length;row++)for(let col=0;col<this.matrixColLabels.length;col++){const pos={row,col};this.isCellInteractive(pos)&&positions.push(pos)}this.cachedAccessiblePositions=positions,this.cachedAccessiblePositionsByKey=new Map(positions.map(position=>[this.accessibleCellKey(position),position])),this.cachedAccessiblePositionIndexByKey=new Map(positions.map((position,index)=>[this.accessibleCellKey(position),index]))}accessibleCellPositions(){return this.cachedAccessiblePositions}accessibleCellKey(pos){return"week"in pos?`calendar-${pos.week}-${pos.weekday}`:`matrix-${pos.row}-${pos.col}`}accessibleCellIdentity(pos){return"week"in pos?pos.date:this.accessibleCellKey(pos)}accessibleCellAtKey(key){return this.cachedAccessiblePositionsByKey.get(key)??null}focusAccessibleCell(pos){pos&&this.updateComplete.then(()=>{[...this.shadowRoot?.querySelectorAll('[part="cell"]')??[]].find(candidate=>candidate.dataset.cellKey===this.accessibleCellKey(pos))?.focus()})}renderAccessibleCells(){if(!this.accessibleCells)return html``;const positions=this.accessibleCellPositions(),tabStop=this.focusedCell??positions[0]??null,focusIndex=tabStop?this.cachedAccessiblePositionIndexByKey.get(this.accessibleCellKey(tabStop))??0:0,start=Math.max(0,Math.min(Math.max(0,positions.length-MAX_ACCESSIBLE_HEATMAP_CELLS),focusIndex-Math.floor(MAX_ACCESSIBLE_HEATMAP_CELLS/2))),renderedPositions=positions.slice(start,start+MAX_ACCESSIBLE_HEATMAP_CELLS),renderedRows=new Map;for(const pos of renderedPositions){const rowIndex="week"in pos?pos.weekday+1:pos.row+1,row=renderedRows.get(rowIndex);row?row.push(pos):renderedRows.set(rowIndex,[pos])}const rowCount=this.effectiveMode==="calendar"?7:this.matrixRowLabels.length,colCount=this.effectiveMode==="calendar"?this.cachedCalendarGrid.weekCount:this.matrixColLabels.length,calendar=this.effectiveMode==="calendar"?this.calendarNavigationGeometry():void 0;return html`
|
|
3
|
+
`)}get matrixPadTop(){if(this.colLabelHeight==="auto")return this.resolvedColLabelHeight;if(typeof this.colLabelHeight!="number")return PAD_TOP;const resolved=finiteNumber(this.colLabelHeight,PAD_TOP);return resolved>=0?resolved:PAD_TOP}measureColLabelHeight(cs){const labels=this.matrixColLabels;if(labels.length===0)return PAD_TOP;const ctx=getScratchCtx(this.ownerDocument);if(!ctx)return PAD_TOP;ctx.font=this.labelFont(cs);let widest=0;const interval=finiteInteger(this.colLabelInterval,1,1);for(let index=0;index<labels.length;index+=interval)widest=Math.max(widest,this.labelWidth(ctx,labels[index]));const radians=this.effectiveColLabelRotation*Math.PI/180,projected=widest*Math.sin(radians);return Math.max(PAD_TOP,Math.min(Math.ceil(projected)+COL_LABEL_INSET,MAX_COL_LABEL_HEIGHT))}measureRowLabelWidth(cs){const labels=this.matrixRowLabels;if(labels.length===0)return PAD_LEFT;const ctx=getScratchCtx(this.ownerDocument);if(!ctx)return PAD_LEFT;ctx.font=this.labelFont(cs);let widest=0;for(const label of labels)widest=Math.max(widest,this.labelWidth(ctx,label));const hostWidth=this.clientWidth||0,cap=hostWidth>0?hostWidth*MAX_ROW_LABEL_FRACTION:Number.POSITIVE_INFINITY;return Math.min(Math.max(PAD_LEFT,Math.ceil(widest)+ROW_LABEL_INSET*2),cap)}withLabelCache(paint){const previous=this.labelCache;this.labelCache=new HeatmapLabelCache;try{paint()}finally{this.labelCache=previous}}labelWidth(ctx,label){return this.labelCache?.width(ctx,label)??ctx.measureText(label).width}ellipsize(ctx,label,maxWidth){return this.labelCache?.clip(ctx,label,maxWidth,()=>this.ellipsizeLabel(ctx,label,maxWidth))??this.ellipsizeLabel(ctx,label,maxWidth)}ellipsizeLabel(ctx,label,maxWidth){if(maxWidth<=0)return"";if(this.labelWidth(ctx,label)<=maxWidth)return label;const characters=[...label],shortened=kept=>`${characters.slice(0,kept).join("")}…`;let fits=0,most=characters.length-1;for(;fits<most;){const kept=fits+most+1>>1;this.labelWidth(ctx,shortened(kept))<=maxWidth?fits=kept:most=kept-1}return fits>0||this.labelWidth(ctx,"…")<=maxWidth?shortened(fits):""}get calendarPadLeft(){const requested=this.calendarWeekdayLabelWidth;return requested==="auto"?this.resolvedCalendarWeekdayLabelWidth:requested??CAL_PAD_LEFT}measureCalendarWeekdayLabelWidth(cs,firstWeekStart){const ctx=getScratchCtx(this.ownerDocument);if(!ctx)return CAL_PAD_LEFT;ctx.font=this.labelFont(cs);let widest=0;for(const label of this.weekdayLabels(firstWeekStart))label&&(widest=Math.max(widest,this.labelWidth(ctx,label)));const hostWidth=this.clientWidth||0,cap=hostWidth>0?Math.max(CAL_PAD_LEFT,hostWidth*MAX_ROW_LABEL_FRACTION):Number.POSITIVE_INFINITY;return Math.min(Math.max(CAL_PAD_LEFT,Math.ceil(widest)+CAL_WEEKDAY_LABEL_INSET*2),cap)}get matrixRowLabels(){return this.cachedMatrixData.rowLabels}get matrixColLabels(){return this.cachedMatrixData.colLabels}get matrixValues(){return this.cachedMatrixData.values}get calendarDays(){return this.data.kind==="calendar"?this.data.days:[]}get calendarData(){return this.data.kind==="calendar"?this.data:void 0}get cellSize(){return this._cellSize??(this.effectiveMode==="calendar"?CAL_CELL:DEFAULT_MATRIX_CELL_SIZE)}set cellSize(value){const oldValue=this._cellSize;this._cellSize=value==null?void 0:finiteRange(value,this.effectiveMode==="calendar"?CAL_CELL:DEFAULT_MATRIX_CELL_SIZE,1),this.requestUpdate("cellSize",oldValue)}get rowHeight(){return this._rowHeight}set rowHeight(value){const oldValue=this._rowHeight;this._rowHeight=value==null||!Number.isFinite(value)?void 0:finiteRange(value,1,1,MAX_MATRIX_ROW_HEIGHT),this.requestUpdate("rowHeight",oldValue)}get signedDomain(){return this.domain!==void 0||this.midpoint!==void 0}rampAlpha(value,lo,hi){const anchor=this.midpoint;return anchor===void 0?linearAlpha(value,lo,hi):midpointAlpha(value,lo,hi,anchor)}rampBucket(value,lo,hi,steps){const anchor=this.midpoint;return anchor===void 0?linearBucket(value,lo,hi,steps):midpointBucket(value,lo,hi,anchor,steps)}isNoData(value){return Number.isFinite(value)?value<0&&!this.signedDomain:!0}get maxCellSize(){return this._maxCellSize}set maxCellSize(value){const oldValue=this._maxCellSize;this._maxCellSize=normalizeCellSizeClamp(value),this.requestUpdate("maxCellSize",oldValue)}get minCellSize(){return this._minCellSize}set minCellSize(value){const oldValue=this._minCellSize;this._minCellSize=normalizeCellSizeClamp(value),this.requestUpdate("minCellSize",oldValue)}get normalizedFirstDayOfWeek(){return(finiteInteger(this.calendarData?.firstDayOfWeek??0,0)%7+7)%7}get bucketCount(){return this._bucketCount}set bucketCount(value){const oldValue=this._bucketCount;this._bucketCount=normalizeBucketCount(value),this.requestUpdate("bucketCount",oldValue)}toggleRowSelection(row){this.toggleSelectionAxis(row,!0)}toggleColumnSelection(col){this.toggleSelectionAxis(col,!1)}get calendarWeekdayLabelText(){return this.calendarData?.weekdayLabelText}get calendarWeekdayLabelWidth(){const value=this.calendarData?.weekdayLabelWidth;if(value==="auto")return value;if(typeof value!="number")return;const resolved=finiteNumber(value,CAL_PAD_LEFT);return resolved>=0?resolved:void 0}get calendarMonthLabelText(){return this.calendarData?.monthLabelText}get calendarColumnX(){return this.calendarData?.columnX}get calendarRowY(){return this.calendarData?.rowY}constructor(){super(),this.data=DEFAULT_MATRIX_DATA,this._stickyLabels="none",this.resolvedColLabelHeight=PAD_TOP,this.resolvedRowLabelWidth=PAD_LEFT,this.resolvedCalendarWeekdayLabelWidth=CAL_PAD_LEFT,this.withoutLegend=!1,this.scale="linear",this.cellGapX=1,this.cellGapY=1,this.cellRadius=0,this.colLabelInterval=1,this.fitToWidth=!1,this._bucketCount=DEFAULT_BUCKET_COUNT,this.annotations=[],this.selectedCell=null,this.multiple=!1,this.selectedCells=[],this.accessibleCells=!1,this.cachedValueRange=null,this.cachedMatrixData={rowLabels:[],colLabels:[],values:[],truncated:!1},this.cachedCalendarGrid=buildCalendarGrid(this.calendarDays),this.cachedCalendarSortedValues=[],this.cachedCalendarCellsByPos=new Map,this.cachedCalendarCellsByDate=new Map,this.cachedAnnotations=[],this.cachedLegendStops=[],this.cachedColorSteps=[],this.cachedCalendarAnnotationDates=new Set,this.cachedMatrixAnnotationPositions=new Set,this.decorationProjectionTruncated=!1,this.cachedCalendarDateByPos=[],this.cachedAccessiblePositions=[],this.cachedAccessiblePositionsByKey=new Map,this.cachedAccessiblePositionIndexByKey=new Map,this.cachedRamp=null,this.canvasHasContent=!1,this.canvasVisible=!0,this.drawDirty=!1,this.overlayRevision=0,this.hoverCell=null,this.focusedCell=null,this.liveText="",this.accessibleTargetSizePx=DEFAULT_ACCESSIBLE_TARGET_SIZE_PX,this.restoringAccessibleFocus=!1,this.accessibleFocusGeneration=0,this.announcements=new AnnouncementSinkController(this,{eager:["polite"]}),this.authorRole=null,this.authorAriaLabel=null,this.generatedAriaLabel="",this.syncingGeneratedSemantics=!1,this.hasSyncedDescribedByElements=!1,this.onDprChange=()=>{this.watchDpr(),this.requestDraw()},this.scheduleDraw=()=>{if(this.drawFrameRequest)return;const owner=this.ownerDocument.defaultView;if(!owner||!this.isConnected)return;const request={owner,handle:0};request.handle=owner.requestAnimationFrame(()=>{this.drawFrameRequest===request&&(this.drawFrameRequest=void 0,this.isConnected&&this.ownerDocument.defaultView===owner&&this.requestDraw())}),this.drawFrameRequest=request},this.selectedPositions=new Map,this.selectionAnchor=null,this.suppressSelectionClick=!1,this.onSelectionPointerDown=event=>{if(!this.multiple||event.button!==0||!event.isPrimary||this.selectionGesture)return;const pos=this.selectionPointerPosition(event);if(!pos)return;event.preventDefault(),this.suppressSelectionClick=!1,this.selectionRangeBase=void 0,this.selectionAnchor=pos,this.focusedCell=pos,this.accessibleCells?this.focusAccessibleCell(pos):this.canvas?.focus();const target=event.currentTarget;this.selectionGesture={pointerId:event.pointerId,target,start:pos,previous:pos,moved:!1,selecting:!this.selectedPositions.has(this.accessibleCellKey(pos)),cells:new Map(this.selectedPositions)};try{target.setPointerCapture(event.pointerId)}catch{}this.paintSelectionTo(pos)},this.onSelectionPointerMove=event=>{if(this.selectionGesture?.pointerId!==event.pointerId)return;const pos=this.selectionPointerPosition(event);pos&&!this.samePos(pos,this.selectionGesture.previous)&&this.paintSelectionTo(pos)},this.onSelectionPointerUp=event=>{const gesture=this.selectionGesture;if(!gesture||gesture.pointerId!==event.pointerId)return;const pos=this.selectionPointerPosition(event);pos&&this.paintSelectionTo(pos),this.cancelSelectionGesture(),this.proposeSelection(gesture.cells,"pointer"),gesture.moved||this.emitCellClick(gesture.start,"pointer",!1)},this.onSelectionPointerCancel=event=>{this.selectionGesture?.pointerId===event.pointerId&&this.cancelSelectionGesture()},this.tooltipSize={inline:0,block:0},this.onPointerMove=e=>{const next=this.hitTest(e.offsetX,e.offsetY);this.samePos(this.hoverCell,next)||(this.hoverCell=next)},this.onPointerLeave=()=>{this.hoverCell=null},this.onCanvasClick=e=>{if(this.consumeSelectionClick(e))return;const pos=this.hitTest(e.offsetX,e.offsetY);pos&&(this.focusedCell=pos,this.announce(pos),this.emitCellClick(pos))},this.onKeyDown=e=>{if(this.selectionKeyDown(e,this.focusedCell))return;const previous=this.focusedCell,edge=this.edgeCell(e);if(edge?(e.preventDefault(),this.focusedCell=edge,this.scrollCellIntoView(edge)):this.effectiveMode==="calendar"?this.onCalendarKeyDown(e):this.onMatrixKeyDown(e),(edge||ARROW_KEYS.has(e.key))&&this.focusedCell){const proposedKeys=this.extendSelection(previous,this.focusedCell,e.shiftKey);this.announce(this.focusedCell,proposedKeys?.has(this.accessibleCellKey(this.focusedCell)))}},this.canvasColorCache=new Map,this.onAccessibleCellFocus=e=>{if(this.restoringAccessibleFocus)return;const key=e.currentTarget.dataset.cellKey,pos=key?this.accessibleCellAtKey(key):null;pos&&(this.samePos(pos,this.focusedCell)||(this.selectionAnchor=pos,this.selectionRangeBase=void 0),this.focusedCell=pos,this.announce(pos))},this.onAccessibleCellClick=e=>{if(this.consumeSelectionClick(e))return;const key=e.currentTarget.dataset.cellKey,pos=key?this.accessibleCellAtKey(key):null;pos&&(this.focusedCell=pos,this.announce(pos),this.emitCellClick(pos,e.detail===0?"keyboard":"pointer"))},this.onAccessibleCellKeyDown=e=>{const key=e.currentTarget.dataset.cellKey,pos=key?this.accessibleCellAtKey(key):null;pos&&(this.selectionKeyDown(e,pos)||GRID_KEYS.has(e.key)&&(e.preventDefault(),this.focusedCell=pos,this.onKeyDown(e),this.focusAccessibleCell(this.focusedCell)))},new ThemeWatcher(this,()=>this.onThemeSignal()),this.calendarSpacingTrackingArmed=!0}requestUpdate(name,oldValue,options){this.calendarSpacingTrackingArmed&&name!==void 0&&CALENDAR_SPACING_PROPERTIES.has(name)&&(this.explicitCalendarSpacingProperties??=new Set).add(name),super.requestUpdate(name,oldValue,options)}explicitCalendarSpacing(name){if(!this.explicitCalendarSpacingProperties?.has(name))return;const value=this[name];return value??void 0}warnOnLegendRampMismatch(){const rampColors=this.cachedColorSteps.map(color=>sanitizeCssColor(color)??color);if(rampColors.length===0)return;const legendColors=this.cachedLegendStops.filter(stop=>!!stop.color&&stop.partOfRamp!==!1).map(stop=>sanitizeCssColor(stop.color??"")??stop.color??"");legendColors.length===0||legendColors.length===rampColors.length&&legendColors.every((color,index)=>color===rampColors[index])||devWarnOnce("lyra-heatmap-legend-ramp-mismatch",`<${this.localName}>: legendStops describes ${legendColors.length} colour(s) that do not match the ${rampColors.length} colorSteps the cells are painted from, so the legend may misdescribe the ramp. Supply legendStops built from the same array as colorSteps, or omit it to keep the built-in gradient key.`)}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value),!(oldValue===value||this.syncingGeneratedSemantics)&&(name==="role"&&(this.authorRole=value),name==="aria-label"&&(this.authorAriaLabel=value))}connectedCallback(){super.connectedCallback(),this.refreshAccessibleTargetSize();const owner=this.ownerDocument.defaultView,ResizeObserverCtor=owner?.ResizeObserver;if(owner&&ResizeObserverCtor){let observer;observer=new ResizeObserverCtor(()=>{!this.isConnected||this.ownerDocument.defaultView!==owner||this.resizeObserver!==observer||this.scheduleDraw()}),this.resizeObserver=observer,observer.observe(this)}const IntersectionObserverCtor=owner?.IntersectionObserver;if(this.canvasVisible=!0,owner&&IntersectionObserverCtor){let observer;observer=new IntersectionObserverCtor(entries=>{if(!this.isConnected||this.ownerDocument.defaultView!==owner||this.intersectionObserver!==observer)return;const entry=entries.find(candidate=>candidate.target===this);!entry||entry.isIntersecting===this.canvasVisible||(this.canvasVisible=entry.isIntersecting,this.canvasVisible&&this.drawDirty&&this.scheduleDraw())}),this.intersectionObserver=observer,observer.observe(this)}this.cachedRamp=null,this.paintedTheme=void 0,this.canvasColorCache.clear(),this.watchDpr(),this.drawDirty&&!ResizeObserverCtor&&this.scheduleDraw()}disconnectedCallback(){super.disconnectedCallback(),this.cancelSelectionGesture(),this.selectionAnchor=null,this.selectionRangeBase=void 0,this.accessibleFocusGeneration++,this.pendingAccessibleFocus=void 0,this.pendingAccessibleFocusOrigin=void 0,this.restoringAccessibleFocus=!1,this.hoverCell=null,this.focusedCell=null,this.liveText="",this.canvasHasContent=!1,this.drawDirty=!0,this.resizeObserver?.disconnect(),this.resizeObserver=void 0,this.intersectionObserver?.disconnect(),this.intersectionObserver=void 0,this.canvasVisible=!0,this.clearDprWatcher(),this.cancelDrawFrame()}adoptedCallback(){super.adoptedCallback(),this.announcements.adopted()}watchDpr(){this.clearDprWatcher();const owner=this.ownerDocument.defaultView;if(!owner||typeof owner.matchMedia!="function")return;const query2=owner.matchMedia(`(resolution: ${owner.devicePixelRatio}dppx)`),listener=()=>{!this.isConnected||this.ownerDocument.defaultView!==owner||this.dprQuery!==query2||this.onDprChange()};this.dprQuery=query2,this.dprChangeListener=listener,query2.addEventListener("change",listener)}clearDprWatcher(){this.dprQuery&&this.dprChangeListener&&this.dprQuery.removeEventListener("change",this.dprChangeListener),this.dprQuery=void 0,this.dprChangeListener=void 0}willUpdate(changed){super.willUpdate(changed),(changed.size!==1||!changed.has("hoverCell"))&&this.overlayRevision++,(changed.has("data")||changed.has("domain")||changed.has("midpoint")||!this.hasUpdated)&&this.rebuildCanonicalMatrixData(),(changed.has("annotations")||changed.has("legendStops")||changed.has("colorSteps")||!this.hasUpdated)&&this.rebuildBoundedDecorations();const accessibleModeChanged=changed.has("accessibleCells")&&this.hasUpdated,collectionChanged=changed.has("data")||changed.has("cellInteractive"),activeRenderedControl=collectionChanged||accessibleModeChanged?shadowFocusTarget(this):null,activeAccessibleCell=activeRenderedControl?.matches('[part="cell"]')?activeRenderedControl:null,renderedAccessibleCells=activeAccessibleCell?.matches('[part="cell"]')?[...this.shadowRoot?.querySelectorAll('[part="cell"]')??[]]:[],accessibleFocusSnapshot=activeAccessibleCell?.matches('[part="cell"]')?{identity:activeAccessibleCell.dataset.cellIdentity,index:renderedAccessibleCells.indexOf(activeAccessibleCell)}:void 0;if(collectionChanged&&(this.focusedCell=null,this.hoverCell=null,this.liveText=""),changed.has("data")||changed.has("locale")||!this.hasUpdated){this.cachedCalendarGrid=buildCalendarGrid(this.calendarDays,this.normalizedFirstDayOfWeek,this.calendarMonthLabelText,this.effectiveLocale),this.cachedCalendarSortedValues=this.cachedCalendarGrid.cells.map(cell=>cell.value).filter(value=>!this.isNoData(value)).sort((a,b)=>a-b),this.cachedCalendarCellsByPos=new Map(this.cachedCalendarGrid.cells.map(cell=>[`${cell.week}:${cell.weekday}`,cell])),this.cachedCalendarCellsByDate=new Map(this.cachedCalendarGrid.cells.map(cell=>[cell.date,cell]));const{firstWeekStart,weekCount}=this.cachedCalendarGrid;this.cachedCalendarDateByPos=Array.from({length:weekCount*7},(_,index)=>isoDateAtOffset(firstWeekStart,index))}if(changed.has("colorSteps")||changed.has("withoutLegend")||!this.hasUpdated){const colorSteps=this.withoutLegend?[]:this.cachedColorSteps.map(sanitizeCssColor);colorSteps.length>=2&&colorSteps.every(color=>color!==void 0)?this.style.setProperty("--lr-heatmap-color-steps-gradient",`linear-gradient(to right, ${colorSteps.join(", ")})`):this.style.removeProperty("--lr-heatmap-color-steps-gradient")}if((changed.has("data")||changed.has("domain")||changed.has("midpoint")||!this.hasUpdated)&&(this.cachedValueRange=this.computeValueRange()),(collectionChanged||!this.hasUpdated)&&this.rebuildAccessiblePositions(),(collectionChanged||accessibleModeChanged||changed.has("multiple"))&&(this.cancelSelectionGesture(),this.selectionAnchor=null,this.selectionRangeBase=void 0,this.proposedSelectionKeys=void 0),(collectionChanged||changed.has("selectedCells")||changed.has("multiple")||!this.hasUpdated)&&(this.rebuildSelectedPositions(),changed.has("selectedCells")&&this.selectionGesture&&this.cancelSelectionGesture(),changed.has("selectedCells")&&this.selectionRangeBase&&(this.proposedSelectionKeys?.size!==this.selectedPositions.size||[...this.selectedPositions.keys()].some(key=>!this.proposedSelectionKeys?.has(key)))&&(this.selectionAnchor=this.focusedCell,this.selectionRangeBase=void 0)),accessibleFocusSnapshot){const positions=this.accessibleCellPositions(),target=(accessibleFocusSnapshot.identity==null?void 0:positions.find(pos=>this.accessibleCellIdentity(pos)===accessibleFocusSnapshot.identity))??positions[Math.min(Math.max(accessibleFocusSnapshot.index,0),positions.length-1)]??null;this.focusedCell=target,this.liveText=target?this.resolveCellText(target):"",this.pendingAccessibleFocus=target??"base",this.pendingAccessibleFocusOrigin=activeAccessibleCell??void 0,this.restoringAccessibleFocus=!0,this.accessibleFocusGeneration++}if(accessibleModeChanged){const previouslyAccessible=changed.get("accessibleCells")===!0;if(previouslyAccessible&&!this.accessibleCells&&activeAccessibleCell){const key=activeAccessibleCell.dataset.cellKey,target=key?this.accessibleCellAtKey(key):null;target&&(this.focusedCell=target,this.liveText=this.resolveCellText(target)),this.pendingAccessibleFocus="canvas",this.pendingAccessibleFocusOrigin=activeAccessibleCell,this.restoringAccessibleFocus=!0,this.accessibleFocusGeneration++}else if(!previouslyAccessible&&this.accessibleCells&&activeRenderedControl?.matches('[part="canvas"]')){const positions=this.accessibleCellPositions(),target=this.focusedCell?positions.find(pos=>this.samePos(pos,this.focusedCell))??positions[0]??null:positions[0]??null;this.focusedCell=target,this.liveText=target?this.resolveCellText(target):"",this.pendingAccessibleFocus=target??"base",this.pendingAccessibleFocusOrigin=activeRenderedControl,this.restoringAccessibleFocus=!0,this.accessibleFocusGeneration++}}const bounds=this.cachedValueRange,range=bounds?`${this.formatNumericValue(bounds[0])}–${this.formatNumericValue(bounds[1])}`:this.localize("heatmapNoDataValue"),valueLabel=this.localizedValueLabel();let label;if(this.effectiveMode==="calendar")label=this.localize("heatmapCalendarLabel",void 0,{days:this.formatCount(this.cachedCalendarGrid.cells.length),label:valueLabel,range});else{const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;label=this.localize("heatmapMatrixLabel",void 0,{rows:this.formatCount(rows),cols:this.formatCount(cols),label:valueLabel,range})}const selectedText=this.selectedCellDescription(),generatedAriaLabel=[label,selectedText,this.projectionDescription()].filter(Boolean).join(" ");this.generatedAriaLabel=generatedAriaLabel,this.syncingGeneratedSemantics=!0;try{this.authorRole===null&&this.getAttribute("role")!=="group"&&this.setAttribute("role","group"),this.authorAriaLabel===null&&this.getAttribute("aria-label")!==generatedAriaLabel&&this.setAttribute("aria-label",generatedAriaLabel)}finally{this.syncingGeneratedSemantics=!1}}rebuildBoundedDecorations(){this.cachedAnnotations=this.annotations.slice(0,MAX_HEATMAP_DECORATIONS).map(entry=>({...entry})),this.cachedLegendStops=(this.legendStops??[]).slice(0,MAX_HEATMAP_DECORATIONS).map(entry=>({...entry})),this.cachedColorSteps=(this.colorSteps??[]).slice(0,MAX_HEATMAP_DECORATIONS),this.warnOnLegendRampMismatch(),this.cachedCalendarAnnotationDates=new Set(this.cachedAnnotations.flatMap(annotation=>annotation.date==null?[]:[annotation.date])),this.cachedMatrixAnnotationPositions=new Set(this.cachedAnnotations.flatMap(annotation=>annotation.row==null||annotation.col==null?[]:[`${annotation.row}:${annotation.col}`])),this.decorationProjectionTruncated=this.annotations.length>MAX_HEATMAP_DECORATIONS||(this.legendStops?.length??0)>MAX_HEATMAP_DECORATIONS||(this.colorSteps?.length??0)>MAX_HEATMAP_DECORATIONS}get projectionTruncated(){return this.decorationProjectionTruncated||(this.effectiveMode==="calendar"?this.cachedCalendarGrid.truncated:this.cachedMatrixData.truncated)}get cellProjectionTruncated(){return this.effectiveMode==="calendar"?this.cachedCalendarGrid.truncated:this.cachedMatrixData.truncated}projectedCellCount(){return this.effectiveMode==="calendar"?this.cachedCalendarGrid.weekCount*7:this.matrixRowLabels.length*this.matrixColLabels.length}projectionDescription(){const messages=[];return this.cellProjectionTruncated&&messages.push(this.localize("heatmapProjectionLimit",void 0,{count:this.formatCount(this.projectedCellCount())})),this.decorationProjectionTruncated&&messages.push(this.localize("heatmapDecorationLimit",void 0,{count:this.formatCount(MAX_HEATMAP_DECORATIONS)})),messages.join(" ")}rebuildCanonicalMatrixData(){if(this.data.kind!=="matrix"){this.cachedMatrixData={rowLabels:[],colLabels:[],values:[],truncated:!1};return}const colCount=Math.min(this.data.colLabels.length,MAX_HEATMAP_CELLS),rowLimit=colCount===0?Math.min(this.data.rowLabels.length,MAX_HEATMAP_CELLS):Math.floor(MAX_HEATMAP_CELLS/colCount),rowCount=Math.min(this.data.rowLabels.length,rowLimit),rowLabels=this.data.rowLabels.slice(0,rowCount).map(String),colLabels=this.data.colLabels.slice(0,colCount).map(String),source=this.data,values=Array.from({length:rowCount},(_,row)=>Array.from({length:colCount},(_2,col)=>source.values[row]?.[col]??(this.signedDomain?Number.NaN:-1)));this.cachedMatrixData={rowLabels,colLabels,values,truncated:rowCount!==this.data.rowLabels.length||colCount!==this.data.colLabels.length||this.data.values.some((row,index)=>index>=rowCount||row.length>colCount)}}selectedCellDescription(){if(this.multiple){const count=this.currentSelectedPositions.size;return count?this.localize("heatmapSelectedCount",void 0,{count:this.formatCount(count)}):""}if(!this.selectedCell)return"";if(this.effectiveMode==="calendar"){if(this.selectedCell.date==null)return"";const match=this.cachedCalendarCellsByDate.get(this.selectedCell.date);return match?this.localize("heatmapSelectedCellLabel",void 0,{cell:this.calendarCellText({week:match.week,weekday:match.weekday,date:match.date})}):""}const{row,col}=this.selectedCell;return row==null||col==null||row<0||row>=this.matrixRowLabels.length||col<0||col>=this.matrixColLabels.length?"":this.localize("heatmapSelectedCellLabel",void 0,{cell:this.matrixCellText({row,col})})}computeValueRange(){const pinned=this.domain;if(pinned){const[lo,hi]=pinned;if(Number.isFinite(lo)&&Number.isFinite(hi)&&lo!==hi)return lo<hi?[lo,hi]:[hi,lo]}const source=this.effectiveMode==="calendar"?this.cachedCalendarGrid.cells.map(cell=>cell.value):this.matrixValues.flat();return minMax(source.filter(v=>!this.isNoData(v)))}localizedValueLabel(){return this.valueLabel===void 0?this.localize("heatmapValueLabel"):this.valueLabel}formatNumericValue(value){return getNumberFormat(this.effectiveLocale||void 0).format(value)}syncExternalDescription(){const describedBy=this.getAttribute("aria-describedby");if(!describedBy&&!this.hasSyncedDescribedByElements)return;const control=this.accessibleCells?this.renderRoot.querySelector('[part="cells"]'):this.canvas;this.hasSyncedDescribedByElements=syncAriaDescribedByElements(this,control??void 0,describedBy)}updated(changed){if(super.updated(changed),this.syncExternalDescription(),this.hoverCell&&this.effectiveStickyLabels!=="none"&&this.scheduleAfterUpdate(()=>this.measureTooltip(),"heatmap-tooltip-metrics"),["data","cellSize","rowHeight","cellGapX","cellGapY","cellRadius","colLabelInterval","maxCellSize","minCellSize","valueLabel","scale","domain","midpoint","fitToWidth","rowLabelWidth","colLabelHeight","colLabelRotation","bucketCount","annotations","focusedCell","colorSteps","cellColor","selectedCell","selectedCells","multiple","selectionPreview","legendStops","accessibleCells","accessibleTargetSizePx","locale","stickyLabels"].some(name=>changed.has(name))){if(changed.has("focusedCell")&&[...changed.keys()].every(key=>key==="focusedCell"||key==="liveText")&&this.repaintFocusRing(changed.get("focusedCell")))return;this.requestDraw()}const pending=this.pendingAccessibleFocus;if(pending===void 0)return;this.pendingAccessibleFocus=void 0;const origin=this.pendingAccessibleFocusOrigin;this.pendingAccessibleFocusOrigin=void 0;const generation=this.accessibleFocusGeneration;this.scheduleAfterUpdate(()=>{try{if(generation!==this.accessibleFocusGeneration||!this.isConnected)return;if(origin){const internalActive=shadowFocusTarget(this),documentActive=activeElementIn(this.ownerDocument),focusStayedAtOrigin=internalActive===origin,originWasRemovedWithoutReplacement=internalActive===null&&(documentActive===null||documentActive===this||documentActive===this.ownerDocument.body);if(!focusStayedAtOrigin&&!originWasRemovedWithoutReplacement)return}if(pending==="base"){this.shadowRoot?.querySelector('[part="base"]')?.focus();return}if(pending==="canvas"){this.shadowRoot?.querySelector('[part="canvas"]')?.focus();return}const identity=this.accessibleCellIdentity(pending);[...this.shadowRoot?.querySelectorAll('[part="cell"]')??[]].find(candidate=>candidate.dataset.cellIdentity===identity)?.focus()}finally{this.restoringAccessibleFocus=!1}},"heatmap-accessible-focus")}refreshTheme(){this.cachedRamp=null,this.refreshAccessibleTargetSize()||this.requestDraw()}themeSignature(){const cs=this.ownerDocument.defaultView?.getComputedStyle(this);return cs?[...this.scaleEndpoints(cs),this.noDataFill(cs),this.labelColor(cs),this.labelFont(cs),this.focusRingColor(cs),this.annotationColor(cs),this.selectedColor(cs),this.stickyLabelBg(cs),...this.cachedColorSteps.map(step=>this.resolveColorStep(step,""))].join("\0"):""}onThemeSignal(){const signature=this.themeSignature(),resized=this.refreshAccessibleTargetSize();signature===this.paintedTheme&&!this.cellColor||(this.paintedTheme=signature,this.cachedRamp=null,resized||this.scheduleDraw())}refreshAccessibleTargetSize(){const raw=this.ownerDocument.defaultView?.getComputedStyle(this).getPropertyValue("--lr-icon-button-size").trim()??"",resolved=resolveCssTokenLength(raw,{host:this}),next=resolved!==void 0&&Number.isFinite(resolved)&&resolved>0?resolved:DEFAULT_ACCESSIBLE_TARGET_SIZE_PX;return next===this.accessibleTargetSizePx?!1:(this.accessibleTargetSizePx=next,!0)}scaleEndpoints(cs){const lo=cs.getPropertyValue("--lr-heatmap-scale-lo").trim()||cs.getPropertyValue("--_lr-heatmap-scale-lo").trim()||FALLBACK_SCALE_LO,hi=cs.getPropertyValue("--lr-heatmap-scale-hi").trim()||cs.getPropertyValue("--_lr-heatmap-scale-hi").trim()||FALLBACK_SCALE_HI;return[lo,hi]}labelColor(cs){return cs.getPropertyValue("--lr-color-text-quiet").trim()||"#6b7280"}labelFont(cs){return cs.getPropertyValue("--lr-heatmap-label-font").trim()||cs.getPropertyValue("--_lr-heatmap-label-font").trim()||FALLBACK_LABEL_FONT}stickyLabelBg(cs){const raw=cs.getPropertyValue("--lr-heatmap-sticky-label-bg").trim()||cs.getPropertyValue("--_lr-heatmap-sticky-label-bg").trim()||FALLBACK_STICKY_LABEL_BG;return formatRgb(resolveRgb(raw,FALLBACK_STICKY_LABEL_BG,this.ownerDocument))}noDataFill(cs){return cs.getPropertyValue("--lr-heatmap-no-data-fill").trim()||cs.getPropertyValue("--_lr-heatmap-no-data-fill").trim()||FALLBACK_NO_DATA_FILL}focusRingColor(cs){return cs.getPropertyValue("--lr-heatmap-focus-ring-color").trim()||cs.getPropertyValue("--_lr-heatmap-focus-ring-color").trim()||FALLBACK_FOCUS_RING_COLOR}annotationColor(cs){return cs.getPropertyValue("--lr-heatmap-annotation-color").trim()||cs.getPropertyValue("--_lr-heatmap-annotation-color").trim()||FALLBACK_ANNOTATION_COLOR}selectedColor(cs){return cs.getPropertyValue("--lr-heatmap-selected-color").trim()||cs.getPropertyValue("--_lr-heatmap-selected-color").trim()||FALLBACK_SELECTED_COLOR}strokeCellState(ctx,x,y,size,state2,color,paintedShape){const shape=paintedShape??(this.effectiveMode==="matrix"?this.matrixCellShape(size):this.calendarCellShape(size)),width=shape?.custom?shape.w:size,height=shape?.custom?shape.h:size;shape?.custom&&(ctx.save(),ctx.beginPath(),ctx.roundRect(x,y,shape.w,shape.h,shape.radius),ctx.clip());const inset=Math.min(state2==="annotation"?.5:state2==="selected"?3.5:6.5,Math.max(.5,(Math.min(width,height)-RING_LINE_WIDTH-1)/2)),w=Math.max(1,width-inset*2),h=Math.max(1,height-inset*2);ctx.lineWidth=RING_LINE_WIDTH,ctx.strokeStyle=color,ctx.setLineDash?.(state2==="annotation"?[]:state2==="selected"?[4,2]:[1,2]),shape?.custom&&shape.radius>0?(ctx.beginPath(),ctx.roundRect(x+inset,y+inset,w,h,Math.max(0,shape.radius-inset)),ctx.stroke()):ctx.strokeRect(x+inset,y+inset,w,h),ctx.setLineDash?.([]),shape?.custom&&ctx.restore()}isSelectedPos(pos){return this.multiple?this.currentSelectedPositions.has(this.accessibleCellKey(pos)):this.selectedCell?"week"in pos?this.selectedCell.date==null?!1:this.calendarCellAt(pos).date===this.selectedCell.date:this.selectedCell.row===pos.row&&this.selectedCell.col===pos.col:!1}draw(){if(!this.canvasVisible){this.drawDirty=!0;return}this.syncDeferredFitFrame(!1),this.drawDirty=!1,this.canvasHasContent=!1,this.paintedTheme??=this.themeSignature(),this.effectiveMode==="calendar"?this.drawCalendar():this.drawMatrix()}requestDraw(){this.drawDirty=!0,this.isConnected&&(this.canvasVisible?this.draw():this.syncDeferredFitFrame(!0))}syncDeferredFitFrame(deferred){const base=this.shadowRoot?.querySelector('[part="base"]');if(!base)return;let contained=!1;deferred&&this.fitToWidth&&this.clientWidth>0&&(contained=(this.effectiveMode==="calendar"?this.columnXFor(Math.max(1,this.cachedCalendarGrid.weekCount)):this.matrixPadLeft+this.matrixColLabels.length*this.matrixCellSize(this.matrixColLabels.length))<=this.clientWidth),base.toggleAttribute("data-fit-frame-contained",contained)}repaintFocusRing(previous){if(!this.canvasHasContent||!this.canvas||this.drawDirty)return!1;const current=this.focusedCell;if(this.effectiveMode==="calendar"){if(previous&&!("week"in previous)||current&&!("week"in current))return!1;this.repaintCalendarFocusCell(previous&&"week"in previous?previous:null),current&&(!previous||!this.samePos(previous,current))&&this.repaintCalendarFocusCell(current)}else{if(previous&&!("row"in previous)||current&&!("row"in current))return!1;this.repaintMatrixFocusCell(previous&&"row"in previous?previous:null),current&&(!previous||!this.samePos(previous,current))&&this.repaintMatrixFocusCell(current)}return!0}cancelDrawFrame(){const request=this.drawFrameRequest;request&&request.owner.cancelAnimationFrame(request.handle),this.drawFrameRequest=void 0}resolveColorStep(color,fallback){const safe=sanitizeCssColor(color);return safe?resolveCanvasColor(this,safe,fallback):fallback}colorRamp(bucketCount,cs){const steps=this.cachedColorSteps;if(steps&&steps.length>=2){const key2=`steps ${steps.join(" ")}`;if(this.cachedRamp?.key===key2)return this.cachedRamp;const resolved=steps.map((color,index)=>this.resolveColorStep(color,index===steps.length-1?FALLBACK_SCALE_HI:FALLBACK_SCALE_LO)),colors2=resolved.map(color=>formatRgb(resolveRgb(color,FALLBACK_SCALE_LO,this.ownerDocument))),loRgb2=resolveRgb(resolved[0],FALLBACK_SCALE_LO,this.ownerDocument),hiRgb2=resolveRgb(resolved[resolved.length-1],FALLBACK_SCALE_HI,this.ownerDocument);return this.cachedRamp={key:key2,colors:colors2,loRgb:loRgb2,hiRgb:hiRgb2},this.cachedRamp}const[scaleLo,scaleHi]=this.scaleEndpoints(cs),normalizedBucketCount=normalizeBucketCount(bucketCount),key=`${scaleLo}\0${scaleHi}\0${normalizedBucketCount}`;if(this.cachedRamp?.key===key)return this.cachedRamp;const loRgb=resolveRgb(scaleLo,FALLBACK_SCALE_LO,this.ownerDocument),hiRgb=resolveRgb(scaleHi,FALLBACK_SCALE_HI,this.ownerDocument),colors=Array.from({length:normalizedBucketCount},(_,i)=>mixRgb(loRgb,hiRgb,i/(normalizedBucketCount-1)));return this.cachedRamp={key,colors,loRgb,hiRgb},this.cachedRamp}calendarCellSize(){return this.calendarSpacing().cellSize}calendarSpacing(){const{weekCount}=this.cachedCalendarGrid,rawGapX=this.explicitCalendarSpacing("cellGapX"),rawGapY=this.explicitCalendarSpacing("cellGapY"),rawRadius=this.explicitCalendarSpacing("cellRadius"),boundGap=(raw,size2)=>raw===void 0?CAL_GAP:finiteRange(raw,CAL_GAP,0,Math.max(0,size2-1));let size;if(this.fitToWidth&&weekCount>0){const fitGap=boundGap(rawGapX,this.cellSize),hostWidth=this.clientWidth||this.calendarPadLeft+weekCount*(this.cellSize+fitGap);size=this.clampFitCellSize((hostWidth-this.calendarPadLeft)/weekCount-fitGap)}else size=this.cellSize;return this.accessibleCells&&(size=Math.max(size,this.accessibleTargetSizePx)),{cellSize:size,gapX:boundGap(rawGapX,size),gapY:boundGap(rawGapY,size),radius:rawRadius===void 0?0:finiteRange(rawRadius,0,0,size/2)}}clampFitCellSize(size){const floored=finiteRange(size,FIT_MIN_CELL,Math.max(FIT_MIN_CELL,this.minCellSize??FIT_MIN_CELL));return this.maxCellSize==null?floored:Math.min(floored,this.maxCellSize)}columnXFor(week){return this.calendarColumnPositions()[week]??this.calendarPadLeft}rowYFor(weekday){return this.calendarRowPositions()[weekday]??CAL_LABEL_H}calendarColumnPositions(){const{cellSize,gapX:gap}=this.calendarSpacing(),weekCount=this.cachedCalendarGrid.weekCount,callback=this.calendarColumnX,padLeft=this.calendarPadLeft,cached=this.cachedColumnGeometry;if(cached!==void 0&&cached.callback===callback&&cached.padLeft===padLeft&&cached.cellSize===cellSize&&cached.gap===gap&&cached.weekCount===weekCount)return cached.positions;const positions=[];for(let index=0;index<=weekCount;index++){const fallback=index===0?padLeft:positions[index-1]+cellSize+gap;let candidate=fallback;if(callback)try{const supplied=callback(index);Number.isFinite(supplied)&&supplied>=0&&(index===0||supplied>=positions[index-1]+cellSize)&&(candidate=supplied)}catch{candidate=fallback}positions.push(candidate)}return this.cachedColumnGeometry={callback,padLeft,cellSize,gap,weekCount,positions},positions}calendarRowPositions(){const{cellSize,gapY:gap}=this.calendarSpacing(),callback=this.calendarRowY,cached=this.cachedRowGeometry;if(cached!==void 0&&cached.callback===callback&&cached.cellSize===cellSize&&cached.gap===gap)return cached.positions;const positions=[];for(let index=0;index<=7;index++){const fallback=index===0?CAL_LABEL_H:positions[index-1]+cellSize+gap;let candidate=fallback;if(callback)try{const supplied=callback(index);Number.isFinite(supplied)&&supplied>=0&&(index===0||supplied>=positions[index-1]+cellSize)&&(candidate=supplied)}catch{candidate=fallback}positions.push(candidate)}return this.cachedRowGeometry={callback,cellSize,gap,positions},positions}weekdayLabels(firstWeekStart){const formatter=getDateTimeFormat(this.effectiveLocale||void 0,{weekday:"short",timeZone:"UTC"}),labels=["","","","","","",""];for(const weekday of[1,3,5]){const row=(weekday-this.normalizedFirstDayOfWeek+7)%7;labels[row]=this.calendarWeekdayLabelText?.(weekday)??formatter.format(new Date(firstWeekStart.getTime()+row*MS_PER_DAY))}return labels}paintCalendarAxisLabels(ctx,cellSize,cs,firstWeekStart,monthLabels,months=!0,weekdays=!0){if(ctx.fillStyle=this.labelColor(cs),ctx.font=this.labelFont(cs),months){const canvasRight=this.columnXFor(Math.max(1,this.cachedCalendarGrid.weekCount)),placed=[];monthLabels.forEach((month,index)=>{const label=this.ellipsize(ctx,month.label,canvasRight);if(!label)return;const width=this.labelWidth(ctx,label),x=Math.max(0,Math.min(this.columnXFor(month.week),canvasRight-width)),nextWeek=monthLabels[index+1]?.week??Math.max(month.week+1,this.cachedCalendarGrid.weekCount),entry={label,x,end:x+width+CAL_MONTH_LABEL_GAP,span:nextWeek-month.week};let previous=placed[placed.length-1];for(;previous&&entry.x<previous.end&&entry.span>previous.span;)placed.pop(),previous=placed[placed.length-1];previous&&entry.x<previous.end||placed.push(entry)});for(const{label,x}of placed)ctx.fillText(label,x,CAL_LABEL_H-4)}if(weekdays){const available=this.calendarPadLeft-CAL_WEEKDAY_LABEL_INSET*2;this.weekdayLabels(firstWeekStart).forEach((label,weekday)=>{const shown=label?this.ellipsize(ctx,label,available):"";shown&&ctx.fillText(shown,CAL_WEEKDAY_LABEL_INSET,this.rowYFor(weekday)+cellSize-1)})}}drawCalendar(){this.withLabelCache(()=>this.paintCalendar())}paintCalendar(){if(!this.canvas)return;const{weekCount,firstWeekStart,monthLabels}=this.cachedCalendarGrid,cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;this.calendarWeekdayLabelWidth==="auto"&&(this.resolvedCalendarWeekdayLabelWidth=this.measureCalendarWeekdayLabelWidth(cs,firstWeekStart));const spacing=this.calendarSpacing(),cellSize=spacing.cellSize,w=this.columnXFor(Math.max(1,weekCount)),h=this.rowYFor(7),ctx=this.sizeCanvas(this.canvas,w,h);if(!ctx)return;ctx.clearRect(0,0,w,h);const buckets=normalizeBucketCount(this.bucketCount),ramp=this.colorRamp(buckets,cs).colors,noDataFill=this.noDataFill(cs);this.canvasColorCache.clear();const bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1;for(let week=0;week<weekCount;week++)for(let weekday=0;weekday<7;weekday++){const value=this.calendarValueAt(week,weekday),x=this.columnXFor(week),y=this.rowYFor(weekday),override=this.cellColor?.(this.calendarPos(week,weekday),value);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(value))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(value,hi,ramp.length);ctx.fillStyle=step<0?noDataFill:ramp[step]}else if(this.cachedColorSteps.length>=2){const step=this.rampBucket(value,lo,hi,ramp.length);ctx.fillStyle=ramp[step]}else ctx.fillStyle=ramp[quartileBucket(value,this.cachedCalendarSortedValues,buckets)];this.fillCalendarCell(ctx,x,y,cellSize,spacing.radius)}if(this.cachedAnnotations.length)for(const ann of this.cachedAnnotations){if(ann.date==null)continue;const match=this.cachedCalendarCellsByDate.get(ann.date);if(!match)continue;const x=this.columnXFor(match.week),y=this.rowYFor(match.weekday);this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs))}for(const match of this.selectedPaintPositions())if("week"in match){const x=this.columnXFor(match.week),y=this.rowYFor(match.weekday);this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs))}if(this.focusedCell&&"week"in this.focusedCell){const{week,weekday}=this.focusedCell;if(week<weekCount&&weekday<7){const x=this.columnXFor(week),y=this.rowYFor(weekday);this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs))}}this.paintCalendarAxisLabels(ctx,cellSize,cs,firstWeekStart,monthLabels),this.canvasHasContent=!0,this.recordCalendarGeometry(spacing,weekCount)&&this.accessibleCells&&this.scheduleAfterUpdate(()=>this.requestUpdate(),"heatmap-calendar-accessible-geometry")}matrixCellSize(cols){let size;if(this.fitToWidth&&cols>0){const padLeft=this.matrixPadLeft,hostWidth=this.clientWidth||padLeft+cols*this.cellSize;size=this.clampFitCellSize((hostWidth-padLeft)/cols)}else size=this.cellSize;if(!this.accessibleCells)return size;const target=this.accessibleTargetSizePx,custom=finiteNumber(this.cellGapX,1)!==1||finiteNumber(this.cellGapY,1)!==1||finiteRange(this.cellRadius,0,0)>0,gap=this.rowHeight!==void 0?finiteRange(this.cellGapX,1,0,target):custom?Math.max(finiteRange(this.cellGapX,1,0,target),finiteRange(this.cellGapY,1,0,target)):0;return Math.max(size,target+gap)}matrixRowHeight(cellSize){if(this.rowHeight===void 0)return cellSize;const height=finiteRange(this.rowHeight,cellSize,1);if(!this.accessibleCells)return height;const target=this.accessibleTargetSizePx;return Math.max(height,target+finiteRange(this.cellGapY,1,0,target))}matrixCellShape(size,height=this.matrixRowHeight(size)){if(height===size&&finiteNumber(this.cellGapX,1)===1&&finiteNumber(this.cellGapY,1)===1&&finiteRange(this.cellRadius,0,0)===0)return{w:size-1,h:size-1,radius:0,custom:!1};const target=this.accessibleCells?this.accessibleTargetSizePx:1,w=size-finiteRange(this.cellGapX,1,0,Math.max(0,size-Math.min(size,target))),h=height-finiteRange(this.cellGapY,1,0,Math.max(0,height-Math.min(height,target))),radius=finiteRange(this.cellRadius,0,0,Math.min(w,h)/2);return{w,h,radius,custom:height!==size||w!==size-1||h!==size-1||radius!==0}}calendarCellShape(size){const radius=this.calendarSpacing().radius;return radius>0?{w:size,h:size,radius:Math.min(radius,size/2),custom:!0}:void 0}fillMatrixCell(ctx,x,y,shape){shape.radius===0?ctx.fillRect(x,y,shape.w,shape.h):(ctx.beginPath(),ctx.roundRect(x,y,shape.w,shape.h,shape.radius),ctx.fill())}paintMatrixCell(ctx,row,col,cellSize,rowHeight,shape,cs,rampData,noDataFill){const value=this.matrixValues[row]?.[col]??Number.NaN,bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1,override=this.cellColor?.({row,col},value);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(value))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(value,hi,rampData.colors.length);ctx.fillStyle=step<0?noDataFill:rampData.colors[step]}else this.cachedColorSteps.length>=2?ctx.fillStyle=rampData.colors[this.rampBucket(value,lo,hi,rampData.colors.length)]:ctx.fillStyle=mixRgb(rampData.loRgb,rampData.hiRgb,this.rampAlpha(value,lo,hi));this.fillMatrixCell(ctx,this.matrixPadLeft+col*cellSize,this.matrixPadTop+row*rowHeight,shape)}paintMatrixFocusOverlays(ctx,row,col,cellSize,rowHeight,shape,cs,state2){const x=this.matrixPadLeft+col*cellSize,y=this.matrixPadTop+row*rowHeight;state2==="annotation"&&this.cachedMatrixAnnotationPositions.has(`${row}:${col}`)&&this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs),shape),state2==="selected"&&this.isSelectedPos({row,col})&&this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs),shape),state2==="focus"&&this.focusedCell&&"row"in this.focusedCell&&this.focusedCell.row===row&&this.focusedCell.col===col&&this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs),shape)}focusRepaintBounds(ctx,x,y,cellSize,cellHeight=cellSize){const padding=RING_LINE_WIDTH+1,dpr=ctx.getTransform().a,left=Math.floor((x-padding)*dpr)/dpr,top=Math.floor((y-padding)*dpr)/dpr,right=Math.ceil((x+cellSize+padding)*dpr)/dpr,bottom=Math.ceil((y+cellHeight+padding)*dpr)/dpr;return{left,top,width:right-left,height:bottom-top,radius:Math.ceil((2*padding+1/dpr)/cellSize),rowRadius:Math.ceil((2*padding+1/dpr)/cellHeight)}}repaintMatrixFocusCell(pos){this.withLabelCache(()=>this.paintMatrixFocusCell(pos))}paintMatrixFocusCell(pos){if(!pos||!this.canvas)return;const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;if(pos.row<0||pos.row>=rows||pos.col<0||pos.col>=cols)return;const cellSize=this.matrixCellSize(cols),rowHeight=this.matrixRowHeight(cellSize),shape=this.matrixCellShape(cellSize,rowHeight),x=this.matrixPadLeft+pos.col*cellSize,y=this.matrixPadTop+pos.row*rowHeight,ctx=this.canvas.getContext("2d");if(!ctx)return;const cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;const{left,top,width,height,radius,rowRadius}=this.focusRepaintBounds(ctx,x,y,cellSize,rowHeight),firstRow=Math.max(0,pos.row-rowRadius),lastRow=Math.min(rows-1,pos.row+rowRadius),firstCol=Math.max(0,pos.col-radius),lastCol=Math.min(cols-1,pos.col+radius),ramp=this.colorRamp(RAMP_STEPS,cs),noData=this.noDataFill(cs),scratch=rowHeight===cellSize?void 0:this.ownerDocument.createElement("canvas"),dpr=ctx.getTransform().a,scratchLeft=Math.floor((this.matrixPadLeft+firstCol*cellSize-RING_LINE_WIDTH-1)*dpr)/dpr,scratchTop=Math.floor((this.matrixPadTop+firstRow*rowHeight-RING_LINE_WIDTH-1)*dpr)/dpr;if(scratch){const right=Math.ceil((this.matrixPadLeft+(lastCol+1)*cellSize+RING_LINE_WIDTH+1)*dpr),bottom=Math.ceil((this.matrixPadTop+(lastRow+1)*rowHeight+RING_LINE_WIDTH+1)*dpr);scratch.width=right-Math.round(scratchLeft*dpr),scratch.height=bottom-Math.round(scratchTop*dpr)}const paintCtx=scratch?.getContext("2d")??ctx;if(scratch&&paintCtx===ctx){this.drawMatrix();return}paintCtx.save();try{scratch?paintCtx.setTransform(dpr,0,0,dpr,-scratchLeft*dpr,-scratchTop*dpr):(paintCtx.beginPath(),paintCtx.rect(left,top,width,height),paintCtx.clip(),paintCtx.clearRect(left,top,width,height));for(let row=firstRow;row<=lastRow;row++)for(let col=firstCol;col<=lastCol;col++)this.paintMatrixCell(paintCtx,row,col,cellSize,rowHeight,shape,cs,ramp,noData);for(const state2 of["annotation","selected","focus"])for(let row=firstRow;row<=lastRow;row++)for(let col=firstCol;col<=lastCol;col++)this.paintMatrixFocusOverlays(paintCtx,row,col,cellSize,rowHeight,shape,cs,state2);left<this.matrixPadLeft&&this.paintMatrixRowLabels(paintCtx,this.matrixPadLeft,this.matrixPadTop,rowHeight,cs,{top,bottom:top+height}),top<this.matrixPadTop&&this.paintMatrixColLabels(paintCtx,this.matrixPadLeft,this.matrixPadTop,cellSize,cs,{first:firstCol,last:lastCol})}finally{paintCtx.restore()}if(scratch){ctx.save();try{ctx.setTransform(1,0,0,1,0,0),ctx.clearRect(left*dpr,top*dpr,width*dpr,height*dpr),ctx.drawImage(scratch,Math.round((left-scratchLeft)*dpr),Math.round((top-scratchTop)*dpr),Math.round(width*dpr),Math.round(height*dpr),Math.round(left*dpr),Math.round(top*dpr),Math.round(width*dpr),Math.round(height*dpr))}finally{ctx.restore()}}}paintCalendarCell(ctx,week,weekday,cellSize,cs,ramp,noDataFill){const value=this.calendarValueAt(week,weekday),bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1,override=this.cellColor?.(this.calendarPos(week,weekday),value);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(value))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(value,hi,ramp.length);ctx.fillStyle=step<0?noDataFill:ramp[step]}else this.cachedColorSteps.length>=2?ctx.fillStyle=ramp[this.rampBucket(value,lo,hi,ramp.length)]:ctx.fillStyle=ramp[quartileBucket(value,this.cachedCalendarSortedValues,ramp.length)];this.fillCalendarCell(ctx,this.columnXFor(week),this.rowYFor(weekday),cellSize,this.calendarSpacing().radius)}fillCalendarCell(ctx,x,y,size,radius){radius===0?ctx.fillRect(x,y,size,size):(ctx.beginPath(),ctx.roundRect(x,y,size,size,radius),ctx.fill())}recordCalendarGeometry(spacing,weekCount){const next={padLeft:this.calendarPadLeft,padTop:CAL_LABEL_H,cellSize:spacing.cellSize,cellWidth:spacing.cellSize,cellHeight:spacing.cellSize,cellGapX:spacing.gapX,cellGapY:spacing.gapY,cellRadius:spacing.radius,weekCount,firstDayOfWeek:this.normalizedFirstDayOfWeek},previous=this.lastPaintedCalendarGeometry;if(previous&&Object.keys(next).every(key=>previous[key]===next[key]))return!1;const frozen=Object.freeze(next);return this.lastPaintedCalendarGeometry=frozen,this.emit("lr-calendar-geometry-change",frozen),!0}paintCalendarFocusOverlays(ctx,week,weekday,cellSize,cs,state2){const date=this.calendarDateAt(week,weekday),x=this.columnXFor(week),y=this.rowYFor(weekday);state2==="annotation"&&this.cachedCalendarCellsByDate.has(date)&&this.cachedCalendarAnnotationDates.has(date)&&this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs)),state2==="selected"&&(this.multiple||this.cachedCalendarCellsByDate.has(date))&&this.isSelectedPos({week,weekday,date})&&this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs)),state2==="focus"&&this.focusedCell&&"week"in this.focusedCell&&this.focusedCell.week===week&&this.focusedCell.weekday===weekday&&this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs))}repaintCalendarFocusCell(pos){this.withLabelCache(()=>this.paintCalendarFocusCell(pos))}paintCalendarFocusCell(pos){if(!pos||!this.canvas)return;const{weekCount,firstWeekStart}=this.cachedCalendarGrid;if(pos.week<0||pos.week>=weekCount||pos.weekday<0||pos.weekday>=7)return;const cellSize=this.calendarCellSize(),x=this.columnXFor(pos.week),y=this.rowYFor(pos.weekday),ctx=this.canvas.getContext("2d");if(!ctx)return;const cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;const{left,top,width,height,radius}=this.focusRepaintBounds(ctx,x,y,cellSize),firstWeek=Math.max(0,pos.week-radius),lastWeek=Math.min(weekCount-1,pos.week+radius),firstDay=Math.max(0,pos.weekday-radius),lastDay=Math.min(6,pos.weekday+radius),ramp=this.colorRamp(normalizeBucketCount(this.bucketCount),cs).colors,noData=this.noDataFill(cs);ctx.save();try{ctx.beginPath(),ctx.rect(left,top,width,height),ctx.clip(),ctx.clearRect(left,top,width,height);for(let week=firstWeek;week<=lastWeek;week++)for(let day=firstDay;day<=lastDay;day++)this.paintCalendarCell(ctx,week,day,cellSize,cs,ramp,noData);for(const state2 of["annotation","selected","focus"])for(let week=firstWeek;week<=lastWeek;week++)for(let day=firstDay;day<=lastDay;day++)this.paintCalendarFocusOverlays(ctx,week,day,cellSize,cs,state2);this.paintCalendarAxisLabels(ctx,cellSize,cs,firstWeekStart,this.cachedCalendarGrid.monthLabels,top<CAL_LABEL_H,left<this.calendarPadLeft)}finally{ctx.restore()}}drawMatrix(){this.withLabelCache(()=>this.paintMatrix())}paintMatrix(){if(!this.canvas)return;const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length,cs=this.ownerDocument.defaultView?.getComputedStyle(this);if(!cs)return;this.rowLabelWidth==="auto"&&(this.resolvedRowLabelWidth=this.measureRowLabelWidth(cs)),this.colLabelHeight==="auto"&&(this.resolvedColLabelHeight=this.measureColLabelHeight(cs));const padLeft=this.matrixPadLeft,padTop=this.matrixPadTop,cellSize=this.matrixCellSize(cols),rowHeight=this.matrixRowHeight(cellSize),shape=this.matrixCellShape(cellSize,rowHeight),dimensions=shape.custom?{cellWidth:shape.w,cellHeight:shape.h,cellRadius:shape.radius}:{},previous=this.lastPaintedMatrixGeometry,geometry=previous&&previous.padLeft===padLeft&&previous.padTop===padTop&&previous.cellSize===cellSize&&previous.rowHeight===(rowHeight===cellSize?void 0:rowHeight)&&previous.cellWidth===dimensions.cellWidth&&previous.cellHeight===dimensions.cellHeight&&previous.cellRadius===dimensions.cellRadius?previous:Object.freeze({padLeft,padTop,cellSize,...rowHeight===cellSize?{}:{rowHeight},...dimensions});this.lastPaintedMatrixGeometry=geometry;const geometryChanged=geometry!==previous;geometryChanged&&this.emit("lr-matrix-geometry-change",geometry);const w=padLeft+cols*cellSize,h=padTop+rows*rowHeight,ctx=this.sizeCanvas(this.canvas,w,h);if(!ctx)return;ctx.clearRect(0,0,w,h);const bounds=this.cachedValueRange,lo=bounds?bounds[0]:0,hi=bounds?bounds[1]:1,rampData=this.colorRamp(RAMP_STEPS,cs),ramp=rampData.colors,{loRgb,hiRgb}=rampData,noDataFill=this.noDataFill(cs);this.canvasColorCache.clear();for(let r=0;r<rows;r++)for(let c=0;c<cols;c++){const v=this.matrixValues[r]?.[c]??Number.NaN,x=padLeft+c*cellSize,y=padTop+r*rowHeight,override=this.cellColor?.({row:r,col:c},v);if(override!=null)ctx.fillStyle=this.resolveCellColor(override,cs);else if(this.isNoData(v))ctx.fillStyle=noDataFill;else if(this.scale==="sqrt"){const step=sqrtStep(v,hi,ramp.length);ctx.fillStyle=step<0?noDataFill:ramp[step]}else if(this.cachedColorSteps.length>=2){const step=this.rampBucket(v,lo,hi,ramp.length);ctx.fillStyle=ramp[step]}else{const t=this.rampAlpha(v,lo,hi);ctx.fillStyle=mixRgb(loRgb,hiRgb,t)}this.fillMatrixCell(ctx,x,y,shape)}if(this.cachedAnnotations.length)for(const ann of this.cachedAnnotations){if(ann.row==null||ann.col==null||ann.row<0||ann.row>=rows||ann.col<0||ann.col>=cols)continue;const x=padLeft+ann.col*cellSize,y=padTop+ann.row*rowHeight;this.strokeCellState(ctx,x,y,cellSize,"annotation",this.annotationColor(cs),shape)}for(const selected of this.selectedPaintPositions()){if(!("row"in selected))continue;const{row,col}=selected;if(row>=0&&row<rows&&col>=0&&col<cols){const x=padLeft+col*cellSize,y=padTop+row*rowHeight;this.strokeCellState(ctx,x,y,cellSize,"selected",this.selectedColor(cs),shape)}}if(this.focusedCell&&"row"in this.focusedCell){const{row,col}=this.focusedCell;if(row<rows&&col<cols){const x=padLeft+col*cellSize,y=padTop+row*rowHeight;this.strokeCellState(ctx,x,y,cellSize,"focus",this.focusRingColor(cs),shape)}}this.paintMatrixRowLabels(ctx,padLeft,padTop,rowHeight,cs),this.paintMatrixColLabels(ctx,padLeft,padTop,cellSize,cs),this.paintFrozenLabelBands(padLeft,padTop,cellSize,rowHeight,w,h,ctx.getTransform().a,cs),this.canvasHasContent=!0,geometryChanged&&this.accessibleCells&&this.scheduleAfterUpdate(()=>this.requestUpdate(),"heatmap-matrix-accessible-geometry")}paintMatrixRowLabels(ctx,padLeft,padTop,cellSize,cs,dirty){ctx.fillStyle=this.labelColor(cs),ctx.font=this.labelFont(cs);const rowLabelSpace=padLeft-ROW_LABEL_INSET*2;let first=0,last=this.matrixRowLabels.length-1;if(dirty){const{fontBoundingBoxAscent,fontBoundingBoxDescent}=ctx.measureText("M"),baseline=padTop+cellSize/2+3;first=Math.max(first,Math.floor((dirty.top-fontBoundingBoxDescent-baseline)/cellSize)),last=Math.min(last,Math.ceil((dirty.bottom+fontBoundingBoxAscent-baseline)/cellSize))}for(let r=first;r<=last;r++){const shown=this.ellipsize(ctx,this.matrixRowLabels[r],rowLabelSpace);shown&&ctx.fillText(shown,ROW_LABEL_INSET,padTop+r*cellSize+cellSize/2+3)}}paintMatrixColLabels(ctx,padLeft,padTop,cellSize,cs,columns){ctx.fillStyle=this.labelColor(cs),ctx.font=this.labelFont(cs);const colRotation=this.effectiveColLabelRotation,interval=finiteInteger(this.colLabelInterval,1,1);if(colRotation===0){const cols=this.matrixColLabels.length;this.matrixColLabels.forEach((label,c)=>{if(c%interval!==0||columns&&(c<columns.first-interval+1||c>columns.last))return;const shown=this.ellipsize(ctx,label,Math.min(interval,cols-c)*cellSize-2);shown&&ctx.fillText(shown,padLeft+c*cellSize+2,padTop-COL_LABEL_INSET)});return}const radians=colRotation*Math.PI/180,previousAlign=ctx.textAlign;ctx.textAlign="right",this.matrixColLabels.forEach((label,c)=>{c%interval===0&&(ctx.save(),ctx.translate(padLeft+c*cellSize+cellSize/2,padTop-COL_LABEL_INSET),ctx.rotate(radians),ctx.fillText(label,0,0),ctx.restore())}),ctx.textAlign=previousAlign}paintFrozenLabelBands(padLeft,padTop,cellSize,rowHeight,width,height,scale,cs){if(this.effectiveStickyLabels==="none")return;const backdrop=this.stickyLabelBg(cs),rowBand=this.frozenBandCanvas("row-labels");rowBand&&this.paintFrozenBand(rowBand,padLeft,height,scale,backdrop,bandCtx=>this.paintMatrixRowLabels(bandCtx,padLeft,padTop,rowHeight,cs));const colBand=this.frozenBandCanvas("col-labels");colBand&&this.paintFrozenBand(colBand,width,padTop,scale,backdrop,bandCtx=>this.paintMatrixColLabels(bandCtx,padLeft,padTop,cellSize,cs))}frozenBandCanvas(part){return this.shadowRoot?.querySelector(`[part="${part}"]`)??null}sizeCanvas(canvas,width,height,desiredScale=this.ownerDocument.defaultView?.devicePixelRatio){const{pixelWidth,pixelHeight,scale}=resolveBoundedCanvasAllocation({cssWidth:width,cssHeight:height,desiredScale,maxDimension:MAX_CANVAS_DIMENSION,maxPixels:MAX_CANVAS_PIXELS});canvas.width=pixelWidth,canvas.height=pixelHeight,canvas.style.width=`${width}px`,canvas.style.height=`${height}px`;const ctx=canvas.getContext("2d");return ctx?.scale(scale,scale),ctx}paintFrozenBand(canvas,width,height,scale,backdrop,paint){const ctx=this.sizeCanvas(canvas,width,height,scale);ctx&&(ctx.clearRect(0,0,width,height),ctx.fillStyle=backdrop,ctx.fillRect(0,0,width,height),paint(ctx))}hitTest(x,y){return this.effectiveMode==="calendar"?this.hitTestCalendar(x,y):this.hitTestMatrix(x,y)}matrixNavigationGeometry(rows,cols){const painted=this.lastPaintedMatrixGeometry;if(painted)return{rows,cols,padLeft:painted.padLeft,padTop:painted.padTop,cellSize:painted.cellSize,rowHeight:painted.rowHeight??painted.cellSize,cellWidth:painted.cellWidth??painted.cellSize-1,cellHeight:painted.cellHeight??painted.cellSize-1,customShape:painted.cellWidth!==void 0};const cellSize=this.matrixCellSize(cols),rowHeight=this.matrixRowHeight(cellSize),shape=this.matrixCellShape(cellSize,rowHeight);return{rows,cols,padLeft:this.matrixPadLeft,padTop:this.matrixPadTop,cellSize,rowHeight,cellWidth:shape.w,cellHeight:shape.h,customShape:shape.custom}}calendarNavigationGeometry(){const cellSize=this.calendarCellSize(),columnPositions=this.calendarColumnPositions(),rowPositions=this.calendarRowPositions();return{weekCount:this.cachedCalendarGrid.weekCount,cellSize,columnPositions,rowPositions,padLeft:this.calendarPadLeft,padTop:CAL_LABEL_H}}hitTestMatrix(x,y){const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;return rows===0||cols===0?null:hitTestMatrixGrid(x,y,this.matrixNavigationGeometry(rows,cols),pos=>this.isCellInteractive(pos))}firstInteractiveMatrixCell(rows,cols){return findFirstInteractiveMatrixCell(rows,cols,pos=>this.isCellInteractive(pos))}nextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols){return findNextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols,pos=>this.isCellInteractive(pos))}firstInteractiveCalendarCell(weekCount){return findFirstInteractiveCalendarCell(weekCount,(week,weekday)=>this.calendarPos(week,weekday),pos=>this.isCellInteractive(pos))}nextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount){return findNextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount,(nextWeek,nextWeekday)=>this.calendarPos(nextWeek,nextWeekday),pos=>this.isCellInteractive(pos))}hitTestCalendar(x,y){const weekCount=this.cachedCalendarGrid.weekCount;if(weekCount===0)return null;const columnPositions=this.calendarColumnPositions();return hitTestCalendarGrid(x,y,weekCount,columnPositions,()=>this.calendarCellSize(),()=>this.calendarRowPositions(),(week,weekday)=>this.calendarPos(week,weekday),pos=>this.isCellInteractive(pos))}calendarCellAt(pos){return readCalendarCell(pos.week,pos.weekday,this.cachedCalendarCellsByPos,this.cachedCalendarDateByPos,this.cachedCalendarGrid.firstWeekStart,this.signedDomain)}calendarValueAt(week,weekday){return readCalendarValue(week,weekday,this.cachedCalendarCellsByPos,this.signedDomain)}calendarDateAt(week,weekday){return readCalendarDate(week,weekday,this.cachedCalendarDateByPos,this.cachedCalendarGrid.firstWeekStart)}calendarPos(week,weekday){return{week,weekday,date:this.calendarDateAt(week,weekday)}}cellRect(pos){return"week"in pos?calendarCellRect(pos.week,pos.weekday,this.calendarNavigationGeometry()):matrixCellRect(pos,this.matrixNavigationGeometry(this.matrixRowLabels.length,this.matrixColLabels.length))}accessibleCellRect(pos){return"week"in pos||!this.lastPaintedMatrixGeometry?this.cellRect(pos):accessibleMatrixCellRect(pos,this.lastPaintedMatrixGeometry)}defaultCellText(pos){return"week"in pos?this.calendarCellText(pos):this.matrixCellText(pos)}matrixCellText(pos){const rowLabel=this.matrixRowLabels[pos.row]??this.localize("heatmapDefaultRowLabel",void 0,{n:this.formatCount(pos.row+1)}),colLabel=this.matrixColLabels[pos.col]??this.localize("heatmapDefaultColLabel",void 0,{n:this.formatCount(pos.col+1)}),v=this.matrixValues[pos.row]?.[pos.col],valueText=v==null||this.isNoData(v)?this.localize("heatmapNoDataValue"):this.formatNumericValue(v);return this.localize("heatmapMatrixCellLabel",void 0,{row:rowLabel,col:colLabel,value:valueText})}calendarCellText(pos){const{date,value}=this.calendarCellAt(pos),label=getDateTimeFormat(this.effectiveLocale||void 0,{month:"short",day:"numeric",timeZone:"UTC"}).format(parseIsoDate(date)),valueText=this.isNoData(value)?this.localize("heatmapNoDataValue"):this.formatNumericValue(value);return this.localize("heatmapCalendarCellLabel",void 0,{date:label,value:valueText})}valueAt(pos){return"week"in pos?this.calendarCellAt(pos).value:this.matrixValues[pos.row]?.[pos.col]??-1}resolveCellText(pos){return this.cellText?this.cellText(pos,this.valueAt(pos)):this.defaultCellText(pos)}isCellInteractive(pos){return this.cellInteractive?.(pos,this.valueAt(pos))??!0}announce(pos,isSelectedOverride){const text=this.resolveCellText(pos),announcement=isSelectedOverride??this.isSelectedPos(pos)?this.localize("heatmapSelectedCellLabel",void 0,{cell:text}):text;this.liveText=announcement,this.announcements.announcePolite(announcement)}emitCellClick(pos,source="pointer",select=!0){if(!this.isCellInteractive(pos))return;this.multiple&&select&&(this.selectionAnchor=pos,this.selectionRangeBase=void 0,this.toggleSelectionPositions([pos],source));let detail;if("week"in pos){const{date,value}=this.calendarCellAt(pos);detail={date,value}}else{const value=this.matrixValues[pos.row]?.[pos.col]??-1;detail={row:pos.row,col:pos.col,value}}this.emit("lr-cell-activate",{...detail})}get currentSelectedPositions(){return this.selectionPreview??this.selectedPositions}selectedPaintPositions(){if(this.multiple)return[...this.currentSelectedPositions.values()];const selected=this.selectedCell;if(!selected)return[];if(this.effectiveMode==="calendar"){const match=selected.date?this.cachedCalendarCellsByDate.get(selected.date):void 0;return match?[match]:[]}return selected.row!=null&&selected.col!=null?[{row:selected.row,col:selected.col}]:[]}rebuildSelectedPositions(){const positions=new Map,dates=this.effectiveMode==="calendar"?new Map(this.cachedAccessiblePositions.map(pos=>[this.accessibleCellIdentity(pos),pos])):void 0,input=Array.isArray(this.selectedCells)?this.selectedCells:[];for(const cell of input.slice(0,MAX_HEATMAP_CELLS)){if(!cell||typeof cell!="object")continue;const pos=dates?typeof cell.date=="string"?dates.get(cell.date):void 0:Number.isInteger(cell.row)&&Number.isInteger(cell.col)?this.cachedAccessiblePositionsByKey.get(`matrix-${cell.row}-${cell.col}`):void 0;pos&&positions.set(this.accessibleCellKey(pos),pos)}this.selectedPositions=positions}selectionCoordinates(pos){return"week"in pos?{row:pos.weekday,col:pos.week}:pos}proposeSelection(positions,source){if(positions.size===this.selectedPositions.size&&[...positions.keys()].every(key=>this.selectedPositions.has(key)))return;this.proposedSelectionKeys=new Set(positions.keys());const selectedCells=[...positions.values()].sort((a,b)=>{const first=this.selectionCoordinates(a),second=this.selectionCoordinates(b);return first.row-second.row||first.col-second.col}).map(pos=>"week"in pos?{date:pos.date}:{row:pos.row,col:pos.col});this.emit("lr-selection-change",{selectedCells,source})}toggleSelectionPositions(positions,source){if(!this.multiple||positions.length===0)return;const next=new Map(this.selectedPositions),remove=positions.every(pos=>next.has(this.accessibleCellKey(pos)));for(const pos of positions){const key=this.accessibleCellKey(pos);remove?next.delete(key):next.set(key,pos)}this.proposeSelection(next,source)}toggleSelectionAxis(index,row){!this.multiple||!Number.isInteger(index)||index<0||(this.cancelSelectionGesture(),this.selectionRangeBase=void 0,this.toggleSelectionPositions(this.cachedAccessiblePositions.filter(pos=>{const coordinates=this.selectionCoordinates(pos);return(row?coordinates.row:coordinates.col)===index}),row?"row":"column"))}selectionKeyDown(event,pos){if(!this.multiple)return!1;if(event.key==="Escape"&&this.selectionGesture)return event.preventDefault(),this.cancelSelectionGesture(),!0;if(event.key!==" "||!pos||!(event.shiftKey||event.ctrlKey||event.metaKey))return!1;event.preventDefault();const coordinates=this.selectionCoordinates(pos);return event.ctrlKey||event.metaKey?this.toggleColumnSelection(coordinates.col):this.toggleRowSelection(coordinates.row),!0}extendSelection(previous,next,range){if(!this.multiple)return;if(!range){this.selectionAnchor=next,this.selectionRangeBase=void 0;return}this.selectionAnchor??=previous??next,this.selectionRangeBase??=new Map(this.selectedPositions);const from=this.selectionCoordinates(this.selectionAnchor),to=this.selectionCoordinates(next),selected=new Map(this.selectionRangeBase);for(const pos of this.cachedAccessiblePositions){const{row,col}=this.selectionCoordinates(pos);row>=Math.min(from.row,to.row)&&row<=Math.max(from.row,to.row)&&col>=Math.min(from.col,to.col)&&col<=Math.max(from.col,to.col)&&selected.set(this.accessibleCellKey(pos),pos)}return this.proposeSelection(selected,"keyboard"),new Set(selected.keys())}selectionPointerPosition(event){if(!this.canvas)return null;const rect=this.canvas.getBoundingClientRect();return this.hitTest(event.clientX-rect.left,event.clientY-rect.top)}paintSelectionTo(pos){const gesture=this.selectionGesture;if(!gesture)return;this.samePos(pos,gesture.previous)||(gesture.moved=!0);const from=this.selectionCoordinates(gesture.previous),to=this.selectionCoordinates(pos),steps=Math.max(Math.abs(to.row-from.row),Math.abs(to.col-from.col),1),changed=[];for(let step=0;step<=steps;step++){const row=Math.round(from.row+(to.row-from.row)*step/steps),col=Math.round(from.col+(to.col-from.col)*step/steps),key=this.effectiveMode==="calendar"?`calendar-${col}-${row}`:`matrix-${row}-${col}`,candidate=this.cachedAccessiblePositionsByKey.get(key);candidate&&(gesture.cells.has(key)!==gesture.selecting&&changed.push(candidate),gesture.selecting?gesture.cells.set(key,candidate):gesture.cells.delete(key))}if(gesture.previous=pos,this.selectionPreview!==gesture.cells){this.selectionPreview=gesture.cells;return}this.requestUpdate(),(changed.length>16||!changed.every(cell=>this.repaintCell(cell)))&&this.requestDraw()}repaintCell(pos){return!this.canvasHasContent||!this.canvas||this.drawDirty?!1:("week"in pos?this.repaintCalendarFocusCell(pos):this.repaintMatrixFocusCell(pos),!0)}cancelSelectionGesture(){const gesture=this.selectionGesture;if(this.selectionGesture=void 0,this.selectionPreview=void 0,!!gesture){this.suppressSelectionClick=!0;try{gesture.target.hasPointerCapture(gesture.pointerId)&&gesture.target.releasePointerCapture(gesture.pointerId)}catch{}}}consumeSelectionClick(event){return!this.suppressSelectionClick||event.detail===0?!1:(this.suppressSelectionClick=!1,!0)}get gridScrollport(){return this.shadowRoot?.querySelector('[part="grid"]')??null}measureTooltip(){if(!this.gridScrollport)return;const tooltip=this.shadowRoot?.querySelector('[part="tooltip"]');if(!tooltip||tooltip.hidden)return;const view=this.ownerDocument.defaultView,gap=view?Math.abs(finiteNumber(Number.parseFloat(view.getComputedStyle(tooltip).marginBlockStart),0)):0,inline=tooltip.offsetWidth,block=tooltip.offsetHeight+gap;inline===this.tooltipSize.inline&&block===this.tooltipSize.block||(this.tooltipSize={inline,block},this.requestUpdate())}tooltipAnchor(pos){const rect=this.cellRect(pos),center=rect.x+rect.w/2,port=this.gridScrollport;if(!port)return{style:{left:`${center}px`,top:`${rect.y}px`},below:!1};const{inline,block}=this.tooltipSize,windowStart=port.scrollLeft+(this.freezesRowLabels?this.matrixPadLeft:0),windowEnd=port.scrollLeft+port.clientWidth,windowTop=port.scrollTop+(this.freezesColLabels?this.matrixPadTop:0),windowBottom=port.scrollTop+port.clientHeight,below=rect.y-block<windowTop&&rect.y+rect.h+block<=windowBottom;return{style:{left:`${Math.max(windowStart+inline/2,Math.min(center,windowEnd-inline/2))}px`,top:`${below?rect.y+rect.h:rect.y}px`},below}}scrollCellIntoView(pos){const port=this.gridScrollport;if(!port)return;const rect=this.cellRect(pos),bandInline=this.freezesRowLabels?this.matrixPadLeft:0,bandBlock=this.freezesColLabels?this.matrixPadTop:0,left=Math.min(Math.max(port.scrollLeft,rect.x+rect.w-port.clientWidth),rect.x-bandInline),top=Math.min(Math.max(port.scrollTop,rect.y+rect.h-port.clientHeight),rect.y-bandBlock);left!==port.scrollLeft&&(port.scrollLeft=left),top!==port.scrollTop&&(port.scrollTop=top)}samePos(a,b){return a===b?!0:!a||!b?!1:"week"in a&&"week"in b?a.week===b.week&&a.weekday===b.weekday:"row"in a&&"row"in b?a.row===b.row&&a.col===b.col:!1}edgeCell(e){if(e.key!=="Home"&&e.key!=="End")return null;const row=this.focusedCell&&!(e.ctrlKey||e.metaKey)?this.selectionCoordinates(this.focusedCell).row:void 0,cells=this.cachedAccessiblePositions.filter(pos=>row===void 0||this.selectionCoordinates(pos).row===row);return cells[e.key==="Home"?0:cells.length-1]??null}onMatrixKeyDown(e){const rows=this.matrixRowLabels.length,cols=this.matrixColLabels.length;if(rows===0||cols===0)return;if(e.key==="Enter"||e.key===" "){e.preventDefault(),this.focusedCell&&this.emitCellClick(this.focusedCell,"keyboard");return}if(!ARROW_KEYS.has(e.key))return;if(e.preventDefault(),!this.focusedCell||!("row"in this.focusedCell)){const next2=this.firstInteractiveMatrixCell(rows,cols);if(!next2)return;this.focusedCell=next2,this.scrollCellIntoView(next2);return}const{row,col}=this.focusedCell;let dRow=0,dCol=0;e.key==="ArrowUp"?dRow=-1:e.key==="ArrowDown"?dRow=1:e.key==="ArrowLeft"?dCol=-1:e.key==="ArrowRight"&&(dCol=1);const next=this.nextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols);this.focusedCell=next,this.scrollCellIntoView(next)}onCalendarKeyDown(e){const{weekCount}=this.cachedCalendarGrid;if(weekCount===0)return;if(e.key==="Enter"||e.key===" "){e.preventDefault(),this.focusedCell&&this.emitCellClick(this.focusedCell,"keyboard");return}if(!ARROW_KEYS.has(e.key))return;if(e.preventDefault(),!this.focusedCell||!("week"in this.focusedCell)){const next2=this.firstInteractiveCalendarCell(weekCount);if(!next2)return;this.focusedCell=next2;return}const{week,weekday}=this.focusedCell;let dWeek=0,dWeekday=0;e.key==="ArrowUp"?dWeekday=-1:e.key==="ArrowDown"?dWeekday=1:e.key==="ArrowLeft"?dWeek=-1:e.key==="ArrowRight"&&(dWeek=1);const next=this.nextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount);this.focusedCell=next}resolveCellColor(value,cs){let color=this.canvasColorCache.get(value);if(color===void 0){const ctx=SCOPED_COLOR.test(value)?null:getScratchCtx(this.ownerDocument);if(ctx){ctx.fillStyle="rgb(1, 2, 3)";const rejected=ctx.fillStyle;ctx.fillStyle=value,ctx.fillStyle!==rejected&&(color=ctx.fillStyle)}color??=resolveCanvasColor(this,value,this.noDataFill(cs)),this.canvasColorCache.set(value,color)}return color}rebuildAccessiblePositions(){const positions=[];if(this.effectiveMode==="calendar"){const{weekCount}=this.cachedCalendarGrid;for(let week=0;week<weekCount;week++)for(let weekday=0;weekday<7;weekday++){const pos=this.calendarPos(week,weekday);this.isCellInteractive(pos)&&positions.push(pos)}}else for(let row=0;row<this.matrixRowLabels.length;row++)for(let col=0;col<this.matrixColLabels.length;col++){const pos={row,col};this.isCellInteractive(pos)&&positions.push(pos)}this.cachedAccessiblePositions=positions,this.cachedAccessiblePositionsByKey=new Map(positions.map(position=>[this.accessibleCellKey(position),position])),this.cachedAccessiblePositionIndexByKey=new Map(positions.map((position,index)=>[this.accessibleCellKey(position),index]))}accessibleCellPositions(){return this.cachedAccessiblePositions}accessibleCellKey(pos){return"week"in pos?`calendar-${pos.week}-${pos.weekday}`:`matrix-${pos.row}-${pos.col}`}accessibleCellIdentity(pos){return"week"in pos?pos.date:this.accessibleCellKey(pos)}accessibleCellAtKey(key){return this.cachedAccessiblePositionsByKey.get(key)??null}focusAccessibleCell(pos){pos&&this.updateComplete.then(()=>{[...this.shadowRoot?.querySelectorAll('[part="cell"]')??[]].find(candidate=>candidate.dataset.cellKey===this.accessibleCellKey(pos))?.focus()})}renderAccessibleCells(){if(!this.accessibleCells)return html``;const positions=this.accessibleCellPositions(),tabStop=this.focusedCell??positions[0]??null,focusIndex=tabStop?this.cachedAccessiblePositionIndexByKey.get(this.accessibleCellKey(tabStop))??0:0,start=Math.max(0,Math.min(Math.max(0,positions.length-MAX_ACCESSIBLE_HEATMAP_CELLS),focusIndex-Math.floor(MAX_ACCESSIBLE_HEATMAP_CELLS/2))),renderedPositions=positions.slice(start,start+MAX_ACCESSIBLE_HEATMAP_CELLS),renderedRows=new Map;for(const pos of renderedPositions){const rowIndex="week"in pos?pos.weekday+1:pos.row+1,row=renderedRows.get(rowIndex);row?row.push(pos):renderedRows.set(rowIndex,[pos])}const rowCount=this.effectiveMode==="calendar"?7:this.matrixRowLabels.length,colCount=this.effectiveMode==="calendar"?this.cachedCalendarGrid.weekCount:this.matrixColLabels.length,calendar=this.effectiveMode==="calendar"?this.calendarNavigationGeometry():void 0;return html`
|
|
4
4
|
<div
|
|
5
5
|
part="cells"
|
|
6
6
|
role="grid"
|
|
@@ -18,12 +18,13 @@ readonly exactValue?:string;}
|
|
|
18
18
|
* pointer modifiers; the platform primary modifier and Shift preserve new-context activation.
|
|
19
19
|
* @csspart base - The component's root wrapper (`<div>`, or a stretched real `<a>` when `href` is safe).
|
|
20
20
|
* @csspart icon - Container for the `start` slot.
|
|
21
|
-
* @csspart label - The label text. Hidden (and collapsed) whenever
|
|
22
|
-
* label-less stat doesn't leave a blank line above the value.
|
|
21
|
+
* @csspart label - The label text, exposed as a term when present. Hidden (and collapsed) whenever
|
|
22
|
+
* `label` is empty, so a label-less stat doesn't leave a blank line above the value.
|
|
23
23
|
* @csspart value-row - Wrapper around the value and unit.
|
|
24
|
-
* @csspart value - The value text
|
|
25
|
-
* `aria-labelledby`) whenever `label` is set, so
|
|
26
|
-
* (focusable when `exactValue` is set)
|
|
24
|
+
* @csspart value - The value text, exposed as a definition when labelled by a metric or unit.
|
|
25
|
+
* Accessibly labelled by the `label` part (via `aria-labelledby`) whenever `label` is set, so
|
|
26
|
+
* tabbing directly to this value (focusable when `exactValue` is set) still announces which
|
|
27
|
+
* metric and visible unit it is.
|
|
27
28
|
* @csspart unit - The unit text.
|
|
28
29
|
* @csspart trend - The trend pill.
|
|
29
30
|
* @csspart sub - Container for the `sub` attribute/slot.
|
|
@@ -31,10 +32,11 @@ readonly exactValue?:string;}
|
|
|
31
32
|
* @csspart caption - Container for the caption attribute/slot.
|
|
32
33
|
* @csspart rows - Container for the `rows` breakdown list.
|
|
33
34
|
* @csspart row - A single breakdown row (one per `rows` entry).
|
|
34
|
-
* @csspart row-label - The label text of a breakdown row.
|
|
35
|
-
* @csspart row-value - The value text of a breakdown row
|
|
36
|
-
* a hover/focus tooltip, same as the headline `value`,
|
|
37
|
-
* `row-label` (via `aria-labelledby`) the same way the
|
|
35
|
+
* @csspart row-label - The label text of a breakdown row, exposed as a term when present.
|
|
36
|
+
* @csspart row-value - The value text of a breakdown row, exposed as a definition when labelled.
|
|
37
|
+
* Shows the row's `exactValue` (if any) as a hover/focus tooltip, same as the headline `value`,
|
|
38
|
+
* and is accessibly labelled by its `row-label` (via `aria-labelledby`) the same way the
|
|
39
|
+
* headline `value` is.
|
|
38
40
|
* @cssprop [--lr-stat-bg=var(--lr-color-surface)] - Resting background of the card. The pressed
|
|
39
41
|
* fill of a linked card mixes from this value too, so one override retints both. `frame="plain"`
|
|
40
42
|
* still paints transparent.
|
|
@@ -3,11 +3,12 @@ import{__decorate}from"tslib";import{html,nothing}from"lit";import{property,stat
|
|
|
3
3
|
><slot name="start" @slotchange=${this.onIconSlotChange}></slot
|
|
4
4
|
></span
|
|
5
5
|
>
|
|
6
|
-
<span part="label" id=${this.labelId} ?hidden=${!this.label}>${this.label}</span>
|
|
6
|
+
<span part="label" id=${this.labelId} role=${this.label?"term":nothing} ?hidden=${!this.label}>${this.label}</span>
|
|
7
7
|
<div part="value-row">
|
|
8
8
|
<span
|
|
9
9
|
part="value"
|
|
10
10
|
id=${this.valueId}
|
|
11
|
+
role=${this.label||this.unit?"definition":nothing}
|
|
11
12
|
title=${this.exactValue||nothing}
|
|
12
13
|
tabindex=${this.exactValue&&!linked?"0":nothing}
|
|
13
14
|
aria-labelledby=${this.label||this.unit?[this.label?this.labelId:"",this.valueId,this.unit?this.unitId:""].filter(Boolean).join(" "):nothing}
|
|
@@ -35,10 +36,11 @@ import{__decorate}from"tslib";import{html,nothing}from"lit";import{property,stat
|
|
|
35
36
|
<div part="rows" ?hidden=${this.rows.length===0}>
|
|
36
37
|
${this.rows.map((row,i)=>{const rowLabelId=this.rowLabelIds[i],rowValueId=`${rowLabelId}-value`;return html`
|
|
37
38
|
<div part="row">
|
|
38
|
-
<span part="row-label" id=${rowLabelId}>${row.label}</span>
|
|
39
|
+
<span part="row-label" id=${rowLabelId} role=${row.label?"term":nothing}>${row.label}</span>
|
|
39
40
|
<span
|
|
40
41
|
part="row-value"
|
|
41
42
|
id=${rowValueId}
|
|
43
|
+
role=${row.label?"definition":nothing}
|
|
42
44
|
title=${row.exactValue||nothing}
|
|
43
45
|
tabindex=${row.exactValue&&!linked?"0":nothing}
|
|
44
46
|
aria-labelledby=${row.label?`${rowLabelId} ${rowValueId}`:nothing}
|