@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.151 → 2.0.0-next.152

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.
Files changed (136) hide show
  1. package/.storybook/vitest.setup.ts +12 -1
  2. package/bundle/openbridge-webcomponents.bundle.js +989 -319
  3. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  4. package/custom-elements.json +1514 -77
  5. package/dist/alert-severity.d.ts +12 -9
  6. package/dist/alert-severity.d.ts.map +1 -1
  7. package/dist/alert-severity.js +30 -38
  8. package/dist/alert-severity.js.map +1 -1
  9. package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts +6 -0
  10. package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts.map +1 -1
  11. package/dist/building-blocks/bar-horizontal/bar-horizontal.js +6 -1
  12. package/dist/building-blocks/bar-horizontal/bar-horizontal.js.map +1 -1
  13. package/dist/building-blocks/bar-vertical/bar-vertical.d.ts +6 -0
  14. package/dist/building-blocks/bar-vertical/bar-vertical.d.ts.map +1 -1
  15. package/dist/building-blocks/bar-vertical/bar-vertical.js +6 -1
  16. package/dist/building-blocks/bar-vertical/bar-vertical.js.map +1 -1
  17. package/dist/building-blocks/chart-line/chart-line-base.d.ts +129 -0
  18. package/dist/building-blocks/chart-line/chart-line-base.d.ts.map +1 -1
  19. package/dist/building-blocks/chart-line/chart-line-base.js +464 -79
  20. package/dist/building-blocks/chart-line/chart-line-base.js.map +1 -1
  21. package/dist/building-blocks/external-scale/external-scale.d.ts +11 -0
  22. package/dist/building-blocks/external-scale/external-scale.d.ts.map +1 -1
  23. package/dist/building-blocks/external-scale/external-scale.js +45 -12
  24. package/dist/building-blocks/external-scale/external-scale.js.map +1 -1
  25. package/dist/charthelpers/index.d.ts +1 -0
  26. package/dist/charthelpers/index.d.ts.map +1 -1
  27. package/dist/charthelpers/index.js +7 -1
  28. package/dist/charthelpers/index.js.map +1 -1
  29. package/dist/charthelpers/range-labels.d.ts +55 -0
  30. package/dist/charthelpers/range-labels.d.ts.map +1 -0
  31. package/dist/charthelpers/range-labels.js +36 -0
  32. package/dist/charthelpers/range-labels.js.map +1 -0
  33. package/dist/components/alert-button/alert-button.css.js +13 -21
  34. package/dist/components/alert-button/alert-button.css.js.map +1 -1
  35. package/dist/components/alert-button/alert-button.d.ts +9 -4
  36. package/dist/components/alert-button/alert-button.d.ts.map +1 -1
  37. package/dist/components/alert-button/alert-button.js +24 -15
  38. package/dist/components/alert-button/alert-button.js.map +1 -1
  39. package/dist/components/alert-frame/alert-frame.css.js +109 -33
  40. package/dist/components/alert-frame/alert-frame.css.js.map +1 -1
  41. package/dist/components/alert-frame/alert-frame.d.ts +34 -7
  42. package/dist/components/alert-frame/alert-frame.d.ts.map +1 -1
  43. package/dist/components/alert-frame/alert-frame.js +134 -30
  44. package/dist/components/alert-frame/alert-frame.js.map +1 -1
  45. package/dist/components/alert-icon/alert-icon.d.ts +10 -7
  46. package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
  47. package/dist/components/alert-icon/alert-icon.js +37 -60
  48. package/dist/components/alert-icon/alert-icon.js.map +1 -1
  49. package/dist/components/alert-menu-item/alert-menu-item.css.js +1 -4
  50. package/dist/components/alert-menu-item/alert-menu-item.css.js.map +1 -1
  51. package/dist/components/date-item/date-item.css.js +3 -3
  52. package/dist/components/keyboard-full/keyboard-full.css.js +4 -4
  53. package/dist/components/message-menu-item/message-menu-item.css.js +2 -6
  54. package/dist/components/message-menu-item/message-menu-item.css.js.map +1 -1
  55. package/dist/components/sequence-toolbar/sequence-toolbar.css.js +1 -2
  56. package/dist/components/sequence-toolbar/sequence-toolbar.css.js.map +1 -1
  57. package/dist/index.js +2 -1
  58. package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts +6 -0
  59. package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts.map +1 -1
  60. package/dist/navigation-instruments/gauge-trend/gauge-trend.js +8 -0
  61. package/dist/navigation-instruments/gauge-trend/gauge-trend.js.map +1 -1
  62. package/dist/navigation-instruments/instrument-field/instrument-field.css.js +2 -2
  63. package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
  64. package/dist/navigation-instruments/readout/readout.js +2 -1
  65. package/dist/navigation-instruments/readout/readout.js.map +1 -1
  66. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
  67. package/dist/navigation-instruments/readout-list-item/readout-list-item.js +2 -1
  68. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  69. package/dist/openbridge.css +19 -4
  70. package/dist/palettes/blinking.d.ts +14 -4
  71. package/dist/palettes/blinking.d.ts.map +1 -1
  72. package/dist/palettes/blinking.js +41 -35
  73. package/dist/palettes/blinking.js.map +1 -1
  74. package/dist/palettes/flashing-controller.d.ts +21 -0
  75. package/dist/palettes/flashing-controller.d.ts.map +1 -0
  76. package/dist/palettes/flashing-controller.js +45 -0
  77. package/dist/palettes/flashing-controller.js.map +1 -0
  78. package/dist/svghelpers/index.d.ts +1 -0
  79. package/dist/svghelpers/index.d.ts.map +1 -1
  80. package/dist/svghelpers/index.js +2 -0
  81. package/dist/svghelpers/index.js.map +1 -1
  82. package/dist/svghelpers/rounded-rect.d.ts +15 -0
  83. package/dist/svghelpers/rounded-rect.d.ts.map +1 -0
  84. package/dist/svghelpers/rounded-rect.js +29 -0
  85. package/dist/svghelpers/rounded-rect.js.map +1 -0
  86. package/dist/types.d.ts +14 -0
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js +9 -0
  89. package/dist/types.js.map +1 -1
  90. package/package.json +1 -1
  91. package/script/check-css-variables.ts +2 -15
  92. package/src/alert-severity.spec.ts +56 -0
  93. package/src/alert-severity.ts +45 -43
  94. package/src/bars-graphs/area-graph/area-graph.stories.ts +235 -1
  95. package/src/bars-graphs/line-graph/line-graph.stories.ts +24 -0
  96. package/src/building-blocks/bar-horizontal/bar-horizontal.ts +7 -0
  97. package/src/building-blocks/bar-vertical/bar-vertical.ts +7 -0
  98. package/src/building-blocks/chart-line/chart-line-base.spec.ts +767 -0
  99. package/src/building-blocks/chart-line/chart-line-base.stories.ts +124 -0
  100. package/src/building-blocks/chart-line/chart-line-base.ts +671 -97
  101. package/src/building-blocks/chart-line/chart-sizing-battleground.stories.ts +17 -0
  102. package/src/building-blocks/external-scale/external-scale.spec.ts +154 -0
  103. package/src/building-blocks/external-scale/external-scale.ts +78 -20
  104. package/src/charthelpers/index.ts +1 -0
  105. package/src/charthelpers/range-labels.spec.ts +46 -0
  106. package/src/charthelpers/range-labels.ts +93 -0
  107. package/src/components/alert-button/alert-button.css +10 -23
  108. package/src/components/alert-button/alert-button.spec.ts +56 -15
  109. package/src/components/alert-button/alert-button.stories.ts +5 -1
  110. package/src/components/alert-button/alert-button.ts +33 -24
  111. package/src/components/alert-frame/alert-flash-scenario.stories.ts +669 -0
  112. package/src/components/alert-frame/alert-frame.css +106 -33
  113. package/src/components/alert-frame/alert-frame.spec.ts +176 -17
  114. package/src/components/alert-frame/alert-frame.stories.ts +61 -0
  115. package/src/components/alert-frame/alert-frame.ts +179 -41
  116. package/src/components/alert-icon/alert-icon.spec.ts +82 -27
  117. package/src/components/alert-icon/alert-icon.stories.ts +7 -1
  118. package/src/components/alert-icon/alert-icon.ts +48 -74
  119. package/src/components/alert-menu-item/alert-menu-item.css +1 -4
  120. package/src/components/date-item/date-item.css +3 -3
  121. package/src/components/keyboard-full/keyboard-full.css +4 -4
  122. package/src/components/message-menu-item/message-menu-item.css +2 -6
  123. package/src/components/sequence-toolbar/sequence-toolbar.css +1 -2
  124. package/src/navigation-instruments/gauge-trend/gauge-trend.stories.ts +29 -0
  125. package/src/navigation-instruments/gauge-trend/gauge-trend.ts +11 -0
  126. package/src/navigation-instruments/instrument-field/instrument-field.css +2 -2
  127. package/src/navigation-instruments/readout/readout.ts +2 -1
  128. package/src/navigation-instruments/readout-list-item/readout-list-item.ts +2 -1
  129. package/src/palettes/blinking.spec.ts +83 -0
  130. package/src/palettes/blinking.ts +47 -35
  131. package/src/palettes/flashing-controller.ts +62 -0
  132. package/src/palettes/manual.css +18 -4
  133. package/src/svghelpers/index.ts +1 -0
  134. package/src/svghelpers/rounded-rect.spec.ts +47 -0
  135. package/src/svghelpers/rounded-rect.ts +42 -0
  136. package/src/types.ts +20 -0
@@ -1 +1 @@
1
- {"version":3,"file":"chart-line-base.js","sources":["../../../src/building-blocks/chart-line/chart-line-base.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport componentStyle from './chart-line-base.css?inline';\nimport chartCommonStyle from '../../charthelpers/chart-common.css?inline';\nimport chartDebugStyle from '../../charthelpers/chart-debug.css?inline';\nimport chartLegendStyle from '../../charthelpers/chart-legend.css?inline';\nimport {\n Chart,\n LineController,\n LineElement,\n PointElement,\n ArcElement,\n Tooltip,\n CategoryScale,\n LinearScale,\n TimeScale,\n Filler,\n} from 'chart.js';\nimport type {ChartOptions, ChartDataset, ChartConfiguration} from 'chart.js';\nimport {\n InstrumentState,\n FrameStyle,\n BorderRadiusPosition,\n Priority,\n} from '../../navigation-instruments/types.js';\nimport {\n CHART_SECTOR_DEFAULT_COLORS,\n CHART_SECTOR_ENHANCED_COLORS,\n RECTANGULAR_CHART_DIMENSIONS,\n LINE_GRAPH_LABEL_CONFIG,\n LINE_GRAPH_GRID_CONFIG,\n CHART_DIMENSIONS,\n CHART_AREA_BACKGROUND_COLOR_VAR,\n getCssVariableValue,\n getChartColorsOrDefault,\n observeThemeChanges,\n formatChartNumber,\n getChartTooltipOptions,\n generateLegendHTML,\n applyAlphaToColor,\n normalizeXValue,\n formatXValue,\n XValueMode,\n observeLabelThreshold,\n} from '../../charthelpers/index.js';\nimport type {ChartXValue} from '../../charthelpers/x-value.js';\nimport {\n EXTERNAL_SCALE_BORDER_RADIUS_CSS_VAR,\n readExternalScaleBorderRadiusPx,\n startExternalScaleBorderRadiusObserver,\n ScaleType,\n} from '../external-scale/external-scale.js';\n\n// Register Chart.js components used by the line graph (scales, elements, plugins)\nChart.register(\n LineController,\n LineElement,\n PointElement,\n ArcElement,\n CategoryScale,\n LinearScale,\n TimeScale,\n Filler,\n Tooltip\n);\n\n/**\n * Dimension information reported by external scale components.\n * Dispatched via 'scale-dimensions-changed' event from slotted scale elements.\n */\nexport interface ExternalScaleDimensions {\n /** Which side this scale is positioned on */\n side: 'top' | 'bottom' | 'left' | 'right';\n /** Natural thickness in pixels (width for vertical, height for horizontal) */\n thickness: number;\n}\n\n/**\n * Type guard to check if an element is an external scale component\n */\ninterface ExternalScaleElement extends HTMLElement {\n minValue?: number;\n maxValue?: number;\n height?: number;\n width?: number;\n paddingTop?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n paddingRight?: number;\n paddingStart?: number;\n paddingEnd?: number;\n primaryTickmarkInterval?: number;\n showLabels?: boolean;\n fixedAspectRatio?: boolean;\n scaleReferenceSize?: number;\n state?: InstrumentState;\n priority?: Priority;\n frameStyle?: FrameStyle;\n borderRadiusPosition?: BorderRadiusPosition;\n}\n\nexport type {ChartXValue, TemporalLike} from '../../charthelpers/x-value.js';\n\nexport enum XAxisType {\n category = 'category',\n time = 'time',\n number = 'number',\n}\n\nexport enum YAxisPosition {\n left = 'left',\n right = 'right',\n}\n\nexport enum LineMode {\n smooth = 'smooth',\n straight = 'straight',\n stepped = 'stepped',\n}\n\nexport enum TimeDisplay {\n minutes = 'minutes',\n date = 'date',\n}\n\nexport type ChartLinePoint = number | {x: ChartXValue; y: number};\n\nexport type ChartLineDataItem = {\n /** Category label. Used when `xAxisType='category'` (the default). */\n label?: string;\n /**\n * X-coordinate for `xAxisType='time'` (epoch ms, ISO string, Date, or\n * Temporal object) or `xAxisType='number'` (plain number). When absent,\n * `label` is parsed as a fallback.\n */\n x?: ChartXValue;\n value: number;\n};\n\nexport type ChartLineYAxisConfig = {\n id?: string;\n position?: 'left' | 'right';\n min?: number;\n max?: number;\n grid?: boolean;\n};\n\nconst LINE_GRAPH_WATCHED_PROP_NAMES = [\n 'data',\n 'datasets',\n 'labels',\n 'colors',\n 'xAxisType',\n 'yAxisPosition',\n 'yAxes',\n 'showGrid',\n 'showGridX',\n 'showGridY',\n 'showTickMarks',\n 'showPoints',\n 'lineMode',\n 'unit', // Used in tooltip display\n 'timeDisplay',\n 'xTicksLimit',\n 'xStepSize',\n 'yTicksLimit',\n 'yStepSize',\n 'priority', // Triggers color palette change\n 'borderRadiusPosition', // Triggers border styling update\n 'borderRadiusPositionExternalScales', // Triggers external scale border styling update\n // legend only affects HTML; do not use it to drive chart updates\n 'width',\n 'height',\n 'fixedAspectRatioScaling', // Triggers responsive mode change\n 'hasLabelPadding', // Toggles edge-to-edge rendering and label visibility\n] as const;\n\nconst LINE_GRAPH_RECREATE_PROP_NAMES = [\n 'showDebugOverlay',\n 'width',\n 'height',\n 'fixedAspectRatioScaling',\n] as const;\n\n/**\n * Properties that define the chart's reference size, and therefore invalidate\n * the derived `computedWidth` / `computedHeight` pair.\n */\nconst LINE_GRAPH_DIMENSION_PROP_NAMES = [\n 'width',\n 'height',\n 'fixedAspectRatioScaling',\n] as const;\n\n/**\n * Abstract base class for line and area chart components built on Chart.js.\n *\n * ## Concrete implementations\n * - `<obc-line-graph>`: Line chart (non-filled)\n * - `<obc-area-graph>`: Area chart with fill modes (semitransparent, solid, threshold)\n *\n * ## Features\n * - **Single or multi-series**: Use `data` for simple single-series or `datasets` for multi-series charts\n * - **Category, time and number axes**: `category` (labels, evenly spaced), `time` (epoch ms,\n * ISO strings, `Date` or Temporal objects — positioned proportionally, so uneven intervals\n * render unevenly) and `number` (plain numeric x-values on a linear scale)\n * - **Line styles**: Choose `smooth` (curved), `straight`, or `stepped` line rendering\n * - **Fill modes**: Area fills with `semitransparent`, `solid`, or `threshold` (red/blue above/below midpoint)\n * - **Stacked charts**: Enable `stacked` for multi-series datasets to stack values on y-axis\n * - **Flexible axes**: Single y-axis via `yAxisPosition` or multi-axis via `yAxes` for complex charts\n * - **Theme-aware**: Automatically updates colors on theme changes using CSS variables\n * - **Responsive sizing**: Fixed height with 1.5:1 aspect ratio (e.g., 320px height → 480px width)\n * - **Grid & ticks**: Toggle grid lines (`showGrid`, `showGridX`, `showGridY`) and tick marks (`showTickMarks`)\n * - **Legend support**: Optional HTML legend showing series labels with `legend` property\n * - **External axis support**: via slots\n * - **Color priority**: Set `priority` to `Priority.enhanced` to use the blue/enhanced\n * color palette instead of the default gray/regular palette (default: `Priority.regular`)\n *\n * ## Size Behavior\n * - Above 192px: Shows labels, tick marks, and grid lines with standard padding\n * - Below 192px: Hides labels/ticks and uses edge-to-edge rendering for compact display\n *\n * ## Examples\n *\n * Basic single-series with category axis:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.data = [\n * {label: 'Jan', value: 10},\n * {label: 'Feb', value: 14},\n * {label: 'Mar', value: 12}\n * ];\n * chart.unit = 'kW';\n * chart.height = 256;\n * </script>\n * ```\n *\n * Multi-series with time axis and legend:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.xAxisType = 'time';\n * chart.timeDisplay = 'date';\n * chart.legend = true;\n * chart.datasets = [\n * {label: 'Temperature', data: [{x: '2025-01-01', y: 20}, {x: '2025-01-02', y: 22}]},\n * {label: 'Humidity', data: [{x: '2025-01-01', y: 65}, {x: '2025-01-02', y: 68}]}\n * ];\n * </script>\n * ```\n *\n * Single-series with time axis (uneven intervals position proportionally;\n * x accepts epoch ms, ISO strings, Date or Temporal objects):\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.xAxisType = 'time';\n * chart.timeDisplay = 'minutes';\n * chart.data = [\n * {x: '2026-07-06T10:00:00Z', value: 10},\n * {x: new Date('2026-07-06T10:03:00Z'), value: 14},\n * {x: Temporal.Instant.from('2026-07-06T10:15:00Z'), value: 12}\n * ];\n * </script>\n * ```\n *\n * Single-series with numeric x-axis:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.xAxisType = 'number';\n * chart.data = [\n * {x: 0, value: 2},\n * {x: 2.5, value: 3},\n * {x: 10, value: 6}\n * ];\n * </script>\n * ```\n *\n * Stacked area chart with solid fill:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.datasets = [\n * {label: 'Series A', data: [2, 3, 4, 3, 5]},\n * {label: 'Series B', data: [1, 2, 3, 2, 4]},\n * {label: 'Series C', data: [3, 2, 1, 2, 3]}\n * ];\n * chart.fillMode = 'solid';\n * chart.stacked = true;\n * chart.legend = true;\n * </script>\n * ```\n *\n * Threshold fill (single-series only):\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.data = [{label: '1', value: 20}, {label: '2', value: 45}, {label: '3', value: 35}];\n * chart.fillMode = 'threshold';\n * </script>\n * ```\n *\n * Multi-axis chart with right-side y-axis:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.yAxes = [\n * {id: 'y-temp', position: 'left', min: 0, max: 100},\n * {id: 'y-pressure', position: 'right', min: 0, max: 10}\n * ];\n * chart.datasets = [\n * {label: 'Temperature', data: [20, 25, 30], yAxisID: 'y-temp'},\n * {label: 'Pressure', data: [2, 3, 2.5], yAxisID: 'y-pressure'}\n * ];\n * </script>\n * ```\n *\n * @property data - Simple single-series data. `{label, value}` items for the category axis;\n * `{x, value}` items for time/number axes (x: epoch ms, ISO string, Date,\n * or Temporal object). Points are drawn in array order (no sorting).\n * @property datasets - Chart.js-style datasets for multi-series use. If provided, takes precedence over `data`.\n * @property labels - Optional explicit labels for the x-axis (category mode). If omitted labels are derived from `data`\n * @property colors - Custom color palette (CSS variable names or color strings).\n * @property legend - Show HTML legend below chart with series labels and colors.\n * @property showDebugOverlay - Development mode: show visual debug overlay with dimension guides.\n * @property width - Width of the chart in pixels. Default: 480.\n * @property height - Height of the chart in pixels. Default: 320.\n * @property fixedAspectRatioScaling - Enable fixed aspect ratio scaling mode.\n * When true, width/height properties define the aspect ratio (not actual pixels).\n * The component fills 100% of parent width and calculates height from aspect ratio.\n * When false (default), width/height are used as actual pixel dimensions.\n * @property scaleReferenceSize - Reference size for external scales when using fixedAspectRatioScaling.\n * This value is passed down to external scales to determine their 1:1 Figma design size.\n * At this reference size, scales render at native size; above/below they scale proportionally.\n * Default: 384 (matches Figma design baseline).\n * @property xAxisType - X-axis mode: 'category' for labeled, evenly spaced data points; 'time'\n * for time-based data positioned proportionally; 'number' for plain\n * numeric x-values.\n * @property yAxisPosition - Single y-axis position ('left' or 'right'). For multiple y-axes, use yAxes instead.\n * @property yAxes - Multiple y-axis definitions for complex multi-axis charts.\n * @property showGrid - Show grid lines.\n * @property showGridX - Show vertical grid lines (x-axis). Default: false.\n * @availableWhen showGridX showGrid==true\n * @property showGridY - Show horizontal grid lines (y-axis). Default: false.\n * @availableWhen showGridY showGrid==true\n * @property showTickMarks - Show axis tick marks and labels.\n * @property showPoints - Show point markers on data points. Default: false.\n * @property lineMode - Line drawing style: 'smooth' (curved), 'straight', or 'stepped'.\n * @property unit - Unit label displayed in tooltips (e.g., 'kW', 'kg', '%').\n * @property timeDisplay - Time axis label format: 'date' (full date/time) or 'minutes' (relative).\n * @availableWhen timeDisplay xAxisType==time\n * @property xTicksLimit - Max number of x-axis ticks/grid lines. Useful for matching external axes.\n * @property xStepSize - Force x-axis tick interval. Useful for matching external axes.\n * @property yTicksLimit - Max number of y-axis ticks/grid lines. Useful for matching external axes.\n * @property yStepSize - Force y-axis tick interval. Useful for matching external axes.\n * @property state - Instrument state affecting colors of external scales.\n * @property priority - Color priority: enhanced uses blue palette instead of default gray.\n * @property frameStyle - Frame style for chart and external scales.\n * @property borderRadiusPosition - Border radius position for the chart's own border.\n * @property borderRadiusPositionExternalScales - Border radius position for external scales based on layout.\n * @property instrumentMode - When true, the chart is used inside an instrument (e.g., gauge-trend).\n * In this mode, only label font size responds to .obc-component-size-* CSS classes.\n * Border radius uses the explicit `borderRadius` property value (or defaults to 8px),\n * rather than reading from CSS variables.\n * @property borderRadius - Explicit border radius value in pixels.\n * When instrumentMode=true, this value is used directly (defaults to 8px).\n * When instrumentMode=false, this is ignored and border radius is read from CSS variable.\n * @availableWhen borderRadius instrumentMode==true\n * @experimental\n */\nexport class ObcChartLineBase extends LitElement {\n @property({type: Array, attribute: false})\n data: ChartLineDataItem[] = [];\n\n @property({type: Array, attribute: false})\n datasets?: ChartDataset<'line', ChartLinePoint[]>[] = undefined;\n\n @property({type: Array, attribute: false})\n labels?: (string | number)[] = undefined;\n\n @property({type: Array, attribute: false})\n colors: string[] = [];\n\n @property({type: Boolean, reflect: true})\n legend = false;\n\n @property({type: Boolean, reflect: true})\n showDebugOverlay = false;\n\n @property({type: Number, reflect: true})\n width = 480;\n\n @property({type: Number, reflect: true})\n height = 320;\n\n @property({type: Boolean, reflect: true})\n fixedAspectRatioScaling = false;\n\n @property({type: Number})\n scaleReferenceSize = 384;\n\n @property({type: String})\n xAxisType: XAxisType = XAxisType.category;\n\n @property({type: String})\n yAxisPosition: YAxisPosition = YAxisPosition.left;\n\n @property({type: Array, attribute: false})\n yAxes?: ChartLineYAxisConfig[] = undefined;\n\n @property({type: Boolean})\n showGrid = false;\n\n @property({type: Boolean})\n showGridX = false;\n\n @property({type: Boolean})\n showGridY = false;\n\n @property({type: Boolean})\n showTickMarks = false;\n\n /**\n * Reserve canvas padding for axis tick labels on sides without an external scale.\n *\n * When `true` (default), the chart leaves room for tick labels and renders them\n * (subject to `showTickMarks` and the 192px auto-compact threshold).\n *\n * When `false`, the chart renders edge-to-edge on sides without a slotted external\n * scale AND axis tick labels are force-hidden so they cannot be clipped. This also\n * suppresses the automatic edge-to-edge switch that normally happens below the\n * 192px threshold, eliminating the visible padding \"jump\" when crossing it.\n *\n * Useful when embedding the chart inside another component that owns framing\n * and never wants to show axis labels (e.g. `obc-automation-tank`).\n *\n * Defaults to `true` to preserve existing behavior. Declared with `attribute: false`\n * because a `true`-default boolean cannot work as an HTML boolean attribute.\n */\n @property({type: Boolean, attribute: false})\n hasLabelPadding = true;\n\n /** @internal - True when the x-axis positions points by numeric value. */\n protected get isNumericXAxis(): boolean {\n return (\n this.xAxisType === XAxisType.time || this.xAxisType === XAxisType.number\n );\n }\n\n /** @internal - Normalization mode for the current x-axis type. */\n protected get xValueMode(): XValueMode {\n return this.xAxisType === XAxisType.number\n ? XValueMode.number\n : XValueMode.time;\n }\n\n /** @internal - Last data/datasets reference already warned about. */\n private lastWarnedXSource?: unknown;\n\n /** @internal - Warn once per data assignment about unparseable x-values. */\n private warnOnInvalidX(xValues: number[], sourceRef: unknown) {\n const invalid = xValues.filter((x) => !Number.isFinite(x)).length;\n if (invalid === 0 || this.lastWarnedXSource === sourceRef) return;\n this.lastWarnedXSource = sourceRef;\n console.warn(\n `[obc-chart] ${invalid} x value(s) could not be parsed for xAxisType='${this.xAxisType}'; the points render as gaps.`\n );\n }\n\n // Internal default tension used when `lineMode` is 'smooth'. Not exposed as a property.\n private readonly DEFAULT_TENSION = 0.4;\n\n // Internal default point radius when points are shown.\n private readonly POINT_RADIUS = 3;\n\n @property({type: Boolean})\n showPoints = false;\n\n @property({type: String})\n lineMode: LineMode = LineMode.smooth;\n\n @property({type: String})\n unit = '';\n\n @property({type: String})\n timeDisplay: TimeDisplay = TimeDisplay.date;\n\n @property({type: Number})\n xTicksLimit?: number = undefined;\n\n @property({type: Number})\n xStepSize?: number = undefined;\n\n @property({type: Number})\n yTicksLimit?: number = undefined;\n\n @property({type: Number})\n yStepSize?: number = undefined;\n\n @property({type: String})\n state: InstrumentState = InstrumentState.active;\n\n @property({type: String})\n priority: Priority = Priority.regular;\n\n @property({type: String})\n frameStyle: FrameStyle = FrameStyle.regular;\n\n @property({type: String})\n borderRadiusPosition?: BorderRadiusPosition = undefined;\n\n @property({type: String})\n borderRadiusPositionExternalScales?: BorderRadiusPosition = undefined;\n\n @property({type: Boolean})\n instrumentMode = false;\n\n @property({type: Number})\n borderRadius?: number = undefined;\n\n /** @internal */\n @query('canvas') private canvasEl?: HTMLCanvasElement;\n\n /** @internal */\n @query('.legend') private legendDiv?: HTMLDivElement;\n\n /** @internal - Slot elements for external scales */\n @query('slot[name=\"top-scale\"]') private topScaleSlot?: HTMLSlotElement;\n @query('slot[name=\"bottom-scale\"]') private bottomScaleSlot?: HTMLSlotElement;\n @query('slot[name=\"left-scale\"]') private leftScaleSlot?: HTMLSlotElement;\n @query('slot[name=\"right-scale\"]') private rightScaleSlot?: HTMLSlotElement;\n\n /** @internal */\n private chart?: Chart;\n\n /** @internal */\n private themeObserver?: MutationObserver;\n\n /** @internal - ResizeObserver for tracking height threshold crossings (e.g. MIN_HEIGHT_WITH_LABELS = 192px) */\n private resizeObserver?: ResizeObserver;\n\n /** @internal - Track external scale dimensions */\n private externalScaleDimensions: Map<string, number> = new Map();\n\n /** @internal - Debounce timer for dimension updates */\n private dimensionUpdateTimer?: ReturnType<typeof setTimeout>;\n\n /** @internal - Flag to prevent infinite update loops */\n private isUpdatingScales = false;\n\n /** @internal - Border radius observer for theme/size changes */\n private borderRadiusObserver?: MutationObserver;\n\n /** @internal - Current computed border radius in pixels */\n private currentBorderRadiusPx = 8;\n\n /** @internal - ResizeObserver for aspect ratio scaling */\n private aspectRatioResizeObserver?: ResizeObserver;\n\n /** @internal - Computed actual width when using fixed aspect ratio scaling */\n private computedWidth = 480;\n\n /** @internal - Computed actual height when using fixed aspect ratio scaling */\n private computedHeight = 320;\n\n /**\n * Should fill be applied to this chart?\n * Line graph returns false, area graph returns true.\n * Must be implemented in subclass.\n */\n protected shouldApplyFill(): boolean {\n throw new Error('shouldApplyFill() must be implemented in subclass');\n }\n\n /**\n * Get fill mode for area rendering.\n * Line graph returns undefined, area graph returns 'semitransparent' | 'solid' | 'threshold'.\n * Must be implemented in subclass.\n */\n protected getFillMode(): string | undefined {\n throw new Error('getFillMode() must be implemented in subclass');\n }\n\n /**\n * Should multi-series datasets be stacked?\n * Line graph returns false, area graph returns stacked property value.\n * Must be implemented in subclass.\n */\n protected shouldStack(): boolean {\n throw new Error('shouldStack() must be implemented in subclass');\n }\n\n /**\n * Compute which corners should be rounded based on borderRadiusPosition and\n * which external scales are present.\n *\n * Logic:\n * - Opposite scales (left+right OR top+bottom) → no rounding (middleChild behavior)\n * - Perpendicular scales (e.g., right+bottom):\n * - innerFirstChild → round corner adjacent to both scales\n * - outerLastChild → round free corner opposite to scales\n * - Single-side scales:\n * - When external scale is on RIGHT, chart is on LEFT\n * - innerFirstChild → round LEFT corners (top-left + bottom-left)\n * - outerLastChild → round RIGHT corners (top-right + bottom-right)\n * - When external scale is on LEFT, chart is on RIGHT (opposite)\n * - When external scale is on TOP, chart is on BOTTOM\n * - innerFirstChild → round BOTTOM corners (bottom-left + bottom-right)\n * - outerLastChild → round TOP corners (top-left + top-right)\n * - When external scale is on BOTTOM, chart is on TOP (opposite)\n * - middleChild → no rounding\n */\n\n /**\n * Check if a slotted scale element is actually visible (renders content).\n * For bar-vertical/bar-horizontal elements, checks hasBar and hasScale properties.\n */\n private hasVisibleScale(side: 'left' | 'right' | 'top' | 'bottom'): boolean {\n const slotMap = {\n left: this.leftScaleSlot,\n right: this.rightScaleSlot,\n top: this.topScaleSlot,\n bottom: this.bottomScaleSlot,\n };\n\n const slot = slotMap[side];\n const elements = slot?.assignedElements() ?? [];\n\n return elements.some((el: Element) => {\n const barEl = el as HTMLElement & {\n hasBar?: boolean;\n hasScale?: boolean;\n };\n\n // If it has hasBar and hasScale properties, check if at least one is true\n if ('hasBar' in barEl && 'hasScale' in barEl) {\n return barEl.hasBar === true || barEl.hasScale === true;\n }\n\n // Otherwise assume it's visible\n return true;\n });\n }\n\n private computeRoundedCorners(): {\n topLeft: boolean;\n topRight: boolean;\n bottomLeft: boolean;\n bottomRight: boolean;\n } {\n if (!this.borderRadiusPosition) {\n return {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n }\n\n if (this.borderRadiusPosition === BorderRadiusPosition.middleChild) {\n return {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n }\n\n // middleRoundedChild → round ALL corners (standalone instrument mode)\n if (this.borderRadiusPosition === BorderRadiusPosition.middleRoundedChild) {\n return {\n topLeft: true,\n topRight: true,\n bottomLeft: true,\n bottomRight: true,\n };\n }\n\n // Determine which external scales are VISIBLE (not just present in slots)\n const hasLeft = this.hasVisibleScale('left');\n const hasRight = this.hasVisibleScale('right');\n const hasTop = this.hasVisibleScale('top');\n const hasBottom = this.hasVisibleScale('bottom');\n\n // If scales exist on opposite sides, behave like middleChild (no rounding)\n if ((hasLeft && hasRight) || (hasTop && hasBottom)) {\n return {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n }\n\n const result = {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n\n const isInner =\n this.borderRadiusPosition === BorderRadiusPosition.innerFirstChild;\n const isOuter =\n this.borderRadiusPosition === BorderRadiusPosition.outerLastChild;\n\n // Handle perpendicular scale configurations (e.g., right + bottom)\n if (hasRight && hasBottom) {\n // Chart is in top-left position\n if (isInner) {\n result.bottomRight = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.topLeft = true; // Free corner\n }\n } else if (hasRight && hasTop) {\n // Chart is in bottom-left position\n if (isInner) {\n result.topRight = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.bottomLeft = true; // Free corner\n }\n } else if (hasLeft && hasBottom) {\n // Chart is in top-right position\n if (isInner) {\n result.bottomLeft = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.topRight = true; // Free corner\n }\n } else if (hasLeft && hasTop) {\n // Chart is in bottom-right position\n if (isInner) {\n result.topLeft = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.bottomRight = true; // Free corner\n }\n }\n // Handle single-side horizontal scales (left OR right, but not both)\n else if (hasRight && !hasLeft) {\n // Chart is on the left side of composition\n if (isInner) {\n result.topLeft = true;\n result.bottomLeft = true;\n } else if (isOuter) {\n result.topRight = true;\n result.bottomRight = true;\n }\n } else if (hasLeft && !hasRight) {\n // Chart is on the right side of composition\n if (isInner) {\n result.topRight = true;\n result.bottomRight = true;\n } else if (isOuter) {\n result.topLeft = true;\n result.bottomLeft = true;\n }\n }\n // Handle single-side vertical scales (top OR bottom, but not both)\n else if (hasBottom && !hasTop) {\n // Chart is on the top of composition\n if (isInner) {\n result.topLeft = true;\n result.topRight = true;\n } else if (isOuter) {\n result.bottomLeft = true;\n result.bottomRight = true;\n }\n } else if (hasTop && !hasBottom) {\n // Chart is on the bottom of composition\n if (isInner) {\n result.bottomLeft = true;\n result.bottomRight = true;\n } else if (isOuter) {\n result.topLeft = true;\n result.topRight = true;\n }\n }\n\n return result;\n }\n\n /**\n * Read current border radius from CSS variable and update state.\n * The chart will be recreated when needed through the normal update mechanism.\n * In instrument mode, uses explicit borderRadius value instead of CSS variable.\n */\n private updateBorderRadius = () => {\n if (!this.canvasEl) return;\n\n // In instrument mode, use explicit value or default (8px)\n // Skip CSS variable reading entirely\n let next: number;\n if (this.instrumentMode) {\n next = this.borderRadius ?? 8;\n } else {\n next = readExternalScaleBorderRadiusPx(\n this.canvasEl,\n ScaleType.regular,\n EXTERNAL_SCALE_BORDER_RADIUS_CSS_VAR\n );\n }\n\n if (this.currentBorderRadiusPx !== next) {\n this.currentBorderRadiusPx = next;\n // Trigger chart recreation to update border plugin\n if (this.chart) {\n this.chart.destroy();\n this.createChart();\n }\n }\n };\n\n /**\n * Create a Chart.js plugin that draws a border around the chart area with selective corner rounding\n * and clips content to that border.\n */\n private createBorderPlugin() {\n const corners = this.computeRoundedCorners();\n const radius = this.currentBorderRadiusPx;\n\n let didApplyClip = false;\n\n const buildRoundedRectPath = (\n ctx: CanvasRenderingContext2D,\n rect: {x: number; y: number; width: number; height: number},\n cornerRadius: number\n ) => {\n const {x, y, width, height} = rect;\n\n // Guard: Avoid invalid paths\n if (width <= 0 || height <= 0) return;\n\n const r = Math.max(\n 0,\n Math.min(cornerRadius, Math.min(width, height) / 2)\n );\n\n // Start at top-left corner (accounting for radius)\n ctx.moveTo(x + (corners.topLeft ? r : 0), y);\n\n ctx.lineTo(x + width - (corners.topRight ? r : 0), y);\n\n if (corners.topRight) {\n ctx.arcTo(x + width, y, x + width, y + r, r);\n }\n\n ctx.lineTo(x + width, y + height - (corners.bottomRight ? r : 0));\n\n if (corners.bottomRight) {\n ctx.arcTo(x + width, y + height, x + width - r, y + height, r);\n }\n\n ctx.lineTo(x + (corners.bottomLeft ? r : 0), y + height);\n\n if (corners.bottomLeft) {\n ctx.arcTo(x, y + height, x, y + height - r, r);\n }\n\n ctx.lineTo(x, y + (corners.topLeft ? r : 0));\n\n if (corners.topLeft) {\n ctx.arcTo(x, y, x + r, y, r);\n }\n };\n\n return {\n id: 'chartAreaBorder',\n beforeDatasetsDraw: (chart: Chart) => {\n const ctx = chart.ctx;\n const chartArea = chart.chartArea;\n\n if (!chartArea) return;\n\n // Draw/clip behavior should match CSS border-box:\n // - The border stroke must be fully INSIDE the chartArea.\n // - The stroke's OUTER edge should align to the chartArea boundary.\n // Reserve space by clipping content inside the border thickness.\n const borderWidthPx = 1;\n const clipInset = borderWidthPx;\n\n const {top, right, bottom, left} = chartArea;\n const rect = {\n x: left + clipInset,\n y: top + clipInset,\n width: right - left - clipInset * 2,\n height: bottom - top - clipInset * 2,\n };\n\n const clipRadius = Math.max(0, radius - clipInset);\n\n ctx.save();\n didApplyClip = true;\n\n // Create clipping path with selective corner rounding\n ctx.beginPath();\n\n buildRoundedRectPath(ctx as CanvasRenderingContext2D, rect, clipRadius);\n ctx.closePath();\n\n // Fill chart area background when in instrument mode\n if (this.instrumentMode) {\n const backgroundColor = getCssVariableValue(\n this,\n CHART_AREA_BACKGROUND_COLOR_VAR\n );\n ctx.fillStyle = backgroundColor;\n ctx.fill();\n }\n\n // Apply clipping\n ctx.clip();\n },\n afterDraw: (chart: Chart) => {\n const ctx = chart.ctx;\n const chartArea = chart.chartArea;\n\n if (!chartArea) return;\n\n const borderWidthPx = 1;\n const strokeInset = borderWidthPx / 2;\n\n const {top, right, bottom, left} = chartArea;\n const rect = {\n x: left + strokeInset,\n y: top + strokeInset,\n width: right - left - strokeInset * 2,\n height: bottom - top - strokeInset * 2,\n };\n\n const strokeRadius = Math.max(0, radius - strokeInset);\n\n // Check which sides have visible scales (edges to skip)\n const skipTop = this.hasVisibleScale('top');\n const skipRight = this.hasVisibleScale('right');\n const skipBottom = this.hasVisibleScale('bottom');\n const skipLeft = this.hasVisibleScale('left');\n\n // Get border color from CSS variable\n const borderColor = getCssVariableValue(\n this,\n '--instrument-frame-tertiary-color'\n );\n\n ctx.save();\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = borderWidthPx;\n\n const {x, y, width, height} = rect;\n const r = Math.max(\n 0,\n Math.min(strokeRadius, Math.min(width, height) / 2)\n );\n\n // Draw border segments, skipping edges that have visible external scales\n if (!skipTop && !skipRight && !skipBottom && !skipLeft) {\n // No scales - draw full border path\n ctx.beginPath();\n buildRoundedRectPath(\n ctx as CanvasRenderingContext2D,\n rect,\n strokeRadius\n );\n ctx.closePath();\n ctx.stroke();\n } else {\n // Draw border in segments, skipping edges with visible scales\n // Each segment is drawn as a continuous path for proper corner rendering\n\n // Top edge (skip if top scale present)\n if (!skipTop) {\n ctx.beginPath();\n // Start: either from top-left corner end or top-left corner point\n if (!skipLeft && corners.topLeft) {\n ctx.moveTo(x + r, y);\n } else {\n ctx.moveTo(x, y);\n }\n // Draw to: either to top-right corner start or top-right corner point\n if (!skipRight && corners.topRight) {\n ctx.lineTo(x + width - r, y);\n } else {\n ctx.lineTo(x + width, y);\n }\n ctx.stroke();\n }\n\n // Right edge (skip if right scale present)\n if (!skipRight) {\n ctx.beginPath();\n // Start: either from top-right corner end or top-right point\n if (!skipTop && corners.topRight) {\n ctx.moveTo(x + width, y + r);\n } else {\n ctx.moveTo(x + width, y);\n }\n // Draw to: either to bottom-right corner start or bottom-right point\n if (!skipBottom && corners.bottomRight) {\n ctx.lineTo(x + width, y + height - r);\n } else {\n ctx.lineTo(x + width, y + height);\n }\n ctx.stroke();\n }\n\n // Bottom edge (skip if bottom scale present)\n if (!skipBottom) {\n ctx.beginPath();\n // Start: either from bottom-right corner end or bottom-right point\n if (!skipRight && corners.bottomRight) {\n ctx.moveTo(x + width - r, y + height);\n } else {\n ctx.moveTo(x + width, y + height);\n }\n // Draw to: either to bottom-left corner start or bottom-left point\n if (!skipLeft && corners.bottomLeft) {\n ctx.lineTo(x + r, y + height);\n } else {\n ctx.lineTo(x, y + height);\n }\n ctx.stroke();\n }\n\n // Left edge (skip if left scale present)\n if (!skipLeft) {\n ctx.beginPath();\n // Start: either from bottom-left corner end or bottom-left point\n if (!skipBottom && corners.bottomLeft) {\n ctx.moveTo(x, y + height - r);\n } else {\n ctx.moveTo(x, y + height);\n }\n // Draw to: either to top-left corner start or top-left point\n if (!skipTop && corners.topLeft) {\n ctx.lineTo(x, y + r);\n } else {\n ctx.lineTo(x, y);\n }\n ctx.stroke();\n }\n\n // Draw corners separately (only if adjacent edges are both drawn)\n if (!skipTop && !skipLeft && corners.topLeft) {\n ctx.beginPath();\n ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);\n ctx.stroke();\n }\n\n if (!skipTop && !skipRight && corners.topRight) {\n ctx.beginPath();\n ctx.arc(x + width - r, y + r, r, Math.PI * 1.5, Math.PI * 2);\n ctx.stroke();\n }\n\n if (!skipRight && !skipBottom && corners.bottomRight) {\n ctx.beginPath();\n ctx.arc(x + width - r, y + height - r, r, 0, Math.PI * 0.5);\n ctx.stroke();\n }\n\n if (!skipBottom && !skipLeft && corners.bottomLeft) {\n ctx.beginPath();\n ctx.arc(x + r, y + height - r, r, Math.PI * 0.5, Math.PI);\n ctx.stroke();\n }\n }\n\n ctx.restore();\n\n // Redraw points above the border so edge points are not clipped.\n // The dataset draw already happened (and may have been clipped), so this pass only\n // matters for points near the chart-area boundary.\n if (this.showPoints) {\n ctx.save();\n\n chart.data.datasets.forEach((_ds, datasetIndex) => {\n const meta = chart.getDatasetMeta(datasetIndex);\n if (!meta || meta.hidden) return;\n\n // For line charts, meta.data contains PointElements\n (meta.data ?? []).forEach((el) => {\n const point = el as unknown as {\n draw: (ctx: CanvasRenderingContext2D) => void;\n skip?: boolean;\n options?: {radius?: number};\n };\n\n if (point.skip) return;\n const r = point.options?.radius;\n if (typeof r === 'number' && r <= 0) return;\n\n point.draw(ctx as CanvasRenderingContext2D);\n });\n });\n\n ctx.restore();\n }\n },\n afterDatasetsDraw: (chart: Chart) => {\n // Restore context after datasets are drawn to remove clipping\n if (didApplyClip) {\n chart.ctx.restore();\n didApplyClip = false;\n }\n },\n };\n }\n\n /**\n * Check if any external scales are slotted\n */\n private hasExternalScales(): boolean {\n const top = this.topScaleSlot?.assignedElements() ?? [];\n const bottom = this.bottomScaleSlot?.assignedElements() ?? [];\n const left = this.leftScaleSlot?.assignedElements() ?? [];\n const right = this.rightScaleSlot?.assignedElements() ?? [];\n return (\n top.length > 0 || bottom.length > 0 || left.length > 0 || right.length > 0\n );\n }\n\n /**\n * Handle slot change events - when scales are added/removed\n */\n private handleSlotChange = () => {\n // Reset ready state when scales change\n this.externalScaleDimensions.clear();\n\n // Wait for slotted elements to report their dimensions\n this.waitForScaleDimensions();\n };\n\n /**\n * Handle scale-dimensions-changed events from slotted scales\n */\n private handleScaleDimensionsChanged = (e: Event) => {\n if (this.isUpdatingScales) return; // Prevent infinite loops\n\n const event = e as CustomEvent<ExternalScaleDimensions>;\n const {side, thickness} = event.detail;\n\n // Update dimension tracking\n const previousThickness = this.externalScaleDimensions.get(side);\n if (previousThickness === thickness) return; // No change\n\n this.externalScaleDimensions.set(side, thickness);\n\n // Debounce updates to avoid layout thrashing\n if (this.dimensionUpdateTimer) {\n clearTimeout(this.dimensionUpdateTimer);\n }\n\n this.dimensionUpdateTimer = setTimeout(() => {\n this.syncScalesAndChart();\n }, 16); // One frame\n };\n\n /**\n * Wait for all slotted scales to report their dimensions\n */\n private async waitForScaleDimensions() {\n if (!this.hasExternalScales()) {\n this.requestUpdate();\n return;\n }\n\n // Collect all slotted scale elements\n const scaleElements: ExternalScaleElement[] = [];\n [\n this.topScaleSlot,\n this.bottomScaleSlot,\n this.leftScaleSlot,\n this.rightScaleSlot,\n ].forEach((slot) => {\n if (slot) {\n const assigned = slot.assignedElements() as ExternalScaleElement[];\n scaleElements.push(...assigned);\n }\n });\n\n // Ensure all scales have fixedAspectRatio matching our fixedAspectRatioScaling setting\n // and use the same scaleReferenceSize for consistent proportional scaling.\n // Each scale handles orientation-specific scaling internally based on its main axis.\n const setScaleProps = (slot: HTMLSlotElement | undefined) => {\n if (!slot) return;\n const scales = slot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n scale.fixedAspectRatio = this.fixedAspectRatioScaling;\n scale.scaleReferenceSize = this.scaleReferenceSize;\n });\n };\n\n // All scales use the same scaleReferenceSize - this avoids churn from\n // conflicting values between here and updateScaleProperties()\n setScaleProps(this.leftScaleSlot);\n setScaleProps(this.rightScaleSlot);\n setScaleProps(this.topScaleSlot);\n setScaleProps(this.bottomScaleSlot);\n\n // Wait for all scales to finish rendering\n await Promise.all(\n scaleElements.map((el) =>\n 'updateComplete' in el && typeof el.updateComplete === 'object'\n ? (el.updateComplete as Promise<unknown>)\n : Promise.resolve()\n )\n );\n\n // Scales should have dispatched their dimensions by now\n // If we don't have dimensions yet, wait a bit more\n if (this.externalScaleDimensions.size === 0 && scaleElements.length > 0) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n\n this.syncScalesAndChart();\n }\n\n /**\n * Synchronize scale and chart dimensions/data\n * This is the main coordination function\n */\n private syncScalesAndChart(): boolean {\n if (this.isUpdatingScales) return false;\n this.isUpdatingScales = true;\n\n try {\n // Step 1: Calculate padding from scale dimensions\n const padding = this.calculatePaddingFromScales();\n\n // Step 2: Calculate effective chart area\n const effectiveWidth = this.width - padding.left - padding.right;\n const effectiveHeight = this.height - padding.top - padding.bottom;\n\n // Guard against invalid dimensions\n if (effectiveWidth <= 0 || effectiveHeight <= 0) {\n console.warn('[chart-line-base] Invalid effective dimensions', {\n width: this.width,\n height: this.height,\n padding,\n effectiveWidth,\n effectiveHeight,\n });\n return false;\n }\n\n // Step 3: Update slotted scales with coordinated properties\n this.updateScaleProperties(padding);\n\n // Step 4: Force recreation of chart with new padding\n if (this.chart) {\n this.chart.destroy();\n }\n this.createChart();\n return true;\n } finally {\n this.isUpdatingScales = false;\n }\n }\n\n /**\n * Calculate chart padding from external scale dimensions.\n *\n * For sides without an external scale, falls back to `CHART_DIMENSIONS.CANVAS_PADDING`\n * (the chart's own padding to reserve room for axis tick labels). When\n * `hasLabelPadding=false` that fallback is 0 so the chart renders edge-to-edge,\n * and this same value is cascaded to slotted scales via `updateScaleProperties()`\n * — so the bar's main-axis padding (`paddingTop`/`paddingBottom` for vertical bars)\n * collapses with the chart's perpendicular padding and they stay visually aligned.\n */\n private calculatePaddingFromScales() {\n const defaultPadding = this.hasLabelPadding\n ? CHART_DIMENSIONS.CANVAS_PADDING\n : 0;\n\n const padding = {\n top: this.externalScaleDimensions.get('top') ?? defaultPadding,\n right: this.externalScaleDimensions.get('right') ?? defaultPadding,\n bottom: this.externalScaleDimensions.get('bottom') ?? defaultPadding,\n left: this.externalScaleDimensions.get('left') ?? defaultPadding,\n };\n\n return padding;\n }\n\n /**\n * Update properties on slotted scale elements\n */\n private updateScaleProperties(padding: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n }) {\n // Get chart scales for min/max values\n const yMin = this.chart?.scales['y']?.min ?? 0;\n const yMax = this.chart?.scales['y']?.max ?? 100;\n const xMin = this.chart?.scales['x']?.min ?? 0;\n const xMax = this.chart?.scales['x']?.max ?? 100;\n\n // Use effective dimensions for threshold checks\n const effectiveWidth = this.getEffectiveWidth();\n const effectiveHeight = this.getEffectiveHeight();\n\n // Determine if we should show labels (above threshold).\n // When `hasLabelPadding=false` the chart reserves no room for axis labels,\n // so slotted scales must also hide their labels — otherwise their\n // `labelThickness` band stays in the reported thickness and the chart\n // gets re-padded inward (leaving whitespace on the scale's side), and any\n // visible labels would be clipped against the canvas edge.\n const showLabels =\n this.hasLabelPadding &&\n effectiveWidth >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS &&\n effectiveHeight >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n\n // Calculate viewBox padding for external scales.\n // When fixedAspectRatioScaling is true, the chart's Canvas padding is scaled by\n // scaleFactor = computedWidth / this.width. For external scales to match, their\n // viewBox padding needs to be: basePadding * scaleReferenceSize / referenceSize\n // This ensures the visual padding matches when the SVG scales to fill the container.\n const verticalViewBoxPadding = this.fixedAspectRatioScaling\n ? {\n top: Math.round(\n (padding.top * this.scaleReferenceSize) / this.height\n ),\n bottom: Math.round(\n (padding.bottom * this.scaleReferenceSize) / this.height\n ),\n }\n : {top: padding.top, bottom: padding.bottom};\n\n const horizontalViewBoxPadding = this.fixedAspectRatioScaling\n ? {\n left: Math.round(\n (padding.left * this.scaleReferenceSize) / this.width\n ),\n right: Math.round(\n (padding.right * this.scaleReferenceSize) / this.width\n ),\n }\n : {left: padding.left, right: padding.right};\n\n // Update each slotted scale\n const updates: Array<\n [\n HTMLSlotElement | undefined,\n ExternalScaleElement,\n Partial<ExternalScaleElement>,\n ]\n > = [];\n\n // Left scale\n if (this.leftScaleSlot) {\n const scales =\n this.leftScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n minValue: yMin,\n maxValue: yMax,\n height: effectiveHeight, // Use effective height for proper sizing\n paddingTop: verticalViewBoxPadding.top,\n paddingBottom: verticalViewBoxPadding.bottom,\n paddingStart: verticalViewBoxPadding.top,\n paddingEnd: verticalViewBoxPadding.bottom,\n showLabels,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.yStepSize !== undefined) {\n props.primaryTickmarkInterval = this.yStepSize;\n }\n updates.push([this.leftScaleSlot, scale, props]);\n });\n }\n\n // Right scale\n if (this.rightScaleSlot) {\n const scales =\n this.rightScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n minValue: yMin,\n maxValue: yMax,\n height: effectiveHeight, // Use effective height for proper sizing\n paddingTop: verticalViewBoxPadding.top,\n paddingBottom: verticalViewBoxPadding.bottom,\n paddingStart: verticalViewBoxPadding.top,\n paddingEnd: verticalViewBoxPadding.bottom,\n showLabels,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.yStepSize !== undefined) {\n props.primaryTickmarkInterval = this.yStepSize;\n }\n updates.push([this.rightScaleSlot, scale, props]);\n });\n }\n\n // Top scale\n if (this.topScaleSlot) {\n const scales =\n this.topScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n minValue: xMin,\n maxValue: xMax,\n width: effectiveWidth, // Use effective width for proper sizing\n paddingLeft: horizontalViewBoxPadding.left,\n paddingRight: horizontalViewBoxPadding.right,\n paddingStart: horizontalViewBoxPadding.left,\n paddingEnd: horizontalViewBoxPadding.right,\n showLabels,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.xStepSize !== undefined) {\n props.primaryTickmarkInterval = this.xStepSize;\n }\n updates.push([this.topScaleSlot, scale, props]);\n });\n }\n\n // Bottom scale\n if (this.bottomScaleSlot) {\n const scales =\n this.bottomScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n minValue: xMin,\n maxValue: xMax,\n width: effectiveWidth, // Use effective width for proper sizing\n paddingLeft: horizontalViewBoxPadding.left,\n paddingRight: horizontalViewBoxPadding.right,\n paddingStart: horizontalViewBoxPadding.left,\n paddingEnd: horizontalViewBoxPadding.right,\n showLabels,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.xStepSize !== undefined) {\n props.primaryTickmarkInterval = this.xStepSize;\n }\n updates.push([this.bottomScaleSlot, scale, props]);\n });\n }\n\n // Apply all updates\n updates.forEach(([_slot, scale, props]) => {\n Object.assign(scale, props);\n });\n }\n\n private hasAnyChanged(\n changed: PropertyValues,\n props: readonly (keyof ObcChartLineBase)[]\n ): boolean {\n return props.some((prop) => changed.has(prop));\n }\n\n /**\n * Apply fillMode rules to datasets. Must be called after the chart is created\n * so scales and pixel coordinates are available for gradient construction.\n *\n * NOTE: For non-threshold modes (solid, semitransparent), backgroundColor is already\n * set correctly in buildDataset(). This method now only handles threshold gradients\n * which require Chart.js scales to be available.\n */\n protected applyFillModes() {\n // Guard: Verify chart and canvas exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const chart = this.chart; // Store reference for TypeScript\n const ctx = chart.ctx as CanvasRenderingContext2D;\n\n // Guard: Verify canvas context is available\n if (!ctx) return;\n\n const fill = this.shouldApplyFill();\n const fillMode = this.getFillMode();\n\n // Only process threshold mode - other modes already have correct backgroundColor from buildDataset()\n if (fillMode !== 'threshold' || !fill) {\n return;\n }\n\n chart.data.datasets.forEach((ds, _idx) => {\n const dataset = ds as ChartDataset<'line'> & {\n fill?:\n | boolean\n | number\n | {target: number; above: string; below: string};\n yAxisID?: string;\n };\n\n // Skip if not filling\n if (dataset.fill === false || !fill) {\n return;\n }\n\n // Threshold fill: only applies to single-series, creates gradients for border\n const yScaleId = dataset.yAxisID ?? 'y';\n const yScale = chart.scales[yScaleId];\n\n if (!yScale) {\n return;\n }\n\n // Calculate threshold and gradient stop position\n const dataValues = (dataset.data as (number | {x: number; y: number})[])\n .map((d) => (typeof d === 'number' ? d : d.y))\n .filter((v) => Number.isFinite(v));\n\n // Guard: Need at least some data to calculate threshold\n if (dataValues.length === 0) {\n return;\n }\n\n const minVal = Math.min(...dataValues);\n const maxVal = Math.max(...dataValues);\n const thresholdVal = (minVal + maxVal) / 2;\n const thresholdPixel = yScale.getPixelForValue(thresholdVal);\n const range = yScale.bottom - yScale.top;\n\n // Guard: Ensure stop is a finite number between 0 and 1\n let stop = (thresholdPixel - yScale.top) / range;\n if (!Number.isFinite(stop) || range === 0) {\n stop = 0.5; // Fallback to middle if calculation fails\n } else {\n stop = Math.max(0, Math.min(1, stop));\n }\n\n // Extract threshold color variables (used for both fill and border)\n const lowRaw = LINE_GRAPH_GRID_CONFIG.thresholdLowColorVar;\n const highRaw = LINE_GRAPH_GRID_CONFIG.thresholdHighColorVar;\n\n // Helper to create threshold gradient\n const createGradient = (lowAlpha: number, highAlpha: number) => {\n const low = applyAlphaToColor(this, lowRaw, lowAlpha);\n const high = applyAlphaToColor(this, highRaw, highAlpha);\n const grad = ctx.createLinearGradient(0, yScale.top, 0, yScale.bottom);\n grad.addColorStop(0, high);\n grad.addColorStop(stop, high);\n grad.addColorStop(stop, low);\n grad.addColorStop(1, low);\n return grad;\n };\n\n // Create fill gradient (35% alpha) and border gradient (80% alpha)\n const fillGradient = createGradient(0.35, 0.35);\n const borderGradient = createGradient(0.8, 0.8);\n dataset.backgroundColor = fillGradient as unknown as string;\n dataset.borderColor = borderGradient as unknown as string;\n });\n }\n\n // Update external library AFTER render\n override updated(changed: PropertyValues) {\n super.updated(changed);\n\n // Only update if watched properties changed\n if (!this.hasAnyChanged(changed, LINE_GRAPH_WATCHED_PROP_NAMES)) {\n return;\n }\n\n // `computedWidth` / `computedHeight` are the pixel size everything below\n // derives from (`--chart-height`, the slotted scales' height, the padding\n // scale factor). They were only ever refreshed from the wrapper's\n // ResizeObserver, so re-assigning `width` / `height` rebuilt the chart\n // against the *previous* aspect ratio and the new one only took effect on\n // the next container resize (issue #1138).\n //\n // This runs before the `hasLabelPadding` branch below: the two can change\n // in the same update (the tank sets both on its embedded gauge-trend), and\n // taking the label-padding path first would rebuild against a stale\n // derived size. Nothing is lost by going through here instead — a rebuild\n // from `updateComputedDimensions()` goes via `syncScalesAndChart()`, which\n // performs the same `updateScaleProperties()` cascade.\n if (this.hasAnyChanged(changed, LINE_GRAPH_DIMENSION_PROP_NAMES)) {\n // Recreates the chart itself when the derived size actually moved.\n if (this.updateComputedDimensions()) return;\n }\n\n // `hasLabelPadding` cascades into slotted scales via `updateScaleProperties()`\n // (toggles `showLabels`, which collapses/expands the bar's label band and\n // changes its reported thickness). That path only runs through\n // `syncScalesAndChart()`, so when only `hasLabelPadding` changes we must\n // route through there — otherwise slotted scales stay stale until the\n // next slot/resize event and the chart re-pads on stale thickness.\n if (changed.has('hasLabelPadding') && this.hasExternalScales()) {\n this.syncScalesAndChart();\n return;\n }\n\n const needsRecreation = this.hasAnyChanged(\n changed,\n LINE_GRAPH_RECREATE_PROP_NAMES\n );\n\n if (needsRecreation) {\n this.chart?.destroy();\n this.createChart();\n } else {\n this.updateChart();\n }\n }\n\n override async firstUpdated() {\n // Wait for external scales to report dimensions before creating chart\n await this.waitForScaleDimensions();\n\n if (!this.hasExternalScales()) {\n // No external scales, create chart normally\n this.createChart();\n }\n // If we have external scales, chart is created in syncScalesAndChart()\n\n this.themeObserver = observeThemeChanges(() => {\n this.updateChartColors();\n this.updateBorderRadius(); // Border color may change with theme\n });\n this.setupResizeObserver();\n this.setupAspectRatioResizeObserver();\n\n // Setup border radius observer and apply initial styling\n // In instrument mode, skip observer - we use fixed border radius\n if (this.canvasEl) {\n if (!this.instrumentMode) {\n this.borderRadiusObserver = startExternalScaleBorderRadiusObserver(\n this.canvasEl,\n this.updateBorderRadius\n );\n }\n this.updateBorderRadius();\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.chart?.destroy();\n this.themeObserver?.disconnect();\n this.resizeObserver?.disconnect();\n this.aspectRatioResizeObserver?.disconnect();\n this.borderRadiusObserver?.disconnect();\n\n if (this.dimensionUpdateTimer) {\n clearTimeout(this.dimensionUpdateTimer);\n }\n }\n\n /**\n * Crossing MIN_HEIGHT_WITH_LABELS changes the plugin set, so the chart is\n * rebuilt rather than updated.\n */\n private setupResizeObserver() {\n if (!this.canvasEl) return;\n\n this.resizeObserver = observeLabelThreshold(\n this.canvasEl,\n () =>\n (this.canvasEl?.clientHeight ?? 0) >=\n RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS,\n {\n rebuild: () => {\n this.chart?.destroy();\n this.createChart();\n },\n update: () => this.updateChart(),\n }\n );\n }\n\n /**\n * Setup resize observer for fixed aspect ratio scaling.\n * Observes the wrapper element and recalculates dimensions when parent size changes.\n */\n private setupAspectRatioResizeObserver() {\n const wrapper = this.renderRoot.querySelector('.wrapper');\n if (!wrapper) return;\n\n // Initialize computed dimensions\n this.updateComputedDimensions();\n\n this.aspectRatioResizeObserver = new ResizeObserver(() => {\n if (!this.fixedAspectRatioScaling) return;\n this.updateComputedDimensions();\n });\n\n this.aspectRatioResizeObserver.observe(wrapper);\n }\n\n /**\n * Refresh `computedWidth` / `computedHeight`, the derived pixel size the\n * chart and its slotted scales are laid out from.\n *\n * In pixel mode they simply mirror `width` / `height`. Only in\n * `fixedAspectRatioScaling` mode are they derived — from the wrapper's\n * measured width and the aspect ratio the `width` / `height` pair defines —\n * and only then can this rebuild the chart.\n *\n * @returns `true` when the change was significant enough that the chart was\n * rebuilt here, so the caller must not rebuild it a second time.\n */\n private updateComputedDimensions(): boolean {\n if (!this.fixedAspectRatioScaling) {\n // In pixel mode, use width/height directly\n this.computedWidth = this.width;\n this.computedHeight = this.height;\n return false;\n }\n\n const wrapper = this.renderRoot.querySelector('.wrapper') as HTMLElement;\n if (!wrapper) return false;\n\n // Get parent's available width\n const parentWidth = wrapper.clientWidth;\n if (parentWidth <= 0) return false;\n\n // Calculate aspect ratio from width/height properties\n const aspectRatio = this.width / this.height;\n\n // Use parent width as actual width, calculate height from aspect ratio\n const newWidth = parentWidth;\n const newHeight = Math.round(parentWidth / aspectRatio);\n\n // Only update if dimensions changed\n if (this.computedWidth !== newWidth || this.computedHeight !== newHeight) {\n this.computedWidth = newWidth;\n this.computedHeight = newHeight;\n\n // Update external scales and recreate chart with new dimensions\n // Note: syncScalesAndChart() handles chart destruction and creation internally,\n // so we only call createChart() directly when there are no external scales.\n if (this.hasExternalScales()) {\n // syncScalesAndChart() bails without rebuilding when a sync is already\n // in flight or the effective chart area is degenerate; reporting its\n // real outcome keeps the caller's own rebuild as the fallback.\n return this.syncScalesAndChart();\n } else if (this.chart) {\n // No external scales - just recreate chart\n this.chart.destroy();\n this.createChart();\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the effective width for chart rendering.\n * Returns computed width when fixedAspectRatioScaling is true, otherwise the width property.\n */\n protected getEffectiveWidth(): number {\n return this.fixedAspectRatioScaling ? this.computedWidth : this.width;\n }\n\n /**\n * Get the effective height for chart rendering.\n * Returns computed height when fixedAspectRatioScaling is true, otherwise the height property.\n */\n protected getEffectiveHeight(): number {\n return this.fixedAspectRatioScaling ? this.computedHeight : this.height;\n }\n\n /**\n * Get the scale factor for proportional scaling when fixedAspectRatioScaling is true.\n * Returns 1.0 when not in fixed aspect ratio mode.\n * The scale factor is based on computed width vs reference width (the width property).\n */\n protected getScaleFactor(): number {\n if (!this.fixedAspectRatioScaling) {\n return 1.0;\n }\n // Scale factor is based on computed width vs the reference width (width property)\n // The width property defines the \"design\" or \"reference\" size\n return this.computedWidth / this.width;\n }\n\n /**\n * Build a complete dataset configuration with all styling properties.\n * Handles both new datasets (from values array) and existing datasets (normalization).\n *\n * @param data - Either numeric values array or existing dataset to normalize\n * @param index - Dataset index for color cycling\n * @param chartColors - Color palette array\n * @param totalCount - Total number of datasets (used for stacked divider logic)\n * @returns Fully configured Chart.js dataset\n */\n protected buildDataset(\n data:\n | number[]\n | {x: number; y: number}[]\n | ChartDataset<'line', ChartLinePoint[]>,\n index: number,\n chartColors: string[],\n totalCount = 1\n ): ChartDataset<'line', ChartLinePoint[]> {\n const currentColor = chartColors[index % chartColors.length];\n\n // Raw input is an array (values or points); anything else is an existing dataset\n const existingDataset = Array.isArray(data)\n ? null\n : (data as ChartDataset<'line', ChartLinePoint[]>);\n const values = Array.isArray(data)\n ? (data as number[] | {x: number; y: number}[])\n : null;\n\n const borderColor = existingDataset?.borderColor ?? currentColor;\n const fillFlag = existingDataset?.fill ?? this.shouldApplyFill();\n const tension = this.lineMode === 'smooth' ? this.DEFAULT_TENSION : 0;\n\n // For stacked mode, add divider lines between datasets (except the topmost one)\n const isStacked = this.shouldStack() && this.getFillMode() !== 'threshold';\n const needsDivider = isStacked && index < totalCount - 1;\n\n // Calculate backgroundColor immediately instead of deferring to applyFillModes()\n // This prevents flicker when chart is recreated multiple times during resize\n let backgroundColor: string = 'transparent';\n const fillMode = this.getFillMode();\n\n if (fillFlag && fillMode) {\n const nextColor = chartColors[(index + 1) % chartColors.length];\n\n if (fillMode === 'solid') {\n backgroundColor = String(borderColor);\n } else if (fillMode === 'semitransparent') {\n backgroundColor = applyAlphaToColor(this, nextColor, 0.5);\n } else if (fillMode === 'threshold') {\n // For threshold, we'll still need gradients from applyFillModes\n // but set a reasonable default to avoid transparent flash\n backgroundColor = applyAlphaToColor(this, nextColor, 0.5);\n }\n }\n\n const result = {\n ...(existingDataset || {}),\n data: existingDataset?.data ?? values!,\n borderColor,\n backgroundColor,\n borderWidth: existingDataset?.borderWidth ?? 2,\n showLine: existingDataset?.showLine ?? true,\n tension: existingDataset?.tension ?? tension,\n pointRadius:\n existingDataset?.pointRadius ??\n (this.showPoints ? this.POINT_RADIUS : 0),\n pointBackgroundColor: existingDataset?.pointBackgroundColor ?? '#fff',\n pointBorderColor: existingDataset?.pointBorderColor ?? borderColor,\n pointBorderWidth: existingDataset?.pointBorderWidth ?? 2,\n stepped: existingDataset?.stepped ?? this.lineMode === 'stepped',\n // Use 'start' to fill from chart bottom, not 'origin' (y=0)\n fill: fillFlag ? 'start' : false,\n spanGaps: existingDataset?.spanGaps ?? true,\n // Add segment styling for stacked divider lines\n ...(needsDivider && {\n segment: {\n borderColor: getCssVariableValue(\n this,\n LINE_GRAPH_GRID_CONFIG.stackedDividerColorVar\n ),\n borderWidth: 1,\n },\n }),\n };\n\n return result as ChartDataset<'line', ChartLinePoint[]>;\n }\n\n /**\n * Create threshold mode datasets: invisible baseline + main dataset with\n * above/below fills. Accepts plain values (category mode) or {x, y} points\n * (time/number mode); the baseline mirrors the input x-positions.\n */\n protected createThresholdDatasets(\n values: number[] | {x: number; y: number}[],\n chartColors: string[]\n ): ChartDataset<'line', ChartLinePoint[]>[] {\n const yValues = values\n .map((v) => (typeof v === 'number' ? v : v.y))\n .filter((n) => Number.isFinite(n));\n const minV = yValues.length ? Math.min(...yValues) : 0;\n const maxV = yValues.length ? Math.max(...yValues) : 100;\n const threshold = (minV + maxV) / 2;\n const baselineData: ChartLinePoint[] = values.map((v) =>\n typeof v === 'number' ? threshold : {x: v.x, y: threshold}\n );\n\n const lowRaw = LINE_GRAPH_GRID_CONFIG.thresholdLowColorVar;\n const highRaw = LINE_GRAPH_GRID_CONFIG.thresholdHighColorVar;\n const highFill = applyAlphaToColor(this, highRaw, 0.35);\n const lowFill = applyAlphaToColor(this, lowRaw, 0.35);\n\n const baselineDataset: ChartDataset<'line', ChartLinePoint[]> = {\n label: 'threshold-baseline',\n data: baselineData,\n borderColor: 'transparent',\n backgroundColor: 'transparent',\n borderWidth: 0,\n pointRadius: 0,\n showLine: false,\n fill: false,\n spanGaps: true,\n };\n\n const main = this.buildDataset(values, 0, chartColors);\n (main as unknown as Record<string, unknown>).fill = {\n target: 0,\n above: highFill,\n below: lowFill,\n };\n // Border gradient will be set by applyFillModes after chart scales are ready\n main.borderWidth = 2;\n\n return [baselineDataset, main];\n }\n\n /**\n * Prepare normalized datasets for multi-series charts.\n * In time/number mode every point's x is normalized (epoch ms / number)\n * so strings, Dates and Temporal objects position correctly.\n */\n protected prepareMultiSeriesDatasets() {\n const defaultPalette =\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS;\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n defaultPalette\n );\n\n // Normalize first, then warn once per assignment with the aggregate\n // count across ALL series — warning inside the per-dataset loop would\n // either flood the console or (with ref-based dedup) silently swallow\n // failures in every series after the first.\n const normalized = this.datasets!.map((ds) => this.normalizeDatasetX(ds));\n if (this.isNumericXAxis) {\n this.warnOnInvalidX(\n normalized.flatMap((ds) =>\n (ds.data ?? []).map((pt) =>\n pt && typeof pt === 'object' ? (pt.x as number) : 0\n )\n ),\n this.datasets\n );\n }\n\n const totalCount = this.datasets!.length;\n return normalized.map((ds, i) =>\n this.buildDataset(ds, i, chartColors, totalCount)\n );\n }\n\n /** @internal - Return a copy of the dataset with normalized point x-values. */\n private normalizeDatasetX(\n ds: ChartDataset<'line', ChartLinePoint[]>\n ): ChartDataset<'line', ChartLinePoint[]> {\n if (!this.isNumericXAxis || !ds.data) return ds;\n const data = ds.data.map((pt) =>\n pt && typeof pt === 'object' && 'x' in pt\n ? {...pt, x: normalizeXValue(pt.x, this.xValueMode)}\n : pt\n );\n return {...ds, data};\n }\n\n /**\n * Prepare datasets for single-series charts.\n * Category mode: labels + numeric values (unchanged legacy path).\n * Time/number mode: normalized {x, y} points on a linear scale.\n * Handles both regular and threshold fill modes.\n */\n protected prepareSingleSeriesDatasets() {\n const defaultPalette =\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS;\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n defaultPalette\n );\n const fill = this.shouldApplyFill();\n const fillMode = this.getFillMode();\n\n if (this.isNumericXAxis) {\n const points = this.data.map((d) => ({\n x: normalizeXValue(d.x ?? d.label ?? NaN, this.xValueMode),\n y: d.value,\n }));\n this.warnOnInvalidX(\n points.map((p) => p.x),\n this.data\n );\n const datasets =\n fill && fillMode === 'threshold'\n ? this.createThresholdDatasets(points, chartColors)\n : [this.buildDataset(points, 0, chartColors)];\n return {datasets, labels: [] as (string | number)[]};\n }\n\n const values = this.data.map((d) => d.value);\n const labels = this.data.map((d) => d.label ?? String(d.x ?? ''));\n\n const datasets =\n fill && fillMode === 'threshold'\n ? this.createThresholdDatasets(values, chartColors)\n : [this.buildDataset(values, 0, chartColors)];\n\n return {datasets, labels};\n }\n\n /**\n * Get Chart.js options with dynamic sizing and padding\n */\n protected getChartOptions(): ChartOptions<'line'> {\n // Use effective dimensions (computed when fixedAspectRatioScaling=true)\n const effectiveWidth = this.getEffectiveWidth();\n const effectiveHeight = this.getEffectiveHeight();\n\n // Determine if chart is too small for labels\n const isTooSmall =\n effectiveWidth < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS ||\n effectiveHeight < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n\n // Get scale factor for proportional scaling in fixed aspect ratio mode\n const scaleFactor = this.getScaleFactor();\n\n // Calculate padding for the chart.\n // External scales report their actual visual (scaled) thickness when in fixedAspectRatio mode,\n // so we use those values directly without additional scaling.\n // For sides without external scales, we apply the chart's scaleFactor to default padding.\n let padding: {top: number; right: number; bottom: number; left: number};\n\n // When hasLabelPadding=false the chart never reserves space for axis tick\n // labels on sides without an external scale (renders edge-to-edge there).\n // External-scale sides still receive their reported visual thickness so\n // slotted scales/bars remain fully visible.\n const defaultPaddingScaled = !this.hasLabelPadding\n ? 0\n : this.fixedAspectRatioScaling\n ? Math.round(CHART_DIMENSIONS.CANVAS_PADDING * scaleFactor)\n : CHART_DIMENSIONS.CANVAS_PADDING;\n\n if (isTooSmall && this.hasLabelPadding) {\n padding = {top: 0, right: 0, bottom: 0, left: 0};\n } else if (this.hasExternalScales()) {\n // External scales report their visual dimensions (already scaled when fixedAspectRatio=true)\n const scalePadding = this.calculatePaddingFromScales();\n padding = {\n top: this.externalScaleDimensions.has('top')\n ? scalePadding.top\n : defaultPaddingScaled,\n right: this.externalScaleDimensions.has('right')\n ? scalePadding.right\n : defaultPaddingScaled,\n bottom: this.externalScaleDimensions.has('bottom')\n ? scalePadding.bottom\n : defaultPaddingScaled,\n left: this.externalScaleDimensions.has('left')\n ? scalePadding.left\n : defaultPaddingScaled,\n };\n } else {\n // No external scales - apply scaleFactor to all default padding\n padding = {\n top: defaultPaddingScaled,\n right: defaultPaddingScaled,\n bottom: defaultPaddingScaled,\n left: defaultPaddingScaled,\n };\n }\n\n // Set CSS variables for wrapper and canvas sizing\n if (this.fixedAspectRatioScaling) {\n // In responsive mode, use 100% width, computed height\n this.style.setProperty('--chart-width', '100%');\n this.style.setProperty('--chart-height', `${effectiveHeight}px`);\n } else {\n // In pixel mode, use width/height directly\n this.style.setProperty('--chart-width', `${this.width}px`);\n this.style.setProperty('--chart-height', `${this.height}px`);\n }\n\n // Compute reference timestamp for time-based x-axis\n const refTs = this.computeTimeReference();\n\n // Force showTickMarks=false when external scales are present\n const effectiveShowTickMarks = this.hasExternalScales()\n ? false\n : this.showTickMarks;\n\n return {\n responsive: true,\n maintainAspectRatio: false, // Use explicit width/height instead\n layout: {\n padding,\n },\n plugins: {\n legend: {\n display: false,\n labels: {\n generateLabels: () => [], // Prevent Chart.js from generating labels internally\n },\n onClick: () => {}, // Disable legend click handler\n },\n tooltip: {\n ...getChartTooltipOptions(this),\n enabled: !isTooSmall,\n callbacks: {\n title: () => '',\n label: (context) => {\n const value =\n typeof context.parsed === 'object' && context.parsed !== null\n ? (context.parsed as {y: number}).y\n : (context.parsed as number);\n const numericValue = formatChartNumber(value, 1, false, 0);\n const unit = this.unit ? `${this.unit}` : '';\n let label = context.label ?? '';\n if (this.isNumericXAxis) {\n const x =\n typeof context.parsed === 'object' && context.parsed !== null\n ? (context.parsed as {x: number}).x\n : NaN;\n const relativeTo =\n this.timeDisplay === TimeDisplay.minutes ? refTs : undefined;\n label = formatXValue(x, this.xValueMode, relativeTo);\n }\n return `${label} ${numericValue}${unit}`;\n },\n },\n },\n },\n animation: false,\n scales: this.buildScalesConfig(refTs, isTooSmall, effectiveShowTickMarks),\n };\n }\n\n /**\n * Compute reference timestamp for time axis formatting.\n * Returns earliest timestamp for 'date' mode, latest for 'minutes' mode.\n */\n private computeTimeReference(): number | undefined {\n if (this.xAxisType !== XAxisType.time) return undefined;\n\n const timestamps: number[] = [];\n\n // Collect timestamps from datasets\n if (this.datasets?.length) {\n this.datasets.forEach((ds) => {\n if (!ds.data) return;\n ds.data.forEach((pt) => {\n if (pt && typeof pt === 'object' && 'x' in pt) {\n const ts = normalizeXValue(pt.x, XValueMode.time);\n if (Number.isFinite(ts)) timestamps.push(ts);\n }\n });\n });\n } else if (this.data?.length) {\n // Collect timestamps from single-series data items\n this.data.forEach((d) => {\n const ts = normalizeXValue(d.x ?? d.label ?? NaN, XValueMode.time);\n if (Number.isFinite(ts)) timestamps.push(ts);\n });\n }\n\n // Collect timestamps from labels if no dataset timestamps found\n if (!timestamps.length && this.labels?.length) {\n this.labels.forEach((l) => {\n if (typeof l === 'string') {\n const ts = new Date(l).getTime();\n if (Number.isFinite(ts)) timestamps.push(ts);\n }\n });\n }\n\n return timestamps.length\n ? this.timeDisplay === 'minutes'\n ? Math.max(...timestamps)\n : Math.min(...timestamps)\n : undefined;\n }\n\n /**\n * Build Chart.js scale configuration with theme-aware styling.\n * Applies CSS variables for grid colors, tick colors, and label typography.\n *\n * @param minX - Reference timestamp for time-based x-axis (used for 'minutes' display)\n * @param isTooSmall - Whether chart is below 192px threshold (hides ticks when true)\n * @param showTickMarks - Whether to show tick marks (overridden to false when external scales present)\n * @returns Configured scales object for Chart.js options\n */\n protected buildScalesConfig(\n minX?: number,\n isTooSmall = false,\n showTickMarks = true\n ) {\n // Build scales typed for ChartOptions<'line'>\n // If we don't have a date adapter available, fall back to numeric linear scale\n // by converting date strings to timestamps before chart creation. We still\n // render formatted tick labels for readability.\n // Read CSS variables for styling\n const gridColor = getCssVariableValue(\n this,\n LINE_GRAPH_GRID_CONFIG.gridColorVar\n );\n const tickColor = getCssVariableValue(\n this,\n LINE_GRAPH_GRID_CONFIG.tickColorVar\n );\n const fontFamily = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontFamily\n );\n const fontSize = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontSizeVar\n );\n const fontWeight = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontWeightVar\n );\n const fontColor = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontColorVar\n );\n\n // Extract common values used for both x and y axes.\n // When hasLabelPadding=false the chart renders edge-to-edge, so labels are\n // force-hidden to prevent clipping.\n const showLabels = showTickMarks && !isTooSmall && this.hasLabelPadding;\n const showTicks = showTickMarks && !isTooSmall && this.hasLabelPadding;\n const fontConfig = {family: fontFamily, size: fontSize, weight: fontWeight};\n\n const x = {\n type: this.xAxisType === XAxisType.category ? 'category' : 'linear',\n offset: false, // Always edge-to-edge (no padding on x-axis)\n grace: 0, // No extra margin\n bounds: 'data', // Use data bounds for edge-to-edge rendering\n grid: {\n display: this.showGrid && this.showGridX,\n color: gridColor,\n offset: false,\n drawTicks: showTicks,\n },\n ticks: {\n display: showLabels,\n color: fontColor,\n font: fontConfig,\n maxRotation: 0, // Keep labels horizontal (no rotation)\n minRotation: 0, // Keep labels horizontal (no rotation)\n maxTicksLimit: this.xTicksLimit,\n stepSize: this.xStepSize,\n callback: (value: unknown) => {\n if (!this.isNumericXAxis) return String(value);\n const n = Number(value);\n if (!Number.isFinite(n)) return String(value);\n const relativeTo =\n this.timeDisplay === TimeDisplay.minutes ? minX : undefined;\n return formatXValue(n, this.xValueMode, relativeTo);\n },\n },\n border: {\n display: showLabels,\n color: tickColor,\n },\n } as unknown;\n\n // Build y-axis scales configuration\n const yAxesConfig = this.yAxes?.length\n ? this.yAxes.map((axis, i) => ({\n id: axis.id ?? `y${i}`,\n position: axis.position ?? ('left' as 'left' | 'right'),\n min: axis.min,\n max: axis.max,\n gridDisplay: axis.grid ?? (this.showGrid && this.showGridY),\n }))\n : [\n {\n id: 'y',\n position: this.yAxisPosition,\n min: undefined,\n max: undefined,\n gridDisplay: this.showGrid && this.showGridY,\n },\n ];\n\n const scalesRecord: Record<string, unknown> = {x};\n\n yAxesConfig.forEach(({id, position, min, max, gridDisplay}) => {\n scalesRecord[id] = {\n type: 'linear',\n display: true,\n position,\n stacked: this.shouldStack() && this.getFillMode() !== 'threshold',\n grace: isTooSmall ? 0 : undefined,\n bounds: isTooSmall ? 'data' : 'ticks',\n grid: {\n display: gridDisplay,\n color: gridColor,\n drawTicks: showTicks,\n },\n ticks: {\n display: showLabels,\n color: fontColor,\n font: fontConfig,\n maxTicksLimit: this.yTicksLimit,\n stepSize: this.yStepSize,\n },\n border: {\n display: showLabels,\n color: tickColor,\n },\n min,\n max,\n };\n });\n\n return scalesRecord as ChartOptions<'line'>['scales'];\n }\n\n /**\n * Prepare chart data and labels for both single and multi-series modes\n */\n private prepareChartDataAndLabels() {\n if (this.datasets?.length) {\n return {\n datasets: this.prepareMultiSeriesDatasets(),\n labels: (this.labels ?? []) as (string | number)[],\n };\n }\n return this.prepareSingleSeriesDatasets();\n }\n\n private createChart() {\n // Guard: Verify canvas exists and is connected to DOM\n if (!this.canvasEl || !this.canvasEl.isConnected) return;\n\n const ctx = this.canvasEl.getContext('2d');\n if (!ctx) return;\n\n // Destroy existing chart instance to prevent canvas reuse errors\n if (this.chart) {\n this.chart.destroy();\n this.chart = undefined;\n }\n\n const {datasets, labels} = this.prepareChartDataAndLabels();\n\n this.chart = new Chart(ctx, {\n type: 'line',\n data: {labels, datasets},\n options: this.getChartOptions(),\n plugins: this.borderRadiusPosition ? [this.createBorderPlugin()] : [],\n } as ChartConfiguration<'line'>);\n\n // Defer legend update to next tick to ensure Chart.js metadata is initialized\n requestAnimationFrame(() => this.updateLegend());\n this.applyFillModes();\n }\n\n private updateChart() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const {datasets, labels} = this.prepareChartDataAndLabels();\n\n this.chart.data.labels = labels;\n this.chart.data.datasets = datasets as unknown as ChartDataset<'line'>[];\n\n // Update options (chart.options is always defined after chart creation)\n Object.assign(this.chart.options, this.getChartOptions());\n\n this.applyFillModes();\n this.chart.update();\n\n // Update legend after chart update completes to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update only chart colors without recalculating layout\n * Used by theme observer for efficient theme changes\n */\n private updateChartColors() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n // Re-apply fill modes which will update gradients for threshold mode\n this.applyFillModes();\n\n // Update without animation for instant theme change\n this.chart.update('none');\n\n // Defer legend update to next frame to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update the legend HTML content\n */\n private updateLegend() {\n // Guard: Check if legend should be shown and chart is ready\n if (!this.legend || !this.legendDiv || !this.chart) return;\n\n // Guard: Check if chart has datasets\n if (!this.chart.data.datasets || this.chart.data.datasets.length === 0) {\n this.legendDiv.innerHTML = '';\n return;\n }\n\n try {\n const legendItems = this.chart.data.datasets\n .map((ds, i) => {\n const meta = this.chart!.getDatasetMeta(i);\n\n // Guard: Check if metadata and controller are available\n if (!meta || !meta.controller) {\n return null;\n }\n\n const style = meta.controller.getStyle(0, false);\n const dataset = ds as ChartDataset<\n 'line',\n (number | {x: number; y: number})[]\n >;\n\n return {\n fillStyle: (dataset.borderColor ??\n style.borderColor ??\n '') as string,\n label: (dataset.label as string) || `Series ${i + 1}`,\n value: '',\n unit: '',\n };\n })\n .filter((item) => item !== null);\n\n // Only update legend if we have valid items\n if (legendItems.length > 0) {\n const legendHTML = generateLegendHTML(legendItems);\n this.legendDiv.innerHTML = legendHTML;\n }\n } catch (error) {\n console.debug(\n '[chart-line-base] updateLegend: error generating legend HTML',\n error\n );\n // Silent failure - don't throw, just skip legend update this time\n }\n }\n\n override render() {\n return html`\n <div class=\"wrapper\">\n <div class=\"canvas-and-slots-container\">\n <slot\n name=\"top-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <slot\n name=\"bottom-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <slot\n name=\"left-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <slot\n name=\"right-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <canvas></canvas>\n </div>\n\n ${this.legend ? html`<div class=\"legend\"></div>` : ''}\n </div>\n `;\n }\n\n static override styles = [\n unsafeCSS(componentStyle),\n unsafeCSS(chartCommonStyle),\n unsafeCSS(chartLegendStyle),\n unsafeCSS(chartDebugStyle),\n ];\n}\n"],"names":["XAxisType","YAxisPosition","LineMode","TimeDisplay","r","datasets"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,MAAM;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAuCO,IAAK,8BAAAA,eAAL;AACLA,aAAA,UAAA,IAAW;AACXA,aAAA,MAAA,IAAO;AACPA,aAAA,QAAA,IAAS;AAHC,SAAAA;AAAA,GAAA,aAAA,CAAA,CAAA;AAML,IAAK,kCAAAC,mBAAL;AACLA,iBAAA,MAAA,IAAO;AACPA,iBAAA,OAAA,IAAQ;AAFE,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAKL,IAAK,6BAAAC,cAAL;AACLA,YAAA,QAAA,IAAS;AACTA,YAAA,UAAA,IAAW;AACXA,YAAA,SAAA,IAAU;AAHA,SAAAA;AAAA,GAAA,YAAA,CAAA,CAAA;AAML,IAAK,gCAAAC,iBAAL;AACLA,eAAA,SAAA,IAAU;AACVA,eAAA,MAAA,IAAO;AAFG,SAAAA;AAAA,GAAA,eAAA,CAAA,CAAA;AA2BZ,MAAM,gCAAgC;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAEA,MAAM,iCAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMA,MAAM,kCAAkC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF;AA2LO,MAAM,oBAAN,MAAM,0BAAyB,WAAW;AAAA,EAA1C,cAAA;AAAA,UAAA,GAAA,SAAA;AAEL,SAAA,OAA4B,CAAA;AAG5B,SAAA,WAAsD;AAGtD,SAAA,SAA+B;AAG/B,SAAA,SAAmB,CAAA;AAGnB,SAAA,SAAS;AAGT,SAAA,mBAAmB;AAGnB,SAAA,QAAQ;AAGR,SAAA,SAAS;AAGT,SAAA,0BAA0B;AAG1B,SAAA,qBAAqB;AAGrB,SAAA,YAAuB;AAGvB,SAAA,gBAA+B;AAG/B,SAAA,QAAiC;AAGjC,SAAA,WAAW;AAGX,SAAA,YAAY;AAGZ,SAAA,YAAY;AAGZ,SAAA,gBAAgB;AAoBhB,SAAA,kBAAkB;AA8BlB,SAAiB,kBAAkB;AAGnC,SAAiB,eAAe;AAGhC,SAAA,aAAa;AAGb,SAAA,WAAqB;AAGrB,SAAA,OAAO;AAGP,SAAA,cAA2B;AAG3B,SAAA,cAAuB;AAGvB,SAAA,YAAqB;AAGrB,SAAA,cAAuB;AAGvB,SAAA,YAAqB;AAGrB,SAAA,QAAyB,gBAAgB;AAGzC,SAAA,WAAqB,SAAS;AAG9B,SAAA,aAAyB,WAAW;AAGpC,SAAA,uBAA8C;AAG9C,SAAA,qCAA4D;AAG5D,SAAA,iBAAiB;AAGjB,SAAA,eAAwB;AAwBxB,SAAQ,8CAAmD,IAAA;AAM3D,SAAQ,mBAAmB;AAM3B,SAAQ,wBAAwB;AAMhC,SAAQ,gBAAgB;AAGxB,SAAQ,iBAAiB;AA8NzB,SAAQ,qBAAqB,MAAM;AACjC,UAAI,CAAC,KAAK,SAAU;AAIpB,UAAI;AACJ,UAAI,KAAK,gBAAgB;AACvB,eAAO,KAAK,gBAAgB;AAAA,MAC9B,OAAO;AACL,eAAO;AAAA,UACL,KAAK;AAAA,UACL,UAAU;AAAA,UACV;AAAA,QAAA;AAAA,MAEJ;AAEA,UAAI,KAAK,0BAA0B,MAAM;AACvC,aAAK,wBAAwB;AAE7B,YAAI,KAAK,OAAO;AACd,eAAK,MAAM,QAAA;AACX,eAAK,YAAA;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAyTA,SAAQ,mBAAmB,MAAM;AAE/B,WAAK,wBAAwB,MAAA;AAG7B,WAAK,uBAAA;AAAA,IACP;AAKA,SAAQ,+BAA+B,CAAC,MAAa;AACnD,UAAI,KAAK,iBAAkB;AAE3B,YAAM,QAAQ;AACd,YAAM,EAAC,MAAM,UAAA,IAAa,MAAM;AAGhC,YAAM,oBAAoB,KAAK,wBAAwB,IAAI,IAAI;AAC/D,UAAI,sBAAsB,UAAW;AAErC,WAAK,wBAAwB,IAAI,MAAM,SAAS;AAGhD,UAAI,KAAK,sBAAsB;AAC7B,qBAAa,KAAK,oBAAoB;AAAA,MACxC;AAEA,WAAK,uBAAuB,WAAW,MAAM;AAC3C,aAAK,mBAAA;AAAA,MACP,GAAG,EAAE;AAAA,IACP;AAAA,EAAA;AAAA;AAAA,EAtsBA,IAAc,iBAA0B;AACtC,WACE,KAAK,cAAc,UAAkB,KAAK,cAAc;AAAA,EAE5D;AAAA;AAAA,EAGA,IAAc,aAAyB;AACrC,WAAO,KAAK,cAAc,WACtB,WAAW,SACX,WAAW;AAAA,EACjB;AAAA;AAAA,EAMQ,eAAe,SAAmB,WAAoB;AAC5D,UAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC,EAAE;AAC3D,QAAI,YAAY,KAAK,KAAK,sBAAsB,UAAW;AAC3D,SAAK,oBAAoB;AACzB,YAAQ;AAAA,MACN,eAAe,OAAO,kDAAkD,KAAK,SAAS;AAAA,IAAA;AAAA,EAE1F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuGU,kBAA2B;AACnC,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,cAAkC;AAC1C,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,cAAuB;AAC/B,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BQ,gBAAgB,MAAoD;AAC1E,UAAM,UAAU;AAAA,MACd,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,KAAK,KAAK;AAAA,MACV,QAAQ,KAAK;AAAA,IAAA;AAGf,UAAM,OAAO,QAAQ,IAAI;AACzB,UAAM,WAAW,MAAM,iBAAA,KAAsB,CAAA;AAE7C,WAAO,SAAS,KAAK,CAAC,OAAgB;AACpC,YAAM,QAAQ;AAMd,UAAI,YAAY,SAAS,cAAc,OAAO;AAC5C,eAAO,MAAM,WAAW,QAAQ,MAAM,aAAa;AAAA,MACrD;AAGA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEQ,wBAKN;AACA,QAAI,CAAC,KAAK,sBAAsB;AAC9B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,aAAa;AAAA,MAAA;AAAA,IAEjB;AAEA,QAAI,KAAK,yBAAyB,qBAAqB,aAAa;AAClE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,aAAa;AAAA,MAAA;AAAA,IAEjB;AAGA,QAAI,KAAK,yBAAyB,qBAAqB,oBAAoB;AACzE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,aAAa;AAAA,MAAA;AAAA,IAEjB;AAGA,UAAM,UAAU,KAAK,gBAAgB,MAAM;AAC3C,UAAM,WAAW,KAAK,gBAAgB,OAAO;AAC7C,UAAM,SAAS,KAAK,gBAAgB,KAAK;AACzC,UAAM,YAAY,KAAK,gBAAgB,QAAQ;AAG/C,QAAK,WAAW,YAAc,UAAU,WAAY;AAClD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,aAAa;AAAA,MAAA;AAAA,IAEjB;AAEA,UAAM,SAAS;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,aAAa;AAAA,IAAA;AAGf,UAAM,UACJ,KAAK,yBAAyB,qBAAqB;AACrD,UAAM,UACJ,KAAK,yBAAyB,qBAAqB;AAGrD,QAAI,YAAY,WAAW;AAEzB,UAAI,SAAS;AACX,eAAO,cAAc;AAAA,MACvB,WAAW,SAAS;AAClB,eAAO,UAAU;AAAA,MACnB;AAAA,IACF,WAAW,YAAY,QAAQ;AAE7B,UAAI,SAAS;AACX,eAAO,WAAW;AAAA,MACpB,WAAW,SAAS;AAClB,eAAO,aAAa;AAAA,MACtB;AAAA,IACF,WAAW,WAAW,WAAW;AAE/B,UAAI,SAAS;AACX,eAAO,aAAa;AAAA,MACtB,WAAW,SAAS;AAClB,eAAO,WAAW;AAAA,MACpB;AAAA,IACF,WAAW,WAAW,QAAQ;AAE5B,UAAI,SAAS;AACX,eAAO,UAAU;AAAA,MACnB,WAAW,SAAS;AAClB,eAAO,cAAc;AAAA,MACvB;AAAA,IACF,WAES,YAAY,CAAC,SAAS;AAE7B,UAAI,SAAS;AACX,eAAO,UAAU;AACjB,eAAO,aAAa;AAAA,MACtB,WAAW,SAAS;AAClB,eAAO,WAAW;AAClB,eAAO,cAAc;AAAA,MACvB;AAAA,IACF,WAAW,WAAW,CAAC,UAAU;AAE/B,UAAI,SAAS;AACX,eAAO,WAAW;AAClB,eAAO,cAAc;AAAA,MACvB,WAAW,SAAS;AAClB,eAAO,UAAU;AACjB,eAAO,aAAa;AAAA,MACtB;AAAA,IACF,WAES,aAAa,CAAC,QAAQ;AAE7B,UAAI,SAAS;AACX,eAAO,UAAU;AACjB,eAAO,WAAW;AAAA,MACpB,WAAW,SAAS;AAClB,eAAO,aAAa;AACpB,eAAO,cAAc;AAAA,MACvB;AAAA,IACF,WAAW,UAAU,CAAC,WAAW;AAE/B,UAAI,SAAS;AACX,eAAO,aAAa;AACpB,eAAO,cAAc;AAAA,MACvB,WAAW,SAAS;AAClB,eAAO,UAAU;AACjB,eAAO,WAAW;AAAA,MACpB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCQ,qBAAqB;AAC3B,UAAM,UAAU,KAAK,sBAAA;AACrB,UAAM,SAAS,KAAK;AAEpB,QAAI,eAAe;AAEnB,UAAM,uBAAuB,CAC3B,KACA,MACA,iBACG;AACH,YAAM,EAAC,GAAG,GAAG,OAAO,WAAU;AAG9B,UAAI,SAAS,KAAK,UAAU,EAAG;AAE/B,YAAM,IAAI,KAAK;AAAA,QACb;AAAA,QACA,KAAK,IAAI,cAAc,KAAK,IAAI,OAAO,MAAM,IAAI,CAAC;AAAA,MAAA;AAIpD,UAAI,OAAO,KAAK,QAAQ,UAAU,IAAI,IAAI,CAAC;AAE3C,UAAI,OAAO,IAAI,SAAS,QAAQ,WAAW,IAAI,IAAI,CAAC;AAEpD,UAAI,QAAQ,UAAU;AACpB,YAAI,MAAM,IAAI,OAAO,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC;AAAA,MAC7C;AAEA,UAAI,OAAO,IAAI,OAAO,IAAI,UAAU,QAAQ,cAAc,IAAI,EAAE;AAEhE,UAAI,QAAQ,aAAa;AACvB,YAAI,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,QAAQ,CAAC;AAAA,MAC/D;AAEA,UAAI,OAAO,KAAK,QAAQ,aAAa,IAAI,IAAI,IAAI,MAAM;AAEvD,UAAI,QAAQ,YAAY;AACtB,YAAI,MAAM,GAAG,IAAI,QAAQ,GAAG,IAAI,SAAS,GAAG,CAAC;AAAA,MAC/C;AAEA,UAAI,OAAO,GAAG,KAAK,QAAQ,UAAU,IAAI,EAAE;AAE3C,UAAI,QAAQ,SAAS;AACnB,YAAI,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;AAAA,MAC7B;AAAA,IACF;AAEA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,oBAAoB,CAAC,UAAiB;AACpC,cAAM,MAAM,MAAM;AAClB,cAAM,YAAY,MAAM;AAExB,YAAI,CAAC,UAAW;AAMhB,cAAM,gBAAgB;AACtB,cAAM,YAAY;AAElB,cAAM,EAAC,KAAK,OAAO,QAAQ,SAAQ;AACnC,cAAM,OAAO;AAAA,UACX,GAAG,OAAO;AAAA,UACV,GAAG,MAAM;AAAA,UACT,OAAO,QAAQ,OAAO,YAAY;AAAA,UAClC,QAAQ,SAAS,MAAM,YAAY;AAAA,QAAA;AAGrC,cAAM,aAAa,KAAK,IAAI,GAAG,SAAS,SAAS;AAEjD,YAAI,KAAA;AACJ,uBAAe;AAGf,YAAI,UAAA;AAEJ,6BAAqB,KAAiC,MAAM,UAAU;AACtE,YAAI,UAAA;AAGJ,YAAI,KAAK,gBAAgB;AACvB,gBAAM,kBAAkB;AAAA,YACtB;AAAA,YACA;AAAA,UAAA;AAEF,cAAI,YAAY;AAChB,cAAI,KAAA;AAAA,QACN;AAGA,YAAI,KAAA;AAAA,MACN;AAAA,MACA,WAAW,CAAC,UAAiB;AAC3B,cAAM,MAAM,MAAM;AAClB,cAAM,YAAY,MAAM;AAExB,YAAI,CAAC,UAAW;AAEhB,cAAM,gBAAgB;AACtB,cAAM,cAAc,gBAAgB;AAEpC,cAAM,EAAC,KAAK,OAAO,QAAQ,SAAQ;AACnC,cAAM,OAAO;AAAA,UACX,GAAG,OAAO;AAAA,UACV,GAAG,MAAM;AAAA,UACT,OAAO,QAAQ,OAAO,cAAc;AAAA,UACpC,QAAQ,SAAS,MAAM,cAAc;AAAA,QAAA;AAGvC,cAAM,eAAe,KAAK,IAAI,GAAG,SAAS,WAAW;AAGrD,cAAM,UAAU,KAAK,gBAAgB,KAAK;AAC1C,cAAM,YAAY,KAAK,gBAAgB,OAAO;AAC9C,cAAM,aAAa,KAAK,gBAAgB,QAAQ;AAChD,cAAM,WAAW,KAAK,gBAAgB,MAAM;AAG5C,cAAM,cAAc;AAAA,UAClB;AAAA,UACA;AAAA,QAAA;AAGF,YAAI,KAAA;AACJ,YAAI,cAAc;AAClB,YAAI,YAAY;AAEhB,cAAM,EAAC,GAAG,GAAG,OAAO,WAAU;AAC9B,cAAM,IAAI,KAAK;AAAA,UACb;AAAA,UACA,KAAK,IAAI,cAAc,KAAK,IAAI,OAAO,MAAM,IAAI,CAAC;AAAA,QAAA;AAIpD,YAAI,CAAC,WAAW,CAAC,aAAa,CAAC,cAAc,CAAC,UAAU;AAEtD,cAAI,UAAA;AACJ;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAEF,cAAI,UAAA;AACJ,cAAI,OAAA;AAAA,QACN,OAAO;AAKL,cAAI,CAAC,SAAS;AACZ,gBAAI,UAAA;AAEJ,gBAAI,CAAC,YAAY,QAAQ,SAAS;AAChC,kBAAI,OAAO,IAAI,GAAG,CAAC;AAAA,YACrB,OAAO;AACL,kBAAI,OAAO,GAAG,CAAC;AAAA,YACjB;AAEA,gBAAI,CAAC,aAAa,QAAQ,UAAU;AAClC,kBAAI,OAAO,IAAI,QAAQ,GAAG,CAAC;AAAA,YAC7B,OAAO;AACL,kBAAI,OAAO,IAAI,OAAO,CAAC;AAAA,YACzB;AACA,gBAAI,OAAA;AAAA,UACN;AAGA,cAAI,CAAC,WAAW;AACd,gBAAI,UAAA;AAEJ,gBAAI,CAAC,WAAW,QAAQ,UAAU;AAChC,kBAAI,OAAO,IAAI,OAAO,IAAI,CAAC;AAAA,YAC7B,OAAO;AACL,kBAAI,OAAO,IAAI,OAAO,CAAC;AAAA,YACzB;AAEA,gBAAI,CAAC,cAAc,QAAQ,aAAa;AACtC,kBAAI,OAAO,IAAI,OAAO,IAAI,SAAS,CAAC;AAAA,YACtC,OAAO;AACL,kBAAI,OAAO,IAAI,OAAO,IAAI,MAAM;AAAA,YAClC;AACA,gBAAI,OAAA;AAAA,UACN;AAGA,cAAI,CAAC,YAAY;AACf,gBAAI,UAAA;AAEJ,gBAAI,CAAC,aAAa,QAAQ,aAAa;AACrC,kBAAI,OAAO,IAAI,QAAQ,GAAG,IAAI,MAAM;AAAA,YACtC,OAAO;AACL,kBAAI,OAAO,IAAI,OAAO,IAAI,MAAM;AAAA,YAClC;AAEA,gBAAI,CAAC,YAAY,QAAQ,YAAY;AACnC,kBAAI,OAAO,IAAI,GAAG,IAAI,MAAM;AAAA,YAC9B,OAAO;AACL,kBAAI,OAAO,GAAG,IAAI,MAAM;AAAA,YAC1B;AACA,gBAAI,OAAA;AAAA,UACN;AAGA,cAAI,CAAC,UAAU;AACb,gBAAI,UAAA;AAEJ,gBAAI,CAAC,cAAc,QAAQ,YAAY;AACrC,kBAAI,OAAO,GAAG,IAAI,SAAS,CAAC;AAAA,YAC9B,OAAO;AACL,kBAAI,OAAO,GAAG,IAAI,MAAM;AAAA,YAC1B;AAEA,gBAAI,CAAC,WAAW,QAAQ,SAAS;AAC/B,kBAAI,OAAO,GAAG,IAAI,CAAC;AAAA,YACrB,OAAO;AACL,kBAAI,OAAO,GAAG,CAAC;AAAA,YACjB;AACA,gBAAI,OAAA;AAAA,UACN;AAGA,cAAI,CAAC,WAAW,CAAC,YAAY,QAAQ,SAAS;AAC5C,gBAAI,UAAA;AACJ,gBAAI,IAAI,IAAI,GAAG,IAAI,GAAG,GAAG,KAAK,IAAI,KAAK,KAAK,GAAG;AAC/C,gBAAI,OAAA;AAAA,UACN;AAEA,cAAI,CAAC,WAAW,CAAC,aAAa,QAAQ,UAAU;AAC9C,gBAAI,UAAA;AACJ,gBAAI,IAAI,IAAI,QAAQ,GAAG,IAAI,GAAG,GAAG,KAAK,KAAK,KAAK,KAAK,KAAK,CAAC;AAC3D,gBAAI,OAAA;AAAA,UACN;AAEA,cAAI,CAAC,aAAa,CAAC,cAAc,QAAQ,aAAa;AACpD,gBAAI,UAAA;AACJ,gBAAI,IAAI,IAAI,QAAQ,GAAG,IAAI,SAAS,GAAG,GAAG,GAAG,KAAK,KAAK,GAAG;AAC1D,gBAAI,OAAA;AAAA,UACN;AAEA,cAAI,CAAC,cAAc,CAAC,YAAY,QAAQ,YAAY;AAClD,gBAAI,UAAA;AACJ,gBAAI,IAAI,IAAI,GAAG,IAAI,SAAS,GAAG,GAAG,KAAK,KAAK,KAAK,KAAK,EAAE;AACxD,gBAAI,OAAA;AAAA,UACN;AAAA,QACF;AAEA,YAAI,QAAA;AAKJ,YAAI,KAAK,YAAY;AACnB,cAAI,KAAA;AAEJ,gBAAM,KAAK,SAAS,QAAQ,CAAC,KAAK,iBAAiB;AACjD,kBAAM,OAAO,MAAM,eAAe,YAAY;AAC9C,gBAAI,CAAC,QAAQ,KAAK,OAAQ;AAG1B,aAAC,KAAK,QAAQ,CAAA,GAAI,QAAQ,CAAC,OAAO;AAChC,oBAAM,QAAQ;AAMd,kBAAI,MAAM,KAAM;AAChB,oBAAMC,KAAI,MAAM,SAAS;AACzB,kBAAI,OAAOA,OAAM,YAAYA,MAAK,EAAG;AAErC,oBAAM,KAAK,GAA+B;AAAA,YAC5C,CAAC;AAAA,UACH,CAAC;AAED,cAAI,QAAA;AAAA,QACN;AAAA,MACF;AAAA,MACA,mBAAmB,CAAC,UAAiB;AAEnC,YAAI,cAAc;AAChB,gBAAM,IAAI,QAAA;AACV,yBAAe;AAAA,QACjB;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAA6B;AACnC,UAAM,MAAM,KAAK,cAAc,iBAAA,KAAsB,CAAA;AACrD,UAAM,SAAS,KAAK,iBAAiB,iBAAA,KAAsB,CAAA;AAC3D,UAAM,OAAO,KAAK,eAAe,iBAAA,KAAsB,CAAA;AACvD,UAAM,QAAQ,KAAK,gBAAgB,iBAAA,KAAsB,CAAA;AACzD,WACE,IAAI,SAAS,KAAK,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,MAAM,SAAS;AAAA,EAE7E;AAAA;AAAA;AAAA;AAAA,EAyCA,MAAc,yBAAyB;AACrC,QAAI,CAAC,KAAK,qBAAqB;AAC7B,WAAK,cAAA;AACL;AAAA,IACF;AAGA,UAAM,gBAAwC,CAAA;AAC9C;AAAA,MACE,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IAAA,EACL,QAAQ,CAAC,SAAS;AAClB,UAAI,MAAM;AACR,cAAM,WAAW,KAAK,iBAAA;AACtB,sBAAc,KAAK,GAAG,QAAQ;AAAA,MAChC;AAAA,IACF,CAAC;AAKD,UAAM,gBAAgB,CAAC,SAAsC;AAC3D,UAAI,CAAC,KAAM;AACX,YAAM,SAAS,KAAK,iBAAA;AACpB,aAAO,QAAQ,CAAC,UAAU;AACxB,cAAM,mBAAmB,KAAK;AAC9B,cAAM,qBAAqB,KAAK;AAAA,MAClC,CAAC;AAAA,IACH;AAIA,kBAAc,KAAK,aAAa;AAChC,kBAAc,KAAK,cAAc;AACjC,kBAAc,KAAK,YAAY;AAC/B,kBAAc,KAAK,eAAe;AAGlC,UAAM,QAAQ;AAAA,MACZ,cAAc;AAAA,QAAI,CAAC,OACjB,oBAAoB,MAAM,OAAO,GAAG,mBAAmB,WAClD,GAAG,iBACJ,QAAQ,QAAA;AAAA,MAAQ;AAAA,IACtB;AAKF,QAAI,KAAK,wBAAwB,SAAS,KAAK,cAAc,SAAS,GAAG;AACvE,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,IACxD;AAEA,SAAK,mBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBAA8B;AACpC,QAAI,KAAK,iBAAkB,QAAO;AAClC,SAAK,mBAAmB;AAExB,QAAI;AAEF,YAAM,UAAU,KAAK,2BAAA;AAGrB,YAAM,iBAAiB,KAAK,QAAQ,QAAQ,OAAO,QAAQ;AAC3D,YAAM,kBAAkB,KAAK,SAAS,QAAQ,MAAM,QAAQ;AAG5D,UAAI,kBAAkB,KAAK,mBAAmB,GAAG;AAC/C,gBAAQ,KAAK,kDAAkD;AAAA,UAC7D,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,QAAA,CACD;AACD,eAAO;AAAA,MACT;AAGA,WAAK,sBAAsB,OAAO;AAGlC,UAAI,KAAK,OAAO;AACd,aAAK,MAAM,QAAA;AAAA,MACb;AACA,WAAK,YAAA;AACL,aAAO;AAAA,IACT,UAAA;AACE,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,6BAA6B;AACnC,UAAM,iBAAiB,KAAK,kBACxB,iBAAiB,iBACjB;AAEJ,UAAM,UAAU;AAAA,MACd,KAAK,KAAK,wBAAwB,IAAI,KAAK,KAAK;AAAA,MAChD,OAAO,KAAK,wBAAwB,IAAI,OAAO,KAAK;AAAA,MACpD,QAAQ,KAAK,wBAAwB,IAAI,QAAQ,KAAK;AAAA,MACtD,MAAM,KAAK,wBAAwB,IAAI,MAAM,KAAK;AAAA,IAAA;AAGpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,SAK3B;AAED,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,GAAG,OAAO;AAC7C,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,GAAG,OAAO;AAC7C,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,GAAG,OAAO;AAC7C,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,GAAG,OAAO;AAG7C,UAAM,iBAAiB,KAAK,kBAAA;AAC5B,UAAM,kBAAkB,KAAK,mBAAA;AAQ7B,UAAM,aACJ,KAAK,mBACL,kBAAkB,6BAA6B,0BAC/C,mBAAmB,6BAA6B;AAOlD,UAAM,yBAAyB,KAAK,0BAChC;AAAA,MACE,KAAK,KAAK;AAAA,QACP,QAAQ,MAAM,KAAK,qBAAsB,KAAK;AAAA,MAAA;AAAA,MAEjD,QAAQ,KAAK;AAAA,QACV,QAAQ,SAAS,KAAK,qBAAsB,KAAK;AAAA,MAAA;AAAA,IACpD,IAEF,EAAC,KAAK,QAAQ,KAAK,QAAQ,QAAQ,OAAA;AAEvC,UAAM,2BAA2B,KAAK,0BAClC;AAAA,MACE,MAAM,KAAK;AAAA,QACR,QAAQ,OAAO,KAAK,qBAAsB,KAAK;AAAA,MAAA;AAAA,MAElD,OAAO,KAAK;AAAA,QACT,QAAQ,QAAQ,KAAK,qBAAsB,KAAK;AAAA,MAAA;AAAA,IACnD,IAEF,EAAC,MAAM,QAAQ,MAAM,OAAO,QAAQ,MAAA;AAGxC,UAAM,UAMF,CAAA;AAGJ,QAAI,KAAK,eAAe;AACtB,YAAM,SACJ,KAAK,cAAc,iBAAA;AACrB,aAAO,QAAQ,CAAC,UAAU;AACxB,cAAM,QAAuC;AAAA,UAC3C,UAAU;AAAA,UACV,UAAU;AAAA,UACV,QAAQ;AAAA;AAAA,UACR,YAAY,uBAAuB;AAAA,UACnC,eAAe,uBAAuB;AAAA,UACtC,cAAc,uBAAuB;AAAA,UACrC,YAAY,uBAAuB;AAAA,UACnC;AAAA,UACA,kBAAkB,KAAK;AAAA;AAAA,UAEvB,oBAAoB,KAAK;AAAA,UACzB,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,YAAY,KAAK;AAAA,UACjB,sBAAsB,KAAK;AAAA,QAAA;AAG7B,YAAI,KAAK,cAAc,QAAW;AAChC,gBAAM,0BAA0B,KAAK;AAAA,QACvC;AACA,gBAAQ,KAAK,CAAC,KAAK,eAAe,OAAO,KAAK,CAAC;AAAA,MACjD,CAAC;AAAA,IACH;AAGA,QAAI,KAAK,gBAAgB;AACvB,YAAM,SACJ,KAAK,eAAe,iBAAA;AACtB,aAAO,QAAQ,CAAC,UAAU;AACxB,cAAM,QAAuC;AAAA,UAC3C,UAAU;AAAA,UACV,UAAU;AAAA,UACV,QAAQ;AAAA;AAAA,UACR,YAAY,uBAAuB;AAAA,UACnC,eAAe,uBAAuB;AAAA,UACtC,cAAc,uBAAuB;AAAA,UACrC,YAAY,uBAAuB;AAAA,UACnC;AAAA,UACA,kBAAkB,KAAK;AAAA;AAAA,UAEvB,oBAAoB,KAAK;AAAA,UACzB,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,YAAY,KAAK;AAAA,UACjB,sBAAsB,KAAK;AAAA,QAAA;AAG7B,YAAI,KAAK,cAAc,QAAW;AAChC,gBAAM,0BAA0B,KAAK;AAAA,QACvC;AACA,gBAAQ,KAAK,CAAC,KAAK,gBAAgB,OAAO,KAAK,CAAC;AAAA,MAClD,CAAC;AAAA,IACH;AAGA,QAAI,KAAK,cAAc;AACrB,YAAM,SACJ,KAAK,aAAa,iBAAA;AACpB,aAAO,QAAQ,CAAC,UAAU;AACxB,cAAM,QAAuC;AAAA,UAC3C,UAAU;AAAA,UACV,UAAU;AAAA,UACV,OAAO;AAAA;AAAA,UACP,aAAa,yBAAyB;AAAA,UACtC,cAAc,yBAAyB;AAAA,UACvC,cAAc,yBAAyB;AAAA,UACvC,YAAY,yBAAyB;AAAA,UACrC;AAAA,UACA,kBAAkB,KAAK;AAAA;AAAA,UAEvB,oBAAoB,KAAK;AAAA,UACzB,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,YAAY,KAAK;AAAA,UACjB,sBAAsB,KAAK;AAAA,QAAA;AAG7B,YAAI,KAAK,cAAc,QAAW;AAChC,gBAAM,0BAA0B,KAAK;AAAA,QACvC;AACA,gBAAQ,KAAK,CAAC,KAAK,cAAc,OAAO,KAAK,CAAC;AAAA,MAChD,CAAC;AAAA,IACH;AAGA,QAAI,KAAK,iBAAiB;AACxB,YAAM,SACJ,KAAK,gBAAgB,iBAAA;AACvB,aAAO,QAAQ,CAAC,UAAU;AACxB,cAAM,QAAuC;AAAA,UAC3C,UAAU;AAAA,UACV,UAAU;AAAA,UACV,OAAO;AAAA;AAAA,UACP,aAAa,yBAAyB;AAAA,UACtC,cAAc,yBAAyB;AAAA,UACvC,cAAc,yBAAyB;AAAA,UACvC,YAAY,yBAAyB;AAAA,UACrC;AAAA,UACA,kBAAkB,KAAK;AAAA;AAAA,UAEvB,oBAAoB,KAAK;AAAA,UACzB,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,YAAY,KAAK;AAAA,UACjB,sBAAsB,KAAK;AAAA,QAAA;AAG7B,YAAI,KAAK,cAAc,QAAW;AAChC,gBAAM,0BAA0B,KAAK;AAAA,QACvC;AACA,gBAAQ,KAAK,CAAC,KAAK,iBAAiB,OAAO,KAAK,CAAC;AAAA,MACnD,CAAC;AAAA,IACH;AAGA,YAAQ,QAAQ,CAAC,CAAC,OAAO,OAAO,KAAK,MAAM;AACzC,aAAO,OAAO,OAAO,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA,EAEQ,cACN,SACA,OACS;AACT,WAAO,MAAM,KAAK,CAAC,SAAS,QAAQ,IAAI,IAAI,CAAC;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUU,iBAAiB;AAEzB,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,YAAY,CAAC,KAAK,SAAS,YAAa;AAEjE,UAAM,QAAQ,KAAK;AACnB,UAAM,MAAM,MAAM;AAGlB,QAAI,CAAC,IAAK;AAEV,UAAM,OAAO,KAAK,gBAAA;AAClB,UAAM,WAAW,KAAK,YAAA;AAGtB,QAAI,aAAa,eAAe,CAAC,MAAM;AACrC;AAAA,IACF;AAEA,UAAM,KAAK,SAAS,QAAQ,CAAC,IAAI,SAAS;AACxC,YAAM,UAAU;AAShB,UAAI,QAAQ,SAAS,SAAS,CAAC,MAAM;AACnC;AAAA,MACF;AAGA,YAAM,WAAW,QAAQ,WAAW;AACpC,YAAM,SAAS,MAAM,OAAO,QAAQ;AAEpC,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AAGA,YAAM,aAAc,QAAQ,KACzB,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,EAAE,CAAE,EAC5C,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAGnC,UAAI,WAAW,WAAW,GAAG;AAC3B;AAAA,MACF;AAEA,YAAM,SAAS,KAAK,IAAI,GAAG,UAAU;AACrC,YAAM,SAAS,KAAK,IAAI,GAAG,UAAU;AACrC,YAAM,gBAAgB,SAAS,UAAU;AACzC,YAAM,iBAAiB,OAAO,iBAAiB,YAAY;AAC3D,YAAM,QAAQ,OAAO,SAAS,OAAO;AAGrC,UAAI,QAAQ,iBAAiB,OAAO,OAAO;AAC3C,UAAI,CAAC,OAAO,SAAS,IAAI,KAAK,UAAU,GAAG;AACzC,eAAO;AAAA,MACT,OAAO;AACL,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;AAAA,MACtC;AAGA,YAAM,SAAS,uBAAuB;AACtC,YAAM,UAAU,uBAAuB;AAGvC,YAAM,iBAAiB,CAAC,UAAkB,cAAsB;AAC9D,cAAM,MAAM,kBAAkB,MAAM,QAAQ,QAAQ;AACpD,cAAM,OAAO,kBAAkB,MAAM,SAAS,SAAS;AACvD,cAAM,OAAO,IAAI,qBAAqB,GAAG,OAAO,KAAK,GAAG,OAAO,MAAM;AACrE,aAAK,aAAa,GAAG,IAAI;AACzB,aAAK,aAAa,MAAM,IAAI;AAC5B,aAAK,aAAa,MAAM,GAAG;AAC3B,aAAK,aAAa,GAAG,GAAG;AACxB,eAAO;AAAA,MACT;AAGA,YAAM,eAAe,eAAe,MAAM,IAAI;AAC9C,YAAM,iBAAiB,eAAe,KAAK,GAAG;AAC9C,cAAQ,kBAAkB;AAC1B,cAAQ,cAAc;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA,EAGS,QAAQ,SAAyB;AACxC,UAAM,QAAQ,OAAO;AAGrB,QAAI,CAAC,KAAK,cAAc,SAAS,6BAA6B,GAAG;AAC/D;AAAA,IACF;AAeA,QAAI,KAAK,cAAc,SAAS,+BAA+B,GAAG;AAEhE,UAAI,KAAK,2BAA4B;AAAA,IACvC;AAQA,QAAI,QAAQ,IAAI,iBAAiB,KAAK,KAAK,qBAAqB;AAC9D,WAAK,mBAAA;AACL;AAAA,IACF;AAEA,UAAM,kBAAkB,KAAK;AAAA,MAC3B;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,iBAAiB;AACnB,WAAK,OAAO,QAAA;AACZ,WAAK,YAAA;AAAA,IACP,OAAO;AACL,WAAK,YAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,MAAe,eAAe;AAE5B,UAAM,KAAK,uBAAA;AAEX,QAAI,CAAC,KAAK,qBAAqB;AAE7B,WAAK,YAAA;AAAA,IACP;AAGA,SAAK,gBAAgB,oBAAoB,MAAM;AAC7C,WAAK,kBAAA;AACL,WAAK,mBAAA;AAAA,IACP,CAAC;AACD,SAAK,oBAAA;AACL,SAAK,+BAAA;AAIL,QAAI,KAAK,UAAU;AACjB,UAAI,CAAC,KAAK,gBAAgB;AACxB,aAAK,uBAAuB;AAAA,UAC1B,KAAK;AAAA,UACL,KAAK;AAAA,QAAA;AAAA,MAET;AACA,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAES,uBAAuB;AAC9B,UAAM,qBAAA;AACN,SAAK,OAAO,QAAA;AACZ,SAAK,eAAe,WAAA;AACpB,SAAK,gBAAgB,WAAA;AACrB,SAAK,2BAA2B,WAAA;AAChC,SAAK,sBAAsB,WAAA;AAE3B,QAAI,KAAK,sBAAsB;AAC7B,mBAAa,KAAK,oBAAoB;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,sBAAsB;AAC5B,QAAI,CAAC,KAAK,SAAU;AAEpB,SAAK,iBAAiB;AAAA,MACpB,KAAK;AAAA,MACL,OACG,KAAK,UAAU,gBAAgB,MAChC,6BAA6B;AAAA,MAC/B;AAAA,QACE,SAAS,MAAM;AACb,eAAK,OAAO,QAAA;AACZ,eAAK,YAAA;AAAA,QACP;AAAA,QACA,QAAQ,MAAM,KAAK,YAAA;AAAA,MAAY;AAAA,IACjC;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iCAAiC;AACvC,UAAM,UAAU,KAAK,WAAW,cAAc,UAAU;AACxD,QAAI,CAAC,QAAS;AAGd,SAAK,yBAAA;AAEL,SAAK,4BAA4B,IAAI,eAAe,MAAM;AACxD,UAAI,CAAC,KAAK,wBAAyB;AACnC,WAAK,yBAAA;AAAA,IACP,CAAC;AAED,SAAK,0BAA0B,QAAQ,OAAO;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcQ,2BAAoC;AAC1C,QAAI,CAAC,KAAK,yBAAyB;AAEjC,WAAK,gBAAgB,KAAK;AAC1B,WAAK,iBAAiB,KAAK;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,KAAK,WAAW,cAAc,UAAU;AACxD,QAAI,CAAC,QAAS,QAAO;AAGrB,UAAM,cAAc,QAAQ;AAC5B,QAAI,eAAe,EAAG,QAAO;AAG7B,UAAM,cAAc,KAAK,QAAQ,KAAK;AAGtC,UAAM,WAAW;AACjB,UAAM,YAAY,KAAK,MAAM,cAAc,WAAW;AAGtD,QAAI,KAAK,kBAAkB,YAAY,KAAK,mBAAmB,WAAW;AACxE,WAAK,gBAAgB;AACrB,WAAK,iBAAiB;AAKtB,UAAI,KAAK,qBAAqB;AAI5B,eAAO,KAAK,mBAAA;AAAA,MACd,WAAW,KAAK,OAAO;AAErB,aAAK,MAAM,QAAA;AACX,aAAK,YAAA;AACL,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,oBAA4B;AACpC,WAAO,KAAK,0BAA0B,KAAK,gBAAgB,KAAK;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,qBAA6B;AACrC,WAAO,KAAK,0BAA0B,KAAK,iBAAiB,KAAK;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,iBAAyB;AACjC,QAAI,CAAC,KAAK,yBAAyB;AACjC,aAAO;AAAA,IACT;AAGA,WAAO,KAAK,gBAAgB,KAAK;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYU,aACR,MAIA,OACA,aACA,aAAa,GAC2B;AACxC,UAAM,eAAe,YAAY,QAAQ,YAAY,MAAM;AAG3D,UAAM,kBAAkB,MAAM,QAAQ,IAAI,IACtC,OACC;AACL,UAAM,SAAS,MAAM,QAAQ,IAAI,IAC5B,OACD;AAEJ,UAAM,cAAc,iBAAiB,eAAe;AACpD,UAAM,WAAW,iBAAiB,QAAQ,KAAK,gBAAA;AAC/C,UAAM,UAAU,KAAK,aAAa,WAAW,KAAK,kBAAkB;AAGpE,UAAM,YAAY,KAAK,YAAA,KAAiB,KAAK,kBAAkB;AAC/D,UAAM,eAAe,aAAa,QAAQ,aAAa;AAIvD,QAAI,kBAA0B;AAC9B,UAAM,WAAW,KAAK,YAAA;AAEtB,QAAI,YAAY,UAAU;AACxB,YAAM,YAAY,aAAa,QAAQ,KAAK,YAAY,MAAM;AAE9D,UAAI,aAAa,SAAS;AACxB,0BAAkB,OAAO,WAAW;AAAA,MACtC,WAAW,aAAa,mBAAmB;AACzC,0BAAkB,kBAAkB,MAAM,WAAW,GAAG;AAAA,MAC1D,WAAW,aAAa,aAAa;AAGnC,0BAAkB,kBAAkB,MAAM,WAAW,GAAG;AAAA,MAC1D;AAAA,IACF;AAEA,UAAM,SAAS;AAAA,MACb,GAAI,mBAAmB,CAAA;AAAA,MACvB,MAAM,iBAAiB,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,aAAa,iBAAiB,eAAe;AAAA,MAC7C,UAAU,iBAAiB,YAAY;AAAA,MACvC,SAAS,iBAAiB,WAAW;AAAA,MACrC,aACE,iBAAiB,gBAChB,KAAK,aAAa,KAAK,eAAe;AAAA,MACzC,sBAAsB,iBAAiB,wBAAwB;AAAA,MAC/D,kBAAkB,iBAAiB,oBAAoB;AAAA,MACvD,kBAAkB,iBAAiB,oBAAoB;AAAA,MACvD,SAAS,iBAAiB,WAAW,KAAK,aAAa;AAAA;AAAA,MAEvD,MAAM,WAAW,UAAU;AAAA,MAC3B,UAAU,iBAAiB,YAAY;AAAA;AAAA,MAEvC,GAAI,gBAAgB;AAAA,QAClB,SAAS;AAAA,UACP,aAAa;AAAA,YACX;AAAA,YACA,uBAAuB;AAAA,UAAA;AAAA,UAEzB,aAAa;AAAA,QAAA;AAAA,MACf;AAAA,IACF;AAGF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,wBACR,QACA,aAC0C;AAC1C,UAAM,UAAU,OACb,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,EAAE,CAAE,EAC5C,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AACnC,UAAM,OAAO,QAAQ,SAAS,KAAK,IAAI,GAAG,OAAO,IAAI;AACrD,UAAM,OAAO,QAAQ,SAAS,KAAK,IAAI,GAAG,OAAO,IAAI;AACrD,UAAM,aAAa,OAAO,QAAQ;AAClC,UAAM,eAAiC,OAAO;AAAA,MAAI,CAAC,MACjD,OAAO,MAAM,WAAW,YAAY,EAAC,GAAG,EAAE,GAAG,GAAG,UAAA;AAAA,IAAS;AAG3D,UAAM,SAAS,uBAAuB;AACtC,UAAM,UAAU,uBAAuB;AACvC,UAAM,WAAW,kBAAkB,MAAM,SAAS,IAAI;AACtD,UAAM,UAAU,kBAAkB,MAAM,QAAQ,IAAI;AAEpD,UAAM,kBAA0D;AAAA,MAC9D,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,aAAa;AAAA,MACb,aAAa;AAAA,MACb,UAAU;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAGZ,UAAM,OAAO,KAAK,aAAa,QAAQ,GAAG,WAAW;AACpD,SAA4C,OAAO;AAAA,MAClD,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,IAAA;AAGT,SAAK,cAAc;AAEnB,WAAO,CAAC,iBAAiB,IAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,6BAA6B;AACrC,UAAM,iBACJ,KAAK,aAAa,SAAS,WACvB,+BACA;AACN,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,MACL;AAAA,IAAA;AAOF,UAAM,aAAa,KAAK,SAAU,IAAI,CAAC,OAAO,KAAK,kBAAkB,EAAE,CAAC;AACxE,QAAI,KAAK,gBAAgB;AACvB,WAAK;AAAA,QACH,WAAW;AAAA,UAAQ,CAAC,QACjB,GAAG,QAAQ,CAAA,GAAI;AAAA,YAAI,CAAC,OACnB,MAAM,OAAO,OAAO,WAAY,GAAG,IAAe;AAAA,UAAA;AAAA,QACpD;AAAA,QAEF,KAAK;AAAA,MAAA;AAAA,IAET;AAEA,UAAM,aAAa,KAAK,SAAU;AAClC,WAAO,WAAW;AAAA,MAAI,CAAC,IAAI,MACzB,KAAK,aAAa,IAAI,GAAG,aAAa,UAAU;AAAA,IAAA;AAAA,EAEpD;AAAA;AAAA,EAGQ,kBACN,IACwC;AACxC,QAAI,CAAC,KAAK,kBAAkB,CAAC,GAAG,KAAM,QAAO;AAC7C,UAAM,OAAO,GAAG,KAAK;AAAA,MAAI,CAAC,OACxB,MAAM,OAAO,OAAO,YAAY,OAAO,KACnC,EAAC,GAAG,IAAI,GAAG,gBAAgB,GAAG,GAAG,KAAK,UAAU,MAChD;AAAA,IAAA;AAEN,WAAO,EAAC,GAAG,IAAI,KAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,8BAA8B;AACtC,UAAM,iBACJ,KAAK,aAAa,SAAS,WACvB,+BACA;AACN,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,MACL;AAAA,IAAA;AAEF,UAAM,OAAO,KAAK,gBAAA;AAClB,UAAM,WAAW,KAAK,YAAA;AAEtB,QAAI,KAAK,gBAAgB;AACvB,YAAM,SAAS,KAAK,KAAK,IAAI,CAAC,OAAO;AAAA,QACnC,GAAG,gBAAgB,EAAE,KAAK,EAAE,SAAS,KAAK,KAAK,UAAU;AAAA,QACzD,GAAG,EAAE;AAAA,MAAA,EACL;AACF,WAAK;AAAA,QACH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;AAAA,QACrB,KAAK;AAAA,MAAA;AAEP,YAAMC,YACJ,QAAQ,aAAa,cACjB,KAAK,wBAAwB,QAAQ,WAAW,IAChD,CAAC,KAAK,aAAa,QAAQ,GAAG,WAAW,CAAC;AAChD,aAAO,EAAC,UAAAA,WAAU,QAAQ,CAAA,EAAC;AAAA,IAC7B;AAEA,UAAM,SAAS,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAC3C,UAAM,SAAS,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK,EAAE,CAAC;AAEhE,UAAM,WACJ,QAAQ,aAAa,cACjB,KAAK,wBAAwB,QAAQ,WAAW,IAChD,CAAC,KAAK,aAAa,QAAQ,GAAG,WAAW,CAAC;AAEhD,WAAO,EAAC,UAAU,OAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKU,kBAAwC;AAEhD,UAAM,iBAAiB,KAAK,kBAAA;AAC5B,UAAM,kBAAkB,KAAK,mBAAA;AAG7B,UAAM,aACJ,iBAAiB,6BAA6B,0BAC9C,kBAAkB,6BAA6B;AAGjD,UAAM,cAAc,KAAK,eAAA;AAMzB,QAAI;AAMJ,UAAM,uBAAuB,CAAC,KAAK,kBAC/B,IACA,KAAK,0BACH,KAAK,MAAM,iBAAiB,iBAAiB,WAAW,IACxD,iBAAiB;AAEvB,QAAI,cAAc,KAAK,iBAAiB;AACtC,gBAAU,EAAC,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAA;AAAA,IAChD,WAAW,KAAK,qBAAqB;AAEnC,YAAM,eAAe,KAAK,2BAAA;AAC1B,gBAAU;AAAA,QACR,KAAK,KAAK,wBAAwB,IAAI,KAAK,IACvC,aAAa,MACb;AAAA,QACJ,OAAO,KAAK,wBAAwB,IAAI,OAAO,IAC3C,aAAa,QACb;AAAA,QACJ,QAAQ,KAAK,wBAAwB,IAAI,QAAQ,IAC7C,aAAa,SACb;AAAA,QACJ,MAAM,KAAK,wBAAwB,IAAI,MAAM,IACzC,aAAa,OACb;AAAA,MAAA;AAAA,IAER,OAAO;AAEL,gBAAU;AAAA,QACR,KAAK;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA;AAAA,IAEV;AAGA,QAAI,KAAK,yBAAyB;AAEhC,WAAK,MAAM,YAAY,iBAAiB,MAAM;AAC9C,WAAK,MAAM,YAAY,kBAAkB,GAAG,eAAe,IAAI;AAAA,IACjE,OAAO;AAEL,WAAK,MAAM,YAAY,iBAAiB,GAAG,KAAK,KAAK,IAAI;AACzD,WAAK,MAAM,YAAY,kBAAkB,GAAG,KAAK,MAAM,IAAI;AAAA,IAC7D;AAGA,UAAM,QAAQ,KAAK,qBAAA;AAGnB,UAAM,yBAAyB,KAAK,kBAAA,IAChC,QACA,KAAK;AAET,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,qBAAqB;AAAA;AAAA,MACrB,QAAQ;AAAA,QACN;AAAA,MAAA;AAAA,MAEF,SAAS;AAAA,QACP,QAAQ;AAAA,UACN,SAAS;AAAA,UACT,QAAQ;AAAA,YACN,gBAAgB,MAAM,CAAA;AAAA;AAAA,UAAC;AAAA,UAEzB,SAAS,MAAM;AAAA,UAAC;AAAA;AAAA,QAAA;AAAA,QAElB,SAAS;AAAA,UACP,GAAG,uBAAuB,IAAI;AAAA,UAC9B,SAAS,CAAC;AAAA,UACV,WAAW;AAAA,YACT,OAAO,MAAM;AAAA,YACb,OAAO,CAAC,YAAY;AAClB,oBAAM,QACJ,OAAO,QAAQ,WAAW,YAAY,QAAQ,WAAW,OACpD,QAAQ,OAAuB,IAC/B,QAAQ;AACf,oBAAM,eAAe,kBAAkB,OAAO,GAAG,OAAO,CAAC;AACzD,oBAAM,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,KAAK;AAC1C,kBAAI,QAAQ,QAAQ,SAAS;AAC7B,kBAAI,KAAK,gBAAgB;AACvB,sBAAM,IACJ,OAAO,QAAQ,WAAW,YAAY,QAAQ,WAAW,OACpD,QAAQ,OAAuB,IAChC;AACN,sBAAM,aACJ,KAAK,gBAAgB,YAAsB,QAAQ;AACrD,wBAAQ,aAAa,GAAG,KAAK,YAAY,UAAU;AAAA,cACrD;AACA,qBAAO,GAAG,KAAK,IAAI,YAAY,GAAG,IAAI;AAAA,YACxC;AAAA,UAAA;AAAA,QACF;AAAA,MACF;AAAA,MAEF,WAAW;AAAA,MACX,QAAQ,KAAK,kBAAkB,OAAO,YAAY,sBAAsB;AAAA,IAAA;AAAA,EAE5E;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAA2C;AACjD,QAAI,KAAK,cAAc,OAAgB,QAAO;AAE9C,UAAM,aAAuB,CAAA;AAG7B,QAAI,KAAK,UAAU,QAAQ;AACzB,WAAK,SAAS,QAAQ,CAAC,OAAO;AAC5B,YAAI,CAAC,GAAG,KAAM;AACd,WAAG,KAAK,QAAQ,CAAC,OAAO;AACtB,cAAI,MAAM,OAAO,OAAO,YAAY,OAAO,IAAI;AAC7C,kBAAM,KAAK,gBAAgB,GAAG,GAAG,WAAW,IAAI;AAChD,gBAAI,OAAO,SAAS,EAAE,EAAG,YAAW,KAAK,EAAE;AAAA,UAC7C;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,WAAW,KAAK,MAAM,QAAQ;AAE5B,WAAK,KAAK,QAAQ,CAAC,MAAM;AACvB,cAAM,KAAK,gBAAgB,EAAE,KAAK,EAAE,SAAS,KAAK,WAAW,IAAI;AACjE,YAAI,OAAO,SAAS,EAAE,EAAG,YAAW,KAAK,EAAE;AAAA,MAC7C,CAAC;AAAA,IACH;AAGA,QAAI,CAAC,WAAW,UAAU,KAAK,QAAQ,QAAQ;AAC7C,WAAK,OAAO,QAAQ,CAAC,MAAM;AACzB,YAAI,OAAO,MAAM,UAAU;AACzB,gBAAM,KAAK,IAAI,KAAK,CAAC,EAAE,QAAA;AACvB,cAAI,OAAO,SAAS,EAAE,EAAG,YAAW,KAAK,EAAE;AAAA,QAC7C;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,WAAW,SACd,KAAK,gBAAgB,YACnB,KAAK,IAAI,GAAG,UAAU,IACtB,KAAK,IAAI,GAAG,UAAU,IACxB;AAAA,EACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWU,kBACR,MACA,aAAa,OACb,gBAAgB,MAChB;AAMA,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,uBAAuB;AAAA,IAAA;AAEzB,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,uBAAuB;AAAA,IAAA;AAEzB,UAAM,aAAa;AAAA,MACjB;AAAA,MACA,wBAAwB;AAAA,IAAA;AAE1B,UAAM,WAAW;AAAA,MACf;AAAA,MACA,wBAAwB;AAAA,IAAA;AAE1B,UAAM,aAAa;AAAA,MACjB;AAAA,MACA,wBAAwB;AAAA,IAAA;AAE1B,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,wBAAwB;AAAA,IAAA;AAM1B,UAAM,aAAa,iBAAiB,CAAC,cAAc,KAAK;AACxD,UAAM,YAAY,iBAAiB,CAAC,cAAc,KAAK;AACvD,UAAM,aAAa,EAAC,QAAQ,YAAY,MAAM,UAAU,QAAQ,WAAA;AAEhE,UAAM,IAAI;AAAA,MACR,MAAM,KAAK,cAAc,aAAqB,aAAa;AAAA,MAC3D,QAAQ;AAAA;AAAA,MACR,OAAO;AAAA;AAAA,MACP,QAAQ;AAAA;AAAA,MACR,MAAM;AAAA,QACJ,SAAS,KAAK,YAAY,KAAK;AAAA,QAC/B,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,WAAW;AAAA,MAAA;AAAA,MAEb,OAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,MAAM;AAAA,QACN,aAAa;AAAA;AAAA,QACb,aAAa;AAAA;AAAA,QACb,eAAe,KAAK;AAAA,QACpB,UAAU,KAAK;AAAA,QACf,UAAU,CAAC,UAAmB;AAC5B,cAAI,CAAC,KAAK,eAAgB,QAAO,OAAO,KAAK;AAC7C,gBAAM,IAAI,OAAO,KAAK;AACtB,cAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO,OAAO,KAAK;AAC5C,gBAAM,aACJ,KAAK,gBAAgB,YAAsB,OAAO;AACpD,iBAAO,aAAa,GAAG,KAAK,YAAY,UAAU;AAAA,QACpD;AAAA,MAAA;AAAA,MAEF,QAAQ;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,MAAA;AAAA,IACT;AAIF,UAAM,cAAc,KAAK,OAAO,SAC5B,KAAK,MAAM,IAAI,CAAC,MAAM,OAAO;AAAA,MAC3B,IAAI,KAAK,MAAM,IAAI,CAAC;AAAA,MACpB,UAAU,KAAK,YAAa;AAAA,MAC5B,KAAK,KAAK;AAAA,MACV,KAAK,KAAK;AAAA,MACV,aAAa,KAAK,SAAS,KAAK,YAAY,KAAK;AAAA,IAAA,EACjD,IACF;AAAA,MACE;AAAA,QACE,IAAI;AAAA,QACJ,UAAU,KAAK;AAAA,QACf,KAAK;AAAA,QACL,KAAK;AAAA,QACL,aAAa,KAAK,YAAY,KAAK;AAAA,MAAA;AAAA,IACrC;AAGN,UAAM,eAAwC,EAAC,EAAA;AAE/C,gBAAY,QAAQ,CAAC,EAAC,IAAI,UAAU,KAAK,KAAK,kBAAiB;AAC7D,mBAAa,EAAE,IAAI;AAAA,QACjB,MAAM;AAAA,QACN,SAAS;AAAA,QACT;AAAA,QACA,SAAS,KAAK,YAAA,KAAiB,KAAK,kBAAkB;AAAA,QACtD,OAAO,aAAa,IAAI;AAAA,QACxB,QAAQ,aAAa,SAAS;AAAA,QAC9B,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,OAAO;AAAA,UACP,WAAW;AAAA,QAAA;AAAA,QAEb,OAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM;AAAA,UACN,eAAe,KAAK;AAAA,UACpB,UAAU,KAAK;AAAA,QAAA;AAAA,QAEjB,QAAQ;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,QAAA;AAAA,QAET;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,4BAA4B;AAClC,QAAI,KAAK,UAAU,QAAQ;AACzB,aAAO;AAAA,QACL,UAAU,KAAK,2BAAA;AAAA,QACf,QAAS,KAAK,UAAU,CAAA;AAAA,MAAC;AAAA,IAE7B;AACA,WAAO,KAAK,4BAAA;AAAA,EACd;AAAA,EAEQ,cAAc;AAEpB,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,SAAS,YAAa;AAElD,UAAM,MAAM,KAAK,SAAS,WAAW,IAAI;AACzC,QAAI,CAAC,IAAK;AAGV,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,QAAA;AACX,WAAK,QAAQ;AAAA,IACf;AAEA,UAAM,EAAC,UAAU,WAAU,KAAK,0BAAA;AAEhC,SAAK,QAAQ,IAAI,MAAM,KAAK;AAAA,MAC1B,MAAM;AAAA,MACN,MAAM,EAAC,QAAQ,SAAA;AAAA,MACf,SAAS,KAAK,gBAAA;AAAA,MACd,SAAS,KAAK,uBAAuB,CAAC,KAAK,mBAAA,CAAoB,IAAI,CAAA;AAAA,IAAC,CACvC;AAG/B,0BAAsB,MAAM,KAAK,cAAc;AAC/C,SAAK,eAAA;AAAA,EACP;AAAA,EAEQ,cAAc;AAEpB,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,YAAY,CAAC,KAAK,SAAS,YAAa;AAEjE,UAAM,EAAC,UAAU,WAAU,KAAK,0BAAA;AAEhC,SAAK,MAAM,KAAK,SAAS;AACzB,SAAK,MAAM,KAAK,WAAW;AAG3B,WAAO,OAAO,KAAK,MAAM,SAAS,KAAK,iBAAiB;AAExD,SAAK,eAAA;AACL,SAAK,MAAM,OAAA;AAGX,0BAAsB,MAAM,KAAK,cAAc;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,oBAAoB;AAE1B,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,YAAY,CAAC,KAAK,SAAS,YAAa;AAGjE,SAAK,eAAA;AAGL,SAAK,MAAM,OAAO,MAAM;AAGxB,0BAAsB,MAAM,KAAK,cAAc;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe;AAErB,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,aAAa,CAAC,KAAK,MAAO;AAGpD,QAAI,CAAC,KAAK,MAAM,KAAK,YAAY,KAAK,MAAM,KAAK,SAAS,WAAW,GAAG;AACtE,WAAK,UAAU,YAAY;AAC3B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,cAAc,KAAK,MAAM,KAAK,SACjC,IAAI,CAAC,IAAI,MAAM;AACd,cAAM,OAAO,KAAK,MAAO,eAAe,CAAC;AAGzC,YAAI,CAAC,QAAQ,CAAC,KAAK,YAAY;AAC7B,iBAAO;AAAA,QACT;AAEA,cAAM,QAAQ,KAAK,WAAW,SAAS,GAAG,KAAK;AAC/C,cAAM,UAAU;AAKhB,eAAO;AAAA,UACL,WAAY,QAAQ,eAClB,MAAM,eACN;AAAA,UACF,OAAQ,QAAQ,SAAoB,UAAU,IAAI,CAAC;AAAA,UACnD,OAAO;AAAA,UACP,MAAM;AAAA,QAAA;AAAA,MAEV,CAAC,EACA,OAAO,CAAC,SAAS,SAAS,IAAI;AAGjC,UAAI,YAAY,SAAS,GAAG;AAC1B,cAAM,aAAa,mBAAmB,WAAW;AACjD,aAAK,UAAU,YAAY;AAAA,MAC7B;AAAA,IACF,SAAS,OAAO;AACd,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MAAA;AAAA,IAGJ;AAAA,EACF;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA,0BAKe,KAAK,gBAAgB;AAAA,wCACP,KAAK,4BAA4B;AAAA;AAAA;AAAA;AAAA,0BAI/C,KAAK,gBAAgB;AAAA,wCACP,KAAK,4BAA4B;AAAA;AAAA;AAAA;AAAA,0BAI/C,KAAK,gBAAgB;AAAA,wCACP,KAAK,4BAA4B;AAAA;AAAA;AAAA;AAAA,0BAI/C,KAAK,gBAAgB;AAAA,wCACP,KAAK,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA,UAK/D,KAAK,SAAS,mCAAmC,EAAE;AAAA;AAAA;AAAA,EAG3D;AAQF;AANE,kBAAgB,SAAS;AAAA,EACvB,UAAU,cAAc;AAAA,EACxB,UAAU,gBAAgB;AAAA,EAC1B,UAAU,gBAAgB;AAAA,EAC1B,UAAU,eAAe;AAAA;AA3lEtB,IAAM,mBAAN;AAEL,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAD9B,iBAEX,WAAA,MAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAJ9B,iBAKX,WAAA,UAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAP9B,iBAQX,WAAA,QAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAV9B,iBAWX,WAAA,QAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,SAAS,SAAS,MAAK;AAAA,GAb7B,iBAcX,WAAA,QAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,SAAS,SAAS,MAAK;AAAA,GAhB7B,iBAiBX,WAAA,kBAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAQ,SAAS,MAAK;AAAA,GAnB5B,iBAoBX,WAAA,OAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAQ,SAAS,MAAK;AAAA,GAtB5B,iBAuBX,WAAA,QAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,SAAS,SAAS,MAAK;AAAA,GAzB7B,iBA0BX,WAAA,yBAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA5Bb,iBA6BX,WAAA,oBAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA/Bb,iBAgCX,WAAA,WAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlCb,iBAmCX,WAAA,eAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GArC9B,iBAsCX,WAAA,OAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAxCd,iBAyCX,WAAA,UAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA3Cd,iBA4CX,WAAA,WAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA9Cd,iBA+CX,WAAA,WAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAjDd,iBAkDX,WAAA,eAAA;AAoBA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GArEhC,iBAsEX,WAAA,iBAAA;AAoCA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAzGd,iBA0GX,WAAA,YAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA5Gb,iBA6GX,WAAA,UAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA/Gb,iBAgHX,WAAA,MAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlHb,iBAmHX,WAAA,aAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GArHb,iBAsHX,WAAA,aAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAxHb,iBAyHX,WAAA,WAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA3Hb,iBA4HX,WAAA,aAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA9Hb,iBA+HX,WAAA,WAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAjIb,iBAkIX,WAAA,OAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApIb,iBAqIX,WAAA,UAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAvIb,iBAwIX,WAAA,YAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA1Ib,iBA2IX,WAAA,sBAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA7Ib,iBA8IX,WAAA,oCAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAhJd,iBAiJX,WAAA,gBAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAnJb,iBAoJX,WAAA,cAAA;AAGyB,gBAAA;AAAA,EAAxB,MAAM,QAAQ;AAAA,GAvJJ,iBAuJc,WAAA,UAAA;AAGC,gBAAA;AAAA,EAAzB,MAAM,SAAS;AAAA,GA1JL,iBA0Je,WAAA,WAAA;AAGe,gBAAA;AAAA,EAAxC,MAAM,wBAAwB;AAAA,GA7JpB,iBA6J8B,WAAA,cAAA;AACG,gBAAA;AAAA,EAA3C,MAAM,2BAA2B;AAAA,GA9JvB,iBA8JiC,WAAA,iBAAA;AACF,gBAAA;AAAA,EAAzC,MAAM,yBAAyB;AAAA,GA/JrB,iBA+J+B,WAAA,eAAA;AACC,gBAAA;AAAA,EAA1C,MAAM,0BAA0B;AAAA,GAhKtB,iBAgKgC,WAAA,gBAAA;"}
1
+ {"version":3,"file":"chart-line-base.js","sources":["../../../src/building-blocks/chart-line/chart-line-base.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport componentStyle from './chart-line-base.css?inline';\nimport chartCommonStyle from '../../charthelpers/chart-common.css?inline';\nimport chartDebugStyle from '../../charthelpers/chart-debug.css?inline';\nimport chartLegendStyle from '../../charthelpers/chart-legend.css?inline';\nimport {\n Chart,\n LineController,\n LineElement,\n PointElement,\n ArcElement,\n Tooltip,\n CategoryScale,\n LinearScale,\n TimeScale,\n Filler,\n} from 'chart.js';\nimport type {ChartOptions, ChartDataset, ChartConfiguration} from 'chart.js';\nimport {\n InstrumentState,\n FrameStyle,\n BorderRadiusPosition,\n Priority,\n} from '../../navigation-instruments/types.js';\nimport {\n CHART_SECTOR_DEFAULT_COLORS,\n CHART_SECTOR_ENHANCED_COLORS,\n RECTANGULAR_CHART_DIMENSIONS,\n LINE_GRAPH_LABEL_CONFIG,\n LINE_GRAPH_GRID_CONFIG,\n CHART_DIMENSIONS,\n CHART_AREA_BACKGROUND_COLOR_VAR,\n getCssVariableValue,\n getChartColorsOrDefault,\n observeThemeChanges,\n formatChartNumber,\n getChartTooltipOptions,\n generateLegendHTML,\n applyAlphaToColor,\n normalizeXValue,\n formatXValue,\n XValueMode,\n observeLabelThreshold,\n measureRangeLabelGutters,\n rangeLabelFontString,\n rangeLabelLineHeight,\n formatRangeValue,\n yRangeLabelValues,\n} from '../../charthelpers/index.js';\nimport type {RangeLabelFont} from '../../charthelpers/index.js';\nimport type {ChartXValue} from '../../charthelpers/x-value.js';\nimport {\n EXTERNAL_SCALE_BORDER_RADIUS_CSS_VAR,\n readExternalScaleBorderRadiusPx,\n startExternalScaleBorderRadiusObserver,\n ScaleType,\n} from '../external-scale/external-scale.js';\n\n// Register Chart.js components used by the line graph (scales, elements, plugins)\nChart.register(\n LineController,\n LineElement,\n PointElement,\n ArcElement,\n CategoryScale,\n LinearScale,\n TimeScale,\n Filler,\n Tooltip\n);\n\n/**\n * Dimension information reported by external scale components.\n * Dispatched via 'scale-dimensions-changed' event from slotted scale elements.\n */\nexport interface ExternalScaleDimensions {\n /** Which side this scale is positioned on */\n side: 'top' | 'bottom' | 'left' | 'right';\n /** Natural thickness in pixels (width for vertical, height for horizontal) */\n thickness: number;\n}\n\n/**\n * Type guard to check if an element is an external scale component\n */\ninterface ExternalScaleElement extends HTMLElement {\n minValue?: number;\n maxValue?: number;\n height?: number;\n width?: number;\n paddingTop?: number;\n paddingBottom?: number;\n paddingLeft?: number;\n paddingRight?: number;\n paddingStart?: number;\n paddingEnd?: number;\n primaryTickmarkInterval?: number;\n showLabels?: boolean;\n showMainTickmarkLabels?: boolean;\n labelThickness?: number;\n fixedAspectRatio?: boolean;\n scaleReferenceSize?: number;\n state?: InstrumentState;\n priority?: Priority;\n frameStyle?: FrameStyle;\n borderRadiusPosition?: BorderRadiusPosition;\n}\n\nexport type {ChartXValue, TemporalLike} from '../../charthelpers/x-value.js';\n\nexport enum XAxisType {\n category = 'category',\n time = 'time',\n number = 'number',\n}\n\nexport enum YAxisPosition {\n left = 'left',\n right = 'right',\n}\n\nexport enum LineMode {\n smooth = 'smooth',\n straight = 'straight',\n stepped = 'stepped',\n}\n\nexport enum TimeDisplay {\n minutes = 'minutes',\n date = 'date',\n}\n\n/** Which axes keep min / max labels below the label threshold. */\nexport enum RangeLabels {\n none = 'none',\n y = 'y',\n x = 'x',\n xy = 'xy',\n}\n\nexport type ChartLinePoint = number | {x: ChartXValue; y: number};\n\nexport type ChartLineDataItem = {\n /** Category label. Used when `xAxisType='category'` (the default). */\n label?: string;\n /**\n * X-coordinate for `xAxisType='time'` (epoch ms, ISO string, Date, or\n * Temporal object) or `xAxisType='number'` (plain number). When absent,\n * `label` is parsed as a fallback.\n */\n x?: ChartXValue;\n value: number;\n};\n\nexport type ChartLineYAxisConfig = {\n id?: string;\n position?: 'left' | 'right';\n min?: number;\n max?: number;\n grid?: boolean;\n};\n\nexport type ChartLineXAxisConfig = {\n min?: number;\n max?: number;\n};\n\nconst LINE_GRAPH_WATCHED_PROP_NAMES = [\n 'data',\n 'datasets',\n 'labels',\n 'colors',\n 'xAxisType',\n 'yAxisPosition',\n 'yAxes',\n 'xAxis',\n 'showGrid',\n 'showGridX',\n 'showGridY',\n 'showTickMarks',\n 'showPoints',\n 'lineMode',\n 'unit', // Used in tooltip display\n 'timeDisplay',\n 'xTicksLimit',\n 'xStepSize',\n 'yTicksLimit',\n 'yStepSize',\n 'priority', // Triggers color palette change\n 'borderRadiusPosition', // Triggers border styling update\n 'borderRadiusPositionExternalScales', // Triggers external scale border styling update\n // legend only affects HTML; do not use it to drive chart updates\n 'width',\n 'height',\n 'fixedAspectRatioScaling', // Triggers responsive mode change\n 'hasLabelPadding', // Toggles edge-to-edge rendering and label visibility\n 'rangeLabels',\n] as const;\n\nconst LINE_GRAPH_RECREATE_PROP_NAMES = [\n 'showDebugOverlay',\n 'width',\n 'height',\n 'fixedAspectRatioScaling',\n 'rangeLabels', // Adds or removes the range-labels plugin\n] as const;\n\n/**\n * Properties that define the chart's reference size, and therefore invalidate\n * the derived `computedWidth` / `computedHeight` pair.\n */\nconst LINE_GRAPH_DIMENSION_PROP_NAMES = [\n 'width',\n 'height',\n 'fixedAspectRatioScaling',\n] as const;\n\n/**\n * Abstract base class for line and area chart components built on Chart.js.\n *\n * ## Concrete implementations\n * - `<obc-line-graph>`: Line chart (non-filled)\n * - `<obc-area-graph>`: Area chart with fill modes (semitransparent, solid, threshold)\n *\n * ## Features\n * - **Single or multi-series**: Use `data` for simple single-series or `datasets` for multi-series charts\n * - **Category, time and number axes**: `category` (labels, evenly spaced), `time` (epoch ms,\n * ISO strings, `Date` or Temporal objects — positioned proportionally, so uneven intervals\n * render unevenly) and `number` (plain numeric x-values on a linear scale)\n * - **Line styles**: Choose `smooth` (curved), `straight`, or `stepped` line rendering\n * - **Fill modes**: Area fills with `semitransparent`, `solid`, or `threshold` (red/blue above/below midpoint)\n * - **Stacked charts**: Enable `stacked` for multi-series datasets to stack values on y-axis\n * - **Flexible axes**: Single y-axis via `yAxisPosition` or multi-axis via `yAxes` for complex charts\n * - **Theme-aware**: Automatically updates colors on theme changes using CSS variables\n * - **Responsive sizing**: Fixed height with 1.5:1 aspect ratio (e.g., 320px height → 480px width)\n * - **Grid & ticks**: Toggle grid lines (`showGrid`, `showGridX`, `showGridY`) and tick marks (`showTickMarks`)\n * - **Legend support**: Optional HTML legend showing series labels with `legend` property\n * - **External axis support**: via slots\n * - **Color priority**: Set `priority` to `Priority.enhanced` to use the blue/enhanced\n * color palette instead of the default gray/regular palette (default: `Priority.regular`)\n *\n * ## Size Behavior\n * - Above 192px: Shows labels, tick marks, and grid lines with standard padding\n * - Below 192px: Hides labels/ticks and uses edge-to-edge rendering for compact display\n *\n * ## Examples\n *\n * Basic single-series with category axis:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.data = [\n * {label: 'Jan', value: 10},\n * {label: 'Feb', value: 14},\n * {label: 'Mar', value: 12}\n * ];\n * chart.unit = 'kW';\n * chart.height = 256;\n * </script>\n * ```\n *\n * Multi-series with time axis and legend:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.xAxisType = 'time';\n * chart.timeDisplay = 'date';\n * chart.legend = true;\n * chart.datasets = [\n * {label: 'Temperature', data: [{x: '2025-01-01', y: 20}, {x: '2025-01-02', y: 22}]},\n * {label: 'Humidity', data: [{x: '2025-01-01', y: 65}, {x: '2025-01-02', y: 68}]}\n * ];\n * </script>\n * ```\n *\n * Single-series with time axis (uneven intervals position proportionally;\n * x accepts epoch ms, ISO strings, Date or Temporal objects):\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.xAxisType = 'time';\n * chart.timeDisplay = 'minutes';\n * chart.data = [\n * {x: '2026-07-06T10:00:00Z', value: 10},\n * {x: new Date('2026-07-06T10:03:00Z'), value: 14},\n * {x: Temporal.Instant.from('2026-07-06T10:15:00Z'), value: 12}\n * ];\n * </script>\n * ```\n *\n * Single-series with numeric x-axis:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.xAxisType = 'number';\n * chart.data = [\n * {x: 0, value: 2},\n * {x: 2.5, value: 3},\n * {x: 10, value: 6}\n * ];\n * </script>\n * ```\n *\n * Stacked area chart with solid fill:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.datasets = [\n * {label: 'Series A', data: [2, 3, 4, 3, 5]},\n * {label: 'Series B', data: [1, 2, 3, 2, 4]},\n * {label: 'Series C', data: [3, 2, 1, 2, 3]}\n * ];\n * chart.fillMode = 'solid';\n * chart.stacked = true;\n * chart.legend = true;\n * </script>\n * ```\n *\n * Threshold fill (single-series only):\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.data = [{label: '1', value: 20}, {label: '2', value: 45}, {label: '3', value: 35}];\n * chart.fillMode = 'threshold';\n * </script>\n * ```\n *\n * Multi-axis chart with right-side y-axis:\n * ```html\n * <obc-line-graph></obc-line-graph>\n * <script>\n * const chart = document.querySelector('obc-line-graph');\n * chart.yAxes = [\n * {id: 'y-temp', position: 'left', min: 0, max: 100},\n * {id: 'y-pressure', position: 'right', min: 0, max: 10}\n * ];\n * chart.datasets = [\n * {label: 'Temperature', data: [20, 25, 30], yAxisID: 'y-temp'},\n * {label: 'Pressure', data: [2, 3, 2.5], yAxisID: 'y-pressure'}\n * ];\n * </script>\n * ```\n *\n * @property data - Simple single-series data. `{label, value}` items for the category axis;\n * `{x, value}` items for time/number axes (x: epoch ms, ISO string, Date,\n * or Temporal object). Points are drawn in array order (no sorting).\n * @property datasets - Chart.js-style datasets for multi-series use. If provided, takes precedence over `data`.\n * @property labels - Optional explicit labels for the x-axis (category mode). If omitted labels are derived from `data`\n * @property colors - Custom color palette (CSS variable names or color strings).\n * @property legend - Show HTML legend below chart with series labels and colors.\n * @property showDebugOverlay - Development mode: show visual debug overlay with dimension guides.\n * @property width - Width of the chart in pixels. Default: 480.\n * @property height - Height of the chart in pixels. Default: 320.\n * @property fixedAspectRatioScaling - Enable fixed aspect ratio scaling mode.\n * When true, width/height properties define the aspect ratio (not actual pixels).\n * The component fills 100% of parent width and calculates height from aspect ratio.\n * When false (default), width/height are used as actual pixel dimensions.\n * @property scaleReferenceSize - Reference size for external scales when using fixedAspectRatioScaling.\n * This value is passed down to external scales to determine their 1:1 Figma design size.\n * At this reference size, scales render at native size; above/below they scale proportionally.\n * Default: 384 (matches Figma design baseline).\n * @property xAxisType - X-axis mode: 'category' for labeled, evenly spaced data points; 'time'\n * for time-based data positioned proportionally; 'number' for plain\n * numeric x-values.\n * @property yAxisPosition - Single y-axis position ('left' or 'right'). For multiple y-axes, use yAxes instead.\n * @property yAxes - Multiple y-axis definitions for complex multi-axis charts.\n * @property xAxis - Pinned x range (`min`/`max`) for time and number axes. Without it the\n * axis spans exactly the data, so a window that is still filling stretches across the\n * full width. In `minutes` display `max` is the `0min` reference.\n * @availableWhen xAxis xAxisType!=category\n * @property showGrid - Show grid lines.\n * @property showGridX - Show vertical grid lines (x-axis). Default: false.\n * @availableWhen showGridX showGrid==true\n * @property showGridY - Show horizontal grid lines (y-axis). Default: false.\n * @availableWhen showGridY showGrid==true\n * @property showTickMarks - Show axis tick marks and labels.\n * @property rangeLabels - Labels kept below the 192px threshold, where the axis labels are\n * otherwise hidden: 'y' draws min, max and (inside the range) 0 in a gutter on the\n * y-axis side; 'x' draws the first and last x value in a bottom gutter; 'xy' both.\n * Ignored when `hasLabelPadding` is false.\n * @availableWhen rangeLabels hasLabelPadding==true\n * @property showPoints - Show point markers on data points. Default: false.\n * @property lineMode - Line drawing style: 'smooth' (curved), 'straight', or 'stepped'.\n * @property unit - Unit label displayed in tooltips (e.g., 'kW', 'kg', '%').\n * @property timeDisplay - Time axis label format: 'date' (full date/time) or 'minutes' (relative).\n * @availableWhen timeDisplay xAxisType==time\n * @property xTicksLimit - Max number of x-axis ticks/grid lines. Useful for matching external axes.\n * @property xStepSize - Force x-axis tick interval. Useful for matching external axes.\n * @property yTicksLimit - Max number of y-axis ticks/grid lines. Useful for matching external axes.\n * @property yStepSize - Force y-axis tick interval. Useful for matching external axes.\n * @property state - Instrument state affecting colors of external scales.\n * @property priority - Color priority: enhanced uses blue palette instead of default gray.\n * @property frameStyle - Frame style for chart and external scales.\n * @property borderRadiusPosition - Border radius position for the chart's own border.\n * @property borderRadiusPositionExternalScales - Border radius position for external scales based on layout.\n * @property instrumentMode - When true, the chart is used inside an instrument (e.g., gauge-trend).\n * In this mode, only label font size responds to .obc-component-size-* CSS classes.\n * Border radius uses the explicit `borderRadius` property value (or defaults to 8px),\n * rather than reading from CSS variables.\n * @property borderRadius - Explicit border radius value in pixels.\n * When instrumentMode=true, this value is used directly (defaults to 8px).\n * When instrumentMode=false, this is ignored and border radius is read from CSS variable.\n * @availableWhen borderRadius instrumentMode==true\n * @experimental\n */\nexport class ObcChartLineBase extends LitElement {\n @property({type: Array, attribute: false})\n data: ChartLineDataItem[] = [];\n\n @property({type: Array, attribute: false})\n datasets?: ChartDataset<'line', ChartLinePoint[]>[] = undefined;\n\n @property({type: Array, attribute: false})\n labels?: (string | number)[] = undefined;\n\n @property({type: Array, attribute: false})\n colors: string[] = [];\n\n @property({type: Boolean, reflect: true})\n legend = false;\n\n @property({type: Boolean, reflect: true})\n showDebugOverlay = false;\n\n @property({type: Number, reflect: true})\n width = 480;\n\n @property({type: Number, reflect: true})\n height = 320;\n\n @property({type: Boolean, reflect: true})\n fixedAspectRatioScaling = false;\n\n @property({type: Number})\n scaleReferenceSize = 384;\n\n @property({type: String})\n xAxisType: XAxisType = XAxisType.category;\n\n @property({type: String})\n yAxisPosition: YAxisPosition = YAxisPosition.left;\n\n @property({type: Array, attribute: false})\n yAxes?: ChartLineYAxisConfig[] = undefined;\n\n @property({type: Object, attribute: false})\n xAxis?: ChartLineXAxisConfig = undefined;\n\n @property({type: Boolean})\n showGrid = false;\n\n @property({type: Boolean})\n showGridX = false;\n\n @property({type: Boolean})\n showGridY = false;\n\n @property({type: Boolean})\n showTickMarks = false;\n\n /**\n * Reserve canvas padding for axis tick labels on sides without an external scale.\n *\n * When `true` (default), the chart leaves room for tick labels and renders them\n * (subject to `showTickMarks` and the 192px auto-compact threshold).\n *\n * When `false`, the chart renders edge-to-edge on sides without a slotted external\n * scale AND axis tick labels are force-hidden so they cannot be clipped. This also\n * suppresses the automatic edge-to-edge switch that normally happens below the\n * 192px threshold, eliminating the visible padding \"jump\" when crossing it.\n *\n * Useful when embedding the chart inside another component that owns framing\n * and never wants to show axis labels (e.g. `obc-automation-tank`).\n *\n * Defaults to `true` to preserve existing behavior. Declared with `attribute: false`\n * because a `true`-default boolean cannot work as an HTML boolean attribute.\n */\n @property({type: Boolean, attribute: false})\n hasLabelPadding = true;\n\n @property({type: String})\n rangeLabels: RangeLabels = RangeLabels.none;\n\n /** @internal - The y side wants range labels; an edge-to-edge chart never does. */\n protected get rangeLabelsY(): boolean {\n return (\n this.hasLabelPadding &&\n (this.rangeLabels === RangeLabels.y ||\n this.rangeLabels === RangeLabels.xy)\n );\n }\n\n /** @internal - The x side wants range labels; an edge-to-edge chart never does. */\n protected get rangeLabelsX(): boolean {\n return (\n this.hasLabelPadding &&\n (this.rangeLabels === RangeLabels.x ||\n this.rangeLabels === RangeLabels.xy)\n );\n }\n\n /** @internal - True when the x-axis positions points by numeric value. */\n protected get isNumericXAxis(): boolean {\n return (\n this.xAxisType === XAxisType.time || this.xAxisType === XAxisType.number\n );\n }\n\n /**\n * Id of the y scale a dataset lands on when it names none. Chart.js would\n * otherwise add a default `y` scale next to the configured ones and draw it.\n */\n private get primaryYAxisId(): string {\n return this.yAxes?.length ? (this.yAxes[0].id ?? 'y0') : 'y';\n }\n\n /** @internal - Normalization mode for the current x-axis type. */\n protected get xValueMode(): XValueMode {\n return this.xAxisType === XAxisType.number\n ? XValueMode.number\n : XValueMode.time;\n }\n\n /** @internal - Last data/datasets reference already warned about. */\n private lastWarnedXSource?: unknown;\n\n /** @internal - Whether the `date`-display scale warning has been issued. */\n private warnedDateDisplayScale = false;\n\n /** @internal - Warn once per data assignment about unparseable x-values. */\n private warnOnInvalidX(xValues: number[], sourceRef: unknown) {\n const invalid = xValues.filter((x) => !Number.isFinite(x)).length;\n if (invalid === 0 || this.lastWarnedXSource === sourceRef) return;\n this.lastWarnedXSource = sourceRef;\n console.warn(\n `[obc-chart] ${invalid} x value(s) could not be parsed for xAxisType='${this.xAxisType}'; the points render as gaps.`\n );\n }\n\n // Internal default tension used when `lineMode` is 'smooth'. Not exposed as a property.\n private readonly DEFAULT_TENSION = 0.4;\n\n // Internal default point radius when points are shown.\n private readonly POINT_RADIUS = 3;\n\n @property({type: Boolean})\n showPoints = false;\n\n @property({type: String})\n lineMode: LineMode = LineMode.smooth;\n\n @property({type: String})\n unit = '';\n\n @property({type: String})\n timeDisplay: TimeDisplay = TimeDisplay.date;\n\n @property({type: Number})\n xTicksLimit?: number = undefined;\n\n @property({type: Number})\n xStepSize?: number = undefined;\n\n @property({type: Number})\n yTicksLimit?: number = undefined;\n\n @property({type: Number})\n yStepSize?: number = undefined;\n\n @property({type: String})\n state: InstrumentState = InstrumentState.active;\n\n @property({type: String})\n priority: Priority = Priority.regular;\n\n @property({type: String})\n frameStyle: FrameStyle = FrameStyle.regular;\n\n @property({type: String})\n borderRadiusPosition?: BorderRadiusPosition = undefined;\n\n @property({type: String})\n borderRadiusPositionExternalScales?: BorderRadiusPosition = undefined;\n\n @property({type: Boolean})\n instrumentMode = false;\n\n @property({type: Number})\n borderRadius?: number = undefined;\n\n /** @internal */\n @query('canvas') private canvasEl?: HTMLCanvasElement;\n\n /** @internal */\n @query('.legend') private legendDiv?: HTMLDivElement;\n\n /** @internal - Slot elements for external scales */\n @query('slot[name=\"top-scale\"]') private topScaleSlot?: HTMLSlotElement;\n @query('slot[name=\"bottom-scale\"]') private bottomScaleSlot?: HTMLSlotElement;\n @query('slot[name=\"left-scale\"]') private leftScaleSlot?: HTMLSlotElement;\n @query('slot[name=\"right-scale\"]') private rightScaleSlot?: HTMLSlotElement;\n\n /** @internal */\n private chart?: Chart;\n\n /** @internal */\n private themeObserver?: MutationObserver;\n\n /** @internal - ResizeObserver for tracking height threshold crossings (e.g. MIN_HEIGHT_WITH_LABELS = 192px) */\n private resizeObserver?: ResizeObserver;\n\n /** @internal - Track external scale dimensions */\n private externalScaleDimensions: Map<string, number> = new Map();\n\n /** @internal - Debounce timer for dimension updates */\n private dimensionUpdateTimer?: ReturnType<typeof setTimeout>;\n\n /** @internal - Flag to prevent infinite update loops */\n private isUpdatingScales = false;\n\n /** @internal - Border radius observer for theme/size changes */\n private borderRadiusObserver?: MutationObserver;\n\n /** @internal - Current computed border radius in pixels */\n private currentBorderRadiusPx = 8;\n\n /** @internal - ResizeObserver for aspect ratio scaling */\n private aspectRatioResizeObserver?: ResizeObserver;\n\n /** @internal - Computed actual width when using fixed aspect ratio scaling */\n private computedWidth = 480;\n\n /** @internal - Computed actual height when using fixed aspect ratio scaling */\n private computedHeight = 320;\n\n /**\n * Should fill be applied to this chart?\n * Line graph returns false, area graph returns true.\n * Must be implemented in subclass.\n */\n protected shouldApplyFill(): boolean {\n throw new Error('shouldApplyFill() must be implemented in subclass');\n }\n\n /**\n * Get fill mode for area rendering.\n * Line graph returns undefined, area graph returns 'semitransparent' | 'solid' | 'threshold'.\n * Must be implemented in subclass.\n */\n protected getFillMode(): string | undefined {\n throw new Error('getFillMode() must be implemented in subclass');\n }\n\n /**\n * Should multi-series datasets be stacked?\n * Line graph returns false, area graph returns stacked property value.\n * Must be implemented in subclass.\n */\n protected shouldStack(): boolean {\n throw new Error('shouldStack() must be implemented in subclass');\n }\n\n /**\n * Compute which corners should be rounded based on borderRadiusPosition and\n * which external scales are present.\n *\n * Logic:\n * - Opposite scales (left+right OR top+bottom) → no rounding (middleChild behavior)\n * - Perpendicular scales (e.g., right+bottom):\n * - innerFirstChild → round corner adjacent to both scales\n * - outerLastChild → round free corner opposite to scales\n * - Single-side scales:\n * - When external scale is on RIGHT, chart is on LEFT\n * - innerFirstChild → round LEFT corners (top-left + bottom-left)\n * - outerLastChild → round RIGHT corners (top-right + bottom-right)\n * - When external scale is on LEFT, chart is on RIGHT (opposite)\n * - When external scale is on TOP, chart is on BOTTOM\n * - innerFirstChild → round BOTTOM corners (bottom-left + bottom-right)\n * - outerLastChild → round TOP corners (top-left + top-right)\n * - When external scale is on BOTTOM, chart is on TOP (opposite)\n * - middleChild → no rounding\n */\n\n /**\n * @internal - Label band each slotted scale had before the chart narrowed\n * it for compact labels, so it can be given back on the way out.\n */\n private savedLabelThickness = new WeakMap<ExternalScaleElement, number>();\n private savedMainTickmarkLabels = new WeakMap<\n ExternalScaleElement,\n boolean\n >();\n /** Last known threshold side, to notice a crossing in `updated()`. */\n private wasBelowThreshold?: boolean;\n\n /**\n * Label band a slotted scale needs for its compact labels, in the scale's\n * own viewBox units. The scale prints the raw values, so those are what is\n * measured; the x band is one text line.\n */\n private compactLabelThickness(axis: 'x' | 'y'): number | undefined {\n const context = this.canvasEl?.getContext('2d');\n if (!context) return undefined;\n const font = this.rangeLabelFont();\n let visual: number;\n if (axis === 'y') {\n const bounds = this.rangeLabelCache.bounds;\n if (!bounds) return undefined;\n const texts = yRangeLabelValues(bounds.min, bounds.max).map(String);\n visual = measureRangeLabelGutters(context, font, texts, []).side + 4;\n } else {\n visual = measureRangeLabelGutters(context, font, [], ['x']).bottom + 8;\n }\n if (!this.fixedAspectRatioScaling) return Math.ceil(visual);\n const effectiveLength =\n axis === 'y' ? this.getEffectiveHeight() : this.getEffectiveWidth();\n return Math.ceil((visual * this.scaleReferenceSize) / effectiveLength);\n }\n\n /** @internal - Labels the range-labels plugin drew last, for tests. */\n lastRangeLabels: {axis: 'x' | 'y'; text: string; x: number; y: number}[] = [];\n\n /**\n * Range labels for the current data and size, refreshed with every\n * `getChartOptions()` so the plugin never rebuilds the datasets on a draw.\n */\n private rangeLabelCache: {\n y: string[];\n x: string[];\n bounds?: {min: number; max: number};\n } = {y: [], x: []};\n\n private slotFor(\n side: 'left' | 'right' | 'top' | 'bottom'\n ): HTMLSlotElement | undefined {\n return {\n left: this.leftScaleSlot,\n right: this.rightScaleSlot,\n top: this.topScaleSlot,\n bottom: this.bottomScaleSlot,\n }[side];\n }\n\n private hasSlottedScale(side: 'left' | 'right' | 'top' | 'bottom'): boolean {\n return (this.slotFor(side)?.assignedElements().length ?? 0) > 0;\n }\n\n /** @internal - Below the label threshold on either dimension. */\n private isBelowThreshold(): boolean {\n return (\n this.getEffectiveWidth() <\n RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS ||\n this.getEffectiveHeight() <\n RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS\n );\n }\n\n private get ySide(): 'left' | 'right' {\n const first = this.yAxes?.[0]?.position;\n return (first ?? this.yAxisPosition) === 'right' ? 'right' : 'left';\n }\n\n private rangeLabelFont(): RangeLabelFont {\n const sizePx = Number.parseFloat(\n getCssVariableValue(this, LINE_GRAPH_LABEL_CONFIG.fontSizeVar)\n );\n return {\n family: getCssVariableValue(this, LINE_GRAPH_LABEL_CONFIG.fontFamily),\n sizePx: Number.isFinite(sizePx) ? sizePx : 12,\n weight: getCssVariableValue(this, LINE_GRAPH_LABEL_CONFIG.fontWeightVar),\n };\n }\n\n /**\n * Extent of the prepared data: one for x, one per y scale id. Each y axis\n * ranges from its own datasets, so a merged extent would label one axis\n * with another's values.\n */\n private dataExtents(\n prepared: ReturnType<ObcChartLineBase['prepareChartDataAndLabels']>\n ): {\n x?: {min: number; max: number};\n y: Map<string, {min: number; max: number}>;\n } {\n const x = {min: Infinity, max: -Infinity};\n const y = new Map<string, {min: number; max: number}>();\n const take = (extent: {min: number; max: number}, v: number) => {\n if (!Number.isFinite(v)) return;\n extent.min = Math.min(extent.min, v);\n extent.max = Math.max(extent.max, v);\n };\n prepared.datasets.forEach((dataset) => {\n const id = dataset.yAxisID ?? this.primaryYAxisId;\n const extent = y.get(id) ?? {min: Infinity, max: -Infinity};\n y.set(id, extent);\n (dataset.data as ChartLinePoint[]).forEach((point) => {\n if (typeof point === 'number') {\n take(extent, point);\n } else if (point) {\n take(x, point.x as number);\n take(extent, point.y);\n }\n });\n });\n y.forEach((extent, id) => {\n if (!(extent.min <= extent.max)) y.delete(id);\n });\n return {x: x.min <= x.max ? x : undefined, y};\n }\n\n /**\n * Range the y labels describe. Below the threshold the axis runs on data\n * bounds, so its datasets' extent is exact and needs no chart to read from.\n */\n private yRangeBounds(\n extents: Map<string, {min: number; max: number}>\n ): {min: number; max: number} | undefined {\n let axis: ChartLineYAxisConfig | undefined;\n let id = 'y';\n if (this.yAxes?.length) {\n const match = this.yAxes.findIndex(\n (a) => (a.position ?? 'left') === this.ySide\n );\n const index = match === -1 ? 0 : match;\n axis = this.yAxes[index];\n id = axis.id ?? `y${index}`;\n }\n const extent = extents.get(id);\n // Stacking makes the axis span the accumulated series, which a per-dataset\n // extent cannot describe, so the laid-out scale is the only source for it.\n const stackedScale = this.shouldStack()\n ? this.chart?.scales[id]\n : undefined;\n const min = axis?.min ?? stackedScale?.min ?? extent?.min;\n const max = axis?.max ?? stackedScale?.max ?? extent?.max;\n return min !== undefined && max !== undefined ? {min, max} : undefined;\n }\n\n /** First and last x label, or nothing when there is no span to label. */\n private xEdgeLabelTexts(\n prepared: ReturnType<ObcChartLineBase['prepareChartDataAndLabels']>,\n extent: {min: number; max: number} | undefined\n ): string[] {\n if (!this.isNumericXAxis) {\n const labels = prepared.labels.map(String);\n const first = labels[0];\n const last = labels[labels.length - 1];\n return labels.length > 1 && first !== last ? [first, last] : [];\n }\n const min = this.xAxis?.min ?? extent?.min;\n const max = this.xAxis?.max ?? extent?.max;\n if (min === undefined || max === undefined || min === max) return [];\n const reference =\n this.timeDisplay === TimeDisplay.minutes\n ? this.computeTimeReference()\n : undefined;\n return [\n formatXValue(min, this.xValueMode, reference),\n formatXValue(max, this.xValueMode, reference),\n ];\n }\n\n /**\n * Recompute the range labels. A side with a slotted scale is labelled by\n * the scale, so it gets no text here; the y bounds are kept regardless,\n * since the scale's compact band is measured from them.\n */\n private refreshRangeLabels(): typeof this.rangeLabelCache {\n const cache: typeof this.rangeLabelCache = {y: [], x: []};\n if (this.isBelowThreshold() && (this.rangeLabelsY || this.rangeLabelsX)) {\n // Prepared once: it restyles every dataset and reads CSS variables.\n const prepared = this.prepareChartDataAndLabels();\n const extents = this.dataExtents(prepared);\n if (this.rangeLabelsY) {\n cache.bounds = this.yRangeBounds(extents.y);\n if (\n cache.bounds &&\n !this.hasSlottedScale('left') &&\n !this.hasSlottedScale('right')\n ) {\n const {min, max} = cache.bounds;\n cache.y = yRangeLabelValues(min, max).map((v) =>\n formatRangeValue(v, min, max)\n );\n }\n }\n if (\n this.rangeLabelsX &&\n !this.hasSlottedScale('top') &&\n !this.hasSlottedScale('bottom')\n ) {\n cache.x = this.xEdgeLabelTexts(prepared, extents.x);\n }\n }\n this.rangeLabelCache = cache;\n return cache;\n }\n\n /**\n * Paints min / 0 / max and first / last once Chart.js has drawn, inside the\n * gutters `getChartOptions()` reserved. The end labels sit flush with the\n * plot edges so no vertical padding is needed for them.\n */\n private createRangeLabelsPlugin() {\n return {\n id: 'rangeLabels',\n afterDraw: (chart: Chart) => {\n this.lastRangeLabels = [];\n const {y: yTexts, x: xTexts, bounds} = this.rangeLabelCache;\n if (!yTexts.length && !xTexts.length) return;\n const area = chart.chartArea;\n const ctx = chart.ctx;\n const font = this.rangeLabelFont();\n const lineHeight = rangeLabelLineHeight(font);\n ctx.save();\n ctx.font = rangeLabelFontString(font);\n ctx.fillStyle = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontColorVar\n );\n\n const scale = chart.scales[this.primaryYAxisId];\n if (yTexts.length && bounds && scale) {\n const onRight = this.ySide === 'right';\n const x = onRight ? area.right + 8 : area.left - 8;\n ctx.textAlign = onRight ? 'left' : 'right';\n const values = yRangeLabelValues(bounds.min, bounds.max);\n // Top-down, so the recorded order reads max, 0, min.\n for (let i = values.length - 1; i >= 0; i--) {\n const isMax = i === values.length - 1;\n const isMin = i === 0;\n const y = isMax\n ? area.top\n : isMin\n ? area.bottom\n : scale.getPixelForValue(values[i]);\n // A 0 within a line of either end would collide with it.\n if (\n !isMax &&\n !isMin &&\n (y - area.top < lineHeight || area.bottom - y < lineHeight)\n ) {\n continue;\n }\n ctx.textBaseline = isMax ? 'top' : isMin ? 'bottom' : 'middle';\n ctx.fillText(yTexts[i], x, y);\n this.lastRangeLabels.push({axis: 'y', text: yTexts[i], x, y});\n }\n }\n\n if (xTexts.length === 2) {\n const y = area.bottom + 4;\n ctx.textBaseline = 'top';\n ctx.textAlign = 'left';\n ctx.fillText(xTexts[0], area.left, y);\n this.lastRangeLabels.push({\n axis: 'x',\n text: xTexts[0],\n x: area.left,\n y,\n });\n ctx.textAlign = 'right';\n ctx.fillText(xTexts[1], area.right, y);\n this.lastRangeLabels.push({\n axis: 'x',\n text: xTexts[1],\n x: area.right,\n y,\n });\n }\n ctx.restore();\n },\n };\n }\n\n /**\n * Check if a slotted scale element is actually visible (renders content).\n * For bar-vertical/bar-horizontal elements, checks hasBar and hasScale properties.\n */\n private hasVisibleScale(side: 'left' | 'right' | 'top' | 'bottom'): boolean {\n const slot = this.slotFor(side);\n const elements = slot?.assignedElements() ?? [];\n\n return elements.some((el: Element) => {\n const barEl = el as HTMLElement & {\n hasBar?: boolean;\n hasScale?: boolean;\n };\n\n // If it has hasBar and hasScale properties, check if at least one is true\n if ('hasBar' in barEl && 'hasScale' in barEl) {\n return barEl.hasBar === true || barEl.hasScale === true;\n }\n\n // Otherwise assume it's visible\n return true;\n });\n }\n\n private computeRoundedCorners(): {\n topLeft: boolean;\n topRight: boolean;\n bottomLeft: boolean;\n bottomRight: boolean;\n } {\n if (!this.borderRadiusPosition) {\n return {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n }\n\n if (this.borderRadiusPosition === BorderRadiusPosition.middleChild) {\n return {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n }\n\n // middleRoundedChild → round ALL corners (standalone instrument mode)\n if (this.borderRadiusPosition === BorderRadiusPosition.middleRoundedChild) {\n return {\n topLeft: true,\n topRight: true,\n bottomLeft: true,\n bottomRight: true,\n };\n }\n\n // Determine which external scales are VISIBLE (not just present in slots)\n const hasLeft = this.hasVisibleScale('left');\n const hasRight = this.hasVisibleScale('right');\n const hasTop = this.hasVisibleScale('top');\n const hasBottom = this.hasVisibleScale('bottom');\n\n // If scales exist on opposite sides, behave like middleChild (no rounding)\n if ((hasLeft && hasRight) || (hasTop && hasBottom)) {\n return {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n }\n\n const result = {\n topLeft: false,\n topRight: false,\n bottomLeft: false,\n bottomRight: false,\n };\n\n const isInner =\n this.borderRadiusPosition === BorderRadiusPosition.innerFirstChild;\n const isOuter =\n this.borderRadiusPosition === BorderRadiusPosition.outerLastChild;\n\n // Handle perpendicular scale configurations (e.g., right + bottom)\n if (hasRight && hasBottom) {\n // Chart is in top-left position\n if (isInner) {\n result.bottomRight = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.topLeft = true; // Free corner\n }\n } else if (hasRight && hasTop) {\n // Chart is in bottom-left position\n if (isInner) {\n result.topRight = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.bottomLeft = true; // Free corner\n }\n } else if (hasLeft && hasBottom) {\n // Chart is in top-right position\n if (isInner) {\n result.bottomLeft = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.topRight = true; // Free corner\n }\n } else if (hasLeft && hasTop) {\n // Chart is in bottom-right position\n if (isInner) {\n result.topLeft = true; // Corner adjacent to both scales\n } else if (isOuter) {\n result.bottomRight = true; // Free corner\n }\n }\n // Handle single-side horizontal scales (left OR right, but not both)\n else if (hasRight && !hasLeft) {\n // Chart is on the left side of composition\n if (isInner) {\n result.topLeft = true;\n result.bottomLeft = true;\n } else if (isOuter) {\n result.topRight = true;\n result.bottomRight = true;\n }\n } else if (hasLeft && !hasRight) {\n // Chart is on the right side of composition\n if (isInner) {\n result.topRight = true;\n result.bottomRight = true;\n } else if (isOuter) {\n result.topLeft = true;\n result.bottomLeft = true;\n }\n }\n // Handle single-side vertical scales (top OR bottom, but not both)\n else if (hasBottom && !hasTop) {\n // Chart is on the top of composition\n if (isInner) {\n result.topLeft = true;\n result.topRight = true;\n } else if (isOuter) {\n result.bottomLeft = true;\n result.bottomRight = true;\n }\n } else if (hasTop && !hasBottom) {\n // Chart is on the bottom of composition\n if (isInner) {\n result.bottomLeft = true;\n result.bottomRight = true;\n } else if (isOuter) {\n result.topLeft = true;\n result.topRight = true;\n }\n }\n\n return result;\n }\n\n /**\n * Read current border radius from CSS variable and update state.\n * The chart will be recreated when needed through the normal update mechanism.\n * In instrument mode, uses explicit borderRadius value instead of CSS variable.\n */\n private updateBorderRadius = () => {\n if (!this.canvasEl) return;\n\n // In instrument mode, use explicit value or default (8px)\n // Skip CSS variable reading entirely\n let next: number;\n if (this.instrumentMode) {\n next = this.borderRadius ?? 8;\n } else {\n next = readExternalScaleBorderRadiusPx(\n this.canvasEl,\n ScaleType.regular,\n EXTERNAL_SCALE_BORDER_RADIUS_CSS_VAR\n );\n }\n\n if (this.currentBorderRadiusPx !== next) {\n this.currentBorderRadiusPx = next;\n // Trigger chart recreation to update border plugin\n if (this.chart) {\n this.chart.destroy();\n this.createChart();\n }\n }\n };\n\n /**\n * Create a Chart.js plugin that draws a border around the chart area with selective corner rounding\n * and clips content to that border.\n */\n private createBorderPlugin() {\n const corners = this.computeRoundedCorners();\n const radius = this.currentBorderRadiusPx;\n\n let didApplyClip = false;\n\n const buildRoundedRectPath = (\n ctx: CanvasRenderingContext2D,\n rect: {x: number; y: number; width: number; height: number},\n cornerRadius: number\n ) => {\n const {x, y, width, height} = rect;\n\n // Guard: Avoid invalid paths\n if (width <= 0 || height <= 0) return;\n\n const r = Math.max(\n 0,\n Math.min(cornerRadius, Math.min(width, height) / 2)\n );\n\n // Start at top-left corner (accounting for radius)\n ctx.moveTo(x + (corners.topLeft ? r : 0), y);\n\n ctx.lineTo(x + width - (corners.topRight ? r : 0), y);\n\n if (corners.topRight) {\n ctx.arcTo(x + width, y, x + width, y + r, r);\n }\n\n ctx.lineTo(x + width, y + height - (corners.bottomRight ? r : 0));\n\n if (corners.bottomRight) {\n ctx.arcTo(x + width, y + height, x + width - r, y + height, r);\n }\n\n ctx.lineTo(x + (corners.bottomLeft ? r : 0), y + height);\n\n if (corners.bottomLeft) {\n ctx.arcTo(x, y + height, x, y + height - r, r);\n }\n\n ctx.lineTo(x, y + (corners.topLeft ? r : 0));\n\n if (corners.topLeft) {\n ctx.arcTo(x, y, x + r, y, r);\n }\n };\n\n return {\n id: 'chartAreaBorder',\n beforeDatasetsDraw: (chart: Chart) => {\n const ctx = chart.ctx;\n const chartArea = chart.chartArea;\n\n if (!chartArea) return;\n\n // Draw/clip behavior should match CSS border-box:\n // - The border stroke must be fully INSIDE the chartArea.\n // - The stroke's OUTER edge should align to the chartArea boundary.\n // Reserve space by clipping content inside the border thickness.\n const borderWidthPx = 1;\n const clipInset = borderWidthPx;\n\n const {top, right, bottom, left} = chartArea;\n const rect = {\n x: left + clipInset,\n y: top + clipInset,\n width: right - left - clipInset * 2,\n height: bottom - top - clipInset * 2,\n };\n\n const clipRadius = Math.max(0, radius - clipInset);\n\n ctx.save();\n didApplyClip = true;\n\n // Create clipping path with selective corner rounding\n ctx.beginPath();\n\n buildRoundedRectPath(ctx as CanvasRenderingContext2D, rect, clipRadius);\n ctx.closePath();\n\n // Fill chart area background when in instrument mode\n if (this.instrumentMode) {\n const backgroundColor = getCssVariableValue(\n this,\n CHART_AREA_BACKGROUND_COLOR_VAR\n );\n ctx.fillStyle = backgroundColor;\n ctx.fill();\n }\n\n // Apply clipping\n ctx.clip();\n },\n afterDraw: (chart: Chart) => {\n const ctx = chart.ctx;\n const chartArea = chart.chartArea;\n\n if (!chartArea) return;\n\n const borderWidthPx = 1;\n const strokeInset = borderWidthPx / 2;\n\n const {top, right, bottom, left} = chartArea;\n const rect = {\n x: left + strokeInset,\n y: top + strokeInset,\n width: right - left - strokeInset * 2,\n height: bottom - top - strokeInset * 2,\n };\n\n const strokeRadius = Math.max(0, radius - strokeInset);\n\n // Check which sides have visible scales (edges to skip)\n const skipTop = this.hasVisibleScale('top');\n const skipRight = this.hasVisibleScale('right');\n const skipBottom = this.hasVisibleScale('bottom');\n const skipLeft = this.hasVisibleScale('left');\n\n // Get border color from CSS variable\n const borderColor = getCssVariableValue(\n this,\n '--instrument-frame-tertiary-color'\n );\n\n ctx.save();\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = borderWidthPx;\n\n const {x, y, width, height} = rect;\n const r = Math.max(\n 0,\n Math.min(strokeRadius, Math.min(width, height) / 2)\n );\n\n // Draw border segments, skipping edges that have visible external scales\n if (!skipTop && !skipRight && !skipBottom && !skipLeft) {\n // No scales - draw full border path\n ctx.beginPath();\n buildRoundedRectPath(\n ctx as CanvasRenderingContext2D,\n rect,\n strokeRadius\n );\n ctx.closePath();\n ctx.stroke();\n } else {\n // Draw border in segments, skipping edges with visible scales\n // Each segment is drawn as a continuous path for proper corner rendering\n\n // Top edge (skip if top scale present)\n if (!skipTop) {\n ctx.beginPath();\n // Start: either from top-left corner end or top-left corner point\n if (!skipLeft && corners.topLeft) {\n ctx.moveTo(x + r, y);\n } else {\n ctx.moveTo(x, y);\n }\n // Draw to: either to top-right corner start or top-right corner point\n if (!skipRight && corners.topRight) {\n ctx.lineTo(x + width - r, y);\n } else {\n ctx.lineTo(x + width, y);\n }\n ctx.stroke();\n }\n\n // Right edge (skip if right scale present)\n if (!skipRight) {\n ctx.beginPath();\n // Start: either from top-right corner end or top-right point\n if (!skipTop && corners.topRight) {\n ctx.moveTo(x + width, y + r);\n } else {\n ctx.moveTo(x + width, y);\n }\n // Draw to: either to bottom-right corner start or bottom-right point\n if (!skipBottom && corners.bottomRight) {\n ctx.lineTo(x + width, y + height - r);\n } else {\n ctx.lineTo(x + width, y + height);\n }\n ctx.stroke();\n }\n\n // Bottom edge (skip if bottom scale present)\n if (!skipBottom) {\n ctx.beginPath();\n // Start: either from bottom-right corner end or bottom-right point\n if (!skipRight && corners.bottomRight) {\n ctx.moveTo(x + width - r, y + height);\n } else {\n ctx.moveTo(x + width, y + height);\n }\n // Draw to: either to bottom-left corner start or bottom-left point\n if (!skipLeft && corners.bottomLeft) {\n ctx.lineTo(x + r, y + height);\n } else {\n ctx.lineTo(x, y + height);\n }\n ctx.stroke();\n }\n\n // Left edge (skip if left scale present)\n if (!skipLeft) {\n ctx.beginPath();\n // Start: either from bottom-left corner end or bottom-left point\n if (!skipBottom && corners.bottomLeft) {\n ctx.moveTo(x, y + height - r);\n } else {\n ctx.moveTo(x, y + height);\n }\n // Draw to: either to top-left corner start or top-left point\n if (!skipTop && corners.topLeft) {\n ctx.lineTo(x, y + r);\n } else {\n ctx.lineTo(x, y);\n }\n ctx.stroke();\n }\n\n // Draw corners separately (only if adjacent edges are both drawn)\n if (!skipTop && !skipLeft && corners.topLeft) {\n ctx.beginPath();\n ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);\n ctx.stroke();\n }\n\n if (!skipTop && !skipRight && corners.topRight) {\n ctx.beginPath();\n ctx.arc(x + width - r, y + r, r, Math.PI * 1.5, Math.PI * 2);\n ctx.stroke();\n }\n\n if (!skipRight && !skipBottom && corners.bottomRight) {\n ctx.beginPath();\n ctx.arc(x + width - r, y + height - r, r, 0, Math.PI * 0.5);\n ctx.stroke();\n }\n\n if (!skipBottom && !skipLeft && corners.bottomLeft) {\n ctx.beginPath();\n ctx.arc(x + r, y + height - r, r, Math.PI * 0.5, Math.PI);\n ctx.stroke();\n }\n }\n\n ctx.restore();\n\n // Redraw points above the border so edge points are not clipped.\n // The dataset draw already happened (and may have been clipped), so this pass only\n // matters for points near the chart-area boundary.\n if (this.showPoints) {\n ctx.save();\n\n chart.data.datasets.forEach((_ds, datasetIndex) => {\n const meta = chart.getDatasetMeta(datasetIndex);\n if (!meta || meta.hidden) return;\n\n // For line charts, meta.data contains PointElements\n (meta.data ?? []).forEach((el) => {\n const point = el as unknown as {\n draw: (ctx: CanvasRenderingContext2D) => void;\n skip?: boolean;\n options?: {radius?: number};\n };\n\n if (point.skip) return;\n const r = point.options?.radius;\n if (typeof r === 'number' && r <= 0) return;\n\n point.draw(ctx as CanvasRenderingContext2D);\n });\n });\n\n ctx.restore();\n }\n },\n afterDatasetsDraw: (chart: Chart) => {\n // Restore context after datasets are drawn to remove clipping\n if (didApplyClip) {\n chart.ctx.restore();\n didApplyClip = false;\n }\n },\n };\n }\n\n /**\n * Check if any external scales are slotted\n */\n private hasExternalScales(): boolean {\n const top = this.topScaleSlot?.assignedElements() ?? [];\n const bottom = this.bottomScaleSlot?.assignedElements() ?? [];\n const left = this.leftScaleSlot?.assignedElements() ?? [];\n const right = this.rightScaleSlot?.assignedElements() ?? [];\n return (\n top.length > 0 || bottom.length > 0 || left.length > 0 || right.length > 0\n );\n }\n\n /**\n * Handle slot change events - when scales are added/removed\n */\n private handleSlotChange = () => {\n // Reset ready state when scales change\n this.externalScaleDimensions.clear();\n\n // Wait for slotted elements to report their dimensions\n this.waitForScaleDimensions();\n };\n\n /**\n * Handle scale-dimensions-changed events from slotted scales\n */\n private handleScaleDimensionsChanged = (e: Event) => {\n if (this.isUpdatingScales) return; // Prevent infinite loops\n\n const event = e as CustomEvent<ExternalScaleDimensions>;\n const {side, thickness} = event.detail;\n\n // Update dimension tracking\n const previousThickness = this.externalScaleDimensions.get(side);\n if (previousThickness === thickness) return; // No change\n\n this.externalScaleDimensions.set(side, thickness);\n\n // Debounce updates to avoid layout thrashing\n if (this.dimensionUpdateTimer) {\n clearTimeout(this.dimensionUpdateTimer);\n }\n\n this.dimensionUpdateTimer = setTimeout(() => {\n this.syncScalesAndChart();\n }, 16); // One frame\n };\n\n /**\n * Wait for all slotted scales to report their dimensions\n */\n private async waitForScaleDimensions() {\n if (!this.hasExternalScales()) {\n this.requestUpdate();\n return;\n }\n\n // Collect all slotted scale elements\n const scaleElements: ExternalScaleElement[] = [];\n [\n this.topScaleSlot,\n this.bottomScaleSlot,\n this.leftScaleSlot,\n this.rightScaleSlot,\n ].forEach((slot) => {\n if (slot) {\n const assigned = slot.assignedElements() as ExternalScaleElement[];\n scaleElements.push(...assigned);\n }\n });\n\n // Ensure all scales have fixedAspectRatio matching our fixedAspectRatioScaling setting\n // and use the same scaleReferenceSize for consistent proportional scaling.\n // Each scale handles orientation-specific scaling internally based on its main axis.\n const setScaleProps = (slot: HTMLSlotElement | undefined) => {\n if (!slot) return;\n const scales = slot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n scale.fixedAspectRatio = this.fixedAspectRatioScaling;\n scale.scaleReferenceSize = this.scaleReferenceSize;\n });\n };\n\n // All scales use the same scaleReferenceSize - this avoids churn from\n // conflicting values between here and updateScaleProperties()\n setScaleProps(this.leftScaleSlot);\n setScaleProps(this.rightScaleSlot);\n setScaleProps(this.topScaleSlot);\n setScaleProps(this.bottomScaleSlot);\n\n // Wait for all scales to finish rendering\n await Promise.all(\n scaleElements.map((el) =>\n 'updateComplete' in el && typeof el.updateComplete === 'object'\n ? (el.updateComplete as Promise<unknown>)\n : Promise.resolve()\n )\n );\n\n // Scales should have dispatched their dimensions by now\n // If we don't have dimensions yet, wait a bit more\n if (this.externalScaleDimensions.size === 0 && scaleElements.length > 0) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n\n this.syncScalesAndChart();\n }\n\n /**\n * Synchronize scale and chart dimensions/data\n * This is the main coordination function\n */\n private syncScalesAndChart(): boolean {\n if (this.isUpdatingScales) return false;\n this.isUpdatingScales = true;\n\n try {\n // Step 1: The padding the chart itself will lay out with, so a slotted\n // scale's drawing area lines up with the chart area on every side.\n const padding = this.computeChartPadding();\n\n // Step 2: The chart area left once the (visual) padding is taken from\n // the visual size — the reference `width` / `height` would go negative\n // in a container larger than the reference.\n const effectiveWidth =\n this.getEffectiveWidth() - padding.left - padding.right;\n const effectiveHeight =\n this.getEffectiveHeight() - padding.top - padding.bottom;\n\n // Guard against invalid dimensions\n if (effectiveWidth <= 0 || effectiveHeight <= 0) {\n console.warn('[chart-line-base] Invalid effective dimensions', {\n width: this.getEffectiveWidth(),\n height: this.getEffectiveHeight(),\n padding,\n effectiveWidth,\n effectiveHeight,\n });\n return false;\n }\n\n // Step 3: Update slotted scales with coordinated properties\n this.updateScaleProperties(padding);\n\n // Step 4: Force recreation of chart with new padding\n if (this.chart) {\n this.chart.destroy();\n }\n this.createChart();\n return true;\n } finally {\n this.isUpdatingScales = false;\n }\n }\n\n /**\n * Calculate chart padding from external scale dimensions.\n *\n * For sides without an external scale, falls back to `CHART_DIMENSIONS.CANVAS_PADDING`\n * (the chart's own padding to reserve room for axis tick labels). When\n * `hasLabelPadding=false` that fallback is 0 so the chart renders edge-to-edge,\n * and this same value is cascaded to slotted scales via `updateScaleProperties()`\n * — so the bar's main-axis padding (`paddingTop`/`paddingBottom` for vertical bars)\n * collapses with the chart's perpendicular padding and they stay visually aligned.\n */\n private calculatePaddingFromScales() {\n const defaultPadding = this.hasLabelPadding\n ? CHART_DIMENSIONS.CANVAS_PADDING\n : 0;\n\n const padding = {\n top: this.externalScaleDimensions.get('top') ?? defaultPadding,\n right: this.externalScaleDimensions.get('right') ?? defaultPadding,\n bottom: this.externalScaleDimensions.get('bottom') ?? defaultPadding,\n left: this.externalScaleDimensions.get('left') ?? defaultPadding,\n };\n\n return padding;\n }\n\n /**\n * Range a slotted scale on the given side has to cover.\n *\n * A range pinned in the axis configuration is used as is: it is the source\n * of truth, and on the first sync there is no chart to read yet. Otherwise\n * the live Chart.js scale is read under the id `buildScalesConfig()` gives\n * it. A side with no axis of its own follows the first configured one.\n */\n private resolveAxisRange(side: 'left' | 'right' | 'x'): {\n min: number;\n max: number;\n } {\n let id = side === 'x' ? 'x' : 'y';\n let configured: {min?: number; max?: number} | undefined;\n\n if (side === 'x') {\n configured = this.isNumericXAxis ? this.xAxis : undefined;\n } else if (this.yAxes?.length) {\n const match = this.yAxes.findIndex(\n (axis) => (axis.position ?? 'left') === side\n );\n const index = match === -1 ? 0 : match;\n const axis = this.yAxes[index];\n id = axis.id ?? `y${index}`;\n configured = axis;\n }\n\n if (configured?.min !== undefined && configured.max !== undefined) {\n return {min: configured.min, max: configured.max};\n }\n const scale = this.chart?.scales[id];\n return {\n min: scale?.min ?? configured?.min ?? 0,\n max: scale?.max ?? configured?.max ?? 100,\n };\n }\n\n /**\n * Range pushed to the top and bottom scales, or `undefined` to leave them\n * alone. A scale prints its values verbatim, and on a `time` axis the raw\n * range is epoch milliseconds. In `minutes` display the range is converted\n * to the minutes the chart's own labels show; `date` display has no numeric\n * equivalent, so the scale keeps its own range.\n */\n private resolveSlottedXRange(): {min: number; max: number} | undefined {\n const range = this.resolveAxisRange('x');\n if (this.xAxisType !== XAxisType.time) return range;\n\n if (this.timeDisplay !== TimeDisplay.minutes) {\n if (!this.warnedDateDisplayScale) {\n this.warnedDateDisplayScale = true;\n console.warn(\n \"[obc-chart] a slotted horizontal scale cannot label a time axis in 'date' display and keeps its own range; use timeDisplay='minutes' or a number axis.\"\n );\n }\n return undefined;\n }\n\n const pinned =\n this.xAxis?.min !== undefined && this.xAxis?.max !== undefined;\n const reference = this.computeTimeReference();\n if (reference === undefined || (!this.chart && !pinned)) return undefined;\n const minute = 60_000;\n return {\n min: (range.min - reference) / minute,\n max: (range.max - reference) / minute,\n };\n }\n\n /**\n * Update properties on slotted scale elements\n */\n private updateScaleProperties(padding: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n }) {\n const leftRange = this.resolveAxisRange('left');\n const rightRange = this.resolveAxisRange('right');\n const xRange = this.resolveSlottedXRange();\n\n // Use effective dimensions for threshold checks\n const effectiveWidth = this.getEffectiveWidth();\n const effectiveHeight = this.getEffectiveHeight();\n\n // Determine if we should show labels (above threshold).\n // When `hasLabelPadding=false` the chart reserves no room for axis labels,\n // so slotted scales must also hide their labels — otherwise their\n // `labelThickness` band stays in the reported thickness and the chart\n // gets re-padded inward (leaving whitespace on the scale's side), and any\n // visible labels would be clipped against the canvas edge.\n const aboveThreshold =\n effectiveWidth >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS &&\n effectiveHeight >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n const showLabels = this.hasLabelPadding && aboveThreshold;\n // Below the threshold a ladder has no room, but min / 0 / max still has.\n const compactY = !aboveThreshold && this.rangeLabelsY;\n const compactX = !aboveThreshold && this.rangeLabelsX;\n const compactYThickness = compactY\n ? this.compactLabelThickness('y')\n : undefined;\n const compactXThickness = compactX\n ? this.compactLabelThickness('x')\n : undefined;\n\n // Compact mode labels a slotted scale's main tickmarks; a scale the chart\n // never compacted keeps whatever the consumer set.\n const mainLabelsFor = (\n scale: ExternalScaleElement,\n compact: boolean\n ): boolean | undefined => {\n if (compact) {\n if (!this.savedMainTickmarkLabels.has(scale)) {\n this.savedMainTickmarkLabels.set(\n scale,\n scale.showMainTickmarkLabels ?? false\n );\n }\n return true;\n }\n if (!this.savedMainTickmarkLabels.has(scale)) return undefined;\n const saved = this.savedMainTickmarkLabels.get(scale);\n this.savedMainTickmarkLabels.delete(scale);\n return saved;\n };\n\n // Narrow a scale's label band to its compact labels, and give the scale\n // its own band back once the chart leaves compact mode.\n const bandFor = (\n scale: ExternalScaleElement,\n compact: boolean,\n thickness: number | undefined\n ): number | undefined => {\n if (compact) {\n if (\n thickness === undefined ||\n typeof scale.labelThickness !== 'number'\n ) {\n return undefined;\n }\n if (!this.savedLabelThickness.has(scale)) {\n this.savedLabelThickness.set(scale, scale.labelThickness);\n }\n return thickness;\n }\n const saved = this.savedLabelThickness.get(scale);\n this.savedLabelThickness.delete(scale);\n return saved;\n };\n\n // Visual pixels into a viewBox stretched to the *effective* length; the\n // reference `width` / `height` only matches in a reference-sized\n // container, and every other one drifts.\n const verticalViewBoxPadding = this.fixedAspectRatioScaling\n ? {\n top: Math.round(\n (padding.top * this.scaleReferenceSize) / effectiveHeight\n ),\n bottom: Math.round(\n (padding.bottom * this.scaleReferenceSize) / effectiveHeight\n ),\n }\n : {top: padding.top, bottom: padding.bottom};\n\n const horizontalViewBoxPadding = this.fixedAspectRatioScaling\n ? {\n left: Math.round(\n (padding.left * this.scaleReferenceSize) / effectiveWidth\n ),\n right: Math.round(\n (padding.right * this.scaleReferenceSize) / effectiveWidth\n ),\n }\n : {left: padding.left, right: padding.right};\n\n // Update each slotted scale\n const updates: Array<\n [\n HTMLSlotElement | undefined,\n ExternalScaleElement,\n Partial<ExternalScaleElement>,\n ]\n > = [];\n\n /** Empty on a side whose slotted scale carries a range of its own. */\n const rangeProps = (\n side: 'left' | 'right' | 'top' | 'bottom',\n range: {min: number; max: number}\n ): Partial<ExternalScaleElement> =>\n this.ownsSlottedScaleRange(side)\n ? {minValue: range.min, maxValue: range.max}\n : {};\n\n // Left scale\n if (this.leftScaleSlot) {\n const scales =\n this.leftScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n ...rangeProps('left', leftRange),\n height: effectiveHeight, // Use effective height for proper sizing\n paddingTop: verticalViewBoxPadding.top,\n paddingBottom: verticalViewBoxPadding.bottom,\n paddingStart: verticalViewBoxPadding.top,\n paddingEnd: verticalViewBoxPadding.bottom,\n showLabels: showLabels || compactY,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.yStepSize !== undefined) {\n props.primaryTickmarkInterval = this.yStepSize;\n }\n const band = bandFor(scale, compactY, compactYThickness);\n const mainLabels = mainLabelsFor(scale, compactY);\n if (mainLabels !== undefined) props.showMainTickmarkLabels = mainLabels;\n if (band !== undefined) props.labelThickness = band;\n updates.push([this.leftScaleSlot, scale, props]);\n });\n }\n\n // Right scale\n if (this.rightScaleSlot) {\n const scales =\n this.rightScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n ...rangeProps('right', rightRange),\n height: effectiveHeight, // Use effective height for proper sizing\n paddingTop: verticalViewBoxPadding.top,\n paddingBottom: verticalViewBoxPadding.bottom,\n paddingStart: verticalViewBoxPadding.top,\n paddingEnd: verticalViewBoxPadding.bottom,\n showLabels: showLabels || compactY,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.yStepSize !== undefined) {\n props.primaryTickmarkInterval = this.yStepSize;\n }\n const band = bandFor(scale, compactY, compactYThickness);\n const mainLabels = mainLabelsFor(scale, compactY);\n if (mainLabels !== undefined) props.showMainTickmarkLabels = mainLabels;\n if (band !== undefined) props.labelThickness = band;\n updates.push([this.rightScaleSlot, scale, props]);\n });\n }\n\n // Top scale\n if (this.topScaleSlot) {\n const scales =\n this.topScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n ...xRange,\n width: effectiveWidth, // Use effective width for proper sizing\n paddingLeft: horizontalViewBoxPadding.left,\n paddingRight: horizontalViewBoxPadding.right,\n paddingStart: horizontalViewBoxPadding.left,\n paddingEnd: horizontalViewBoxPadding.right,\n showLabels: showLabels || compactX,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.xStepSize !== undefined) {\n props.primaryTickmarkInterval = this.xStepSize;\n }\n const band = bandFor(scale, compactX, compactXThickness);\n const mainLabels = mainLabelsFor(scale, compactX);\n if (mainLabels !== undefined) props.showMainTickmarkLabels = mainLabels;\n if (band !== undefined) props.labelThickness = band;\n updates.push([this.topScaleSlot, scale, props]);\n });\n }\n\n // Bottom scale\n if (this.bottomScaleSlot) {\n const scales =\n this.bottomScaleSlot.assignedElements() as ExternalScaleElement[];\n scales.forEach((scale) => {\n const props: Partial<ExternalScaleElement> = {\n ...xRange,\n width: effectiveWidth, // Use effective width for proper sizing\n paddingLeft: horizontalViewBoxPadding.left,\n paddingRight: horizontalViewBoxPadding.right,\n paddingStart: horizontalViewBoxPadding.left,\n paddingEnd: horizontalViewBoxPadding.right,\n showLabels: showLabels || compactX,\n fixedAspectRatio: this.fixedAspectRatioScaling,\n // Use chart's scaleReferenceSize property for proportional scaling\n scaleReferenceSize: this.scaleReferenceSize,\n state: this.state,\n priority: this.priority,\n frameStyle: this.frameStyle,\n borderRadiusPosition: this.borderRadiusPositionExternalScales,\n };\n // Only override interval if explicitly set\n if (this.xStepSize !== undefined) {\n props.primaryTickmarkInterval = this.xStepSize;\n }\n const band = bandFor(scale, compactX, compactXThickness);\n const mainLabels = mainLabelsFor(scale, compactX);\n if (mainLabels !== undefined) props.showMainTickmarkLabels = mainLabels;\n if (band !== undefined) props.labelThickness = band;\n updates.push([this.bottomScaleSlot, scale, props]);\n });\n }\n\n // Apply all updates\n updates.forEach(([_slot, scale, props]) => {\n Object.assign(scale, props);\n });\n }\n\n /**\n * Whether the chart's axis range is what a slotted scale on this side should\n * describe. A subclass that slots a scale of its own and gives it a separate\n * range returns false for that side, otherwise the sync below overwrites it.\n */\n protected ownsSlottedScaleRange(\n _side: 'left' | 'right' | 'top' | 'bottom'\n ): boolean {\n return true;\n }\n\n /**\n * Push the current axis ranges to the slotted scales. The full\n * `updateScaleProperties()` cascade runs before the chart is (re)built and\n * so reads the previous chart's ranges; this closes that gap once the new\n * chart exists, and keeps auto-ranged scales in step with the data.\n */\n private syncSlottedScaleRanges() {\n const apply = (\n side: 'left' | 'right' | 'top' | 'bottom',\n slot: HTMLSlotElement | undefined,\n range: {min: number; max: number} | undefined\n ) => {\n if (!slot || !range || !this.ownsSlottedScaleRange(side)) return;\n (slot.assignedElements() as ExternalScaleElement[]).forEach((scale) => {\n scale.minValue = range.min;\n scale.maxValue = range.max;\n });\n };\n apply('left', this.leftScaleSlot, this.resolveAxisRange('left'));\n apply('right', this.rightScaleSlot, this.resolveAxisRange('right'));\n const xRange = this.resolveSlottedXRange();\n apply('top', this.topScaleSlot, xRange);\n apply('bottom', this.bottomScaleSlot, xRange);\n }\n\n private hasAnyChanged(\n changed: PropertyValues,\n props: readonly (keyof ObcChartLineBase)[]\n ): boolean {\n return props.some((prop) => changed.has(prop));\n }\n\n /**\n * Apply fillMode rules to datasets. Must be called after the chart is created\n * so scales and pixel coordinates are available for gradient construction.\n *\n * NOTE: For non-threshold modes (solid, semitransparent), backgroundColor is already\n * set correctly in buildDataset(). This method now only handles threshold gradients\n * which require Chart.js scales to be available.\n */\n protected applyFillModes() {\n // Guard: Verify chart and canvas exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const chart = this.chart; // Store reference for TypeScript\n const ctx = chart.ctx as CanvasRenderingContext2D;\n\n // Guard: Verify canvas context is available\n if (!ctx) return;\n\n const fill = this.shouldApplyFill();\n const fillMode = this.getFillMode();\n\n // Only process threshold mode - other modes already have correct backgroundColor from buildDataset()\n if (fillMode !== 'threshold' || !fill) {\n return;\n }\n\n chart.data.datasets.forEach((ds, _idx) => {\n const dataset = ds as ChartDataset<'line'> & {\n fill?:\n | boolean\n | number\n | {target: number; above: string; below: string};\n yAxisID?: string;\n };\n\n // Skip if not filling\n if (dataset.fill === false || !fill) {\n return;\n }\n\n // Threshold fill: only applies to single-series, creates gradients for border\n const yScaleId = dataset.yAxisID ?? 'y';\n const yScale = chart.scales[yScaleId];\n\n if (!yScale) {\n return;\n }\n\n // Calculate threshold and gradient stop position\n const dataValues = (dataset.data as (number | {x: number; y: number})[])\n .map((d) => (typeof d === 'number' ? d : d.y))\n .filter((v) => Number.isFinite(v));\n\n // Guard: Need at least some data to calculate threshold\n if (dataValues.length === 0) {\n return;\n }\n\n const minVal = Math.min(...dataValues);\n const maxVal = Math.max(...dataValues);\n const thresholdVal = (minVal + maxVal) / 2;\n const thresholdPixel = yScale.getPixelForValue(thresholdVal);\n const range = yScale.bottom - yScale.top;\n\n // Guard: Ensure stop is a finite number between 0 and 1\n let stop = (thresholdPixel - yScale.top) / range;\n if (!Number.isFinite(stop) || range === 0) {\n stop = 0.5; // Fallback to middle if calculation fails\n } else {\n stop = Math.max(0, Math.min(1, stop));\n }\n\n // Extract threshold color variables (used for both fill and border)\n const lowRaw = LINE_GRAPH_GRID_CONFIG.thresholdLowColorVar;\n const highRaw = LINE_GRAPH_GRID_CONFIG.thresholdHighColorVar;\n\n // Helper to create threshold gradient\n const createGradient = (lowAlpha: number, highAlpha: number) => {\n const low = applyAlphaToColor(this, lowRaw, lowAlpha);\n const high = applyAlphaToColor(this, highRaw, highAlpha);\n const grad = ctx.createLinearGradient(0, yScale.top, 0, yScale.bottom);\n grad.addColorStop(0, high);\n grad.addColorStop(stop, high);\n grad.addColorStop(stop, low);\n grad.addColorStop(1, low);\n return grad;\n };\n\n // Create fill gradient (35% alpha) and border gradient (80% alpha)\n const fillGradient = createGradient(0.35, 0.35);\n const borderGradient = createGradient(0.8, 0.8);\n dataset.backgroundColor = fillGradient as unknown as string;\n dataset.borderColor = borderGradient as unknown as string;\n });\n }\n\n // Update external library AFTER render\n override updated(changed: PropertyValues) {\n super.updated(changed);\n\n // Only update if watched properties changed\n if (!this.hasAnyChanged(changed, LINE_GRAPH_WATCHED_PROP_NAMES)) {\n return;\n }\n\n // `computedWidth` / `computedHeight` are the pixel size everything below\n // derives from (`--chart-height`, the slotted scales' height, the padding\n // scale factor). They were only ever refreshed from the wrapper's\n // ResizeObserver, so re-assigning `width` / `height` rebuilt the chart\n // against the *previous* aspect ratio and the new one only took effect on\n // the next container resize (issue #1138).\n //\n // This runs before the `hasLabelPadding` branch below: the two can change\n // in the same update (the tank sets both on its embedded gauge-trend), and\n // taking the label-padding path first would rebuild against a stale\n // derived size. Nothing is lost by going through here instead — a rebuild\n // from `updateComputedDimensions()` goes via `syncScalesAndChart()`, which\n // performs the same `updateScaleProperties()` cascade.\n if (this.hasAnyChanged(changed, LINE_GRAPH_DIMENSION_PROP_NAMES)) {\n // Recreates the chart itself when the derived size actually moved.\n if (this.updateComputedDimensions()) return;\n }\n\n // Only `syncScalesAndChart()` re-cascades to slotted scales, and these are\n // the changes that need it: the two flags decide what a scale renders, and\n // a threshold crossing reaches a plain rebuild in pixel mode.\n const belowThreshold = this.isBelowThreshold();\n const crossedThreshold =\n this.wasBelowThreshold !== undefined &&\n this.wasBelowThreshold !== belowThreshold;\n this.wasBelowThreshold = belowThreshold;\n\n if (\n (changed.has('hasLabelPadding') ||\n changed.has('rangeLabels') ||\n crossedThreshold) &&\n this.hasExternalScales()\n ) {\n this.syncScalesAndChart();\n return;\n }\n\n const needsRecreation = this.hasAnyChanged(\n changed,\n LINE_GRAPH_RECREATE_PROP_NAMES\n );\n\n if (needsRecreation) {\n this.chart?.destroy();\n this.createChart();\n } else {\n this.updateChart();\n }\n }\n\n override async firstUpdated() {\n // Wait for external scales to report dimensions before creating chart\n await this.waitForScaleDimensions();\n\n if (!this.hasExternalScales()) {\n // No external scales, create chart normally\n this.createChart();\n }\n // If we have external scales, chart is created in syncScalesAndChart()\n\n this.themeObserver = observeThemeChanges(() => {\n this.updateChartColors();\n this.updateBorderRadius(); // Border color may change with theme\n });\n this.setupResizeObserver();\n this.setupAspectRatioResizeObserver();\n\n // Setup border radius observer and apply initial styling\n // In instrument mode, skip observer - we use fixed border radius\n if (this.canvasEl) {\n if (!this.instrumentMode) {\n this.borderRadiusObserver = startExternalScaleBorderRadiusObserver(\n this.canvasEl,\n this.updateBorderRadius\n );\n }\n this.updateBorderRadius();\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.chart?.destroy();\n this.themeObserver?.disconnect();\n this.resizeObserver?.disconnect();\n this.aspectRatioResizeObserver?.disconnect();\n this.borderRadiusObserver?.disconnect();\n\n if (this.dimensionUpdateTimer) {\n clearTimeout(this.dimensionUpdateTimer);\n }\n }\n\n /**\n * Crossing MIN_HEIGHT_WITH_LABELS changes the plugin set, so the chart is\n * rebuilt rather than updated.\n */\n private setupResizeObserver() {\n if (!this.canvasEl) return;\n\n this.resizeObserver = observeLabelThreshold(\n this.canvasEl,\n () =>\n (this.canvasEl?.clientHeight ?? 0) >=\n RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS &&\n (this.canvasEl?.clientWidth ?? 0) >=\n RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS,\n {\n rebuild: () => {\n this.chart?.destroy();\n this.createChart();\n },\n update: () => this.updateChart(),\n }\n );\n }\n\n /**\n * Setup resize observer for fixed aspect ratio scaling.\n * Observes the wrapper element and recalculates dimensions when parent size changes.\n */\n private setupAspectRatioResizeObserver() {\n const wrapper = this.renderRoot.querySelector('.wrapper');\n if (!wrapper) return;\n\n // Initialize computed dimensions\n this.updateComputedDimensions();\n\n this.aspectRatioResizeObserver = new ResizeObserver(() => {\n if (!this.fixedAspectRatioScaling) return;\n this.updateComputedDimensions();\n });\n\n this.aspectRatioResizeObserver.observe(wrapper);\n }\n\n /**\n * Refresh `computedWidth` / `computedHeight`, the derived pixel size the\n * chart and its slotted scales are laid out from.\n *\n * In pixel mode they simply mirror `width` / `height`. Only in\n * `fixedAspectRatioScaling` mode are they derived — from the wrapper's\n * measured width and the aspect ratio the `width` / `height` pair defines —\n * and only then can this rebuild the chart.\n *\n * @returns `true` when the change was significant enough that the chart was\n * rebuilt here, so the caller must not rebuild it a second time.\n */\n private updateComputedDimensions(): boolean {\n if (!this.fixedAspectRatioScaling) {\n // In pixel mode, use width/height directly\n this.computedWidth = this.width;\n this.computedHeight = this.height;\n return false;\n }\n\n const wrapper = this.renderRoot.querySelector('.wrapper') as HTMLElement;\n if (!wrapper) return false;\n\n // Get parent's available width\n const parentWidth = wrapper.clientWidth;\n if (parentWidth <= 0) return false;\n\n // Calculate aspect ratio from width/height properties\n const aspectRatio = this.width / this.height;\n\n // Use parent width as actual width, calculate height from aspect ratio\n const newWidth = parentWidth;\n const newHeight = Math.round(parentWidth / aspectRatio);\n\n // Only update if dimensions changed\n if (this.computedWidth !== newWidth || this.computedHeight !== newHeight) {\n this.computedWidth = newWidth;\n this.computedHeight = newHeight;\n\n // Update external scales and recreate chart with new dimensions\n // Note: syncScalesAndChart() handles chart destruction and creation internally,\n // so we only call createChart() directly when there are no external scales.\n if (this.hasExternalScales()) {\n // syncScalesAndChart() bails without rebuilding when a sync is already\n // in flight or the effective chart area is degenerate; reporting its\n // real outcome keeps the caller's own rebuild as the fallback.\n return this.syncScalesAndChart();\n } else if (this.chart) {\n // No external scales - just recreate chart\n this.chart.destroy();\n this.createChart();\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the effective width for chart rendering.\n * Returns computed width when fixedAspectRatioScaling is true, otherwise the width property.\n */\n protected getEffectiveWidth(): number {\n return this.fixedAspectRatioScaling ? this.computedWidth : this.width;\n }\n\n /**\n * Get the effective height for chart rendering.\n * Returns computed height when fixedAspectRatioScaling is true, otherwise the height property.\n */\n protected getEffectiveHeight(): number {\n return this.fixedAspectRatioScaling ? this.computedHeight : this.height;\n }\n\n /**\n * Get the scale factor for proportional scaling when fixedAspectRatioScaling is true.\n * Returns 1.0 when not in fixed aspect ratio mode.\n * The scale factor is based on computed width vs reference width (the width property).\n */\n protected getScaleFactor(): number {\n if (!this.fixedAspectRatioScaling) {\n return 1.0;\n }\n // Scale factor is based on computed width vs the reference width (width property)\n // The width property defines the \"design\" or \"reference\" size\n return this.computedWidth / this.width;\n }\n\n /**\n * Build a complete dataset configuration with all styling properties.\n * Handles both new datasets (from values array) and existing datasets (normalization).\n *\n * @param data - Either numeric values array or existing dataset to normalize\n * @param index - Dataset index for color cycling\n * @param chartColors - Color palette array\n * @param totalCount - Total number of datasets (used for stacked divider logic)\n * @returns Fully configured Chart.js dataset\n */\n protected buildDataset(\n data:\n | number[]\n | {x: number; y: number}[]\n | ChartDataset<'line', ChartLinePoint[]>,\n index: number,\n chartColors: string[],\n totalCount = 1\n ): ChartDataset<'line', ChartLinePoint[]> {\n const currentColor = chartColors[index % chartColors.length];\n\n // Raw input is an array (values or points); anything else is an existing dataset\n const existingDataset = Array.isArray(data)\n ? null\n : (data as ChartDataset<'line', ChartLinePoint[]>);\n const values = Array.isArray(data)\n ? (data as number[] | {x: number; y: number}[])\n : null;\n\n const borderColor = existingDataset?.borderColor ?? currentColor;\n const fillFlag = existingDataset?.fill ?? this.shouldApplyFill();\n const tension = this.lineMode === 'smooth' ? this.DEFAULT_TENSION : 0;\n\n // For stacked mode, add divider lines between datasets (except the topmost one)\n const isStacked = this.shouldStack() && this.getFillMode() !== 'threshold';\n const needsDivider = isStacked && index < totalCount - 1;\n\n // Calculate backgroundColor immediately instead of deferring to applyFillModes()\n // This prevents flicker when chart is recreated multiple times during resize\n let backgroundColor: string = 'transparent';\n const fillMode = this.getFillMode();\n\n if (fillFlag && fillMode) {\n const nextColor = chartColors[(index + 1) % chartColors.length];\n\n if (fillMode === 'solid') {\n backgroundColor = String(borderColor);\n } else if (fillMode === 'semitransparent') {\n backgroundColor = applyAlphaToColor(this, nextColor, 0.5);\n } else if (fillMode === 'threshold') {\n // For threshold, we'll still need gradients from applyFillModes\n // but set a reasonable default to avoid transparent flash\n backgroundColor = applyAlphaToColor(this, nextColor, 0.5);\n }\n }\n\n const result = {\n ...(existingDataset || {}),\n data: existingDataset?.data ?? values!,\n yAxisID: existingDataset?.yAxisID ?? this.primaryYAxisId,\n borderColor,\n backgroundColor,\n borderWidth: existingDataset?.borderWidth ?? 2,\n showLine: existingDataset?.showLine ?? true,\n tension: existingDataset?.tension ?? tension,\n pointRadius:\n existingDataset?.pointRadius ??\n (this.showPoints ? this.POINT_RADIUS : 0),\n pointBackgroundColor: existingDataset?.pointBackgroundColor ?? '#fff',\n pointBorderColor: existingDataset?.pointBorderColor ?? borderColor,\n pointBorderWidth: existingDataset?.pointBorderWidth ?? 2,\n stepped: existingDataset?.stepped ?? this.lineMode === 'stepped',\n // Use 'start' to fill from chart bottom, not 'origin' (y=0)\n fill: fillFlag ? 'start' : false,\n spanGaps: existingDataset?.spanGaps ?? true,\n // Add segment styling for stacked divider lines\n ...(needsDivider && {\n segment: {\n borderColor: getCssVariableValue(\n this,\n LINE_GRAPH_GRID_CONFIG.stackedDividerColorVar\n ),\n borderWidth: 1,\n },\n }),\n };\n\n return result as ChartDataset<'line', ChartLinePoint[]>;\n }\n\n /**\n * Create threshold mode datasets: invisible baseline + main dataset with\n * above/below fills. Accepts plain values (category mode) or {x, y} points\n * (time/number mode); the baseline mirrors the input x-positions.\n */\n protected createThresholdDatasets(\n values: number[] | {x: number; y: number}[],\n chartColors: string[]\n ): ChartDataset<'line', ChartLinePoint[]>[] {\n const yValues = values\n .map((v) => (typeof v === 'number' ? v : v.y))\n .filter((n) => Number.isFinite(n));\n const minV = yValues.length ? Math.min(...yValues) : 0;\n const maxV = yValues.length ? Math.max(...yValues) : 100;\n const threshold = (minV + maxV) / 2;\n const baselineData: ChartLinePoint[] = values.map((v) =>\n typeof v === 'number' ? threshold : {x: v.x, y: threshold}\n );\n\n const lowRaw = LINE_GRAPH_GRID_CONFIG.thresholdLowColorVar;\n const highRaw = LINE_GRAPH_GRID_CONFIG.thresholdHighColorVar;\n const highFill = applyAlphaToColor(this, highRaw, 0.35);\n const lowFill = applyAlphaToColor(this, lowRaw, 0.35);\n\n const baselineDataset: ChartDataset<'line', ChartLinePoint[]> = {\n label: 'threshold-baseline',\n data: baselineData,\n yAxisID: this.primaryYAxisId,\n borderColor: 'transparent',\n backgroundColor: 'transparent',\n borderWidth: 0,\n pointRadius: 0,\n showLine: false,\n fill: false,\n spanGaps: true,\n };\n\n const main = this.buildDataset(values, 0, chartColors);\n (main as unknown as Record<string, unknown>).fill = {\n target: 0,\n above: highFill,\n below: lowFill,\n };\n // Border gradient will be set by applyFillModes after chart scales are ready\n main.borderWidth = 2;\n\n return [baselineDataset, main];\n }\n\n /**\n * Prepare normalized datasets for multi-series charts.\n * In time/number mode every point's x is normalized (epoch ms / number)\n * so strings, Dates and Temporal objects position correctly.\n */\n protected prepareMultiSeriesDatasets() {\n const defaultPalette =\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS;\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n defaultPalette\n );\n\n // Normalize first, then warn once per assignment with the aggregate\n // count across ALL series — warning inside the per-dataset loop would\n // either flood the console or (with ref-based dedup) silently swallow\n // failures in every series after the first.\n const normalized = this.datasets!.map((ds) => this.normalizeDatasetX(ds));\n if (this.isNumericXAxis) {\n this.warnOnInvalidX(\n normalized.flatMap((ds) =>\n (ds.data ?? []).map((pt) =>\n pt && typeof pt === 'object' ? (pt.x as number) : 0\n )\n ),\n this.datasets\n );\n }\n\n const totalCount = this.datasets!.length;\n return normalized.map((ds, i) =>\n this.buildDataset(ds, i, chartColors, totalCount)\n );\n }\n\n /** @internal - Return a copy of the dataset with normalized point x-values. */\n private normalizeDatasetX(\n ds: ChartDataset<'line', ChartLinePoint[]>\n ): ChartDataset<'line', ChartLinePoint[]> {\n if (!this.isNumericXAxis || !ds.data) return ds;\n const data = ds.data.map((pt) =>\n pt && typeof pt === 'object' && 'x' in pt\n ? {...pt, x: normalizeXValue(pt.x, this.xValueMode)}\n : pt\n );\n return {...ds, data};\n }\n\n /**\n * Prepare datasets for single-series charts.\n * Category mode: labels + numeric values (unchanged legacy path).\n * Time/number mode: normalized {x, y} points on a linear scale.\n * Handles both regular and threshold fill modes.\n */\n protected prepareSingleSeriesDatasets() {\n const defaultPalette =\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS;\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n defaultPalette\n );\n const fill = this.shouldApplyFill();\n const fillMode = this.getFillMode();\n\n if (this.isNumericXAxis) {\n const points = this.data.map((d) => ({\n x: normalizeXValue(d.x ?? d.label ?? NaN, this.xValueMode),\n y: d.value,\n }));\n this.warnOnInvalidX(\n points.map((p) => p.x),\n this.data\n );\n const datasets =\n fill && fillMode === 'threshold'\n ? this.createThresholdDatasets(points, chartColors)\n : [this.buildDataset(points, 0, chartColors)];\n return {datasets, labels: [] as (string | number)[]};\n }\n\n const values = this.data.map((d) => d.value);\n const labels = this.data.map((d) => d.label ?? String(d.x ?? ''));\n\n const datasets =\n fill && fillMode === 'threshold'\n ? this.createThresholdDatasets(values, chartColors)\n : [this.buildDataset(values, 0, chartColors)];\n\n return {datasets, labels};\n }\n\n /**\n * One padding source for the Chart.js layout and the slotted scales: two\n * sources painted the canvas over a scale and inset a scale inside a chart.\n */\n private computeChartPadding(): {\n top: number;\n right: number;\n bottom: number;\n left: number;\n } {\n const isTooSmall = this.isBelowThreshold();\n // Get scale factor for proportional scaling in fixed aspect ratio mode\n const scaleFactor = this.getScaleFactor();\n\n const defaultPaddingScaled = !this.hasLabelPadding\n ? 0\n : this.fixedAspectRatioScaling\n ? Math.round(CHART_DIMENSIONS.CANVAS_PADDING * scaleFactor)\n : CHART_DIMENSIONS.CANVAS_PADDING;\n\n const {y: yTexts, x: xTexts} = this.refreshRangeLabels();\n const context = this.canvasEl?.getContext('2d');\n const gutters =\n (yTexts.length || xTexts.length) && context\n ? measureRangeLabelGutters(\n context,\n this.rangeLabelFont(),\n yTexts,\n xTexts\n )\n : {side: 0, bottom: 0};\n\n const scalePadding = this.calculatePaddingFromScales();\n const freeSide = (side: 'top' | 'right' | 'bottom' | 'left'): number => {\n if (!isTooSmall) return defaultPaddingScaled;\n if (side === 'bottom') return gutters.bottom;\n return side === this.ySide ? gutters.side : 0;\n };\n const padding = {\n top: this.externalScaleDimensions.has('top')\n ? scalePadding.top\n : freeSide('top'),\n right: this.externalScaleDimensions.has('right')\n ? scalePadding.right\n : freeSide('right'),\n bottom: this.externalScaleDimensions.has('bottom')\n ? scalePadding.bottom\n : freeSide('bottom'),\n left: this.externalScaleDimensions.has('left')\n ? scalePadding.left\n : freeSide('left'),\n };\n\n return padding;\n }\n\n /**\n * Get Chart.js options with dynamic sizing and padding\n */\n protected getChartOptions(): ChartOptions<'line'> {\n // Use effective dimensions (computed when fixedAspectRatioScaling=true)\n const effectiveWidth = this.getEffectiveWidth();\n const effectiveHeight = this.getEffectiveHeight();\n\n // Determine if chart is too small for labels\n const isTooSmall =\n effectiveWidth < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS ||\n effectiveHeight < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n\n const padding = this.computeChartPadding();\n\n // Set CSS variables for wrapper and canvas sizing\n if (this.fixedAspectRatioScaling) {\n // In responsive mode, use 100% width, computed height\n this.style.setProperty('--chart-width', '100%');\n this.style.setProperty('--chart-height', `${effectiveHeight}px`);\n } else {\n // In pixel mode, use width/height directly\n this.style.setProperty('--chart-width', `${this.width}px`);\n this.style.setProperty('--chart-height', `${this.height}px`);\n }\n\n // Compute reference timestamp for time-based x-axis\n const refTs = this.computeTimeReference();\n\n // Force showTickMarks=false when external scales are present\n const effectiveShowTickMarks = this.hasExternalScales()\n ? false\n : this.showTickMarks;\n\n return {\n responsive: true,\n maintainAspectRatio: false, // Use explicit width/height instead\n layout: {\n padding,\n },\n plugins: {\n legend: {\n display: false,\n labels: {\n generateLabels: () => [], // Prevent Chart.js from generating labels internally\n },\n onClick: () => {}, // Disable legend click handler\n },\n tooltip: {\n ...getChartTooltipOptions(this),\n enabled: !isTooSmall,\n callbacks: {\n title: () => '',\n label: (context) => {\n const value =\n typeof context.parsed === 'object' && context.parsed !== null\n ? (context.parsed as {y: number}).y\n : (context.parsed as number);\n const numericValue = formatChartNumber(value, 1, false, 0);\n const unit = this.unit ? `${this.unit}` : '';\n let label = context.label ?? '';\n if (this.isNumericXAxis) {\n const x =\n typeof context.parsed === 'object' && context.parsed !== null\n ? (context.parsed as {x: number}).x\n : NaN;\n const relativeTo =\n this.timeDisplay === TimeDisplay.minutes ? refTs : undefined;\n label = formatXValue(x, this.xValueMode, relativeTo);\n }\n return `${label} ${numericValue}${unit}`;\n },\n },\n },\n },\n animation: false,\n scales: this.buildScalesConfig(refTs, isTooSmall, effectiveShowTickMarks),\n };\n }\n\n /**\n * Compute reference timestamp for time axis formatting.\n * Returns earliest timestamp for 'date' mode, latest for 'minutes' mode.\n * A pinned x range supplies the reference instead, so the axis edge stays\n * the reference while the data has not reached it yet.\n */\n private computeTimeReference(): number | undefined {\n if (this.xAxisType !== XAxisType.time) return undefined;\n\n const pinned =\n this.timeDisplay === TimeDisplay.minutes\n ? this.xAxis?.max\n : this.xAxis?.min;\n if (pinned !== undefined && Number.isFinite(pinned)) return pinned;\n\n const timestamps: number[] = [];\n\n // Collect timestamps from datasets\n if (this.datasets?.length) {\n this.datasets.forEach((ds) => {\n if (!ds.data) return;\n ds.data.forEach((pt) => {\n if (pt && typeof pt === 'object' && 'x' in pt) {\n const ts = normalizeXValue(pt.x, XValueMode.time);\n if (Number.isFinite(ts)) timestamps.push(ts);\n }\n });\n });\n } else if (this.data?.length) {\n // Collect timestamps from single-series data items\n this.data.forEach((d) => {\n const ts = normalizeXValue(d.x ?? d.label ?? NaN, XValueMode.time);\n if (Number.isFinite(ts)) timestamps.push(ts);\n });\n }\n\n // Collect timestamps from labels if no dataset timestamps found\n if (!timestamps.length && this.labels?.length) {\n this.labels.forEach((l) => {\n if (typeof l === 'string') {\n const ts = new Date(l).getTime();\n if (Number.isFinite(ts)) timestamps.push(ts);\n }\n });\n }\n\n return timestamps.length\n ? this.timeDisplay === 'minutes'\n ? Math.max(...timestamps)\n : Math.min(...timestamps)\n : undefined;\n }\n\n /**\n * Build Chart.js scale configuration with theme-aware styling.\n * Applies CSS variables for grid colors, tick colors, and label typography.\n *\n * @param minX - Reference timestamp for time-based x-axis (used for 'minutes' display)\n * @param isTooSmall - Whether chart is below 192px threshold (hides ticks when true)\n * @param showTickMarks - Whether to show tick marks (overridden to false when external scales present)\n * @returns Configured scales object for Chart.js options\n */\n protected buildScalesConfig(\n minX?: number,\n isTooSmall = false,\n showTickMarks = true\n ) {\n // Build scales typed for ChartOptions<'line'>\n // If we don't have a date adapter available, fall back to numeric linear scale\n // by converting date strings to timestamps before chart creation. We still\n // render formatted tick labels for readability.\n // Read CSS variables for styling\n const gridColor = getCssVariableValue(\n this,\n LINE_GRAPH_GRID_CONFIG.gridColorVar\n );\n const tickColor = getCssVariableValue(\n this,\n LINE_GRAPH_GRID_CONFIG.tickColorVar\n );\n const fontFamily = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontFamily\n );\n const fontSize = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontSizeVar\n );\n const fontWeight = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontWeightVar\n );\n const fontColor = getCssVariableValue(\n this,\n LINE_GRAPH_LABEL_CONFIG.fontColorVar\n );\n\n // Extract common values used for both x and y axes.\n // When hasLabelPadding=false the chart renders edge-to-edge, so labels are\n // force-hidden to prevent clipping.\n const showLabels = showTickMarks && !isTooSmall && this.hasLabelPadding;\n const showTicks = showTickMarks && !isTooSmall && this.hasLabelPadding;\n const fontConfig = {family: fontFamily, size: fontSize, weight: fontWeight};\n\n const x = {\n type: this.xAxisType === XAxisType.category ? 'category' : 'linear',\n offset: false, // Always edge-to-edge (no padding on x-axis)\n grace: 0, // No extra margin\n bounds: 'data', // Use data bounds for edge-to-edge rendering\n // A category axis has no numeric range to pin.\n min: this.isNumericXAxis ? this.xAxis?.min : undefined,\n max: this.isNumericXAxis ? this.xAxis?.max : undefined,\n grid: {\n display: this.showGrid && this.showGridX,\n color: gridColor,\n offset: false,\n drawTicks: showTicks,\n },\n ticks: {\n display: showLabels,\n color: fontColor,\n font: fontConfig,\n maxRotation: 0, // Keep labels horizontal (no rotation)\n minRotation: 0, // Keep labels horizontal (no rotation)\n maxTicksLimit: this.xTicksLimit,\n stepSize: this.xStepSize,\n callback: (value: unknown) => {\n if (!this.isNumericXAxis) return String(value);\n const n = Number(value);\n if (!Number.isFinite(n)) return String(value);\n const relativeTo =\n this.timeDisplay === TimeDisplay.minutes ? minX : undefined;\n return formatXValue(n, this.xValueMode, relativeTo);\n },\n },\n border: {\n display: showLabels,\n color: tickColor,\n },\n } as unknown;\n\n // Build y-axis scales configuration\n const yAxesConfig = this.yAxes?.length\n ? this.yAxes.map((axis, i) => ({\n id: axis.id ?? `y${i}`,\n position: axis.position ?? ('left' as 'left' | 'right'),\n min: axis.min,\n max: axis.max,\n gridDisplay: axis.grid ?? (this.showGrid && this.showGridY),\n }))\n : [\n {\n id: 'y',\n position: this.yAxisPosition,\n min: undefined,\n max: undefined,\n gridDisplay: this.showGrid && this.showGridY,\n },\n ];\n\n const scalesRecord: Record<string, unknown> = {x};\n\n yAxesConfig.forEach(({id, position, min, max, gridDisplay}) => {\n scalesRecord[id] = {\n type: 'linear',\n display: true,\n position,\n stacked: this.shouldStack() && this.getFillMode() !== 'threshold',\n grace: isTooSmall ? 0 : undefined,\n bounds: isTooSmall ? 'data' : 'ticks',\n grid: {\n display: gridDisplay,\n color: gridColor,\n drawTicks: showTicks,\n },\n ticks: {\n display: showLabels,\n color: fontColor,\n font: fontConfig,\n maxTicksLimit: this.yTicksLimit,\n stepSize: this.yStepSize,\n },\n border: {\n display: showLabels,\n color: tickColor,\n },\n min,\n max,\n };\n });\n\n return scalesRecord as ChartOptions<'line'>['scales'];\n }\n\n /**\n * Prepare chart data and labels for both single and multi-series modes\n */\n private prepareChartDataAndLabels() {\n if (this.datasets?.length) {\n return {\n datasets: this.prepareMultiSeriesDatasets(),\n labels: (this.labels ?? []) as (string | number)[],\n };\n }\n return this.prepareSingleSeriesDatasets();\n }\n\n private createChart() {\n // Guard: Verify canvas exists and is connected to DOM\n if (!this.canvasEl || !this.canvasEl.isConnected) return;\n\n const ctx = this.canvasEl.getContext('2d');\n if (!ctx) return;\n\n // Destroy existing chart instance to prevent canvas reuse errors\n if (this.chart) {\n this.chart.destroy();\n this.chart = undefined;\n }\n\n const {datasets, labels} = this.prepareChartDataAndLabels();\n\n this.chart = new Chart(ctx, {\n type: 'line',\n data: {labels, datasets},\n options: this.getChartOptions(),\n plugins: [\n ...(this.borderRadiusPosition ? [this.createBorderPlugin()] : []),\n ...(this.rangeLabels !== RangeLabels.none\n ? [this.createRangeLabelsPlugin()]\n : []),\n ],\n } as ChartConfiguration<'line'>);\n\n // Defer legend update to next tick to ensure Chart.js metadata is initialized\n requestAnimationFrame(() => this.updateLegend());\n this.applyFillModes();\n this.syncSlottedScaleRanges();\n }\n\n private updateChart() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const {datasets, labels} = this.prepareChartDataAndLabels();\n\n this.chart.data.labels = labels;\n this.chart.data.datasets = datasets as unknown as ChartDataset<'line'>[];\n\n // Update options (chart.options is always defined after chart creation)\n Object.assign(this.chart.options, this.getChartOptions());\n\n this.applyFillModes();\n this.chart.update();\n this.syncSlottedScaleRanges();\n\n // Update legend after chart update completes to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update only chart colors without recalculating layout\n * Used by theme observer for efficient theme changes\n */\n private updateChartColors() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n // Re-apply fill modes which will update gradients for threshold mode\n this.applyFillModes();\n\n // Update without animation for instant theme change\n this.chart.update('none');\n\n // Defer legend update to next frame to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update the legend HTML content\n */\n private updateLegend() {\n // Guard: Check if legend should be shown and chart is ready\n if (!this.legend || !this.legendDiv || !this.chart) return;\n\n // Guard: Check if chart has datasets\n if (!this.chart.data.datasets || this.chart.data.datasets.length === 0) {\n this.legendDiv.innerHTML = '';\n return;\n }\n\n try {\n const legendItems = this.chart.data.datasets\n .map((ds, i) => {\n const meta = this.chart!.getDatasetMeta(i);\n\n // Guard: Check if metadata and controller are available\n if (!meta || !meta.controller) {\n return null;\n }\n\n const style = meta.controller.getStyle(0, false);\n const dataset = ds as ChartDataset<\n 'line',\n (number | {x: number; y: number})[]\n >;\n\n return {\n fillStyle: (dataset.borderColor ??\n style.borderColor ??\n '') as string,\n label: (dataset.label as string) || `Series ${i + 1}`,\n value: '',\n unit: '',\n };\n })\n .filter((item) => item !== null);\n\n // Only update legend if we have valid items\n if (legendItems.length > 0) {\n const legendHTML = generateLegendHTML(legendItems);\n this.legendDiv.innerHTML = legendHTML;\n }\n } catch (error) {\n console.debug(\n '[chart-line-base] updateLegend: error generating legend HTML',\n error\n );\n // Silent failure - don't throw, just skip legend update this time\n }\n }\n\n override render() {\n return html`\n <div class=\"wrapper\">\n <div class=\"canvas-and-slots-container\">\n <slot\n name=\"top-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <slot\n name=\"bottom-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <slot\n name=\"left-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <slot\n name=\"right-scale\"\n @slotchange=${this.handleSlotChange}\n @scale-dimensions-changed=${this.handleScaleDimensionsChanged}\n ></slot>\n <canvas></canvas>\n </div>\n\n ${this.legend ? html`<div class=\"legend\"></div>` : ''}\n </div>\n `;\n }\n\n static override styles = [\n unsafeCSS(componentStyle),\n unsafeCSS(chartCommonStyle),\n unsafeCSS(chartLegendStyle),\n unsafeCSS(chartDebugStyle),\n ];\n}\n"],"names":["XAxisType","YAxisPosition","LineMode","TimeDisplay","RangeLabels","r","axis","datasets"],"mappings":"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"}