@wick-charts/vue 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +2 -0
  2. package/dist/BandSeries.vue.js +43 -32
  3. package/dist/BarSeries.vue.js +44 -33
  4. package/dist/CandlestickSeries.vue.js +24 -23
  5. package/dist/ChartContainer.vue.js +1 -1
  6. package/dist/HeatmapSeries.vue.js +21 -20
  7. package/dist/LineSeries.vue.js +43 -32
  8. package/dist/PieSeries.vue.js +25 -24
  9. package/dist/composables.js +63 -36
  10. package/dist/core/dist/axis/dom-labels.js +64 -53
  11. package/dist/core/dist/chart/badge-animator.js +38 -28
  12. package/dist/core/dist/chart/options.js +1 -1
  13. package/dist/core/dist/chart/y-target.js +38 -32
  14. package/dist/core/dist/chart.js +852 -709
  15. package/dist/core/dist/data/decimation.js +52 -51
  16. package/dist/core/dist/data/store.js +38 -20
  17. package/dist/core/dist/data/sync.js +97 -59
  18. package/dist/core/dist/navigator/controller.js +11 -11
  19. package/dist/core/dist/perf/perf-hud.js +3 -3
  20. package/dist/core/dist/scales/tick-tracker.js +2 -1
  21. package/dist/core/dist/scales/time-ticks.js +99 -0
  22. package/dist/core/dist/scales/x-scale.js +33 -27
  23. package/dist/core/dist/series/band.js +83 -83
  24. package/dist/core/dist/series/bar.js +240 -211
  25. package/dist/core/dist/series/base-multi-layer.js +288 -240
  26. package/dist/core/dist/series/candlestick.js +168 -168
  27. package/dist/core/dist/series/line.js +545 -455
  28. package/dist/core/dist/snapshots.js +109 -86
  29. package/dist/core/dist/utils/point.js +4 -0
  30. package/dist/core/dist/utils/time.js +42 -26
  31. package/dist/index.d.ts +67 -28
  32. package/dist/ui/InfoBar.vue.js +69 -69
  33. package/dist/ui/NumberFlow.vue.js +36 -27
  34. package/dist/ui/Tooltip.vue.js +128 -131
  35. package/dist/ui/YLabel.vue.js +47 -47
  36. package/package.json +2 -2
  37. package/src/BandSeries.vue +20 -5
  38. package/src/BarSeries.vue +20 -5
  39. package/src/CandlestickSeries.vue +5 -4
  40. package/src/ChartContainer.vue +15 -9
  41. package/src/HeatmapSeries.vue +5 -4
  42. package/src/LineSeries.vue +20 -5
  43. package/src/PieSeries.vue +6 -5
  44. package/src/composables.ts +64 -1
  45. package/src/ui/InfoBar.vue +11 -3
  46. package/src/ui/NumberFlow.vue +17 -3
  47. package/src/ui/Tooltip.vue +23 -12
  48. package/src/ui/YLabel.vue +28 -27
@@ -1,100 +1,117 @@
1
- import { Animator as nt } from "./animation/animator.js";
2
- import { AnimationConfig as at, DEFAULT_LINE_PULSE as ot } from "./animation/config.js";
3
- import { easeOutCubic as W } from "./animation/easing.js";
4
- import { prefersReducedMotion as ht } from "./animation/reduced-motion.js";
5
- import { createViewportEngine as lt } from "./animation/viewport-engine.js";
6
- import { CanvasManager as ct } from "./canvas-manager.js";
7
- import { resolveEdgeAnchorValue as dt, drawEdgeIndicators as ut, resolveEdgeBoundary as mt } from "./chart/edge-indicators.js";
8
- import { computeFitToData as ft } from "./chart/fit-to-data.js";
9
- import { getLastValue as gt, getPreviousClose as pt, getStackedLastValue as yt } from "./chart/last-value.js";
10
- import { resolveFade as Y, resolveMaxVisibleBars as xt, resolvePadding as E, resolvePerfOptions as vt, isSameHorizontalPadding as B } from "./chart/options.js";
11
- import { computePan as St, computeZoom as bt } from "./chart/pan-zoom-math.js";
12
- import { warnUnplottableBounds as C, assertStackingFitsScale as L, warnScaleSideTaken as kt, warnUnknownScale as wt, warnStackingOffScale as Tt, warnUnplottableValues as At } from "./chart/scale-guards.js";
13
- import { StreamingCadence as Mt } from "./chart/streaming-cadence.js";
14
- import { computeStreamingTarget as Pt } from "./chart/streaming-target.js";
15
- import { resolvePaddingTime as N } from "./chart/viewport-padding.js";
16
- import { assertSeriesFitsXAxis as Ct, warnXMisfit as Lt, warnXTimeMixed as Dt, warnTimeOnlyFeature as Rt, warnXTypeChange as It } from "./chart/x-guards.js";
17
- import { fromScaleSpace as Ht, computeTargetYRange as Vt, resolveYTarget as zt } from "./chart/y-target.js";
18
- import { renderCrosshair as Ft } from "./components/crosshair.js";
19
- import { renderGrid as X } from "./components/grid.js";
20
- import { renderMarker as Ot } from "./components/marker.js";
21
- import { renderReferenceLine as $t } from "./components/reference-line.js";
22
- import { resolveTimeRegionColors as Wt, renderTimeRegion as Yt } from "./components/time-region.js";
23
- import { EventEmitter as Et } from "./events.js";
24
- import { InteractionHandler as Bt } from "./interactions/handler.js";
25
- import { RenderScheduler as Z } from "./render-scheduler.js";
26
- import { XScale as Nt } from "./scales/x-scale.js";
27
- import { YScale as U, isPlottableOn as _ } from "./scales/y-scale.js";
28
- import { resolveSeriesDefinition as Xt } from "./series/definition.js";
29
- import { isTimeSeriesRenderer as v } from "./series/types.js";
30
- import { catppuccin as Zt } from "./theme/themes/catppuccin.js";
31
- import { deepEqual as Ut } from "./utils/deep-equal.js";
32
- import { clamp as _t } from "./utils/math.js";
33
- import { crispLineWidth as Gt, crispCenterOffset as Kt } from "./utils/pixel-grid.js";
34
- import { pointValue as G, isBandPoint as jt } from "./utils/point.js";
35
- import { normalizeTime as k, detectInterval as qt } from "./utils/time.js";
36
- const Jt = 200, Qt = 1500, te = 48, K = 12, D = 9, ee = ["left", "right"], ie = { entries: [], isAnimating: !1 }, se = [], re = ["left"], ne = ["right"], ae = 55;
37
- function j(p, t) {
1
+ import { Animator as gt } from "./animation/animator.js";
2
+ import { AnimationConfig as pt, DEFAULT_LINE_PULSE as yt } from "./animation/config.js";
3
+ import { easeOutCubic as X } from "./animation/easing.js";
4
+ import { prefersReducedMotion as xt } from "./animation/reduced-motion.js";
5
+ import { createViewportEngine as vt } from "./animation/viewport-engine.js";
6
+ import { CanvasManager as St } from "./canvas-manager.js";
7
+ import { resolveEdgeAnchorValue as bt, drawEdgeIndicators as kt, resolveEdgeBoundary as Tt } from "./chart/edge-indicators.js";
8
+ import { computeFitToData as Z } from "./chart/fit-to-data.js";
9
+ import { getLastValue as wt, getPreviousClose as Mt, getStackedLastValue as At } from "./chart/last-value.js";
10
+ import { resolveFade as _, resolveMaxVisibleBars as Pt, resolvePadding as U, resolvePerfOptions as Ct, isSameHorizontalPadding as G } from "./chart/options.js";
11
+ import { computePan as Lt, computeZoom as It } from "./chart/pan-zoom-math.js";
12
+ import { warnUnplottableBounds as D, assertStackingFitsScale as R, warnScaleSideTaken as Dt, warnUnknownScale as Rt, warnStackingOffScale as Vt, warnUnplottableValues as Ht } from "./chart/scale-guards.js";
13
+ import { StreamingCadence as Nt } from "./chart/streaming-cadence.js";
14
+ import { computeStreamingTarget as Ft } from "./chart/streaming-target.js";
15
+ import { resolvePaddingTime as j } from "./chart/viewport-padding.js";
16
+ import { assertSeriesFitsXAxis as Wt, warnXMisfit as $t, warnXTimeMixed as zt, warnTimeOnlyFeature as Ot, warnXTypeChange as Yt } from "./chart/x-guards.js";
17
+ import { fromScaleSpace as Et, computeTargetYRange as Bt, resolveYTarget as Xt, widenFlatRange as Zt } from "./chart/y-target.js";
18
+ import { renderCrosshair as _t } from "./components/crosshair.js";
19
+ import { renderGrid as K } from "./components/grid.js";
20
+ import { renderMarker as Ut } from "./components/marker.js";
21
+ import { renderReferenceLine as Gt } from "./components/reference-line.js";
22
+ import { resolveTimeRegionColors as jt, renderTimeRegion as Kt } from "./components/time-region.js";
23
+ import { EventEmitter as qt } from "./events.js";
24
+ import { InteractionHandler as Jt } from "./interactions/handler.js";
25
+ import { RenderScheduler as q } from "./render-scheduler.js";
26
+ import { XScale as Qt } from "./scales/x-scale.js";
27
+ import { YScale as J, isPlottableOn as Q } from "./scales/y-scale.js";
28
+ import { resolveSeriesDefinition as te } from "./series/definition.js";
29
+ import { isTimeSeriesRenderer as S } from "./series/types.js";
30
+ import { catppuccin as ee } from "./theme/themes/catppuccin.js";
31
+ import { deepEqual as ie } from "./utils/deep-equal.js";
32
+ import { clamp as se } from "./utils/math.js";
33
+ import { crispLineWidth as re, crispCenterOffset as ne } from "./utils/pixel-grid.js";
34
+ import { pointValue as tt, isBandPoint as ae } from "./utils/point.js";
35
+ import { normalizeTime as k, detectInterval as V } from "./utils/time.js";
36
+ const oe = 200, he = 1500, le = 48, et = 12, H = 9, ce = ["left", "right"], de = { entries: [], isAnimating: !1 }, ue = [], me = ["left"], fe = ["right"], ge = 55, it = 2e3, st = 20;
37
+ function A(d) {
38
+ return Number.isInteger(d) && d >= 2;
39
+ }
40
+ function pe(d) {
41
+ if (typeof d == "number") return A(d) ? d : void 0;
42
+ if (!(d !== void 0 && "bars" in d && !A(d.bars)))
43
+ return d;
44
+ }
45
+ function ye(d) {
46
+ return typeof d == "object" && "to" in d;
47
+ }
48
+ function rt(d, t) {
38
49
  return {
39
- yScale: p,
50
+ yScale: d,
40
51
  bounds: { min: t?.min, max: t?.max },
41
52
  range: { min: 0, max: 0 },
42
53
  prevMin: Number.NaN,
43
- prevMax: Number.NaN
54
+ prevMax: Number.NaN,
55
+ paintedMin: Number.NaN,
56
+ paintedMax: Number.NaN
44
57
  };
45
58
  }
46
- function q(p) {
47
- return p === "left" ? "right" : "left";
59
+ function nt(d) {
60
+ const t = d.range.min !== d.paintedMin || d.range.max !== d.paintedMax;
61
+ return d.paintedMin = d.range.min, d.paintedMax = d.range.max, t;
62
+ }
63
+ function at(d) {
64
+ return d === "left" ? "right" : "left";
48
65
  }
49
- function J(p, t) {
50
- return p === void 0 || p === "auto" ? !1 : !(typeof p == "number" && !t.isPlottable(p));
66
+ function ot(d, t) {
67
+ return d === void 0 || d === "auto" ? !1 : !(typeof d == "number" && !t.isPlottable(d));
51
68
  }
52
- let oe = 0, he = 0, le = 0, ce = 0;
53
- function Q(p, t) {
54
- return p === t ? !0 : !p || !t || p.length !== t.length ? !1 : p.every((e, i) => e === t[i]);
69
+ let xe = 0, ve = 0, Se = 0, be = 0;
70
+ function ht(d, t) {
71
+ return d === t ? !0 : !d || !t || d.length !== t.length ? !1 : d.every((e, i) => e === t[i]);
55
72
  }
56
- function tt(p) {
57
- return v(p) ? p.stacking : void 0;
73
+ function lt(d) {
74
+ return S(d) ? d.stacking : void 0;
58
75
  }
59
- function de(p, t) {
60
- return p === t ? !0 : !p || !t || p.length !== t.length ? !1 : p.every((e, i) => e === t[i]);
76
+ function ke(d, t) {
77
+ return d === t ? !0 : !d || !t || d.length !== t.length ? !1 : d.every((e, i) => e === t[i]);
61
78
  }
62
- class _e extends Et {
79
+ class ri extends qt {
63
80
  /** Canvas lifecycle and DPR-aware sizing. */
64
- #l;
81
+ #c;
65
82
  /** Schedules main-layer redraws (background, grid, series). */
66
83
  #i;
67
84
  /** Schedules overlay redraws (crosshair). */
68
- #c;
85
+ #d;
69
86
  /** Maps time values to horizontal pixel coordinates. */
70
87
  timeScale;
71
88
  /** Maps price/value to vertical pixel coordinates — the default Y scale. */
72
89
  yScale;
73
90
  /** Default-scale Y state; `yScale` is its scale. */
74
- #P;
91
+ #w;
75
92
  /** Named Y scales from `options.scales`, in declaration order. */
76
- #a = /* @__PURE__ */ new Map();
93
+ #o = /* @__PURE__ */ new Map();
77
94
  /** Copy of the `scales` option as last applied — `setScales` skips a deep-equal replay,
78
95
  * and the copy keeps an in-place edit of the caller's object from comparing equal. */
79
- #At = {};
96
+ #It = {};
80
97
  /** Set when a named scale's range moved, so the crosshair re-emits for its axis label. */
81
- #nt = !1;
98
+ #ot = !1;
82
99
  /** Keys of dev warnings already printed, so each fires once. */
83
- #Mt = /* @__PURE__ */ new Set();
100
+ #Dt = /* @__PURE__ */ new Set();
84
101
  /** What the X axis maps — read from `axis.x.type` once, at construction. */
85
- #r;
102
+ #n;
86
103
  /** Category axis: name → band index, in first-seen order across the series. */
87
- #Y = /* @__PURE__ */ new Map();
104
+ #O = /* @__PURE__ */ new Map();
88
105
  /** Zoom, pan, crosshair — null when interactive=false. */
89
- #V;
106
+ #N;
90
107
  /** All registered series (candlestick, line, bar, pie). */
91
108
  #t = [];
92
109
  /** Point annotations (event markers) drawn on the overlay layer, kept out of the series model. */
93
110
  #y = [];
94
111
  /** Time-region bands drawn on the main layer behind the series, kept out of the series model. */
95
- #T = [];
112
+ #M = [];
96
113
  /** Reference lines (horizontal threshold / vertical event) drawn on the overlay layer, kept out of the series model. */
97
- #b = [];
114
+ #S = [];
98
115
  /**
99
116
  * Overlay-intro latch. Annotations ride the *initial* reveal, then stay put.
100
117
  * `#overlayIntroSeen` flips once we've actually watched an intro in progress
@@ -103,29 +120,31 @@ class _e extends Et {
103
120
  * later — which re-arms `getIntroFront()`'s global min — can't blink settled
104
121
  * markers / reference lines back out.
105
122
  */
106
- #Pt = !1;
107
- #Ct = !1;
123
+ #Rt = !1;
124
+ #Vt = !1;
108
125
  /** Active visual theme (colors, fonts, grid style). */
109
- #n;
126
+ #h;
110
127
  /** Whether to render the background grid. */
111
- #G;
128
+ #j;
112
129
  /**
113
130
  * Gridline layer opacity, multiplied into every per-tick fade: `0 → 1` on
114
131
  * the opening reveal, `1 → 0` when {@link setGrid} hides the grid. The
115
132
  * per-tick fades stay snapped during mount (see the tracker's arming), so
116
133
  * this is what keeps `fitToData` tick churn from flickering the reveal.
117
134
  */
118
- #E;
135
+ #Y;
136
+ /** Whether a tick fade ran on the last main frame — the frame it settles on still owes the DOM labels a sync. */
137
+ #Ht = !1;
119
138
  /** Resolved edge-fade zones — a `null` side is auto: the axis-column ramp on the Y-axis side, off on the other. */
120
139
  #C;
121
140
  /** See {@link headerHeight}. */
122
- #at = 0;
141
+ #ht = 0;
123
142
  /** Memoized destination-out mask gradients, one per edge, keyed by the
124
143
  * zone's bitmap geometry so a resize / DPR change / `setFade` rebuilds
125
144
  * them and steady frames reuse them. */
126
- #k = { top: null, axis: { left: null, right: null }, edge: { left: null, right: null }, tail: null, overhang: null };
145
+ #b = { top: null, axis: { left: null, right: null }, edge: { left: null, right: null }, tail: null, overhang: null };
127
146
  /** Detected time interval between data points (milliseconds). */
128
- #o = 6e4;
147
+ #r = 6e4;
129
148
  /** Current crosshair position, null when cursor is outside the chart. */
130
149
  #f = null;
131
150
  /**
@@ -135,12 +154,12 @@ class _e extends Et {
135
154
  * `time`/`y`; `'time'` (programmatic {@link setCrosshair}) keeps
136
155
  * `time`/`y` and re-projects the pixel position.
137
156
  */
138
- #ot = "pointer";
157
+ #lt = "pointer";
139
158
  /** Whether the last overlay pass painted anything — gates the full-bitmap
140
159
  * clear so an empty overlay isn't cleared again every main frame. */
141
- #Lt = !1;
160
+ #Nt = !1;
142
161
  /** Cached series ID list — invalidated on add/remove. */
143
- #z = null;
162
+ #F = null;
144
163
  /** Axis visibility and sizing configuration. */
145
164
  #v = {};
146
165
  /** Host-declared state per edge — drives the edge-indicator overlay. */
@@ -151,27 +170,27 @@ class _e extends Et {
151
170
  * fetched data lands. `null` = no fade in flight. */
152
171
  #K = { left: null, right: null };
153
172
  /** Cached boundary timestamps from the last `edgeReached` emission, by side. */
154
- #Dt = { left: null, right: null };
173
+ #Ft = { left: null, right: null };
155
174
  /** Latest placeholder shapes a `loading` indicator reported per side —
156
175
  * the morph hand-off candidate consumed by {@link prependData}. */
157
- #ht = { left: null, right: null };
176
+ #ct = { left: null, right: null };
158
177
  /** True after a prepend consumed a side's placeholder snapshot: the series'
159
178
  * reveal owns those pixels now, so the still-`loading` indicator is hidden
160
179
  * and the upcoming `loading → idle` transition skips its exit fade. Reset
161
180
  * by the next {@link setEdgeState} call. */
162
- #B = { left: !1, right: !1 };
181
+ #E = { left: !1, right: !1 };
163
182
  /** Host-supplied callback fired when the user releases a pan/zoom past a data edge. */
164
- #Rt;
183
+ #Wt;
165
184
  /** Per-side custom painter for the edge `loading` spinner. `null` falls back to the built-in dots. */
166
- #It = { left: null, right: null };
185
+ #$t = { left: null, right: null };
167
186
  /** Nesting depth for batch updates. Suppresses recomputes while > 0. */
168
187
  #R = 0;
169
188
  /** True when batched operations include data changes (triggers full onDataChanged on end). */
170
- #lt = !1;
189
+ #dt = !1;
171
190
  /** True when batched operations include visibility changes (triggers Y-range + redraw on end). */
172
- #N = !1;
191
+ #B = !1;
173
192
  /** True when batched operations bumped overlay version (emits a single overlayChange on flush). */
174
- #ct = !1;
193
+ #ut = !1;
175
194
  /**
176
195
  * Monotonic counter bumped on any mutation that affects overlay output —
177
196
  * data, visibility, series options, theme. Used by snapshot helpers in
@@ -181,10 +200,13 @@ class _e extends Et {
181
200
  *
182
201
  * @internal
183
202
  */
184
- #Ht = 0;
203
+ #mt = 0;
204
+ /** Main frames that moved a series' animated values; see `seriesFrame`. */
205
+ #zt = 0;
206
+ #Ot = !1;
185
207
  /** CSS px of the default Y-axis column. The default collapses to `0` on a spatial-only chart. */
186
208
  get yAxisWidth() {
187
- return this.#j(this.#v.y);
209
+ return this.#q(this.#v.y);
188
210
  }
189
211
  /** Side of the plot area the default Y-axis column sits on. */
190
212
  get yAxisPosition() {
@@ -204,33 +226,33 @@ class _e extends Et {
204
226
  */
205
227
  getAxisColumnWidth(t) {
206
228
  if (t === this.yAxisPosition && this.yAxisWidth > 0) return this.yAxisWidth;
207
- for (const e of this.#a.values())
208
- if (e.column === t) return this.#j(e.config);
229
+ for (const e of this.#o.values())
230
+ if (e.column === t) return this.#q(e.config);
209
231
  return 0;
210
232
  }
211
233
  /** The named scale whose axis column sits on `side`, `null` when the default axis's does or none. */
212
234
  getAxisColumnScale(t) {
213
- for (const [e, i] of this.#a)
235
+ for (const [e, i] of this.#o)
214
236
  if (i.column === t) return e;
215
237
  return null;
216
238
  }
217
239
  /** Both Y-axis columns together — the plot area is the canvas width minus this. */
218
- #w() {
240
+ #k() {
219
241
  return this.getAxisColumnWidth("left") + this.getAxisColumnWidth("right");
220
242
  }
221
243
  /** Column width a Y-axis config asks for; `0` when hidden, and by default on a spatial-only chart. */
222
- #j(t) {
223
- return t?.visible === !1 ? 0 : t?.width !== void 0 ? t.width : this.#Q() ? 0 : ae;
244
+ #q(t) {
245
+ return t?.visible === !1 ? 0 : t?.width !== void 0 ? t.width : this.#it() ? 0 : ge;
224
246
  }
225
247
  /** CSS px height of the floating Title / InfoBar header, `0` without one. A left
226
248
  * axis shares its column with it, so tick labels fade out underneath. */
227
249
  get headerHeight() {
228
- return this.#at;
250
+ return this.#ht;
229
251
  }
230
252
  /** CSS px of the time-axis row. The default collapses to `0` on a spatial-only chart. */
231
253
  get xAxisHeight() {
232
254
  const t = this.#v.x;
233
- return t?.visible === !1 ? 0 : t?.height !== void 0 ? t.height : this.#Q() ? 0 : 30;
255
+ return t?.visible === !1 ? 0 : t?.height !== void 0 ? t.height : this.#it() ? 0 : 30;
234
256
  }
235
257
  /** Resolved animation config derived from `options.animations` at construction. */
236
258
  #g;
@@ -248,7 +270,7 @@ class _e extends Et {
248
270
  * longer than the producer's tick interval — the spring never quite
249
271
  * settles between ticks, so velocity carries continuously and the slide
250
272
  * doesn't pulse. */
251
- #F;
273
+ #W;
252
274
  /**
253
275
  * Mirrors `#dataReplaceSnapPending` for the engine signal that follows
254
276
  * inside the same `onDataChanged` call. `#dataReplaceSnapPending` is
@@ -258,9 +280,9 @@ class _e extends Et {
258
280
  * field carries the decision across that gap. The closure also reads
259
281
  * `#dataStart` / `#dataEnd` directly for the timestamps.
260
282
  */
261
- #Vt = !1;
283
+ #Yt = !1;
262
284
  /** Earliest data timestamp registered across all series, `null` before any data has arrived. */
263
- #S = null;
285
+ #T = null;
264
286
  /** Latest data timestamp registered across all series, `null` before any data has arrived. */
265
287
  #s = null;
266
288
  /**
@@ -269,7 +291,7 @@ class _e extends Et {
269
291
  * left of the tail keeps that offset as new bars arrive, instead of
270
292
  * snapping back to the natural-pin position every frame.
271
293
  */
272
- #q = null;
294
+ #J = null;
273
295
  /**
274
296
  * Warm-up window flag — `setVisibleRange({ from, bars })` arms it and
275
297
  * the streaming-target math suppresses pan ticks while the data hasn't
@@ -282,14 +304,14 @@ class _e extends Et {
282
304
  * the right edge and trims the left. Resolved once at construction from
283
305
  * `options.viewport.maxVisibleBars`.
284
306
  */
285
- #zt;
307
+ #ft;
286
308
  /**
287
309
  * Committed logical X range — the "where X should be" target. Engine
288
310
  * eases its visual toward this. Pan / zoom / setRange / fitContent /
289
311
  * streaming-target writes go here. Initialized to `{0,0}` and treated
290
312
  * as "uninitialized" by `#computeXTarget` until first paint.
291
313
  */
292
- #h = { from: 0, to: 0 };
314
+ #a = { from: 0, to: 0 };
293
315
  /**
294
316
  * Auto-scroll flag — when `true`, streaming ticks slide X to track the
295
317
  * data tail. Pan flips this off when the gesture pushes the tail off
@@ -298,20 +320,22 @@ class _e extends Et {
298
320
  */
299
321
  #p = !0;
300
322
  /** Resolved viewport padding (top/bottom px + left/right pixels-or-intervals). */
301
- #d;
323
+ #l;
302
324
  /** Cached chart width — passed by interactions on every call; kept for the rare
303
325
  * call that omits it (e.g. programmatic `chart.pan(...)` without explicit width). */
304
- #J = 0;
326
+ #Q = 0;
327
+ /** X range the last main paint drew. */
328
+ #tt = { from: Number.NaN, to: Number.NaN };
305
329
  /** Active performance monitor, or `null` when instrumentation is disabled (the default). */
306
- #M;
330
+ #P;
307
331
  /** When true, `destroy()` tears down the monitor; false for caller-supplied monitors we must not destroy. */
308
- #dt = !1;
332
+ #gt = !1;
309
333
  /** Visible HUD overlay (mounted by the perf config); non-null only when the caller requested one. */
310
- #ut = null;
334
+ #pt = null;
311
335
  constructor(t, e) {
312
- super(), e?.axis && (this.#v = e.axis), this.#r = this.#v.x?.type ?? "time", this.#n = e?.theme ?? Zt.theme, this.#G = e?.grid?.visible !== !1, this.#C = Y(e?.fade), this.#g = at.resolve(e?.animations), this.#zt = xt(e?.viewport?.maxVisibleBars), this.#d = E(e?.padding), this.#F = new Mt();
336
+ super(), e?.axis && (this.#v = e.axis), this.#n = this.#v.x?.type ?? "time", this.#h = e?.theme ?? ee.theme, this.#j = e?.grid?.visible !== !1, this.#C = _(e?.fade), this.#g = pt.resolve(e?.animations), this.#ft = Pt(e?.viewport?.maxVisibleBars), this.#l = U(e?.padding), this.#W = new Nt();
313
337
  const i = this.#g.axis.y, s = this.#g.axis.x;
314
- this.#e = lt({
338
+ this.#e = vt({
315
339
  initial: { yRange: { min: 0, max: 0 }, xRange: { from: 0, to: 0 } },
316
340
  y: {
317
341
  curve: i.curve,
@@ -326,36 +350,36 @@ class _e extends Et {
326
350
  settleMs: s.settleMs,
327
351
  gestureMs: s.gestureMs
328
352
  },
329
- computeXTarget: () => this.#we(),
330
- computeYTarget: ({ xTarget: o, scale: h }) => this.#_(o, h),
353
+ computeXTarget: () => this.#Ne(),
354
+ computeYTarget: ({ xTarget: o, scale: h }) => this.#G(o, h),
331
355
  onWake: () => this.#i?.markDirty()
332
- }), e?.onEdgeReached && this.checkTimeOnlyFeature("onEdgeReached") && (this.#Rt = e.onEdgeReached), this.#it = e?.viewport?.initialRange;
333
- const r = vt(e?.perf);
334
- this.#M = r.monitor, this.#dt = r.ownsMonitor, this.#l = new ct(t, this.#M ?? void 0), this.timeScale = new Nt(), this.timeScale.setType(this.#r), this.timeScale.setBandPadding(this.#v.x?.padding), this.yScale = new U(), this.#P = j(this.yScale, this.#v.y), this.yScale.setTransform(this.#v.y?.scale ?? null), C({ y: this.#v.y, isPlottable: this.#gt(void 0) }), this.timeScale.setLocale(e?.locale), this.timeScale.setTimeZone(e?.timeZone);
356
+ }), e?.onEdgeReached && this.checkTimeOnlyFeature("onEdgeReached") && (this.#Wt = e.onEdgeReached), this.#H = pe(e?.viewport?.initialRange);
357
+ const r = Ct(e?.perf);
358
+ this.#P = r.monitor, this.#gt = r.ownsMonitor, this.#c = new St(t, this.#P ?? void 0), this.timeScale = new Qt(), this.timeScale.setType(this.#n), this.timeScale.setBandPadding(this.#v.x?.padding), this.yScale = new J(), this.#w = rt(this.yScale, this.#v.y), this.yScale.setTransform(this.#v.y?.scale ?? null), D({ y: this.#v.y, isPlottable: this.#vt(void 0) }), this.timeScale.setLocale(e?.locale), this.timeScale.setTimeZone(e?.timeZone);
335
359
  const n = this.#g.axis.ticksMs;
336
- this.timeScale.tickTracker.setFadeMs(n), this.yScale.tickTracker.setFadeMs(n), this.#Xt(e?.scales ?? {}), this.#St(), this.#E = new nt({
360
+ this.timeScale.tickTracker.setFadeMs(n), this.yScale.tickTracker.setFadeMs(n), this.#qt(e?.scales ?? {}), this.#wt(), this.#Y = new gt({
337
361
  initial: 0,
338
362
  duration: this.#g.axis.gridMs,
339
363
  lerp: (o, h, l) => o + (h - o) * l
340
- }), this.#i = new Z((o) => this.#wt(o)), this.#c = new Z(
341
- (o) => this.#Tt("overlay", o, () => this.renderOverlay(o))
342
- ), this.#M && r.hud && (this.#ut = r.hud(t, this.#M));
364
+ }), this.#i = new q((o) => this.#Ct(o)), this.#d = new q(
365
+ (o) => this.#Lt("overlay", o, () => this.renderOverlay(o))
366
+ ), this.#P && r.hud && (this.#pt = r.hud(t, this.#P));
343
367
  const a = e?.interactive !== !1;
344
- this.#V = a ? new Bt(this.#l.canvas, this, this.timeScale, this.yScale) : null, this.#l.on("resize", () => {
345
- this.syncScales(), this.#wt(), this.emit("viewportChange");
346
- }), this.syncScales(), this.#V?.on("crosshairMove", (o) => {
347
- const h = o === null ? null : this.#mt(o);
348
- this.#ot = "pointer", this.#f = h, this.#c.markDirty(), this.emit("crosshairMove", h), this.#bt(h);
349
- }), this.#V?.on("click", (o) => {
350
- const h = this.#mt(o);
351
- this.emit("pointClick", { ...h, spatialHit: this.#Ut(h) });
352
- }), this.#V?.on("dblclick", (o) => {
353
- const h = this.#mt(o);
354
- this.fitContent(), this.emit("pointDoubleClick", { ...h, spatialHit: this.#Ut(h) });
368
+ this.#N = a ? new Jt(this.#c.canvas, this, this.timeScale, this.yScale) : null, this.#c.on("resize", () => {
369
+ this.syncScales(), this.#Ct(), this.emit("viewportChange");
370
+ }), this.syncScales(), this.#N?.on("crosshairMove", (o) => {
371
+ const h = o === null ? null : this.#yt(o);
372
+ this.#lt = "pointer", this.#f = h, this.#d.markDirty(), this.emit("crosshairMove", h), this.#Mt(h);
373
+ }), this.#N?.on("click", (o) => {
374
+ const h = this.#yt(o);
375
+ this.emit("pointClick", { ...h, spatialHit: this.#Qt(h) });
376
+ }), this.#N?.on("dblclick", (o) => {
377
+ const h = this.#yt(o);
378
+ this.fitContent(), this.emit("pointDoubleClick", { ...h, spatialHit: this.#Qt(h) });
355
379
  });
356
380
  }
357
381
  /** A pointer position on a category axis snaps to the nearest band; `x` is the coordinate in the axis domain. */
358
- #mt(t) {
382
+ #yt(t) {
359
383
  const e = this.timeScale.snapToBand(t.time);
360
384
  return { ...t, time: e, x: this.timeScale.domainValue(e) };
361
385
  }
@@ -371,9 +395,9 @@ class _e extends Et {
371
395
  * `setSeriesVisible` / `setLayerVisible` calls — produce one overlay
372
396
  * render instead of N.
373
397
  */
374
- #u() {
375
- if (this.#Ht++, this.#R > 0) {
376
- this.#ct = !0;
398
+ #m() {
399
+ if (this.#mt++, this.#R > 0) {
400
+ this.#ut = !0;
377
401
  return;
378
402
  }
379
403
  this.emit("overlayChange");
@@ -387,59 +411,86 @@ class _e extends Et {
387
411
  * @internal
388
412
  */
389
413
  getOverlayVersion() {
390
- return this.#Ht;
414
+ return this.#mt;
415
+ }
416
+ /**
417
+ * {@link getOverlayVersion} that also advances on every `seriesFrame`: the
418
+ * snapshot helpers key their cache on it, since a snapshot reads the
419
+ * animated values a frame moves.
420
+ *
421
+ * @internal
422
+ */
423
+ getSnapshotVersion() {
424
+ return this.#mt + this.#zt;
391
425
  }
392
426
  /**
393
427
  * Return a series ID: use the provided hint if it's non-empty and not already taken,
394
428
  * otherwise generate a new auto ID. Auto-generated IDs never collide with each other
395
429
  * or with user-provided IDs because they use a monotonically increasing counter.
396
430
  */
397
- #ne(t) {
431
+ #ge(t) {
398
432
  if (t && !this.#t.some((i) => i.id === t))
399
433
  return t;
400
434
  let e;
401
435
  do
402
- e = `series_${++oe}`;
436
+ e = `series_${++xe}`;
403
437
  while (this.#t.some((i) => i.id === e));
404
438
  return e;
405
439
  }
406
440
  addSeries(t, e = {}) {
407
- const i = typeof t == "string" ? Xt(t) : t;
441
+ const i = typeof t == "string" ? te(t) : t;
408
442
  if (!i)
409
443
  throw new Error(
410
444
  `[wick-charts] Unknown series type '${String(t)}'. The string form of addSeries resolves through the series registry — call registerBuiltinSeries() once at startup, or pass the definition directly: chart.addSeries(LineSeriesDef, options).`
411
445
  );
412
446
  const { layers: s, id: r, label: n, labels: a, scale: o, ...h } = e, l = s ?? 1;
413
- o === void 0 && L({
447
+ o === void 0 && R({
414
448
  seriesId: r ?? i.type,
415
449
  stacking: h.stacking,
416
- isPlottable: this.#gt(o)
450
+ isPlottable: this.#vt(o)
417
451
  });
418
- const d = {
452
+ const c = {
419
453
  ...this.#g.defaults(i.type),
420
454
  ...h,
421
455
  ...this.#g.overrides(i.type)
422
- }, f = i.create({ theme: this.#n, layerCount: l }, d);
423
- v(f) && Ct({ seriesType: i.type, axisType: this.#r, supported: i.xTypes ?? ["time"] });
424
- const c = a ?? (typeof n == "string" ? [n] : void 0), m = this.#ne(r);
425
- f.onDataChanged?.(() => this.onDataChanged());
426
- const y = this.#Z();
456
+ }, f = this.#pe({ type: i.type, count: l }), g = i.create({ theme: this.#h, layerCount: l, paletteIndex: f }, c);
457
+ S(g) && Wt({ seriesType: i.type, axisType: this.#n, supported: i.xTypes ?? ["time"] });
458
+ const y = a ?? (typeof n == "string" ? [n] : void 0), u = this.#ge(r);
459
+ g.onDataChanged?.(() => this.onDataChanged());
460
+ const m = this.#Z();
427
461
  return this.#t.push({
428
- id: m,
429
- labels: c,
430
- renderer: f,
462
+ id: u,
463
+ labels: y,
464
+ renderer: g,
431
465
  visible: !0,
432
466
  scale: o,
433
467
  xKeys: { x: !1, time: !1 },
434
- categoryPoints: []
435
- }), this.#z = null, this.#et(), this.#tt(y), this.emit("seriesChange"), this.#u(), m;
468
+ categoryPoints: [],
469
+ palette: { type: i.type, start: f, count: l }
470
+ }), this.#F = null, this.#rt(), this.#st(m), this.emit("seriesChange"), this.#m(), u;
471
+ }
472
+ /** The lowest run of `count` palette slots that no other series of `type` holds. */
473
+ #pe(t) {
474
+ const e = /* @__PURE__ */ new Set();
475
+ for (const r of this.#t)
476
+ if (r.palette.type === t.type)
477
+ for (let n = 0; n < r.palette.count; n++)
478
+ e.add(r.palette.start + n);
479
+ const i = (r) => {
480
+ for (let n = r; n < r + t.count; n++)
481
+ if (e.has(n)) return !0;
482
+ return !1;
483
+ };
484
+ let s = 0;
485
+ for (; i(s); ) s++;
486
+ return s;
436
487
  }
437
488
  /** Remove a series by ID and clean up its resources. */
438
489
  removeSeries(t) {
439
490
  const e = this.#t.findIndex((i) => i.id === t);
440
491
  if (e >= 0) {
441
492
  const i = this.#Z();
442
- this.#t[e].renderer.dispose(), this.#t.splice(e, 1), this.#z = null, this.#r === "category" && this.#Bt(), this.#et(), this.#tt(i), this.#i.markDirty(), this.emit("seriesChange"), this.#u();
493
+ this.#t[e].renderer.dispose(), this.#t.splice(e, 1), this.#F = null, this.#n === "category" && this.#Gt(), this.#rt(), this.#st(i), this.#i.markDirty(), this.emit("seriesChange"), this.#m();
443
494
  }
444
495
  }
445
496
  // --- Markers (point annotations) -----------------------------------------
@@ -453,24 +504,24 @@ class _e extends Et {
453
504
  * appear in series queries.
454
505
  */
455
506
  addMarker(t) {
456
- const e = `marker_${++he}`;
457
- return this.#y.push(this.#Ft(e, t)), this.#c.markDirty(), e;
507
+ const e = `marker_${++ve}`;
508
+ return this.#y.push(this.#Et(e, t)), this.#d.markDirty(), e;
458
509
  }
459
510
  /** Replace a marker's config in place. No-op when the id is unknown. */
460
511
  updateMarker(t, e) {
461
512
  const i = this.#y.findIndex((s) => s.id === t);
462
- i !== -1 && (this.#y[i] = this.#Ft(t, e), this.#c.markDirty());
513
+ i !== -1 && (this.#y[i] = this.#Et(t, e), this.#d.markDirty());
463
514
  }
464
515
  /** Remove a marker by id. No-op when the id is unknown. */
465
516
  removeMarker(t) {
466
517
  const e = this.#y.findIndex((i) => i.id === t);
467
- e !== -1 && (this.#y.splice(e, 1), this.#c.markDirty());
518
+ e !== -1 && (this.#y.splice(e, 1), this.#d.markDirty());
468
519
  }
469
520
  /** Read-only snapshot of the registered markers (normalized). Mutate via add / update / removeMarker. */
470
521
  getMarkers() {
471
522
  return this.#y;
472
523
  }
473
- #Ft(t, e) {
524
+ #Et(t, e) {
474
525
  return {
475
526
  id: t,
476
527
  time: k(e.time),
@@ -484,43 +535,43 @@ class _e extends Et {
484
535
  };
485
536
  }
486
537
  /** The scale a marker's value maps through: its own `scale`, else its series' scale. */
487
- #ae(t) {
538
+ #ye(t) {
488
539
  return t.scale !== void 0 || t.seriesId === void 0 ? this.getYScale(t.scale) : this.getYScale(this.getSeriesScale(t.seriesId));
489
540
  }
490
541
  /** Resolve a marker's Y value: explicit `value`, else snapped to its series at `time`. Null when neither resolves. */
491
- #oe(t) {
542
+ #xe(t) {
492
543
  if (t.value !== void 0 && Number.isFinite(t.value)) return t.value;
493
544
  if (t.seriesId === void 0) return null;
494
545
  const e = this.getDataAtTime(t.seriesId, t.time);
495
- return e ? G(e) : null;
546
+ return e ? tt(e) : null;
496
547
  }
497
548
  /** Resolve a marker's color: explicit `color`, else the series color, else the theme line color. */
498
- #he(t) {
549
+ #ve(t) {
499
550
  if (t.color !== void 0) return t.color;
500
551
  if (t.seriesId !== void 0) {
501
552
  const e = this.getSeriesColor(t.seriesId);
502
553
  if (e !== null) return e;
503
554
  }
504
- return this.#n.line.color;
555
+ return this.#h.line.color;
505
556
  }
506
- #le(t, e, i) {
557
+ #Se(t, e, i) {
507
558
  if (this.#y.length === 0) return;
508
- const s = performance.now() / (ot * 2 * Math.PI) % 1, r = this.#pt();
559
+ const s = performance.now() / (yt * 2 * Math.PI) % 1, r = this.#St();
509
560
  for (const n of this.#y) {
510
- const a = this.#oe(n);
561
+ const a = this.#xe(n);
511
562
  if (a === null) continue;
512
- const o = this.#Yt(r, n.time);
563
+ const o = this.#_t(r, n.time);
513
564
  if (o <= 0) continue;
514
565
  const h = t.context.globalAlpha;
515
- o < 1 && (t.context.globalAlpha = h * o), Ot({
566
+ o < 1 && (t.context.globalAlpha = h * o), Ut({
516
567
  scope: t,
517
568
  timeScale: this.timeScale,
518
- yScale: this.#ae(n),
519
- theme: this.#n,
569
+ yScale: this.#ye(n),
570
+ theme: this.#h,
520
571
  marker: {
521
572
  time: n.time,
522
573
  value: a,
523
- color: this.#he(n),
574
+ color: this.#ve(n),
524
575
  shape: n.shape,
525
576
  pulse: n.pulse,
526
577
  label: n.label
@@ -544,24 +595,24 @@ class _e extends Et {
544
595
  * legend.
545
596
  */
546
597
  addRegion(t) {
547
- const e = `region_${++le}`;
548
- return this.checkTimeOnlyFeature("TimeRegion") && (this.#T.push(this.#Ot(e, t)), this.#i.markDirty()), e;
598
+ const e = `region_${++Se}`;
599
+ return this.checkTimeOnlyFeature("TimeRegion") && (this.#M.push(this.#Bt(e, t)), this.#i.markDirty()), e;
549
600
  }
550
601
  /** Replace a region's config in place. No-op when the id is unknown. */
551
602
  updateRegion(t, e) {
552
- const i = this.#T.findIndex((s) => s.id === t);
553
- i !== -1 && (this.#T[i] = this.#Ot(t, e), this.#i.markDirty());
603
+ const i = this.#M.findIndex((s) => s.id === t);
604
+ i !== -1 && (this.#M[i] = this.#Bt(t, e), this.#i.markDirty());
554
605
  }
555
606
  /** Remove a region by id. No-op when the id is unknown. */
556
607
  removeRegion(t) {
557
- const e = this.#T.findIndex((i) => i.id === t);
558
- e !== -1 && (this.#T.splice(e, 1), this.#i.markDirty());
608
+ const e = this.#M.findIndex((i) => i.id === t);
609
+ e !== -1 && (this.#M.splice(e, 1), this.#i.markDirty());
559
610
  }
560
611
  /** Read-only snapshot of the registered regions (normalized). Mutate via add / update / removeRegion. */
561
612
  getRegions() {
562
- return this.#T;
613
+ return this.#M;
563
614
  }
564
- #Ot(t, e) {
615
+ #Bt(t, e) {
565
616
  const { to: i } = e, s = i === void 0 || i === "now" ? null : k(i);
566
617
  return {
567
618
  id: t,
@@ -572,14 +623,14 @@ class _e extends Et {
572
623
  label: e.label
573
624
  };
574
625
  }
575
- #ce(t, e, i) {
576
- if (this.#T.length !== 0)
577
- for (const s of this.#T) {
578
- const { color: r, fill: n } = Wt(s, this.#n);
579
- Yt({
626
+ #be(t, e, i) {
627
+ if (this.#M.length !== 0)
628
+ for (const s of this.#M) {
629
+ const { color: r, fill: n } = jt(s, this.#h);
630
+ Kt({
580
631
  scope: t,
581
632
  timeScale: this.timeScale,
582
- theme: this.#n,
633
+ theme: this.#h,
583
634
  region: { from: s.from, to: s.to, fill: n, color: r, label: s.label },
584
635
  plotWidth: e,
585
636
  plotHeight: i
@@ -598,24 +649,24 @@ class _e extends Et {
598
649
  * legend.
599
650
  */
600
651
  addLine(t) {
601
- const e = `line_${++ce}`;
602
- return this.#b.push(this.#$t(e, t)), this.#c.markDirty(), e;
652
+ const e = `line_${++be}`;
653
+ return this.#S.push(this.#Xt(e, t)), this.#d.markDirty(), e;
603
654
  }
604
655
  /** Replace a reference line's config in place. No-op when the id is unknown. */
605
656
  updateLine(t, e) {
606
- const i = this.#b.findIndex((s) => s.id === t);
607
- i !== -1 && (this.#b[i] = this.#$t(t, e), this.#c.markDirty());
657
+ const i = this.#S.findIndex((s) => s.id === t);
658
+ i !== -1 && (this.#S[i] = this.#Xt(t, e), this.#d.markDirty());
608
659
  }
609
660
  /** Remove a reference line by id. No-op when the id is unknown. */
610
661
  removeLine(t) {
611
- const e = this.#b.findIndex((i) => i.id === t);
612
- e !== -1 && (this.#b.splice(e, 1), this.#c.markDirty());
662
+ const e = this.#S.findIndex((i) => i.id === t);
663
+ e !== -1 && (this.#S.splice(e, 1), this.#d.markDirty());
613
664
  }
614
665
  /** Read-only snapshot of the registered reference lines (normalized). Mutate via add / update / removeLine. */
615
666
  getLines() {
616
- return this.#b;
667
+ return this.#S;
617
668
  }
618
- #$t(t, e) {
669
+ #Xt(t, e) {
619
670
  const { time: i, value: s } = e, r = {
620
671
  id: t,
621
672
  color: e.color,
@@ -626,22 +677,22 @@ class _e extends Et {
626
677
  };
627
678
  return i !== void 0 ? { ...r, orientation: "vertical", coord: k(i) } : { ...r, orientation: "horizontal", coord: s ?? Number.NaN };
628
679
  }
629
- #de(t, e, i) {
630
- if (this.#b.length === 0) return;
631
- const s = this.#pt();
632
- for (const r of this.#b) {
633
- const n = s >= 1 ? 1 : r.orientation === "vertical" ? this.#Yt(s, r.coord) : W(s);
680
+ #ke(t, e, i) {
681
+ if (this.#S.length === 0) return;
682
+ const s = this.#St();
683
+ for (const r of this.#S) {
684
+ const n = s >= 1 ? 1 : r.orientation === "vertical" ? this.#_t(s, r.coord) : X(s);
634
685
  if (n <= 0) continue;
635
686
  const a = t.context.globalAlpha;
636
- n < 1 && (t.context.globalAlpha = a * n), $t({
687
+ n < 1 && (t.context.globalAlpha = a * n), Gt({
637
688
  scope: t,
638
689
  timeScale: this.timeScale,
639
690
  yScale: this.getYScale(r.scale),
640
- theme: this.#n,
691
+ theme: this.#h,
641
692
  line: {
642
693
  orientation: r.orientation,
643
694
  coord: r.coord,
644
- color: r.color ?? this.#n.line.color,
695
+ color: r.color ?? this.#h.line.color,
645
696
  style: r.style,
646
697
  width: r.width,
647
698
  label: r.label
@@ -658,20 +709,20 @@ class _e extends Et {
658
709
  * underlying animator mutates between frames.
659
710
  */
660
711
  getAnimationState() {
661
- return this.#ft(this.#e.getAnimationState());
712
+ return this.#xt(this.#e.getAnimationState());
662
713
  }
663
714
  /** The engine animates Y in scale space (the scale's forward); readers outside it get values. */
664
- #ft(t, e = this.yScale) {
715
+ #xt(t, e = this.yScale) {
665
716
  const i = e.getTransform();
666
- return i === null ? t : { ...t, yRange: Ht(t.yRange, i) };
717
+ return i === null ? t : { ...t, yRange: Et(t.yRange, i) };
667
718
  }
668
719
  /** The animation state as a named scale's series see it: its own Y, in values. */
669
- #Wt(t, e) {
720
+ #Zt(t, e) {
670
721
  const i = this.#e.getScaleYRange(e) ?? t.yRange;
671
- return this.#ft({ ...t, yRange: i }, this.getYScale(e));
722
+ return this.#xt({ ...t, yRange: i }, this.getYScale(e));
672
723
  }
673
724
  /** `isPlottable` of a scale (`undefined` = default), as a predicate for the guard helpers. */
674
- #gt(t) {
725
+ #vt(t) {
675
726
  const e = this.getYScale(t);
676
727
  return (i) => e.isPlottable(i);
677
728
  }
@@ -701,10 +752,10 @@ class _e extends Et {
701
752
  * has actually been observed in progress, so an annotation drawn on a chart
702
753
  * that has no data yet still rides the reveal once data arrives.
703
754
  */
704
- #pt() {
705
- if (this.#Ct) return 1;
755
+ #St() {
756
+ if (this.#Vt) return 1;
706
757
  const t = this.getIntroFront();
707
- return t < 1 ? (this.#Pt = !0, t) : (this.#Pt && (this.#Ct = !0), 1);
758
+ return t < 1 ? (this.#Rt = !0, t) : (this.#Rt && (this.#Vt = !0), 1);
708
759
  }
709
760
  /**
710
761
  * Entrance alpha for an overlay pinned at `time`, given the intro reveal
@@ -712,10 +763,10 @@ class _e extends Et {
712
763
  * then fades in over a short band — so annotations surface in step with the
713
764
  * series drawing past them. `1` once the intro has settled.
714
765
  */
715
- #Yt(t, e) {
766
+ #_t(t, e) {
716
767
  if (t >= 1) return 1;
717
768
  const { from: i, to: s } = this.timeScale.getRange(), r = s - i, n = r > 0 ? (e - i) / r : 0;
718
- return _t((t - n) / 0.12, 0, 1);
769
+ return se((t - n) / 0.12, 0, 1);
719
770
  }
720
771
  /**
721
772
  * Replace all data for a series.
@@ -732,24 +783,24 @@ class _e extends Et {
732
783
  setSeriesData(t, e, i) {
733
784
  const s = this.#t.find((a) => a.id === t);
734
785
  if (!s) return;
735
- const r = this.#r === "category" && this.#vt(s);
736
- if (this.#kt = !r, !this.#vt(s)) {
786
+ const r = this.#n === "category" && this.#Tt(s);
787
+ if (this.#nt = !r, !this.#Tt(s)) {
737
788
  s.renderer.setData(e, i);
738
789
  return;
739
790
  }
740
- const n = this.#Et(s, e ?? []);
791
+ const n = this.#Ut(s, e ?? []);
741
792
  if (!r) {
742
793
  s.renderer.setData(n, i);
743
794
  return;
744
795
  }
745
- this.#xt({ entry: s, layerIndex: i, mutate: () => n });
796
+ this.#kt({ entry: s, layerIndex: i, mutate: () => n });
746
797
  }
747
798
  /** Append a new data point to the end of a series (real-time tick). */
748
799
  appendData(t, e, i) {
749
800
  const s = this.#t.find((n) => n.id === t);
750
801
  if (s === void 0 || s.renderer.appendPoint === void 0) return;
751
802
  const r = s.renderer.appendPoint.bind(s.renderer);
752
- this.#yt({
803
+ this.#bt({
753
804
  entry: s,
754
805
  layerIndex: i,
755
806
  points: [e],
@@ -763,19 +814,19 @@ class _e extends Et {
763
814
  * category axis applies `mutateCategory` to the layer's input-order points
764
815
  * instead, then re-sets the store from them.
765
816
  */
766
- #yt(t) {
817
+ #bt(t) {
767
818
  const { entry: e, apply: i } = t;
768
- if (!this.#vt(e)) {
819
+ if (!this.#Tt(e)) {
769
820
  i(t.points.slice());
770
821
  return;
771
822
  }
772
- const s = this.#Et(e, t.points);
823
+ const s = this.#Ut(e, t.points);
773
824
  if (s.length !== 0) {
774
- if (this.#r === "numeric") {
825
+ if (this.#n === "numeric") {
775
826
  i(s);
776
827
  return;
777
828
  }
778
- this.#xt({
829
+ this.#kt({
779
830
  entry: e,
780
831
  layerIndex: t.layerIndex,
781
832
  mutate: (r) => t.mutateCategory(r, s)
@@ -783,66 +834,66 @@ class _e extends Et {
783
834
  }
784
835
  }
785
836
  /** Replace a category layer's input-order points with `mutate`'s result and sync the categories and stores. */
786
- #xt(t) {
837
+ #kt(t) {
787
838
  const { entry: e } = t, i = t.layerIndex ?? 0;
788
- e.categoryPoints[i] = t.mutate(e.categoryPoints[i] ?? []), this.#Bt({ entry: e, layerIndex: i });
839
+ e.categoryPoints[i] = t.mutate(e.categoryPoints[i] ?? []), this.#Gt({ entry: e, layerIndex: i });
789
840
  }
790
841
  /** Whether `entry`'s points go through the numeric / category ingest. */
791
- #vt(t) {
792
- return this.#r !== "time" && v(t.renderer);
842
+ #Tt(t) {
843
+ return this.#n !== "time" && S(t.renderer);
793
844
  }
794
845
  /**
795
846
  * Points that fit the X axis, a numeric one with its `x` copied to `time`.
796
847
  * The rest are skipped with a dev warning, as is a series mixing `x` and `time`.
797
848
  */
798
- #Et(t, e) {
849
+ #Ut(t, e) {
799
850
  const i = [];
800
851
  for (const s of e) {
801
852
  const r = s.x !== void 0;
802
- if (r && (t.xKeys.x = !0), s.time !== void 0 && (t.xKeys.time = !0), !(this.#r === "category" ? typeof s.x == "string" : !r || typeof s.x == "number")) {
803
- this.#I(
853
+ if (r && (t.xKeys.x = !0), s.time !== void 0 && (t.xKeys.time = !0), !(this.#n === "category" ? typeof s.x == "string" : !r || typeof s.x == "number")) {
854
+ this.#V(
804
855
  `x-misfit:${t.id}`,
805
- () => Lt({ seriesId: t.id, axisType: this.#r, x: s.x })
856
+ () => $t({ seriesId: t.id, axisType: this.#n, x: s.x })
806
857
  );
807
858
  continue;
808
859
  }
809
- i.push(r && this.#r === "numeric" ? { ...s, time: s.x } : s);
860
+ i.push(r && this.#n === "numeric" ? { ...s, time: s.x } : s);
810
861
  }
811
- return t.xKeys.x && t.xKeys.time && this.#I(`x-mixed:${t.id}`, () => Dt({ seriesId: t.id })), i;
862
+ return t.xKeys.x && t.xKeys.time && this.#V(`x-mixed:${t.id}`, () => zt({ seriesId: t.id })), i;
812
863
  }
813
864
  /** Category points with `time` set to their band index. */
814
- #ue(t) {
815
- return t.map((e) => ({ ...e, time: this.#Y.get(e.x) }));
865
+ #Te(t) {
866
+ return t.map((e) => ({ ...e, time: this.#O.get(e.x) }));
816
867
  }
817
868
  /**
818
869
  * Re-derive the categories — first-seen order across the series (mount
819
870
  * order, then layers, then points in input order) — and re-set every store
820
871
  * whose band indices moved, plus the `changed` layer.
821
872
  */
822
- #Bt(t) {
873
+ #Gt(t) {
823
874
  const e = /* @__PURE__ */ new Set();
824
875
  for (const a of this.#t)
825
876
  for (const o of a.categoryPoints)
826
877
  for (const h of o ?? [])
827
878
  e.add(h.x);
828
- const i = [...e], s = this.timeScale.getCategories(), r = i.length !== s.length || i.some((a, o) => a !== s[o]), n = this.#Y;
829
- this.#Y = new Map(i.map((a, o) => [a, o])), this.timeScale.setCategories(i), this.batch(() => {
879
+ const i = [...e], s = this.timeScale.getCategories(), r = i.length !== s.length || i.some((a, o) => a !== s[o]), n = this.#O;
880
+ this.#O = new Map(i.map((a, o) => [a, o])), this.timeScale.setCategories(i), this.batch(() => {
830
881
  for (const a of this.#t)
831
- this.#me({ entry: a, previous: n, changed: t });
882
+ this.#we({ entry: a, previous: n, changed: t });
832
883
  r && this.onDataChanged();
833
884
  });
834
885
  }
835
886
  /** Re-set `entry`'s layers whose points moved band, or that `changed` names, from their input-order points. */
836
- #me(t) {
887
+ #we(t) {
837
888
  const { entry: e, previous: i, changed: s } = t;
838
889
  for (let r = 0; r < e.categoryPoints.length; r++) {
839
890
  const n = e.categoryPoints[r] ?? [], a = s?.entry === e && s.layerIndex === r, o = n.some(
840
- (d) => i.get(d.x) !== this.#Y.get(d.x)
891
+ (c) => i.get(c.x) !== this.#O.get(c.x)
841
892
  );
842
893
  if (!a && !o) continue;
843
- const h = this.#ue(n).sort((d, f) => d.time - f.time), l = n.some((d) => {
844
- const f = i.get(d.x);
845
- return f !== void 0 && f !== this.#Y.get(d.x);
894
+ const h = this.#Te(n).sort((c, f) => c.time - f.time), l = n.some((c) => {
895
+ const f = i.get(c.x);
896
+ return f !== void 0 && f !== this.#O.get(c.x);
846
897
  });
847
898
  a && !l && e.renderer.morphData !== void 0 ? e.renderer.morphData(h, r) : e.renderer.setData(h, r);
848
899
  }
@@ -863,10 +914,10 @@ class _e extends Et {
863
914
  prependData(t, e, i) {
864
915
  const s = this.#t.find((a) => a.id === t);
865
916
  if (s === void 0 || s.renderer.prependPoints === void 0) return;
866
- const r = this.#ht.left;
867
- r !== null && s.renderer.setHistoryHandoff !== void 0 && performance.now() - r.at < Qt && (s.renderer.setHistoryHandoff(r.bars), this.#B.left = !0, this.#K.left = null, this.#ht.left = null, this.#c.markDirty());
917
+ const r = this.#ct.left;
918
+ r !== null && s.renderer.setHistoryHandoff !== void 0 && performance.now() - r.at < he && (s.renderer.setHistoryHandoff(r.bars), this.#E.left = !0, this.#K.left = null, this.#ct.left = null, this.#d.markDirty());
868
919
  const n = s.renderer.prependPoints.bind(s.renderer);
869
- this.#yt({
920
+ this.#bt({
870
921
  entry: s,
871
922
  layerIndex: i,
872
923
  points: e,
@@ -879,7 +930,7 @@ class _e extends Et {
879
930
  const s = this.#t.find((n) => n.id === t);
880
931
  if (s === void 0 || s.renderer.updateLastPoint === void 0) return;
881
932
  const r = s.renderer.updateLastPoint.bind(s.renderer);
882
- this.#yt({
933
+ this.#bt({
883
934
  entry: s,
884
935
  layerIndex: i,
885
936
  points: [e],
@@ -904,11 +955,11 @@ class _e extends Et {
904
955
  keepLast(t, e, i) {
905
956
  const s = this.#t.find((r) => r.id === t);
906
957
  if (s?.renderer.keepLast !== void 0) {
907
- if (this.#r !== "category") {
958
+ if (this.#n !== "category") {
908
959
  s.renderer.keepLast(e, i);
909
960
  return;
910
961
  }
911
- this.#xt({
962
+ this.#kt({
912
963
  entry: s,
913
964
  layerIndex: i,
914
965
  mutate: (r) => e < 0 ? [...r] : r.slice(Math.max(0, r.length - e))
@@ -920,21 +971,21 @@ class _e extends Et {
920
971
  * (time series) moves it onto a named Y scale, `undefined` back to the default.
921
972
  */
922
973
  updateSeriesOptions(t, e) {
923
- const i = this.#t.find((u) => u.id === t);
974
+ const i = this.#t.find((m) => m.id === t);
924
975
  if (!i) return;
925
976
  const { scale: s, ...r } = e, n = "scale" in e, a = n ? s : i.scale;
926
977
  if (("stacking" in e || n) && a === void 0) {
927
- const u = "stacking" in e ? e.stacking : tt(i.renderer);
928
- L({ seriesId: t, stacking: u, isPlottable: this.#gt(a) });
978
+ const m = "stacking" in e ? e.stacking : lt(i.renderer);
979
+ R({ seriesId: t, stacking: m, isPlottable: this.#vt(a) });
929
980
  }
930
981
  const o = i.labels, h = i.renderer.getLayerColors().slice(), l = this.#g.overrides(i.renderer.kind);
931
982
  i.renderer.updateOptions({ ...r, ...l }), "label" in e && typeof e.label == "string" && (i.labels = [e.label]), this.#i.markDirty();
932
- const d = this.#D(i);
983
+ const c = this.#I(i);
933
984
  i.scale = a;
934
- const f = this.#D(i) !== d;
935
- f && this.#xe();
936
- const c = i.renderer.getLayerColors(), m = h.length !== c.length || h.some((u, g) => u !== c[g]), y = !Q(o, i.labels);
937
- (m || y || f) && this.#u();
985
+ const f = this.#I(i) !== c;
986
+ f && this.#Le();
987
+ const g = i.renderer.getLayerColors(), y = h.length !== g.length || h.some((m, p) => m !== g[p]), u = !ht(o, i.labels);
988
+ (y || u || f) && this.#m();
938
989
  }
939
990
  /**
940
991
  * Batch multiple updates: suppress recomputes until `fn` returns. Exceptions
@@ -946,14 +997,14 @@ class _e extends Et {
946
997
  t();
947
998
  } finally {
948
999
  if (--this.#R <= 0) {
949
- if (this.#R = 0, this.#lt)
950
- this.#lt = !1, this.#N = !1, this.onDataChanged();
951
- else if (this.#N) {
952
- this.#N = !1, this.#m = !0;
1000
+ if (this.#R = 0, this.#dt)
1001
+ this.#dt = !1, this.#B = !1, this.onDataChanged();
1002
+ else if (this.#B) {
1003
+ this.#B = !1, this.#u = !0;
953
1004
  const e = performance.now();
954
1005
  this.#e.onSeriesVisibilityChanged(e), this.#x(e), this.#i.markDirty();
955
1006
  }
956
- this.#ct && (this.#ct = !1, this.emit("overlayChange"));
1007
+ this.#ut && (this.#ut = !1, this.emit("overlayChange"));
957
1008
  }
958
1009
  }
959
1010
  }
@@ -967,13 +1018,13 @@ class _e extends Et {
967
1018
  setSeriesVisible(t, e) {
968
1019
  const i = this.#t.find((n) => n.id === t);
969
1020
  if (!i || i.visible === e) return;
970
- i.visible = e, this.#u(), this.#et();
1021
+ i.visible = e, this.#m(), this.#rt();
971
1022
  const s = this.#g.toggleMs;
972
1023
  if (i.renderer.setAlpha?.(e ? 1 : 0, s), this.#i.markDirty(), this.#R > 0) {
973
- this.#N = !0;
1024
+ this.#B = !0;
974
1025
  return;
975
1026
  }
976
- this.#m = !0;
1027
+ this.#u = !0;
977
1028
  const r = performance.now();
978
1029
  this.#e.onSeriesVisibilityChanged(r), this.#x(r);
979
1030
  }
@@ -1003,28 +1054,28 @@ class _e extends Et {
1003
1054
  setLayerVisible(t, e, i) {
1004
1055
  const s = this.#t.find((a) => a.id === t);
1005
1056
  if (!s || s.renderer.getLayerCount() <= 1 || s.renderer.isLayerVisible(e) === i) return;
1006
- s.renderer.setLayerVisible(e, i), this.#u();
1057
+ s.renderer.setLayerVisible(e, i), this.#m();
1007
1058
  const r = this.#g.toggleMs;
1008
1059
  if (s.renderer.setLayerAlpha?.(e, i ? 1 : 0, r), this.#i.markDirty(), this.#R > 0) {
1009
- this.#N = !0;
1060
+ this.#B = !0;
1010
1061
  return;
1011
1062
  }
1012
- this.#m = !0;
1063
+ this.#u = !0;
1013
1064
  const n = performance.now();
1014
1065
  this.#e.onSeriesVisibilityChanged(n), this.#x(n);
1015
1066
  }
1016
1067
  isLayerVisible(t, e) {
1017
1068
  return this.#t.find((i) => i.id === t)?.renderer.isLayerVisible(e) ?? !0;
1018
1069
  }
1019
- /** Auto-fit the viewport to show all data across every series. */
1070
+ /** Auto-fit the viewport to show all data across every series, however many bars that is. */
1020
1071
  fitContent() {
1021
1072
  const { first: t, last: e } = this.getDataBounds();
1022
1073
  if (t === void 0 || e === void 0) return;
1023
- const i = this.#l.size.media.width - this.#w();
1024
- this.#O(t, e, i), this.#st({ xEase: !0 });
1074
+ const i = this.#c.size.media.width - this.#k();
1075
+ this.#et(), this.#Pt({ firstTime: t, lastTime: e, chartWidth: i }), this.#se({ xEase: !0 });
1025
1076
  }
1026
1077
  getVisibleRange() {
1027
- return this.#h.from === 0 && this.#h.to === 0 ? this.#e.getAnimationState().xRange : this.#h;
1078
+ return this.#a.from === 0 && this.#a.to === 0 ? this.#e.getAnimationState().xRange : this.#a;
1028
1079
  }
1029
1080
  /**
1030
1081
  * Return the full span of registered data, or `null` before any data has
@@ -1032,7 +1083,7 @@ class _e extends Et {
1032
1083
  * tracking and is cheaper than recomputing from series stores.
1033
1084
  */
1034
1085
  getDataRange() {
1035
- return this.#S === null || this.#s === null ? null : { from: this.#S, to: this.#s };
1086
+ return this.#T === null || this.#s === null ? null : { from: this.#T, to: this.#s };
1036
1087
  }
1037
1088
  /**
1038
1089
  * Imperatively set the visible time range. Three forms:
@@ -1059,31 +1110,44 @@ class _e extends Et {
1059
1110
  * lockstep rather than lagging behind on the long sticky contract.
1060
1111
  */
1061
1112
  setVisibleRange(t, e) {
1113
+ const i = this.#jt(t);
1114
+ if (i !== null) {
1115
+ if (this.#et(), e?.gesture && ye(t)) {
1116
+ i && this.#$e();
1117
+ return;
1118
+ }
1119
+ this.#se();
1120
+ }
1121
+ }
1122
+ /**
1123
+ * Write `spec` into the logical X range, the autoscroll flag and the warm-up
1124
+ * hold, without touching the engine. Returns whether the range changed, or
1125
+ * `null` when the spec is invalid or a bar count has no data to count back from.
1126
+ */
1127
+ #jt(t) {
1062
1128
  if (typeof t == "number") {
1063
- if (!Number.isInteger(t) || t < 2) return;
1064
- const { first: n, last: a } = this.getDataBounds();
1065
- if (n === void 0 || a === void 0) return;
1066
- const o = Math.max(n, a - (t - 1) * this.#o), h = this.#l.size.media.width - this.#w();
1067
- this.#O(o, a, h), this.#st();
1068
- return;
1129
+ if (!A(t)) return null;
1130
+ const { first: s, last: r } = this.getDataBounds();
1131
+ if (s === void 0 || r === void 0) return null;
1132
+ const n = Math.max(s, r - (t - 1) * this.#r), a = this.#c.size.media.width - this.#k();
1133
+ return this.#Pt({ firstTime: n, lastTime: r, chartWidth: a });
1069
1134
  }
1070
1135
  if ("bars" in t) {
1071
- if (!Number.isInteger(t.bars) || t.bars < 2) return;
1072
- const n = k(t.from), a = n + t.bars * this.#o;
1073
- this.#p = this.#s !== null && this.#s >= n && this.#s <= a, this.#H({ from: n, to: a }, { emitChange: !0 }), this.#L = !0, this.#st();
1074
- return;
1075
- }
1076
- const i = k(t.from), s = k(t.to);
1077
- this.#p = this.#s !== null && this.#s >= i && this.#s <= s, this.#L = !1;
1078
- const r = this.#H({ from: i, to: s }, { emitChange: !0 });
1079
- if (e?.gesture) {
1080
- r && this.#Te();
1081
- return;
1136
+ if (!A(t.bars)) return null;
1137
+ const s = k(t.from), r = s + t.bars * this.#r;
1138
+ this.#p = this.#s !== null && this.#s >= s && this.#s <= r;
1139
+ const n = this.#D({ from: s, to: r }, { emitChange: !0 });
1140
+ return this.#L = !0, n;
1082
1141
  }
1083
- this.#st();
1142
+ const e = k(t.from), i = k(t.to);
1143
+ return this.#p = this.#s !== null && this.#s >= e && this.#s <= i, this.#L = !1, this.#D({ from: e, to: i }, { emitChange: !0 });
1144
+ }
1145
+ /** The user or the app took over the view: drop `initialRange` and stop growing the chart's own fit. */
1146
+ #et() {
1147
+ this.#H = void 0, this.#U = !1;
1084
1148
  }
1085
1149
  getYRange() {
1086
- return this.#P.range;
1150
+ return this.#w.range;
1087
1151
  }
1088
1152
  getCrosshairPosition() {
1089
1153
  return this.#f;
@@ -1124,7 +1188,7 @@ class _e extends Et {
1124
1188
  setCrosshair(t) {
1125
1189
  if (t === null) {
1126
1190
  if (this.#f === null) return;
1127
- this.#f = null, this.#c.markDirty(), this.emit("crosshairMove", null);
1191
+ this.#f = null, this.#d.markDirty(), this.emit("crosshairMove", null);
1128
1192
  return;
1129
1193
  }
1130
1194
  const { time: e } = t;
@@ -1133,19 +1197,19 @@ class _e extends Et {
1133
1197
  let s;
1134
1198
  if (t.y !== void 0 ? s = t.y : i !== null ? s = i.y : s = this.yScale.yToValue(this.yScale.getMediaHeight() / 2), !Number.isFinite(s) || i !== null && i.time === e && i.y === s) return;
1135
1199
  const r = this.plotLeft + this.timeScale.timeToX(e), n = this.yScale.valueToY(s);
1136
- this.#ot = "time", this.#f = { mediaX: r, mediaY: n, time: e, x: this.timeScale.domainValue(e), y: s }, this.#c.markDirty(), this.emit("crosshairMove", this.#f);
1200
+ this.#lt = "time", this.#f = { mediaX: r, mediaY: n, time: e, x: this.timeScale.domainValue(e), y: s }, this.#d.markDirty(), this.emit("crosshairMove", this.#f);
1137
1201
  }
1138
1202
  /** Get the last visible value and whether the absolute last point is on screen. */
1139
1203
  getLastValue(t) {
1140
- return gt(t, this.#t, this.#e.getAnimationState().xRange);
1204
+ return wt(t, this.#t, this.#e.getAnimationState().xRange);
1141
1205
  }
1142
1206
  /** Get the second-to-last value, useful for computing change. */
1143
1207
  getPreviousClose(t) {
1144
- return pt(t, this.#t);
1208
+ return Mt(t, this.#t);
1145
1209
  }
1146
1210
  getLastData(t) {
1147
1211
  const e = this.#t.find((i) => i.id === t);
1148
- return !e || !v(e.renderer) ? null : e.renderer.getLastDataPoint();
1212
+ return !e || !S(e.renderer) ? null : e.renderer.getLastDataPoint();
1149
1213
  }
1150
1214
  /** Find the data point closest to the given timestamp within one data interval. */
1151
1215
  getDataAtTime(t, e) {
@@ -1169,10 +1233,10 @@ class _e extends Et {
1169
1233
  * past a wide gap is still the nearest.
1170
1234
  */
1171
1235
  #X() {
1172
- return this.#r === "category" ? 0.5 : this.#r === "time" || this.#S === null || this.#s === null ? this.#o : Math.max(this.#o, this.#s - this.#S);
1236
+ return this.#n === "category" ? 0.5 : this.#n === "time" || this.#T === null || this.#s === null ? this.#r : Math.max(this.#r, this.#s - this.#T);
1173
1237
  }
1174
1238
  getSeriesIds() {
1175
- return this.#z || (this.#z = this.#t.map((t) => t.id)), this.#z.slice();
1239
+ return this.#F || (this.#F = this.#t.map((t) => t.id)), this.#F.slice();
1176
1240
  }
1177
1241
  /**
1178
1242
  * True if any visible series has a time axis (line / bar / candlestick).
@@ -1180,9 +1244,9 @@ class _e extends Et {
1180
1244
  * has no meaningful x/y coordinate system, so the dashed hairlines would
1181
1245
  * just be visual noise.
1182
1246
  */
1183
- #Nt() {
1247
+ #Kt() {
1184
1248
  for (const t of this.#t)
1185
- if (t.visible && v(t.renderer))
1249
+ if (t.visible && S(t.renderer))
1186
1250
  return !0;
1187
1251
  return !1;
1188
1252
  }
@@ -1192,8 +1256,8 @@ class _e extends Et {
1192
1256
  * to reserve and nothing slides under an axis column. Reads registration,
1193
1257
  * not visibility — a legend toggle must not shift the layout.
1194
1258
  */
1195
- #Q() {
1196
- return this.#t.length === 0 ? !1 : this.#t.every((t) => !v(t.renderer));
1259
+ #it() {
1260
+ return this.#t.length === 0 ? !1 : this.#t.every((t) => !S(t.renderer));
1197
1261
  }
1198
1262
  #Z() {
1199
1263
  return {
@@ -1206,8 +1270,8 @@ class _e extends Et {
1206
1270
  }
1207
1271
  /** Reassign the Y-axis columns, then resync the scales if the gutters moved
1208
1272
  * and let DOM axis / label components re-read the layout, as they do after a resize. */
1209
- #tt(t) {
1210
- this.#St();
1273
+ #st(t) {
1274
+ this.#wt();
1211
1275
  const e = this.#Z();
1212
1276
  (e.yAxisWidth !== t.yAxisWidth || e.xAxisHeight !== t.xAxisHeight || e.yAxisPosition !== t.yAxisPosition || e.leftWidth !== t.leftWidth || e.rightWidth !== t.rightWidth) && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
1213
1277
  }
@@ -1218,7 +1282,7 @@ class _e extends Et {
1218
1282
  * capturing wheel and touch events, so the page scrolls normally under the cursor.
1219
1283
  */
1220
1284
  canPanZoom() {
1221
- return (this.#v.x?.panZoom ?? this.#r !== "category") && this.#Nt();
1285
+ return (this.#v.x?.panZoom ?? this.#n !== "category") && this.#Kt();
1222
1286
  }
1223
1287
  /**
1224
1288
  * Whether a time-only feature (Navigator, EdgeLoader, TimeRegion) can run
@@ -1228,7 +1292,7 @@ class _e extends Et {
1228
1292
  * @internal
1229
1293
  */
1230
1294
  checkTimeOnlyFeature(t) {
1231
- return this.#r === "time" ? !0 : (this.#I(`time-only:${t}`, () => Rt({ feature: t, axisType: this.#r })), !1);
1295
+ return this.#n === "time" ? !0 : (this.#V(`time-only:${t}`, () => Ot({ feature: t, axisType: this.#n })), !1);
1232
1296
  }
1233
1297
  /**
1234
1298
  * Push the current pan/zoom capability into the interaction layer (canvas
@@ -1237,8 +1301,8 @@ class _e extends Et {
1237
1301
  * every mutation that can flip {@link canPanZoom}: series add/remove and
1238
1302
  * series visibility.
1239
1303
  */
1240
- #et() {
1241
- this.#V?.syncPanZoomMode();
1304
+ #rt() {
1305
+ this.#N?.syncPanZoomMode();
1242
1306
  }
1243
1307
  /**
1244
1308
  * Filter `getSeriesIds()` by renderer type. A concrete kind (`'pie'`,
@@ -1254,7 +1318,7 @@ class _e extends Et {
1254
1318
  getSeriesIdsByType(t, e) {
1255
1319
  const i = e?.visibleOnly === !0, s = e?.singleLayerOnly === !0, r = [];
1256
1320
  for (const n of this.#t) {
1257
- if (!(t === "time" ? v(n.renderer) : n.renderer.kind === t)) continue;
1321
+ if (!(t === "time" ? S(n.renderer) : n.renderer.kind === t)) continue;
1258
1322
  const a = n.renderer.getLayerCount();
1259
1323
  if (!(s && a > 1)) {
1260
1324
  if (i) {
@@ -1281,7 +1345,7 @@ class _e extends Et {
1281
1345
  * Returns `null` for unknown ids or empty series.
1282
1346
  */
1283
1347
  getStackedLastValue(t) {
1284
- return yt(t, this.#t, this.#e.getAnimationState().xRange);
1348
+ return At(t, this.#t, this.#e.getAnimationState().xRange);
1285
1349
  }
1286
1350
  /**
1287
1351
  * Stacked value at an arbitrary `time` — the cumulative stack top at that
@@ -1296,7 +1360,7 @@ class _e extends Et {
1296
1360
  const s = i.renderer.getStackedValueAtTime?.(e, this.#X());
1297
1361
  if (s != null) return s;
1298
1362
  const r = i.renderer.getDataAtTime?.(e, this.#X());
1299
- return !r || jt(r) ? null : G(r);
1363
+ return !r || ae(r) ? null : tt(r);
1300
1364
  }
1301
1365
  /**
1302
1366
  * Per-layer last snapshots with each layer's own `time`. Returns `null`
@@ -1320,7 +1384,7 @@ class _e extends Et {
1320
1384
  /** Get the primary display color for a series. */
1321
1385
  getSeriesColor(t) {
1322
1386
  const e = this.#t.find((i) => i.id === t);
1323
- return e ? e.renderer.getLayerColors()[0] ?? this.#n.line.color : null;
1387
+ return e ? e.renderer.getLayerColors()[0] ?? this.#h.line.color : null;
1324
1388
  }
1325
1389
  /** The series' primary name (first layer). Used for single-layer overlays. */
1326
1390
  getSeriesLabel(t) {
@@ -1338,7 +1402,7 @@ class _e extends Et {
1338
1402
  */
1339
1403
  setSeriesLabels(t, e) {
1340
1404
  const i = this.#t.find((s) => s.id === t);
1341
- !i || Q(i.labels, e) || (i.labels = e, this.#u());
1405
+ !i || ht(i.labels, e) || (i.labels = e, this.#m());
1342
1406
  }
1343
1407
  /**
1344
1408
  * Set the per-layer color overrides carried in `data` (sparse — `undefined`
@@ -1349,7 +1413,7 @@ class _e extends Et {
1349
1413
  */
1350
1414
  setLayerColors(t, e) {
1351
1415
  const i = this.#t.find((s) => s.id === t);
1352
- !i || de(i.colorOverrides, e) || (i.colorOverrides = e, i.renderer.setColorOverrides?.(e), this.#i.markDirty(), this.#u());
1416
+ !i || ke(i.colorOverrides, e) || (i.colorOverrides = e, i.renderer.setColorOverrides?.(e), this.#i.markDirty(), this.#m());
1353
1417
  }
1354
1418
  /** Get per-layer colors for a series. Returns null for single-layer non-bar/line series. */
1355
1419
  getSeriesLayers(t) {
@@ -1362,50 +1426,50 @@ class _e extends Et {
1362
1426
  }
1363
1427
  /** Get all slices with computed colors and percentages. Returns null for series without slice data (e.g. candlestick, line, bar). */
1364
1428
  getSliceInfo(t) {
1365
- return this.#t.find((e) => e.id === t)?.renderer.getSliceInfo?.(this.#n) ?? null;
1429
+ return this.#t.find((e) => e.id === t)?.renderer.getSliceInfo?.(this.#h) ?? null;
1366
1430
  }
1367
1431
  /** Get hover info (label/value/percent/color) for the currently hovered element, or null. */
1368
1432
  getHoverInfo(t) {
1369
- return this.#t.find((e) => e.id === t)?.renderer.getHoverInfo?.(this.#n) ?? null;
1433
+ return this.#t.find((e) => e.id === t)?.renderer.getHoverInfo?.(this.#h) ?? null;
1370
1434
  }
1371
1435
  /** Apply a new theme and update series colors where appropriate. */
1372
1436
  setTheme(t) {
1373
- const e = this.#n;
1374
- this.#n = t;
1437
+ const e = this.#h;
1438
+ this.#h = t;
1375
1439
  for (const i of this.#t)
1376
1440
  i.renderer.applyTheme(t, e);
1377
- this.#i.markDirty(), this.#u();
1441
+ this.#i.markDirty(), this.#m();
1378
1442
  }
1379
1443
  getTheme() {
1380
- return this.#n;
1444
+ return this.#h;
1381
1445
  }
1382
1446
  /** BCP 47 locale applied to the built-in time-axis / tooltip / crosshair formatting. */
1383
1447
  setLocale(t) {
1384
- this.timeScale.setLocale(t), this.#u();
1448
+ this.timeScale.setLocale(t), this.#m();
1385
1449
  }
1386
1450
  getLocale() {
1387
1451
  return this.timeScale.getLocale();
1388
1452
  }
1389
1453
  /** IANA timezone applied to the same built-in date-time formatting. */
1390
1454
  setTimeZone(t) {
1391
- this.timeScale.setTimeZone(t), this.#u();
1455
+ this.timeScale.setTimeZone(t), this.#m();
1392
1456
  }
1393
1457
  getTimeZone() {
1394
1458
  return this.timeScale.getTimeZone();
1395
1459
  }
1396
1460
  /** Update axis configuration and re-render. */
1397
1461
  setAxis(t) {
1398
- const e = t.y?.scale ?? null, i = (d) => _(e, d);
1399
- for (const d of this.#t)
1400
- !v(d.renderer) || d.scale !== void 0 || L({ seriesId: d.id, stacking: d.renderer.stacking, isPlottable: i });
1462
+ const e = t.y?.scale ?? null, i = (c) => Q(e, c);
1463
+ for (const c of this.#t)
1464
+ !S(c.renderer) || c.scale !== void 0 || R({ seriesId: c.id, stacking: c.renderer.stacking, isPlottable: i });
1401
1465
  const s = this.#Z(), r = e !== this.yScale.getTransform(), n = t.x?.type ?? "time";
1402
- n !== this.#r && this.#I("x-type", () => It({ from: this.#r, to: n }));
1466
+ n !== this.#n && this.#V("x-type", () => Yt({ from: this.#n, to: n }));
1403
1467
  const a = this.timeScale.getBandPadding();
1404
1468
  this.timeScale.setBandPadding(t.x?.padding);
1405
1469
  const o = this.timeScale.getBandPadding(), h = a.inner !== o.inner || a.outer !== o.outer;
1406
- this.#v = t, this.#P.bounds = { min: t.y?.min, max: t.y?.max }, C({ y: t.y, isPlottable: i });
1470
+ this.#v = t, this.#w.bounds = { min: t.y?.min, max: t.y?.max }, D({ y: t.y, isPlottable: i });
1407
1471
  const l = performance.now();
1408
- r && (this.yScale.setTransform(e), this.yScale.tickTracker.reset(), this.#_() === null && this.#e.snap({ y: { min: 0, max: 0 } }, l)), this.#m = !0, this.#e.onAxisReconfig(l), this.#x(l), this.#tt(s), this.#et(), h && this.#r === "category" && this.fitContent(), this.#i.markDirty();
1472
+ r && (this.yScale.setTransform(e), this.yScale.tickTracker.reset(), this.#G() === null && this.#e.snap({ y: { min: 0, max: 0 } }, l)), this.#u = !0, this.#e.onAxisReconfig(l), this.#x(l), this.#st(s), this.#rt(), h && this.#n === "category" && this.fitContent(), this.#i.markDirty();
1409
1473
  }
1410
1474
  /**
1411
1475
  * Replace the named Y scales (see {@link ChartOptions.scales}). Added,
@@ -1414,69 +1478,69 @@ class _e extends Et {
1414
1478
  */
1415
1479
  setScales(t) {
1416
1480
  const e = t ?? {};
1417
- if (Ut(e, this.#At)) return;
1418
- const i = this.#Z(), s = this.#Xt(e);
1419
- this.#St();
1481
+ if (ie(e, this.#It)) return;
1482
+ const i = this.#Z(), s = this.#qt(e);
1483
+ this.#wt();
1420
1484
  const r = performance.now(), n = {};
1421
1485
  for (const a of s)
1422
- this.#_(void 0, a) === null && (n[a] = { min: 0, max: 0 });
1423
- this.#e.snap({ scales: n }, r), this.#m = !0, this.#e.onAxisReconfig(r), this.#x(r), this.#tt(i), this.emit("viewportChange"), this.#u(), this.#i.markDirty();
1486
+ this.#G(void 0, a) === null && (n[a] = { min: 0, max: 0 });
1487
+ this.#e.snap({ scales: n }, r), this.#u = !0, this.#e.onAxisReconfig(r), this.#x(r), this.#st(i), this.emit("viewportChange"), this.#m(), this.#i.markDirty();
1424
1488
  }
1425
1489
  /**
1426
1490
  * Create, update and drop named-scale slots to match `next`, in its key
1427
1491
  * order. Returns the ids of existing scales whose transform changed.
1428
1492
  */
1429
- #Xt(t) {
1493
+ #qt(t) {
1430
1494
  const e = /* @__PURE__ */ new Map(), i = [];
1431
1495
  for (const [s, r] of Object.entries(t)) {
1432
1496
  const n = r.scale ?? null;
1433
- let a = this.#a.get(s);
1497
+ let a = this.#o.get(s);
1434
1498
  if (a === void 0) {
1435
- const o = new U();
1436
- o.setTransform(n), o.tickTracker.setFadeMs(this.#g.axis.ticksMs), a = { ...j(o, r), config: r, column: null };
1499
+ const o = new J();
1500
+ o.setTransform(n), o.tickTracker.setFadeMs(this.#g.axis.ticksMs), a = { ...rt(o, r), config: r, column: null };
1437
1501
  } else n !== a.yScale.getTransform() && (a.yScale.setTransform(n), a.yScale.tickTracker.reset(), i.push(s));
1438
- a.config = { ...r }, a.bounds = { min: r.min, max: r.max }, C({
1502
+ a.config = { ...r }, a.bounds = { min: r.min, max: r.max }, D({
1439
1503
  y: r,
1440
- isPlottable: (o) => _(n, o),
1504
+ isPlottable: (o) => Q(n, o),
1441
1505
  path: `scales.${s}`
1442
1506
  }), e.set(s, a);
1443
1507
  }
1444
- return this.#a = e, this.#At = Object.fromEntries([...e].map(([s, r]) => [s, r.config])), this.#e.setYScales([...e.keys()]), i;
1508
+ return this.#o = e, this.#It = Object.fromEntries([...e].map(([s, r]) => [s, r.config])), this.#e.setYScales([...e.keys()]), i;
1445
1509
  }
1446
1510
  /**
1447
1511
  * Hand out the Y-axis columns: the default axis keeps its side, and each
1448
1512
  * visible named scale takes its side unless an earlier one holds it —
1449
1513
  * that one becomes an overlay scale (dev warning).
1450
1514
  */
1451
- #St() {
1515
+ #wt() {
1452
1516
  const t = /* @__PURE__ */ new Set();
1453
1517
  this.yAxisWidth > 0 && t.add(this.yAxisPosition);
1454
- const e = q(this.yAxisPosition);
1455
- for (const [i, s] of this.#a) {
1456
- if (s.column = null, this.#j(s.config) <= 0) continue;
1518
+ const e = at(this.yAxisPosition);
1519
+ for (const [i, s] of this.#o) {
1520
+ if (s.column = null, this.#q(s.config) <= 0) continue;
1457
1521
  const r = s.config.position ?? e;
1458
1522
  if (t.has(r)) {
1459
- this.#I(`side:${i}`, () => kt({ scaleId: i, side: r }));
1523
+ this.#V(`side:${i}`, () => Dt({ scaleId: i, side: r }));
1460
1524
  continue;
1461
1525
  }
1462
1526
  t.add(r), s.column = r;
1463
1527
  }
1464
1528
  }
1465
1529
  /** Dev warnings for a series' `scale`: an id `scales` doesn't define, a percent stack on a scale without 0. */
1466
- #fe(t) {
1530
+ #Me(t) {
1467
1531
  const e = t.scale;
1468
- e !== void 0 && (this.#a.has(e) || this.#I(`unknown:${e}`, () => wt({ seriesId: t.id, scaleId: e })), tt(t.renderer) === "percent" && !this.getYScale(this.#D(t)).isPlottable(0) && this.#I(`percent:${t.id}`, () => Tt({ seriesId: t.id })));
1532
+ e !== void 0 && (this.#o.has(e) || this.#V(`unknown:${e}`, () => Rt({ seriesId: t.id, scaleId: e })), lt(t.renderer) === "percent" && !this.getYScale(this.#I(t)).isPlottable(0) && this.#V(`percent:${t.id}`, () => Vt({ seriesId: t.id })));
1469
1533
  }
1470
- #I(t, e) {
1471
- this.#Mt.has(t) || (this.#Mt.add(t), e());
1534
+ #V(t, e) {
1535
+ this.#Dt.has(t) || (this.#Dt.add(t), e());
1472
1536
  }
1473
1537
  /** Ids of the named Y scales, in declaration order. */
1474
1538
  getYScaleIds() {
1475
- return [...this.#a.keys()];
1539
+ return [...this.#o.keys()];
1476
1540
  }
1477
1541
  /** The Y scale named `scaleId`; the default scale for `undefined` or an id `scales` doesn't define. */
1478
1542
  getYScale(t) {
1479
- return t === void 0 ? this.yScale : this.#a.get(t)?.yScale ?? this.yScale;
1543
+ return t === void 0 ? this.yScale : this.#o.get(t)?.yScale ?? this.yScale;
1480
1544
  }
1481
1545
  /**
1482
1546
  * The column a scale's axis sits in — always the default axis's for
@@ -1484,31 +1548,31 @@ class _e extends Et {
1484
1548
  */
1485
1549
  getYScaleColumn(t) {
1486
1550
  if (t === void 0) return { position: this.yAxisPosition, width: this.yAxisWidth };
1487
- const e = this.#a.get(t);
1488
- return e === void 0 || e.column === null ? null : { position: e.column, width: this.#j(e.config) };
1551
+ const e = this.#o.get(t);
1552
+ return e === void 0 || e.column === null ? null : { position: e.column, width: this.#q(e.config) };
1489
1553
  }
1490
1554
  /** The named scale a series maps through, `undefined` for the default scale. */
1491
1555
  getSeriesScale(t) {
1492
1556
  const e = this.#t.find((i) => i.id === t);
1493
- return e === void 0 ? void 0 : this.#D(e);
1557
+ return e === void 0 ? void 0 : this.#I(e);
1494
1558
  }
1495
1559
  /** `scale` if `options.scales` defines it, else `undefined` (the default scale). */
1496
- #ge(t) {
1497
- return t !== void 0 && this.#a.has(t) ? t : void 0;
1560
+ #Ae(t) {
1561
+ return t !== void 0 && this.#o.has(t) ? t : void 0;
1498
1562
  }
1499
- #D(t) {
1500
- return this.#ge(t.scale);
1563
+ #I(t) {
1564
+ return this.#Ae(t.scale);
1501
1565
  }
1502
- #pe(t) {
1503
- return t === void 0 ? this.#P : this.#a.get(t) ?? this.#P;
1566
+ #Pe(t) {
1567
+ return t === void 0 ? this.#w : this.#o.get(t) ?? this.#w;
1504
1568
  }
1505
1569
  /** The series a scale autoscales from. */
1506
- #ye(t) {
1507
- return this.#a.size === 0 ? this.#t : this.#t.filter((e) => this.#D(e) === t);
1570
+ #Ce(t) {
1571
+ return this.#o.size === 0 ? this.#t : this.#t.filter((e) => this.#I(e) === t);
1508
1572
  }
1509
1573
  /** Snap every scale to a fresh fit — what each one holds just changed. */
1510
- #xe() {
1511
- this.#m = !0;
1574
+ #Le() {
1575
+ this.#u = !0;
1512
1576
  const t = performance.now();
1513
1577
  this.#e.onAxisReconfig(t), this.#x(t), this.emit("viewportChange"), this.#i.markDirty();
1514
1578
  }
@@ -1518,7 +1582,7 @@ class _e extends Et {
1518
1582
  * picks a named scale; an id `scales` doesn't define is a no-op.
1519
1583
  */
1520
1584
  setYAxisFormat(t) {
1521
- t.scale !== void 0 && !this.#a.has(t.scale) || (this.getYScale(t.scale).setFormat(t.format), this.#u());
1585
+ t.scale !== void 0 && !this.#o.has(t.scale) || (this.getYScale(t.scale).setFormat(t.format), this.#m());
1522
1586
  }
1523
1587
  /**
1524
1588
  * Apply label-density knobs driven by `<YAxis labelCount=… minLabelSpacing=…>`
@@ -1528,7 +1592,7 @@ class _e extends Et {
1528
1592
  * charts react without waiting for pan/zoom.
1529
1593
  */
1530
1594
  setYAxisLabelDensity(t) {
1531
- if (t.scale !== void 0 && !this.#a.has(t.scale)) return;
1595
+ if (t.scale !== void 0 && !this.#o.has(t.scale)) return;
1532
1596
  const e = this.getYScale(t.scale);
1533
1597
  let i = !1;
1534
1598
  "labelCount" in t && (e.setLabelCount(t.labelCount ?? null), i = !0), "minLabelSpacing" in t && (e.setMinSpacing(t.minLabelSpacing ?? null), i = !0), i && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
@@ -1539,7 +1603,7 @@ class _e extends Et {
1539
1603
  * info-bar headers read it.
1540
1604
  */
1541
1605
  setXAxisFormat(t) {
1542
- this.timeScale.setFormat(t), this.#u();
1606
+ this.timeScale.setFormat(t), this.#m();
1543
1607
  }
1544
1608
  /** Label-density knobs for the X axis — mirror of {@link setYAxisLabelDensity}. */
1545
1609
  setTimeAxisLabelDensity(t) {
@@ -1547,11 +1611,11 @@ class _e extends Et {
1547
1611
  "labelCount" in t && (this.timeScale.setLabelCount(t.labelCount ?? null), e = !0), "minLabelSpacing" in t && (this.timeScale.setMinSpacing(t.minLabelSpacing ?? null), e = !0), e && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
1548
1612
  }
1549
1613
  getMediaSize() {
1550
- return this.#l.size.media;
1614
+ return this.#c.size.media;
1551
1615
  }
1552
1616
  /** Returns layout metrics for the chart area, Y axis, and time axis. */
1553
1617
  getLayout() {
1554
- const t = this.#l.size.media, e = this.yAxisWidth, i = this.xAxisHeight, s = t.width - this.#w();
1618
+ const t = this.#c.size.media, e = this.yAxisWidth, i = this.xAxisHeight, s = t.width - this.#k();
1555
1619
  return {
1556
1620
  chartArea: { x: this.plotLeft, y: 0, width: s, height: t.height - i },
1557
1621
  yAxisWidth: e,
@@ -1560,7 +1624,7 @@ class _e extends Et {
1560
1624
  };
1561
1625
  }
1562
1626
  getDataInterval() {
1563
- return this.#o;
1627
+ return this.#r;
1564
1628
  }
1565
1629
  /**
1566
1630
  * Update viewport padding at runtime. Refits the visible time range to
@@ -1571,18 +1635,15 @@ class _e extends Et {
1571
1635
  * InfoBar ResizeObserver).
1572
1636
  */
1573
1637
  setPadding(t) {
1574
- const e = this.#d;
1575
- this.#d = E(t);
1576
- const i = this.#d, s = !B(e.left, i.left) || !B(e.right, i.right), r = e.top !== i.top || e.bottom !== i.bottom;
1638
+ const e = this.#l;
1639
+ this.#l = U(t);
1640
+ const i = this.#l, s = !G(e.left, i.left) || !G(e.right, i.right), r = e.top !== i.top || e.bottom !== i.bottom;
1577
1641
  if (s) {
1578
- const { first: n, last: a } = this.getDataBounds();
1579
- if (n !== void 0 && a !== void 0) {
1580
- const o = this.#l.size.media.width - this.#w();
1581
- this.#O(n, a, o);
1582
- }
1642
+ const n = this.#c.size.media.width - this.#k();
1643
+ this.#At(n);
1583
1644
  }
1584
1645
  if (s || r) {
1585
- this.#m = !0;
1646
+ this.#u = !0;
1586
1647
  const n = performance.now();
1587
1648
  this.#e.onAxisReconfig(n), this.#x(n);
1588
1649
  }
@@ -1590,7 +1651,7 @@ class _e extends Et {
1590
1651
  }
1591
1652
  /** Show or hide the background grid. Takes effect on the next render frame. */
1592
1653
  setGrid(t) {
1593
- this.#G = t.visible, this.#i.markDirty();
1654
+ this.#j = t.visible, this.#i.markDirty();
1594
1655
  }
1595
1656
  /**
1596
1657
  * Set or clear the edge fade masks (see {@link ChartOptions.fade}).
@@ -1600,14 +1661,14 @@ class _e extends Et {
1600
1661
  * the next render frame.
1601
1662
  */
1602
1663
  setFade(t) {
1603
- const e = Y(t), i = this.#C;
1664
+ const e = _(t), i = this.#C;
1604
1665
  e.top === i.top && e.right === i.right && e.left === i.left || (this.#C = e, this.#i.markDirty());
1605
1666
  }
1606
1667
  /** Report the floating header's height (see {@link headerHeight}). The
1607
1668
  * framework wrappers keep it in sync with the measured Title / InfoBar. */
1608
1669
  setHeaderHeight(t) {
1609
1670
  const e = Number.isFinite(t) && t > 0 ? t : 0;
1610
- e !== this.#at && (this.#at = e, this.#u());
1671
+ e !== this.#ht && (this.#ht = e, this.#m());
1611
1672
  }
1612
1673
  /**
1613
1674
  * Set the visual state for one side of the chart. Typically called in
@@ -1620,8 +1681,8 @@ class _e extends Et {
1620
1681
  */
1621
1682
  setEdgeState(t, e) {
1622
1683
  if (this.#A[t] === e || !this.checkTimeOnlyFeature("EdgeLoader")) return;
1623
- const i = this.#A[t] === "loading", s = this.#B[t];
1624
- this.#B[t] = !1, this.#K[t] = i && !s && (e === "idle" || e === "has-more") ? performance.now() : null, this.#A[t] = e, this.#c.markDirty();
1684
+ const i = this.#A[t] === "loading", s = this.#E[t];
1685
+ this.#E[t] = !1, this.#K[t] = i && !s && (e === "idle" || e === "has-more") ? performance.now() : null, this.#A[t] = e, this.#d.markDirty();
1625
1686
  }
1626
1687
  /** Read the current host-declared state for a given edge. */
1627
1688
  getEdgeState(t) {
@@ -1631,11 +1692,11 @@ class _e extends Et {
1631
1692
  * Alpha for a side's `loading` exit fade, or `null` when none is in
1632
1693
  * flight. Self-cleaning: an elapsed fade clears its start stamp.
1633
1694
  */
1634
- #Zt(t) {
1695
+ #Jt(t) {
1635
1696
  const e = this.#K[t];
1636
1697
  if (e === null) return null;
1637
- const i = (performance.now() - e) / Jt;
1638
- return i >= 1 ? (this.#K[t] = null, null) : 1 - W(Math.max(0, i));
1698
+ const i = (performance.now() - e) / oe;
1699
+ return i >= 1 ? (this.#K[t] = null, null) : 1 - X(Math.max(0, i));
1639
1700
  }
1640
1701
  /**
1641
1702
  * Swap the painter used for a side's `loading` spinner — the same
@@ -1644,7 +1705,7 @@ class _e extends Et {
1644
1705
  * immediately if that side is currently in the `loading` state.
1645
1706
  */
1646
1707
  setEdgeIndicator(t, e) {
1647
- e !== null && !this.checkTimeOnlyFeature("EdgeLoader") || (this.#It[t] = e, this.#A[t] === "loading" && this.#c.markDirty());
1708
+ e !== null && !this.checkTimeOnlyFeature("EdgeLoader") || (this.#$t[t] = e, this.#A[t] === "loading" && this.#d.markDirty());
1648
1709
  }
1649
1710
  /**
1650
1711
  * Resolve the boundary point's Y position and series kind on the primary
@@ -1654,14 +1715,14 @@ class _e extends Et {
1654
1715
  * `open` (the value immediately preceding the boundary); `right` from the
1655
1716
  * last visible candle's `close`.
1656
1717
  */
1657
- #ve(t, e) {
1718
+ #Ie(t, e) {
1658
1719
  const i = this.getSeriesIdsByType("time", { visibleOnly: !0, singleLayerOnly: !0 })[0] ?? this.getSeriesIdsByType("time", { visibleOnly: !0 })[0];
1659
1720
  if (!i) return null;
1660
1721
  const s = this.getDataAtTime(i, e);
1661
1722
  if (!s) return null;
1662
1723
  const r = this.#t.find((n) => n.id === i);
1663
1724
  return r ? {
1664
- valueY: this.getYScale(this.#D(r)).valueToY(dt(t, s)),
1725
+ valueY: this.getYScale(this.#I(r)).valueToY(bt(t, s)),
1665
1726
  seriesKind: r.renderer.kind
1666
1727
  } : null;
1667
1728
  }
@@ -1671,8 +1732,8 @@ class _e extends Et {
1671
1732
  * placeholder shapes to match the real bars that will render once data
1672
1733
  * lands. `null` when the viewport has no meaningful span yet.
1673
1734
  */
1674
- #Se() {
1675
- const t = this.timeScale.barWidthMedia(this.#o);
1735
+ #De() {
1736
+ const t = this.timeScale.barWidthMedia(this.#r);
1676
1737
  return Number.isFinite(t) && t > 0 ? t : null;
1677
1738
  }
1678
1739
  /**
@@ -1690,8 +1751,8 @@ class _e extends Et {
1690
1751
  * probed, not kind-gated: a kind check here silently kills hover for the
1691
1752
  * next spatial renderer.
1692
1753
  */
1693
- #bt(t) {
1694
- const e = this.#l.size, i = this.#d, s = {
1754
+ #Mt(t) {
1755
+ const e = this.#c.size, i = this.#l, s = {
1695
1756
  top: i.top * e.verticalPixelRatio,
1696
1757
  bottom: i.bottom * e.verticalPixelRatio
1697
1758
  };
@@ -1703,7 +1764,7 @@ class _e extends Et {
1703
1764
  const h = (t.mediaX - this.plotLeft) * e.horizontalPixelRatio, l = t.mediaY * e.verticalPixelRatio;
1704
1765
  o = a.renderer.hitTest(h, l, e.bitmap.width, e.bitmap.height, s);
1705
1766
  }
1706
- a.renderer.setHoverIndex(o) && (r = !0), o >= 0 && !n && (n = { seriesId: a.id, index: o, info: a.renderer.getHoverInfo?.(this.#n) ?? null });
1767
+ a.renderer.setHoverIndex(o) && (r = !0), o >= 0 && !n && (n = { seriesId: a.id, index: o, info: a.renderer.getHoverInfo?.(this.#h) ?? null });
1707
1768
  }
1708
1769
  r && (this.#i.markDirty(), this.emit("seriesHover", n));
1709
1770
  }
@@ -1714,8 +1775,8 @@ class _e extends Et {
1714
1775
  * Returns the first spatial series (pie, heatmap, or a custom spatial kind)
1715
1776
  * whose `hitTest` claims the position, or `null` if none does.
1716
1777
  */
1717
- #Ut(t) {
1718
- const e = this.#l.size, i = this.#d, s = {
1778
+ #Qt(t) {
1779
+ const e = this.#c.size, i = this.#l, s = {
1719
1780
  top: i.top * e.verticalPixelRatio,
1720
1781
  bottom: i.bottom * e.verticalPixelRatio
1721
1782
  }, r = (t.mediaX - this.plotLeft) * e.horizontalPixelRatio, n = t.mediaY * e.verticalPixelRatio;
@@ -1746,42 +1807,42 @@ class _e extends Et {
1746
1807
  * viewport didn't move, the re-derived values are bit-identical and the
1747
1808
  * method exits without emitting.
1748
1809
  */
1749
- #be() {
1750
- const t = this.#nt;
1751
- this.#nt = !1;
1810
+ #Re() {
1811
+ const t = this.#ot;
1812
+ this.#ot = !1;
1752
1813
  const e = this.#f;
1753
1814
  if (e === null) return;
1754
1815
  const { from: i, to: s } = this.timeScale.getRange(), r = this.yScale.getRange(), n = Math.abs(s - i) * 1e-9, a = Math.abs(r.max - r.min) * 1e-9, o = 1e-6;
1755
1816
  let h;
1756
- if (this.#ot === "pointer") {
1757
- const l = this.timeScale.snapToBand(this.timeScale.xToTime(e.mediaX - this.plotLeft)), d = this.yScale.yToValue(e.mediaY);
1758
- if (!Number.isFinite(l) || !Number.isFinite(d) || Math.abs(l - e.time) <= n && Math.abs(d - e.y) <= a && !t && e.x === this.timeScale.domainValue(e.time)) return;
1759
- h = { mediaX: e.mediaX, mediaY: e.mediaY, time: l, x: this.timeScale.domainValue(l), y: d };
1817
+ if (this.#lt === "pointer") {
1818
+ const l = this.timeScale.snapToBand(this.timeScale.xToTime(e.mediaX - this.plotLeft)), c = this.yScale.yToValue(e.mediaY);
1819
+ if (!Number.isFinite(l) || !Number.isFinite(c) || Math.abs(l - e.time) <= n && Math.abs(c - e.y) <= a && !t && e.x === this.timeScale.domainValue(e.time)) return;
1820
+ h = { mediaX: e.mediaX, mediaY: e.mediaY, time: l, x: this.timeScale.domainValue(l), y: c };
1760
1821
  } else {
1761
1822
  if (e.time < i || e.time > s) {
1762
- this.#f = null, this.#c.markDirty(), this.emit("crosshairMove", null), this.#bt(null);
1823
+ this.#f = null, this.#d.markDirty(), this.emit("crosshairMove", null), this.#Mt(null);
1763
1824
  return;
1764
1825
  }
1765
- const l = this.plotLeft + this.timeScale.timeToX(e.time), d = this.yScale.valueToY(e.y);
1766
- if (!Number.isFinite(l) || !Number.isFinite(d) || Math.abs(l - e.mediaX) <= o && Math.abs(d - e.mediaY) <= o && !t && e.x === this.timeScale.domainValue(e.time)) return;
1767
- h = { mediaX: l, mediaY: d, time: e.time, x: this.timeScale.domainValue(e.time), y: e.y };
1826
+ const l = this.plotLeft + this.timeScale.timeToX(e.time), c = this.yScale.valueToY(e.y);
1827
+ if (!Number.isFinite(l) || !Number.isFinite(c) || Math.abs(l - e.mediaX) <= o && Math.abs(c - e.mediaY) <= o && !t && e.x === this.timeScale.domainValue(e.time)) return;
1828
+ h = { mediaX: l, mediaY: c, time: e.time, x: this.timeScale.domainValue(e.time), y: e.y };
1768
1829
  }
1769
- this.#f = h, this.#c.markDirty(), this.emit("crosshairMove", h), this.#bt(h);
1830
+ this.#f = h, this.#d.markDirty(), this.emit("crosshairMove", h), this.#Mt(h);
1770
1831
  }
1771
1832
  /** Tear down the chart: cancel animations, remove listeners, and detach the canvas. */
1772
1833
  destroy() {
1773
1834
  for (const t of this.#t) t.renderer.dispose();
1774
- this.#t = [], this.#y = [], this.#T = [], this.#b = [], this.#z = null, this.#i.destroy(), this.#c.destroy(), this.#V?.destroy(), this.#l.destroy(), this.#ut?.destroy(), this.#ut = null, this.#dt && this.#M?.destroy(), this.#M = null, this.#dt = !1, this.removeAllListeners();
1835
+ this.#t = [], this.#y = [], this.#M = [], this.#S = [], this.#F = null, this.#i.destroy(), this.#d.destroy(), this.#N?.destroy(), this.#c.destroy(), this.#pt?.destroy(), this.#pt = null, this.#gt && this.#P?.destroy(), this.#P = null, this.#gt = !1, this.removeAllListeners();
1775
1836
  }
1776
1837
  /** The attached performance monitor, or `null` when instrumentation is disabled. */
1777
1838
  getPerfMonitor() {
1778
- return this.#M;
1839
+ return this.#P;
1779
1840
  }
1780
1841
  /** Compute the earliest and latest timestamps across all series. */
1781
1842
  getDataBounds() {
1782
1843
  let t, e;
1783
1844
  for (const i of this.#t) {
1784
- if (!i.visible || !v(i.renderer)) continue;
1845
+ if (!i.visible || !S(i.renderer)) continue;
1785
1846
  const s = i.renderer.getTimeBounds();
1786
1847
  s !== null && ((t === void 0 || s.first < t) && (t = s.first), (e === void 0 || s.last > e) && (e = s.last));
1787
1848
  }
@@ -1790,62 +1851,72 @@ class _e extends Et {
1790
1851
  /** Set by `setSeriesData`/bulk-replace paths so the next `onDataChanged`
1791
1852
  * snaps the Y range (instead of easing) and `yScale.getRange()` reflects
1792
1853
  * the new domain synchronously. Cleared by `onDataChanged` after each run. */
1793
- #kt = !1;
1854
+ #nt = !1;
1794
1855
  onDataChanged() {
1795
1856
  if (this.#R > 0) {
1796
- this.#lt = !0;
1857
+ this.#dt = !0;
1797
1858
  return;
1798
1859
  }
1799
- this.updateDataInterval();
1860
+ this.updateDataInterval({ full: this.#nt || !this.#u });
1800
1861
  const { first: t, last: e } = this.getDataBounds();
1801
- t !== void 0 && (this.#S = t), e !== void 0 && (this.#q = this.#s, this.#s = e);
1802
- const i = this.#kt;
1803
- this.#kt = !1;
1804
- const s = !this.#m && t !== void 0;
1862
+ t !== void 0 && (this.#T = t), e !== void 0 && (this.#J = this.#s, this.#s = e);
1863
+ const i = this.#nt;
1864
+ this.#nt = !1;
1865
+ const s = !this.#u && t !== void 0;
1805
1866
  if (i) {
1806
1867
  this.yScale.tickTracker.reset(), this.timeScale.tickTracker.reset();
1807
- for (const n of this.#a.values())
1868
+ for (const n of this.#o.values())
1808
1869
  n.yScale.tickTracker.reset();
1809
1870
  }
1810
- this.#Vt = i;
1871
+ this.#Yt = i;
1811
1872
  const r = performance.now();
1812
- i || s ? (this.#F.seed(r), this.#e.onDataReplaced(r)) : this.#e.onPointAppended(r), this.#e.lastXTarget !== null && (this.#U = !0), t !== void 0 && (this.#m = !0), this.#x(r), this.syncScales(), s ? this.#wt() : this.#i.markDirty(), this.emit("dataUpdate"), this.#u();
1873
+ i || s ? (this.#W.seed(r), this.#e.onDataReplaced(r)) : this.#e.onPointAppended(r), this.#e.lastXTarget !== null && (this.#_ = !0), t !== void 0 && (this.#u = !0), this.#x(r), this.syncScales(), s ? this.#Ct() : this.#i.markDirty(), this.emit("dataUpdate"), this.#m();
1813
1874
  }
1814
- updateDataInterval() {
1815
- if (this.#r === "category") {
1816
- this.#o = 1;
1875
+ /** `full`: the data was replaced, so a long series is read whole instead of from its tail. */
1876
+ updateDataInterval(t) {
1877
+ if (this.#n === "category") {
1878
+ this.#r = 1;
1817
1879
  return;
1818
1880
  }
1819
- for (const t of this.#t) {
1820
- if (!v(t.renderer)) continue;
1821
- const e = t.renderer.sampleTimes(20);
1822
- if (e.length >= 2) {
1823
- this.#o = qt(e);
1824
- break;
1881
+ for (const e of this.#t) {
1882
+ if (!S(e.renderer)) continue;
1883
+ const i = e.renderer.sampleTimes(it + 1);
1884
+ if (!(i.length < 2)) {
1885
+ this.#r = this.#Ve({ renderer: e.renderer, head: i, full: t.full });
1886
+ return;
1825
1887
  }
1826
1888
  }
1827
1889
  }
1890
+ /** The step of one series. Past {@link FULL_INTERVAL_SCAN_POINTS}, an append can only refine it from the tail. */
1891
+ #Ve(t) {
1892
+ const { renderer: e, head: i, full: s } = t;
1893
+ if (i.length <= it) return V(i);
1894
+ if (s) return V(e.sampleTimes(Number.POSITIVE_INFINITY));
1895
+ const r = e.sampleTimes(st, "end");
1896
+ return r.length < st ? this.#r : Math.min(this.#r, V(r));
1897
+ }
1828
1898
  /** Whether the Y range has been initialized (first snap vs smooth lerp).
1829
1899
  * Pre-init Y emits are forced to `instant` so the first paint snaps to
1830
1900
  * data regardless of the caller's requested kind. Also reset by paths
1831
1901
  * that intentionally invalidate the current Y baseline (axis bound
1832
1902
  * change, empty viewport). */
1833
- #m = !1;
1903
+ #u = !1;
1834
1904
  /** Whether the engine's X slot has received its first emit. Pre-init X
1835
1905
  * emits are forced to `instant` so first paint snaps to the fitted
1836
1906
  * range — without this guard the engine would ease from `{0,0}` into
1837
1907
  * the new target and the very first frame would render with a
1838
1908
  * zero-width X domain. */
1839
- #U = !1;
1909
+ #_ = !1;
1840
1910
  /**
1841
- * One-shot `setVisibleRange` argument applied on the first data arrival.
1842
- * Captured at chart construction from {@link ChartOptions.viewport.initialRange};
1843
- * cleared the moment it's consumed so subsequent data swaps don't snap
1844
- * back to the initial window.
1911
+ * {@link ChartOptions.viewport.initialRange}: the chart's own window until the
1912
+ * user or the app moves the view, so more series or a re-seed keep it. A
1913
+ * `{ from, to }` or `{ from, bars }` window also ends once streaming moves it.
1845
1914
  */
1846
- #it;
1915
+ #H;
1916
+ /** The chart's own fit holds fewer bars than it asks for, so appends widen it until it is full. */
1917
+ #U = !1;
1847
1918
  /** Dev warning for values the Y scale can't place — fires once per chart. */
1848
- #_t = !1;
1919
+ #te = !1;
1849
1920
  /**
1850
1921
  * Sample the visible data window and return the resolved Y bounds of one
1851
1922
  * scale (`undefined` = default) in its scale space (see {@link resolveYTarget}),
@@ -1855,23 +1926,23 @@ class _e extends Et {
1855
1926
  * converge together. Clears {@link #yInited} on empty so the next emit
1856
1927
  * with valid data lands as an instant snap.
1857
1928
  */
1858
- #_(t, e) {
1859
- const i = t ?? this.#h, { yScale: s, bounds: r } = this.#pe(e), n = r.min !== void 0 && r.min !== "auto" && typeof r.min != "number" || r.max !== void 0 && r.max !== "auto" && typeof r.max != "number" ? [] : null, a = this.#ye(e), o = s.getTransform(), h = o === null ? void 0 : (d) => s.isPlottable(d);
1860
- h && this.#ke({ window: i, series: a, yScale: s });
1861
- const l = Vt({ targetVisible: i, series: a, allValues: n, plottable: h });
1862
- return l === null ? (e === void 0 && (this.#m = !1), null) : (e !== void 0 && (this.#m = !0), zt({ raw: l, bounds: r, allValues: n ?? [], transform: o }));
1929
+ #G(t, e) {
1930
+ const i = t ?? this.#a, { yScale: s, bounds: r } = this.#Pe(e), n = r.min !== void 0 && r.min !== "auto" && typeof r.min != "number" || r.max !== void 0 && r.max !== "auto" && typeof r.max != "number" ? [] : null, a = this.#Ce(e), o = s.getTransform(), h = o === null ? void 0 : (c) => s.isPlottable(c);
1931
+ h && this.#He({ window: i, series: a, yScale: s });
1932
+ const l = Bt({ targetVisible: i, series: a, allValues: n, plottable: h });
1933
+ return l === null ? (e === void 0 && (this.#u = !1), null) : (e !== void 0 && (this.#u = !0), Xt({ raw: Zt(l), bounds: r, allValues: n ?? [], transform: o }));
1863
1934
  }
1864
1935
  /** Dev-only sweep behind {@link warnUnplottableValues}; stops once it has warned. */
1865
- #ke(t) {
1866
- if (this.#_t || process.env.NODE_ENV === "production") return;
1936
+ #He(t) {
1937
+ if (this.#te || process.env.NODE_ENV === "production") return;
1867
1938
  const { window: e, series: i, yScale: s } = t;
1868
1939
  for (const r of i) {
1869
- if (!r.visible || !v(r.renderer)) continue;
1940
+ if (!r.visible || !S(r.renderer)) continue;
1870
1941
  const n = r.renderer.getValueRange(e.from, e.to);
1871
1942
  if (n === null) continue;
1872
1943
  const a = (r.renderer.stacking === "normal" || r.renderer.stacking === "percent" ? n.min < 0 && !s.isPlottable(n.min) : !s.isPlottable(n.min)) ? n.min : s.isPlottable(n.max) ? null : n.max;
1873
1944
  if (a !== null) {
1874
- this.#_t = !0, At({ seriesId: r.id, value: a });
1945
+ this.#te = !0, Ht({ seriesId: r.id, value: a });
1875
1946
  return;
1876
1947
  }
1877
1948
  }
@@ -1894,53 +1965,112 @@ class _e extends Et {
1894
1965
  * - **autoscroll off** → `null` (no X retarget; user has panned away
1895
1966
  * from the tail).
1896
1967
  */
1897
- #we() {
1898
- if (this.#S === null || this.#s === null) return null;
1899
- const { from: t, to: e } = this.#h, i = t === 0 && e === 0, s = this.#l.size.media.width - this.#w();
1900
- if (this.#r === "category")
1901
- return this.#O(this.#S, this.#s, s), this.#h;
1902
- if (i) {
1903
- if (this.#O(this.#S, this.#s, s), this.#it !== void 0 && (this.setVisibleRange(this.#it), this.#it = void 0, !this.#p && this.#s !== null)) {
1904
- const { to: n } = this.#h;
1905
- this.#s >= n && this.#s - n <= this.#o * 1.5 && (this.#p = !0);
1906
- }
1907
- return this.#h;
1908
- }
1968
+ #Ne() {
1969
+ if (this.#T === null || this.#s === null) return null;
1970
+ const { from: t, to: e } = this.#a, i = t === 0 && e === 0, s = this.#c.size.media.width - this.#k();
1971
+ if (this.#n === "category")
1972
+ return this.#Pt({ firstTime: this.#T, lastTime: this.#s, chartWidth: s }), this.#a;
1973
+ if (i)
1974
+ return this.#At(s), this.#a;
1909
1975
  if (!this.#p) return null;
1910
- if (this.#Vt)
1911
- return this.#O(this.#S, this.#s, s), this.#h;
1912
- const r = Pt({
1913
- currentLogical: this.#h,
1976
+ if (this.#Yt)
1977
+ return this.#At(s), this.#a;
1978
+ if (this.#U) {
1979
+ const n = this.#ie(s);
1980
+ if (n !== null) return this.#Fe(n);
1981
+ }
1982
+ const r = Ft({
1983
+ currentLogical: this.#a,
1914
1984
  lastTime: this.#s,
1915
- prevDataEnd: this.#q,
1916
- dataInterval: this.#o,
1917
- paddingRight: this.#d.right,
1985
+ prevDataEnd: this.#J,
1986
+ dataInterval: this.#r,
1987
+ paddingRight: this.#l.right,
1918
1988
  chartWidth: s,
1919
1989
  holdUntilFilled: this.#L
1920
1990
  });
1921
- return r.releaseHold && (this.#L = !1), r.reengageAutoScroll && (this.#p = !0), r.newLogical === null ? null : (this.#F.observe(performance.now()), this.#e.setXSettleMs(this.#F.pickSettleMs(this.#g.axis.x.settleMs)), this.#H(r.newLogical, { emitChange: !1, skipValidation: !0 }), this.#q = this.#s, r.newLogical);
1991
+ return r.releaseHold && (this.#L = !1), r.reengageAutoScroll && (this.#p = !0), r.newLogical === null ? null : (typeof this.#H == "object" && (this.#H = void 0), this.#ee(r.newLogical));
1992
+ }
1993
+ /** Commit an X target that follows the data tail; the engine eases there. */
1994
+ #ee(t) {
1995
+ return this.#W.observe(performance.now()), this.#e.setXSettleMs(this.#W.pickSettleMs(this.#g.axis.x.settleMs)), this.#D(t, { emitChange: !1, skipValidation: !0 }), this.#J = this.#s, t;
1922
1996
  }
1923
1997
  /**
1924
- * Fit the viewport's logical X range around a data span. Mirrors the
1925
- * old `viewport.fitToData` side effects: clears the warm-up hold,
1926
- * forces autoscroll on (data tail is in the new window by construction),
1927
- * commits the new range via `viewport.setRange` (which emits `change`).
1998
+ * Fit X to the window the chart picks for itself: `initialRange` while it
1999
+ * holds, else every bar up to `maxVisibleBars`. Runs on the first data, on a
2000
+ * bulk replace and on a horizontal padding change.
1928
2001
  */
1929
- #O(t, e, i) {
1930
- const s = this.timeScale.bandRange();
1931
- if (this.#r === "category" && s !== null) {
1932
- this.#L = !1, this.#p = !0, this.#H(s, { emitChange: !0, skipValidation: !0 });
1933
- return;
2002
+ #At(t) {
2003
+ const e = this.#H;
2004
+ if (typeof e == "object") {
2005
+ if (this.#U = !1, this.#jt(e), this.#a.from !== 0 || this.#a.to !== 0) {
2006
+ this.#We();
2007
+ return;
2008
+ }
2009
+ this.#H = void 0;
1934
2010
  }
1935
- const r = this.#d, n = ft({
1936
- firstTime: t,
1937
- lastTime: e,
1938
- dataInterval: this.#o,
1939
- maxVisibleBars: this.#zt,
1940
- chartWidth: i,
1941
- padding: { left: r.left, right: r.right }
2011
+ const i = this.#ie(t);
2012
+ i !== null && (this.#L = !1, this.#p = !0, this.#U = i.filling, this.#D(i.range, { emitChange: !0 }));
2013
+ }
2014
+ /**
2015
+ * The chart's own window over the current data: the last `initialRange`
2016
+ * bars, else every bar up to `maxVisibleBars`. `filling` while the data holds
2017
+ * fewer bars than that. `null` before data, or for a `{ from, … }` window.
2018
+ */
2019
+ #ie(t) {
2020
+ const e = this.#H, i = this.#T, s = this.#s;
2021
+ if (i === null || s === null || typeof e == "object") return null;
2022
+ const r = e ?? this.#ft, n = Math.max(i, s - (r - 1) * this.#r);
2023
+ return { range: Z({
2024
+ firstTime: e === void 0 ? i : n,
2025
+ lastTime: s,
2026
+ dataInterval: this.#r,
2027
+ // An explicit bar count is shown whole; only the default fit is capped.
2028
+ maxVisibleBars: e === void 0 ? this.#ft : Number.POSITIVE_INFINITY,
2029
+ chartWidth: t,
2030
+ padding: { left: this.#l.left, right: this.#l.right }
2031
+ }), filling: n === i };
2032
+ }
2033
+ /** Widen the chart's own fit to the data tail. A trimmed head never narrows it (`keepLast`). */
2034
+ #Fe(t) {
2035
+ this.#U = t.filling;
2036
+ const e = this.#a, i = e.to - e.from, s = t.range.to - t.range.from;
2037
+ if (t.range.to === e.to && s <= i) return null;
2038
+ const r = Math.max(s, i);
2039
+ return this.#ee({ from: t.range.to - r, to: t.range.to });
2040
+ }
2041
+ /**
2042
+ * `setVisibleRange` reads a window that ends before the data tail as
2043
+ * "panned into history" and drops tail-follow. That is wrong for a streaming
2044
+ * lead-in that parks the seed just past the right edge so the first tick
2045
+ * scrolls it into view (the Sparkline `flow.align: 'offscreen'` drive-in) —
2046
+ * without follow-live the stream accumulates off-canvas forever. Re-arm when
2047
+ * the tail sits within ~one interval past the window.
2048
+ */
2049
+ #We() {
2050
+ if (this.#p || this.#s === null) return;
2051
+ const { to: t } = this.#a;
2052
+ this.#s >= t && this.#s - t <= this.#r * 1.5 && (this.#p = !0);
2053
+ }
2054
+ /**
2055
+ * Fit the viewport's logical X range around a data span, padding included.
2056
+ * Clears the warm-up hold, forces autoscroll on (the data tail is in the new
2057
+ * window by construction) and emits `viewportChange`. Returns whether the range changed.
2058
+ */
2059
+ #Pt(t) {
2060
+ const { firstTime: e, lastTime: i, chartWidth: s } = t;
2061
+ this.#L = !1, this.#p = !0;
2062
+ const r = this.timeScale.bandRange();
2063
+ if (this.#n === "category" && r !== null)
2064
+ return this.#D(r, { emitChange: !0, skipValidation: !0 });
2065
+ const n = Z({
2066
+ firstTime: e,
2067
+ lastTime: i,
2068
+ dataInterval: this.#r,
2069
+ maxVisibleBars: Number.POSITIVE_INFINITY,
2070
+ chartWidth: s,
2071
+ padding: { left: this.#l.left, right: this.#l.right }
1942
2072
  });
1943
- this.#L = !1, this.#p = !0, this.#H(n, { emitChange: !0 });
2073
+ return this.#D(n, { emitChange: !0 });
1944
2074
  }
1945
2075
  /**
1946
2076
  * Commit a programmatic zoom — `fitContent` or `setVisibleRange`. Reads
@@ -1956,12 +2086,12 @@ class _e extends Et {
1956
2086
  * passes `xEase: true` so X eases instead — viewport and axis converge
1957
2087
  * on the same frame.
1958
2088
  */
1959
- #st(t) {
1960
- const e = this.#h;
2089
+ #se(t) {
2090
+ const e = this.#a;
1961
2091
  if (e.to <= e.from) return;
1962
2092
  const i = performance.now();
1963
- if (!this.#U || !this.#m) {
1964
- this.#Gt(i);
2093
+ if (!this.#_ || !this.#u) {
2094
+ this.#re(i);
1965
2095
  return;
1966
2096
  }
1967
2097
  this.#e.onProgrammaticZoom({ xTarget: e, xEase: t?.xEase }, i), this.#x(i);
@@ -1978,12 +2108,12 @@ class _e extends Et {
1978
2108
  * instead of lagging on the long sticky contract. First paint still snaps
1979
2109
  * (same as the programmatic path) so synchronous readers see final values.
1980
2110
  */
1981
- #Te() {
1982
- const t = this.#h;
2111
+ #$e() {
2112
+ const t = this.#a;
1983
2113
  if (t.to <= t.from) return;
1984
2114
  const e = performance.now();
1985
- if (!this.#U || !this.#m) {
1986
- this.#Gt(e);
2115
+ if (!this.#_ || !this.#u) {
2116
+ this.#re(e);
1987
2117
  return;
1988
2118
  }
1989
2119
  this.#e.onPanZoom({ xTarget: t, yAuto: !0 }, e), this.#x(e);
@@ -1995,13 +2125,13 @@ class _e extends Et {
1995
2125
  * commits — both must snap before the chart has painted once so a
1996
2126
  * synchronous `getYRange()` / `getVisibleRange()` read sees final values.
1997
2127
  */
1998
- #Gt(t) {
1999
- const e = this.#h, i = this.#_(e), s = {};
2000
- for (const r of this.#a.keys()) {
2001
- const n = this.#_(e, r);
2128
+ #re(t) {
2129
+ const e = this.#a, i = this.#G(e), s = {};
2130
+ for (const r of this.#o.keys()) {
2131
+ const n = this.#G(e, r);
2002
2132
  n !== null && (s[r] = n);
2003
2133
  }
2004
- this.#U = !0, i !== null && (this.#m = !0), this.#e.snap({ x: e, y: i ?? void 0, scales: s }, t), this.#x(t);
2134
+ this.#_ = !0, i !== null && (this.#u = !0), this.#e.snap({ x: e, y: i ?? void 0, scales: s }, t), this.#x(t);
2005
2135
  }
2006
2136
  /**
2007
2137
  * Validate and commit a new logical X range. Mirrors the old
@@ -2021,9 +2151,9 @@ class _e extends Et {
2021
2151
  * see `setVisibleRange`'s gesture path, where a per-frame echo would
2022
2152
  * otherwise re-arm and stall the in-flight Y ease.
2023
2153
  */
2024
- #H(t, e) {
2154
+ #D(t, e) {
2025
2155
  const { from: i, to: s } = t;
2026
- return !Number.isFinite(i) || !Number.isFinite(s) || s <= i || !e.skipValidation && (s - i) / this.#o < 2 || this.#h.from === i && this.#h.to === s ? !1 : (this.#h = { from: i, to: s }, e.emitChange && (this.syncScales(), this.#i?.markDirty(), this.emit("viewportChange")), !0);
2156
+ return !Number.isFinite(i) || !Number.isFinite(s) || s <= i || !e.skipValidation && (s - i) / this.#r < 2 || this.#a.from === i && this.#a.to === s ? !1 : (this.#a = { from: i, to: s }, e.emitChange && (this.syncScales(), this.#i?.markDirty(), this.emit("viewportChange")), !0);
2027
2157
  }
2028
2158
  /**
2029
2159
  * Apply pixel-padding to the engine's Y (scale space) and return it as
@@ -2032,23 +2162,23 @@ class _e extends Et {
2032
2162
  * that has an explicit (fixed) axis bound. Padding in scale space keeps
2033
2163
  * the pixel gutters even on a log axis.
2034
2164
  */
2035
- #Ae(t) {
2036
- const { slot: e, min: i, max: s, chartHeight: r } = t, { yScale: n } = e, { min: a, max: o } = this.#Me(e), h = s - i, l = r > 0 ? this.#d.top / r * h : 0, d = r > 0 ? this.#d.bottom / r * h : 0, f = {
2037
- min: a ? i : i - d,
2165
+ #ze(t) {
2166
+ const { slot: e, min: i, max: s, chartHeight: r } = t, { yScale: n } = e, { min: a, max: o } = this.#Oe(e), h = s - i, l = r > 0 ? this.#l.top / r * h : 0, c = r > 0 ? this.#l.bottom / r * h : 0, f = {
2167
+ min: a ? i : i - c,
2038
2168
  max: o ? s : s + l
2039
- }, c = n.getTransform();
2040
- if (c === null) return f;
2041
- const m = c.inverse(f.min), y = c.inverse(f.max), u = n.isPlottable(m) && m <= c.inverse(i), g = n.isPlottable(y) && y >= c.inverse(s);
2169
+ }, g = n.getTransform();
2170
+ if (g === null) return f;
2171
+ const y = g.inverse(f.min), u = g.inverse(f.max), m = n.isPlottable(y) && y <= g.inverse(i), p = n.isPlottable(u) && u >= g.inverse(s);
2042
2172
  return {
2043
- min: u ? m : c.inverse(i),
2044
- max: g ? y : c.inverse(s)
2173
+ min: m ? y : g.inverse(i),
2174
+ max: p ? u : g.inverse(s)
2045
2175
  };
2046
2176
  }
2047
2177
  /** Which Y edges of a scale the user pinned — a pinned edge takes no padding. */
2048
- #Me(t) {
2178
+ #Oe(t) {
2049
2179
  return {
2050
- min: J(t.bounds.min, t.yScale),
2051
- max: J(t.bounds.max, t.yScale)
2180
+ min: ot(t.bounds.min, t.yScale),
2181
+ max: ot(t.bounds.max, t.yScale)
2052
2182
  };
2053
2183
  }
2054
2184
  /**
@@ -2061,18 +2191,18 @@ class _e extends Et {
2061
2191
  * as a gesture for visual easing. Public so consumers can drive pan
2062
2192
  * programmatically.
2063
2193
  */
2064
- pan(t, e = this.#J) {
2065
- e > 0 && (this.#J = e), this.#L = !1;
2066
- const i = St({
2067
- currentLogical: this.#h,
2194
+ pan(t, e = this.#Q) {
2195
+ e > 0 && (this.#Q = e), this.#L = !1, this.#et();
2196
+ const i = Lt({
2197
+ currentLogical: this.#a,
2068
2198
  timeDelta: t,
2069
2199
  chartWidth: e,
2070
- dataInterval: this.#o,
2071
- padding: { left: this.#d.left, right: this.#d.right },
2072
- dataStart: this.#S,
2200
+ dataInterval: this.#r,
2201
+ padding: { left: this.#l.left, right: this.#l.right },
2202
+ dataStart: this.#T,
2073
2203
  dataEnd: this.#s
2074
2204
  });
2075
- i.newLogical !== null && (this.#p = !i.autoScrollOff, this.#H(i.newLogical, { emitChange: !0 }), i.edgeReached !== null && (this.#Dt[i.edgeReached.side] = i.edgeReached.boundaryTime, this.#Rt?.(i.edgeReached)), this.#F.pause(), this.#Kt());
2205
+ i.newLogical !== null && (this.#p = !i.autoScrollOff, this.#D(i.newLogical, { emitChange: !0 }), i.edgeReached !== null && (this.#Ft[i.edgeReached.side] = i.edgeReached.boundaryTime, this.#Wt?.(i.edgeReached)), this.#W.pause(), this.#ne());
2076
2206
  }
2077
2207
  /**
2078
2208
  * Zoom around a time anchor. `factor < 1` zooms in, `> 1` zooms out.
@@ -2089,35 +2219,35 @@ class _e extends Et {
2089
2219
  * and produce a visible jump). Cursor-anchored zoom is intentionally
2090
2220
  * sacrificed in follow-live mode — pan first to inspect history.
2091
2221
  */
2092
- zoomAt(t, e, i = this.#J) {
2093
- i > 0 && (this.#J = i), this.#L = !1;
2094
- const s = bt({
2095
- currentLogical: this.#h,
2222
+ zoomAt(t, e, i = this.#Q) {
2223
+ i > 0 && (this.#Q = i), this.#L = !1, this.#et();
2224
+ const s = It({
2225
+ currentLogical: this.#a,
2096
2226
  centerTime: t,
2097
2227
  factor: e,
2098
2228
  chartWidth: i,
2099
- dataInterval: this.#o,
2100
- padding: { left: this.#d.left, right: this.#d.right },
2101
- dataStart: this.#S,
2229
+ dataInterval: this.#r,
2230
+ padding: { left: this.#l.left, right: this.#l.right },
2231
+ dataStart: this.#T,
2102
2232
  dataEnd: this.#s
2103
2233
  });
2104
2234
  if (s.newLogical === null) return;
2105
2235
  let r = s.newLogical;
2106
2236
  if (this.#p && this.#s !== null) {
2107
- const n = r.to - r.from, a = N(this.#d.right, n, this.#o, i), o = this.#s + a;
2108
- r = { from: o - n, to: o }, this.#q = this.#s;
2237
+ const n = r.to - r.from, a = j(this.#l.right, n, this.#r, i), o = this.#s + a;
2238
+ r = { from: o - n, to: o }, this.#J = this.#s;
2109
2239
  }
2110
- this.#H(r, { emitChange: !0 }), this.#F.pause(), this.#Kt();
2240
+ this.#D(r, { emitChange: !0 }), this.#W.pause(), this.#ne();
2111
2241
  }
2112
2242
  /**
2113
2243
  * Common tail for `pan` / `zoomAt`: routes the just-committed `#logical`
2114
2244
  * to the engine as a gesture so the X spring retargets and the Y spring
2115
2245
  * eases over `animations.axis.y.gesture`.
2116
2246
  */
2117
- #Kt() {
2118
- const t = this.#h;
2247
+ #ne() {
2248
+ const t = this.#a;
2119
2249
  if (t.to <= t.from) return;
2120
- this.#U = !0, this.#m = !0;
2250
+ this.#_ = !0, this.#u = !0;
2121
2251
  const e = performance.now();
2122
2252
  this.#e.onPanZoom({ xTarget: t, yAuto: !0 }, e), this.#x(e);
2123
2253
  }
@@ -2135,26 +2265,34 @@ class _e extends Et {
2135
2265
  * events long enough for the slot processor to snap them.
2136
2266
  */
2137
2267
  #x(t) {
2138
- const e = this.#e.tick(t), i = this.#l.size;
2268
+ const e = this.#e.tick(t), i = this.#c.size;
2139
2269
  if (i.media.width === 0 || i.media.height === 0) return;
2140
2270
  const s = i.media.height - this.xAxisHeight;
2141
- for (const { slot: r, range: n } of this.#jt(e))
2142
- this.#qt({ slot: r, range: n, chartHeight: s });
2271
+ for (const { slot: r, range: n } of this.#ae(e))
2272
+ this.#oe({ slot: r, range: n, chartHeight: s });
2143
2273
  this.syncScales();
2144
2274
  }
2275
+ /** Record the X and Y ranges this paint draws; `true` when any moved since the last paint. */
2276
+ #Ye(t) {
2277
+ let e = t.from !== this.#tt.from || t.to !== this.#tt.to;
2278
+ this.#tt.from = t.from, this.#tt.to = t.to, nt(this.#w) && (e = !0);
2279
+ for (const i of this.#o.values())
2280
+ nt(i) && (e = !0);
2281
+ return e;
2282
+ }
2145
2283
  /** Each scale's slot with the engine's current Y (scale space) for it. */
2146
- #jt(t) {
2147
- const e = [{ slot: this.#P, range: t.yRange }];
2148
- for (const [i, s] of this.#a) {
2284
+ #ae(t) {
2285
+ const e = [{ slot: this.#w, range: t.yRange }];
2286
+ for (const [i, s] of this.#o) {
2149
2287
  const r = this.#e.getScaleYRange(i);
2150
2288
  r !== null && e.push({ slot: s, range: r });
2151
2289
  }
2152
2290
  return e;
2153
2291
  }
2154
2292
  /** Pad an engine Y (scale space) into the slot's value range and remember it. */
2155
- #qt(t) {
2293
+ #oe(t) {
2156
2294
  const { slot: e, range: i, chartHeight: s } = t, r = e.range;
2157
- e.range = this.#Ae({ slot: e, min: i.min, max: i.max, chartHeight: s }), e.prevMin = i.min, e.prevMax = i.max, (r.min !== e.range.min || r.max !== e.range.max) && e !== this.#P && (this.#nt = !0);
2295
+ e.range = this.#ze({ slot: e, min: i.min, max: i.max, chartHeight: s }), e.prevMin = i.min, e.prevMax = i.max, (r.min !== e.range.min || r.max !== e.range.max) && e !== this.#w && (this.#ot = !0);
2158
2296
  }
2159
2297
  /**
2160
2298
  * Lightweight scale sync: updates timeScale/yScale from current viewport state
@@ -2162,99 +2300,104 @@ class _e extends Et {
2162
2300
  * handler, so DOM axis components always read fresh coordinates on re-render.
2163
2301
  */
2164
2302
  syncScales() {
2165
- const t = this.#l.size;
2303
+ const t = this.#c.size;
2166
2304
  if (t.media.width === 0 || t.media.height === 0) return;
2167
- const e = t.media.width - this.#w(), i = t.media.height - this.xAxisHeight;
2305
+ const e = t.media.width - this.#k(), i = t.media.height - this.xAxisHeight;
2168
2306
  this.timeScale.update(
2169
2307
  this.#e.getAnimationState().xRange,
2170
2308
  e,
2171
2309
  t.horizontalPixelRatio,
2172
- this.#o
2173
- ), this.yScale.update(this.#P.range, i, t.verticalPixelRatio);
2174
- for (const s of this.#a.values())
2310
+ this.#r
2311
+ ), this.yScale.update(this.#w.range, i, t.verticalPixelRatio);
2312
+ for (const s of this.#o.values())
2175
2313
  s.yScale.update(s.range, i, t.verticalPixelRatio);
2176
2314
  }
2177
2315
  /** Expensive: background, grid, all series. Only on data/viewport/resize change. */
2178
2316
  renderMain(t) {
2179
- const e = this.#l.size;
2317
+ const e = this.#c.size;
2180
2318
  if (e.media.width === 0 || e.media.height === 0) return;
2181
2319
  const i = typeof t == "number" ? t : performance.now(), s = this.#e.tick(i);
2182
2320
  s.animating && this.#i.markDirty();
2183
2321
  const r = e.media.height - this.xAxisHeight;
2184
2322
  let n = !1;
2185
- for (const { slot: c, range: m } of this.#jt(s))
2186
- m.min === c.prevMin && m.max === c.prevMax || (this.#qt({ slot: c, range: m, chartHeight: r }), n = !0);
2187
- if (this.syncScales(), this.#be(), this.#s !== null && !this.#p) {
2188
- const c = this.#e.lastXTarget ?? this.#h, m = c.to - c.from;
2323
+ for (const { slot: u, range: m } of this.#ae(s))
2324
+ m.min === u.prevMin && m.max === u.prevMax || (this.#oe({ slot: u, range: m, chartHeight: r }), n = !0);
2325
+ if (this.syncScales(), this.#Re(), this.#s !== null && !this.#p) {
2326
+ const u = this.#e.lastXTarget ?? this.#a, m = u.to - u.from;
2189
2327
  if (m > 0) {
2190
- const y = this.#l.size.media.width - this.#w(), u = N(this.#d.right, m, this.#o, y), g = this.#o * 0.5;
2191
- Math.abs(c.to - (this.#s + u)) < g && (this.#p = !0);
2328
+ const p = this.#c.size.media.width - this.#k(), x = j(this.#l.right, m, this.#r, p), T = this.#r * 0.5;
2329
+ Math.abs(u.to - (this.#s + x)) < T && (this.#p = !0);
2192
2330
  }
2193
2331
  }
2194
- n && this.emit("viewportChange");
2195
- let a = !1, o = !1, h = !1, l = !1;
2196
- this.#l.useMainLayer((c) => {
2197
- const { context: m, bitmapSize: y } = c, u = (e.media.width - this.#w()) * e.horizontalPixelRatio, g = (e.media.height - this.xAxisHeight) * e.verticalPixelRatio, S = this.#W(c);
2198
- m.clearRect(0, 0, y.width, y.height), m.save(), m.translate(S, 0), m.beginPath(), m.rect(0, 0, this.#re(c, u), g), m.clip(), this.yScale.tickTracker.setCurrentTicks(this.yScale.niceTickValues()), this.timeScale.tickTracker.setCurrentTicks(this.timeScale.niceTickValues(this.#o).ticks), this.yScale.tickTracker.tick(i), this.timeScale.tickTracker.tick(i);
2199
- for (const x of this.#a.values()) {
2200
- const b = x.yScale.tickTracker;
2201
- b.setCurrentTicks(x.yScale.niceTickValues()), b.tick(i) && (h = !0);
2332
+ const a = this.#Ye(s.xRange);
2333
+ (n || a && !s.animating) && this.emit("viewportChange");
2334
+ let o = !1, h = !1, l = !1, c = !1;
2335
+ this.#c.useMainLayer((u) => {
2336
+ const { context: m, bitmapSize: p } = u, x = (e.media.width - this.#k()) * e.horizontalPixelRatio, T = (e.media.height - this.xAxisHeight) * e.verticalPixelRatio, N = this.#z(u);
2337
+ m.clearRect(0, 0, p.width, p.height), m.save(), m.translate(N, 0), m.beginPath(), m.rect(0, 0, this.#fe(u, x), T), m.clip(), this.yScale.tickTracker.setCurrentTicks(this.yScale.niceTickValues()), this.timeScale.tickTracker.setCurrentTicks(this.timeScale.niceTickValues(this.#r).ticks), this.yScale.tickTracker.tick(i), this.timeScale.tickTracker.tick(i);
2338
+ for (const v of this.#o.values()) {
2339
+ const b = v.yScale.tickTracker;
2340
+ b.setCurrentTicks(v.yScale.niceTickValues()), b.tick(i) && (l = !0);
2202
2341
  }
2203
- const w = this.yScale.tickTracker.snapshot(), T = this.timeScale.tickTracker.snapshot();
2204
- a = w.isAnimating, o = T.isAnimating, (w.isAnimating || T.isAnimating || h || s.animating) && this.emit("tickFrame");
2205
- const A = this.#G ? 1 : 0;
2206
- if ((A === 0 || w.entries.length > 0 || T.entries.length > 0) && A !== this.#E.target) {
2207
- const x = ht() ? 0 : this.#g.axis.gridMs;
2208
- this.#E.setTarget(A, { now: i, duration: x });
2342
+ const w = this.yScale.tickTracker.snapshot(), M = this.timeScale.tickTracker.snapshot();
2343
+ o = w.isAnimating, h = M.isAnimating;
2344
+ const P = w.isAnimating || M.isAnimating || l, ct = this.#Ht && !P;
2345
+ this.#Ht = P, (P || ct || s.animating) && this.emit("tickFrame");
2346
+ const C = this.#j ? 1 : 0;
2347
+ if ((C === 0 || w.entries.length > 0 || M.entries.length > 0) && C !== this.#Y.target) {
2348
+ const v = xt() ? 0 : this.#g.axis.gridMs;
2349
+ this.#Y.setTarget(C, { now: i, duration: v });
2209
2350
  }
2210
- l = this.#E.tick(i);
2211
- const R = this.#E.current, I = this.#r === "category" ? ie : T, H = {
2212
- scope: c,
2351
+ c = this.#Y.tick(i);
2352
+ const F = this.#Y.current, W = this.#n === "category" ? de : M, $ = {
2353
+ scope: u,
2213
2354
  timeScale: this.timeScale,
2214
2355
  yScale: this.yScale,
2215
- theme: this.#n,
2356
+ theme: this.#h,
2216
2357
  yTicks: w,
2217
- timeTicks: I,
2218
- alpha: R
2219
- }, M = this.#ie(c, u);
2220
- M === 0 && X(H), this.#ce(c, u, g);
2221
- const V = this.#d, et = { top: V.top, bottom: V.bottom }, it = this.#ft(s), z = this.#M;
2222
- for (const x of this.#t) {
2223
- this.#fe(x);
2224
- const b = x.renderer.getAlpha?.() ?? (x.visible ? 1 : 0);
2358
+ timeTicks: W,
2359
+ alpha: F
2360
+ }, L = this.#ue(u, x);
2361
+ L === 0 && K($), this.#be(u, x, T);
2362
+ const z = this.#l, dt = { top: z.top, bottom: z.bottom }, ut = this.#xt(s), O = this.#P;
2363
+ for (const v of this.#t) {
2364
+ this.#Me(v);
2365
+ const b = v.renderer.getAlpha?.() ?? (v.visible ? 1 : 0);
2225
2366
  if (b <= 0) continue;
2226
- const P = this.#D(x), st = this.getYScale(P), O = {
2227
- scope: c,
2367
+ const I = this.#I(v), mt = this.getYScale(I), E = {
2368
+ scope: u,
2228
2369
  timeScale: this.timeScale,
2229
- yScale: st,
2230
- theme: this.#n,
2231
- dataInterval: this.#o,
2232
- padding: et,
2233
- state: P === void 0 ? it : this.#Wt(s, P),
2234
- seriesId: x.id
2235
- }, $ = m.globalAlpha;
2236
- if (b < 1 && (m.globalAlpha = $ * b), z) {
2237
- const rt = performance.now();
2238
- x.renderer.render(O), z.recordSeries(x.id, performance.now() - rt, i);
2370
+ yScale: mt,
2371
+ theme: this.#h,
2372
+ dataInterval: this.#r,
2373
+ padding: dt,
2374
+ state: I === void 0 ? ut : this.#Zt(s, I),
2375
+ seriesId: v.id
2376
+ }, B = m.globalAlpha;
2377
+ if (b < 1 && (m.globalAlpha = B * b), O) {
2378
+ const ft = performance.now();
2379
+ v.renderer.render(E), O.recordSeries(v.id, performance.now() - ft, i);
2239
2380
  } else
2240
- x.renderer.render(O);
2241
- b < 1 && (m.globalAlpha = $);
2381
+ v.renderer.render(E);
2382
+ b < 1 && (m.globalAlpha = B);
2242
2383
  }
2243
2384
  m.restore();
2244
- const F = { left: S, width: u, height: g };
2245
- M === 0 ? (this.#Qt({ scope: c, pane: F, timeTicks: I, alpha: R }), this.#$(c, u, "left"), this.#$(c, u, "right")) : (this.#$(c, u, "left"), this.#Le({ grid: H, pane: F, overhang: M }), this.#$(c, u, "right")), this.#ee(c, u), this.#Jt(c, g);
2246
- }), this.#pt();
2247
- let d = !1;
2248
- for (const c of this.#t)
2249
- if (c.renderer.needsAnimation) {
2250
- d = !0, this.#i.markDirty();
2385
+ const Y = { left: N, width: x, height: T };
2386
+ L === 0 ? (this.#le({ scope: u, pane: Y, timeTicks: W, alpha: F }), this.#$(u, x, "left"), this.#$(u, x, "right")) : (this.#$(u, x, "left"), this.#Xe({ grid: $, pane: Y, overhang: L }), this.#$(u, x, "right")), this.#de(u, x), this.#he(u, T);
2387
+ }), this.#St();
2388
+ let f = !1;
2389
+ for (const u of this.#t)
2390
+ if (u.renderer.needsAnimation) {
2391
+ f = !0, this.#i.markDirty();
2251
2392
  break;
2252
2393
  }
2253
- const f = a || o || h;
2254
- if ((f || l) && this.#i.markDirty(), !s.animating && !d && !f) {
2394
+ const g = f || this.#Ot;
2395
+ this.#Ot = f, g && (this.#zt++, this.emit("seriesFrame"));
2396
+ const y = o || h || l;
2397
+ if ((y || c) && this.#i.markDirty(), !s.animating && !f && !y) {
2255
2398
  this.yScale.tickTracker.markArmed(), this.timeScale.tickTracker.markArmed();
2256
- for (const c of this.#a.values())
2257
- c.yScale.tickTracker.markArmed();
2399
+ for (const u of this.#o.values())
2400
+ u.yScale.tickTracker.markArmed();
2258
2401
  }
2259
2402
  }
2260
2403
  /**
@@ -2264,12 +2407,12 @@ class _e extends Et {
2264
2407
  * a paint-over — so the container background behind the canvas (solid or
2265
2408
  * CSS gradient) shows through untouched.
2266
2409
  */
2267
- #Jt(t, e) {
2410
+ #he(t, e) {
2268
2411
  if (this.#C.top <= 0) return;
2269
2412
  const i = Math.min(Math.round(this.#C.top * t.verticalPixelRatio), Math.round(e));
2270
2413
  if (i < 1) return;
2271
2414
  const { context: s } = t;
2272
- s.save(), s.globalCompositeOperation = "destination-out", s.fillStyle = this.#Re(s, i), s.fillRect(0, 0, t.bitmapSize.width, i), s.restore();
2415
+ s.save(), s.globalCompositeOperation = "destination-out", s.fillStyle = this.#_e(s, i), s.fillRect(0, 0, t.bitmapSize.width, i), s.restore();
2273
2416
  }
2274
2417
  /**
2275
2418
  * Run the vertical gridlines a short stub past the pane floor, dissolving
@@ -2279,23 +2422,23 @@ class _e extends Et {
2279
2422
  * nothing else paints) and faded with the same destination-out ramp the
2280
2423
  * edge masks use, so the taper stays correct over any background.
2281
2424
  */
2282
- #Qt(t) {
2425
+ #le(t) {
2283
2426
  const { scope: e, pane: i, timeTicks: s, alpha: r } = t;
2284
- if (!this.#G && r <= 0.01 || this.xAxisHeight === 0) return;
2285
- const { context: n, horizontalPixelRatio: a, verticalPixelRatio: o } = e, h = Math.round(i.height), l = Math.round(D * o);
2427
+ if (!this.#j && r <= 0.01 || this.xAxisHeight === 0) return;
2428
+ const { context: n, horizontalPixelRatio: a, verticalPixelRatio: o } = e, h = Math.round(i.height), l = Math.round(H * o);
2286
2429
  if (l < 1) return;
2287
- const d = this.#n.grid;
2288
- n.save(), n.strokeStyle = d.color, d.style === "dashed" ? n.setLineDash([4 * a, 4 * a]) : d.style === "dotted" && n.setLineDash([1 * a, 3 * a]), n.lineDashOffset = h, n.lineWidth = Gt(a);
2289
- const f = Kt(a), c = Math.round(i.width);
2290
- for (const { value: m, opacity: y } of s.entries) {
2291
- const u = y * r;
2292
- if (u <= 0.01) continue;
2293
- const g = Math.round(this.timeScale.timeToBitmapX(m)) + f;
2294
- if (g < 0 || g > c) continue;
2295
- const S = i.left + g;
2296
- n.globalAlpha = u, n.beginPath(), n.moveTo(S, h), n.lineTo(S, h + l), n.stroke();
2430
+ const c = this.#h.grid;
2431
+ n.save(), n.strokeStyle = c.color, c.style === "dashed" ? n.setLineDash([4 * a, 4 * a]) : c.style === "dotted" && n.setLineDash([1 * a, 3 * a]), n.lineDashOffset = h, n.lineWidth = re(a);
2432
+ const f = ne(a), g = Math.round(i.width);
2433
+ for (const { value: y, opacity: u } of s.entries) {
2434
+ const m = u * r;
2435
+ if (m <= 0.01) continue;
2436
+ const p = Math.round(this.timeScale.timeToBitmapX(y)) + f;
2437
+ if (p < 0 || p > g) continue;
2438
+ const x = i.left + p;
2439
+ n.globalAlpha = m, n.beginPath(), n.moveTo(x, h), n.lineTo(x, h + l), n.stroke();
2297
2440
  }
2298
- n.restore(), this.#te(e, i.height);
2441
+ n.restore(), this.#ce(e, i.height);
2299
2442
  }
2300
2443
  /**
2301
2444
  * Erase ramp over the below-pane overrun strip — the gridline tail stubs
@@ -2303,12 +2446,12 @@ class _e extends Et {
2303
2446
  * erased at the pane floor, total at the strip's bottom edge, so whatever
2304
2447
  * crosses the floor tapers out short of the time-axis labels.
2305
2448
  */
2306
- #te(t, e) {
2449
+ #ce(t, e) {
2307
2450
  if (this.xAxisHeight === 0) return;
2308
- const i = Math.round(e), s = Math.round(D * t.verticalPixelRatio);
2451
+ const i = Math.round(e), s = Math.round(H * t.verticalPixelRatio);
2309
2452
  if (s < 1) return;
2310
2453
  const { context: r } = t;
2311
- r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#He({ context: r, start: i, height: s }), r.fillRect(0, i, t.bitmapSize.width, s), r.restore();
2454
+ r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#Ge({ context: r, start: i, height: s }), r.fillRect(0, i, t.bitmapSize.width, s), r.restore();
2312
2455
  }
2313
2456
  /**
2314
2457
  * Crosshair hairlines with the same edge melt the main layer runs: the
@@ -2320,18 +2463,18 @@ class _e extends Et {
2320
2463
  * edge. Erases alpha (destination-out), so it must run while the
2321
2464
  * crosshair is the only content on the layer.
2322
2465
  */
2323
- #Pe(t) {
2466
+ #Ee(t) {
2324
2467
  const e = this.#f;
2325
2468
  if (e === null) return;
2326
- const { scope: i, chartBitmapWidth: s, chartBitmapHeight: r } = t, { context: n } = i, a = this.#W(i), o = this.#re(i, s), h = this.#ie(i, s), l = this.xAxisHeight > 0 ? Math.round(D * i.verticalPixelRatio) : 0;
2327
- n.save(), n.translate(a, 0), n.beginPath(), n.rect(-h, 0, o + h, r + l), n.clip(), Ft({
2469
+ const { scope: i, chartBitmapWidth: s, chartBitmapHeight: r } = t, { context: n } = i, a = this.#z(i), o = this.#fe(i, s), h = this.#ue(i, s), l = this.xAxisHeight > 0 ? Math.round(H * i.verticalPixelRatio) : 0;
2470
+ n.save(), n.translate(a, 0), n.beginPath(), n.rect(-h, 0, o + h, r + l), n.clip(), _t({
2328
2471
  scope: i,
2329
2472
  bitmapX: e.mediaX * i.horizontalPixelRatio - a,
2330
2473
  bitmapY: e.mediaY * i.verticalPixelRatio,
2331
- theme: this.#n,
2474
+ theme: this.#h,
2332
2475
  pane: { width: s, height: r },
2333
2476
  leftOverhang: h
2334
- }), n.restore(), this.#te(i, r), h === 0 ? this.#$(i, s, "left") : this.#se(i, h), this.#$(i, s, "right"), this.#ee(i, s), this.#Jt(i, r);
2477
+ }), n.restore(), this.#ce(i, r), h === 0 ? this.#$(i, s, "left") : this.#me(i, h), this.#$(i, s, "right"), this.#de(i, s), this.#he(i, r);
2335
2478
  }
2336
2479
  /**
2337
2480
  * Horizontal companion to {@link #applyTopFade}: dissolve content that
@@ -2341,57 +2484,57 @@ class _e extends Et {
2341
2484
  * at the edges in step with their lines above.
2342
2485
  */
2343
2486
  #$(t, e, i) {
2344
- const s = this.#rt(t, e, i);
2487
+ const s = this.#at(t, e, i);
2345
2488
  if (s === null) return;
2346
2489
  const { context: r } = t, n = Math.min(s.inner, s.outer), a = Math.abs(s.outer - s.inner);
2347
- r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#Ie({ context: r, side: i, zone: s }), r.fillRect(n, 0, a, t.bitmapSize.height), r.restore();
2490
+ r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#Ue({ context: r, side: i, zone: s }), r.fillRect(n, 0, a, t.bitmapSize.height), r.restore();
2348
2491
  }
2349
2492
  /** Dissolve content leaving through a plain canvas edge — the side opposite
2350
2493
  * the Y axis, or either side on a spatial-only chart — when configured. */
2351
- #ee(t, e) {
2494
+ #de(t, e) {
2352
2495
  const { context: i } = t;
2353
- for (const s of this.#Ce()) {
2354
- const r = this.#De({ scope: t, paneBitmapWidth: e, side: s });
2496
+ for (const s of this.#Be()) {
2497
+ const r = this.#Ze({ scope: t, paneBitmapWidth: e, side: s });
2355
2498
  if (r === null) continue;
2356
2499
  const n = Math.min(r.edge, r.inner), a = Math.abs(r.inner - r.edge);
2357
- i.save(), i.globalCompositeOperation = "destination-out", i.fillStyle = this.#ze({ context: i, side: s, zone: r }), i.fillRect(n, 0, a, t.bitmapSize.height), i.restore();
2500
+ i.save(), i.globalCompositeOperation = "destination-out", i.fillStyle = this.#Ke({ context: i, side: s, zone: r }), i.fillRect(n, 0, a, t.bitmapSize.height), i.restore();
2358
2501
  }
2359
2502
  }
2360
2503
  /** Sides whose fade is a plain edge zone rather than the axis-column ramp —
2361
2504
  * neither the default axis's side nor one a named scale's column holds. */
2362
- #Ce() {
2363
- if (this.#Q()) return ee;
2364
- const t = q(this.yAxisPosition);
2365
- return this.getAxisColumnWidth(t) > 0 ? se : t === "left" ? re : ne;
2505
+ #Be() {
2506
+ if (this.#it()) return ce;
2507
+ const t = at(this.yAxisPosition);
2508
+ return this.getAxisColumnWidth(t) > 0 ? ue : t === "left" ? me : fe;
2366
2509
  }
2367
2510
  /** Bitmap px the gridlines and crosshair run under a left Y-axis column, where
2368
2511
  * data can't follow (see {@link #axisFadeZone}). `0` without one or with its fade off. */
2369
- #ie(t, e) {
2370
- return this.#rt(t, e, "left") === null ? 0 : Math.min(Math.round(K * t.horizontalPixelRatio), this.#W(t));
2512
+ #ue(t, e) {
2513
+ return this.#at(t, e, "left") === null ? 0 : Math.min(Math.round(et * t.horizontalPixelRatio), this.#z(t));
2371
2514
  }
2372
2515
  /** Left-axis grid pass, run after the axis fade: `destination-over` keeps the
2373
2516
  * gridlines out of the data ramp, then they taper out under the column. */
2374
- #Le(t) {
2517
+ #Xe(t) {
2375
2518
  const { grid: e, pane: i, overhang: s } = t, { scope: r } = e, { context: n } = r;
2376
2519
  n.save(), n.globalCompositeOperation = "destination-over";
2377
- const a = this.#rt(r, i.width, "right")?.intrusion ?? 0;
2378
- n.save(), n.translate(i.left, 0), n.beginPath(), n.rect(-s, 0, i.width + s + a, i.height), n.clip(), X({ ...e, leftOverhang: s }), n.restore(), this.#Qt({ scope: r, pane: i, timeTicks: e.timeTicks, alpha: e.alpha ?? 1 }), n.restore(), this.#se(r, s);
2520
+ const a = this.#at(r, i.width, "right")?.intrusion ?? 0;
2521
+ n.save(), n.translate(i.left, 0), n.beginPath(), n.rect(-s, 0, i.width + s + a, i.height), n.clip(), K({ ...e, leftOverhang: s }), n.restore(), this.#le({ scope: r, pane: i, timeTicks: e.timeTicks, alpha: e.alpha ?? 1 }), n.restore(), this.#me(r, s);
2379
2522
  }
2380
2523
  /** Erase the {@link #gridOverhang} strip: none at the pane edge, total at its outer end. */
2381
- #se(t, e) {
2382
- const i = this.#W(t), s = i - e, { context: r } = t;
2383
- r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#Ve({ context: r, start: s, end: i }), r.fillRect(s, 0, e, t.bitmapSize.height), r.restore();
2524
+ #me(t, e) {
2525
+ const i = this.#z(t), s = i - e, { context: r } = t;
2526
+ r.save(), r.globalCompositeOperation = "destination-out", r.fillStyle = this.#je({ context: r, start: s, end: i }), r.fillRect(s, 0, e, t.bitmapSize.height), r.restore();
2384
2527
  }
2385
2528
  /** Canvas bitmap x of the pane's left edge — whole device pixels, so the
2386
2529
  * translated pane keeps crisp strokes. */
2387
- #W(t) {
2530
+ #z(t) {
2388
2531
  return Math.round(this.plotLeft * t.horizontalPixelRatio);
2389
2532
  }
2390
2533
  /** Pane-local width of the pane clip: the pane plus the right fade
2391
2534
  * intrusion, so content can slide under a right Y-axis column before the
2392
2535
  * mask dissolves it. */
2393
- #re(t, e) {
2394
- const i = this.#rt(t, e, "right")?.intrusion ?? 0;
2536
+ #fe(t, e) {
2537
+ const i = this.#at(t, e, "right")?.intrusion ?? 0;
2395
2538
  return e + i;
2396
2539
  }
2397
2540
  /**
@@ -2405,22 +2548,22 @@ class _e extends Et {
2405
2548
  * total-erased anyway). `null` when no column sits on `side`, its fade
2406
2549
  * is `0`, or the chart is spatial-only.
2407
2550
  */
2408
- #rt(t, e, i) {
2409
- if (this.#Q()) return null;
2410
- const s = i === "left", r = t.bitmapSize.width, n = this.#W(t), a = s ? n : Math.max(0, Math.round(r - n - e));
2551
+ #at(t, e, i) {
2552
+ if (this.#it()) return null;
2553
+ const s = i === "left", r = t.bitmapSize.width, n = this.#z(t), a = s ? n : Math.max(0, Math.round(r - n - e));
2411
2554
  if (a === 0) return null;
2412
- const o = t.horizontalPixelRatio, h = Math.round(K * o), l = Math.round(te * o), d = s ? 0 : Math.min(h, a), f = s ? h + l : d + l, c = s ? this.#C.left : this.#C.right, m = c === null ? f : Math.round(c * o);
2413
- if (m < 1) return null;
2555
+ const o = t.horizontalPixelRatio, h = Math.round(et * o), l = Math.round(le * o), c = s ? 0 : Math.min(h, a), f = s ? h + l : c + l, g = s ? this.#C.left : this.#C.right, y = g === null ? f : Math.round(g * o);
2556
+ if (y < 1) return null;
2414
2557
  if (s) {
2415
- const g = a, S = Math.min(m, r - g);
2416
- return { inner: g + S, outer: g, intrusion: d };
2558
+ const p = a, x = Math.min(y, r - p);
2559
+ return { inner: p + x, outer: p, intrusion: c };
2417
2560
  }
2418
- const y = n + e + d, u = Math.min(m, y);
2419
- return { inner: y - u, outer: y, intrusion: d };
2561
+ const u = n + e + c, m = Math.min(y, u);
2562
+ return { inner: u - m, outer: u, intrusion: c };
2420
2563
  }
2421
2564
  /** Bitmap geometry of a plain fade at the `side` canvas edge — total erase
2422
2565
  * at `edge`, none at `inner`. Off unless that side's fade is configured. */
2423
- #De(t) {
2566
+ #Ze(t) {
2424
2567
  const { scope: e, paneBitmapWidth: i, side: s } = t, r = this.#C[s];
2425
2568
  if (r === null) return null;
2426
2569
  const n = Math.min(Math.round(r * e.horizontalPixelRatio), Math.round(i));
@@ -2435,15 +2578,15 @@ class _e extends Et {
2435
2578
  * changes (resize, DPR change, `setFade`). Ease-out ramp (`1 - t²`):
2436
2579
  * near-total erasure across the upper half keeps a floating header
2437
2580
  * legible, then a soft tail into full opacity at the zone's bottom. */
2438
- #Re(t, e) {
2439
- const i = this.#k.top;
2581
+ #_e(t, e) {
2582
+ const i = this.#b.top;
2440
2583
  if (i !== null && i.height === e) return i.gradient;
2441
2584
  const s = t.createLinearGradient(0, 0, 0, e);
2442
2585
  for (let r = 0; r <= 4; r++) {
2443
2586
  const n = r / 4;
2444
2587
  s.addColorStop(n, `rgba(0, 0, 0, ${1 - n * n})`);
2445
2588
  }
2446
- return this.#k.top = { height: e, gradient: s }, s;
2589
+ return this.#b.top = { height: e, gradient: s }, s;
2447
2590
  }
2448
2591
  /** Axis-column mask — erase grows from 0 at the ramp's inner start to
2449
2592
  * total at its outer end on an ease-in (`s³`): zero slope *and* zero
@@ -2451,51 +2594,51 @@ class _e extends Et {
2451
2594
  * candles at rest and the aggressive erasing all happens deep under the
2452
2595
  * axis column. Nine stops keep the piecewise interpolation smooth across
2453
2596
  * the zone. */
2454
- #Ie(t) {
2455
- const { context: e, side: i, zone: s } = t, r = this.#k.axis[i];
2597
+ #Ue(t) {
2598
+ const { context: e, side: i, zone: s } = t, r = this.#b.axis[i];
2456
2599
  if (r !== null && r.inner === s.inner && r.outer === s.outer) return r.gradient;
2457
2600
  const n = e.createLinearGradient(s.inner, 0, s.outer, 0);
2458
2601
  for (let a = 0; a <= 8; a++) {
2459
2602
  const o = a / 8;
2460
2603
  n.addColorStop(o, `rgba(0, 0, 0, ${o * o * o})`);
2461
2604
  }
2462
- return this.#k.axis[i] = { inner: s.inner, outer: s.outer, gradient: n }, n;
2605
+ return this.#b.axis[i] = { inner: s.inner, outer: s.outer, gradient: n }, n;
2463
2606
  }
2464
2607
  /** Erase ramp for the gridline tail stubs — nothing erased at the pane
2465
2608
  * floor, total at the stub tip, ease-in (`t²`) so a stub holds strength
2466
2609
  * briefly before melting away short of the label glyphs. */
2467
- #He(t) {
2468
- const e = this.#k.tail;
2610
+ #Ge(t) {
2611
+ const e = this.#b.tail;
2469
2612
  if (e !== null && e.start === t.start && e.height === t.height) return e.gradient;
2470
2613
  const i = t.context.createLinearGradient(0, t.start, 0, t.start + t.height);
2471
2614
  for (let s = 0; s <= 4; s++) {
2472
2615
  const r = s / 4;
2473
2616
  i.addColorStop(r, `rgba(0, 0, 0, ${r * r})`);
2474
2617
  }
2475
- return this.#k.tail = { start: t.start, height: t.height, gradient: i }, i;
2618
+ return this.#b.tail = { start: t.start, height: t.height, gradient: i }, i;
2476
2619
  }
2477
2620
  /** Gridline overhang ramp — ease-in (`t²`) like the tail stubs. */
2478
- #Ve(t) {
2479
- const e = this.#k.overhang;
2621
+ #je(t) {
2622
+ const e = this.#b.overhang;
2480
2623
  if (e !== null && e.start === t.start && e.end === t.end) return e.gradient;
2481
2624
  const i = t.context.createLinearGradient(t.end, 0, t.start, 0);
2482
2625
  for (let s = 0; s <= 4; s++) {
2483
2626
  const r = s / 4;
2484
2627
  i.addColorStop(r, `rgba(0, 0, 0, ${r * r})`);
2485
2628
  }
2486
- return this.#k.overhang = { start: t.start, end: t.end, gradient: i }, i;
2629
+ return this.#b.overhang = { start: t.start, end: t.end, gradient: i }, i;
2487
2630
  }
2488
2631
  /** Opposite-edge mask — mirror of the top ramp: total erase at the
2489
2632
  * canvas edge, fully opaque at the zone's inner boundary. */
2490
- #ze(t) {
2491
- const { context: e, side: i, zone: s } = t, r = this.#k.edge[i];
2633
+ #Ke(t) {
2634
+ const { context: e, side: i, zone: s } = t, r = this.#b.edge[i];
2492
2635
  if (r !== null && r.edge === s.edge && r.inner === s.inner) return r.gradient;
2493
2636
  const n = e.createLinearGradient(s.edge, 0, s.inner, 0);
2494
2637
  for (let a = 0; a <= 4; a++) {
2495
2638
  const o = a / 4;
2496
2639
  n.addColorStop(o, `rgba(0, 0, 0, ${1 - o * o})`);
2497
2640
  }
2498
- return this.#k.edge[i] = { edge: s.edge, inner: s.inner, gradient: n }, n;
2641
+ return this.#b.edge[i] = { edge: s.edge, inner: s.inner, gradient: n }, n;
2499
2642
  }
2500
2643
  /**
2501
2644
  * Paint a full frame: the main layer, then the overlay synchronously on
@@ -2506,13 +2649,13 @@ class _e extends Et {
2506
2649
  * `markDirty` calls made *during* `renderOverlay` (pulse, edge spinner)
2507
2650
  * land after the consume and re-arm cleanly for the next frame.
2508
2651
  */
2509
- #wt(t) {
2510
- this.#Tt("main", t, () => this.renderMain(t)), this.#c.consume(), this.#Tt("overlay", t, () => this.renderOverlay(t));
2652
+ #Ct(t) {
2653
+ this.#Lt("main", t, () => this.renderMain(t)), this.#d.consume(), this.#Lt("overlay", t, () => this.renderOverlay(t));
2511
2654
  }
2512
2655
  /** Run a layer's paint, booking duration + draw calls to the perf monitor
2513
2656
  * when one is attached — keeps overlay time out of the `main` samples. */
2514
- #Tt(t, e, i) {
2515
- const s = this.#M;
2657
+ #Lt(t, e, i) {
2658
+ const s = this.#P;
2516
2659
  if (!s) {
2517
2660
  i();
2518
2661
  return;
@@ -2523,7 +2666,7 @@ class _e extends Et {
2523
2666
  }
2524
2667
  /** Cheap overlay: crosshair, nearest-point dots, pulse animation, edge indicator. */
2525
2668
  renderOverlay(t) {
2526
- const e = this.#l.size;
2669
+ const e = this.#c.size;
2527
2670
  if (e.media.width === 0 || e.media.height === 0) return;
2528
2671
  let i = !1;
2529
2672
  for (const l of this.#t)
@@ -2533,71 +2676,71 @@ class _e extends Et {
2533
2676
  }
2534
2677
  this.#y.some((l) => l.pulse) && (i = !0);
2535
2678
  const s = {
2536
- left: this.#B.left && this.#A.left === "loading" ? "idle" : this.#A.left,
2537
- right: this.#B.right && this.#A.right === "loading" ? "idle" : this.#A.right
2679
+ left: this.#E.left && this.#A.left === "loading" ? "idle" : this.#A.left,
2680
+ right: this.#E.right && this.#A.right === "loading" ? "idle" : this.#A.right
2538
2681
  }, r = {
2539
- left: this.#Zt("left"),
2540
- right: this.#Zt("right")
2541
- }, n = r.left !== null || r.right !== null, a = s.left === "loading" || s.right === "loading" || n, o = s.left !== "idle" || s.right !== "idle" || n, h = !!this.#f || i || o || this.#y.length > 0 || this.#b.length > 0;
2542
- if (!(!h && !this.#Lt)) {
2543
- if (this.#Lt = h, this.#l.useOverlayLayer((l) => {
2682
+ left: this.#Jt("left"),
2683
+ right: this.#Jt("right")
2684
+ }, n = r.left !== null || r.right !== null, a = s.left === "loading" || s.right === "loading" || n, o = s.left !== "idle" || s.right !== "idle" || n, h = !!this.#f || i || o || this.#y.length > 0 || this.#S.length > 0;
2685
+ if (!(!h && !this.#Nt)) {
2686
+ if (this.#Nt = h, this.#c.useOverlayLayer((l) => {
2544
2687
  if (!h) return;
2545
- const d = (e.media.width - this.#w()) * e.horizontalPixelRatio, f = (e.media.height - this.xAxisHeight) * e.verticalPixelRatio;
2546
- this.#f && this.#Nt() && this.#Pe({ scope: l, chartBitmapWidth: d, chartBitmapHeight: f }), l.context.save(), l.context.translate(this.#W(l), 0), l.context.beginPath(), l.context.rect(0, 0, d, f), l.context.clip();
2547
- const c = this.#d, m = { top: c.top, bottom: c.bottom }, y = this.getAnimationState();
2548
- for (const u of this.#t) {
2549
- if (!u.visible) continue;
2550
- const g = this.#D(u);
2551
- u.renderer.drawOverlay?.({
2688
+ const c = (e.media.width - this.#k()) * e.horizontalPixelRatio, f = (e.media.height - this.xAxisHeight) * e.verticalPixelRatio;
2689
+ this.#f && this.#Kt() && this.#Ee({ scope: l, chartBitmapWidth: c, chartBitmapHeight: f }), l.context.save(), l.context.translate(this.#z(l), 0), l.context.beginPath(), l.context.rect(0, 0, c, f), l.context.clip();
2690
+ const g = this.#l, y = { top: g.top, bottom: g.bottom }, u = this.getAnimationState();
2691
+ for (const m of this.#t) {
2692
+ if (!m.visible) continue;
2693
+ const p = this.#I(m);
2694
+ m.renderer.drawOverlay?.({
2552
2695
  scope: l,
2553
2696
  timeScale: this.timeScale,
2554
- yScale: this.getYScale(g),
2555
- theme: this.#n,
2697
+ yScale: this.getYScale(p),
2698
+ theme: this.#h,
2556
2699
  // Overlays only snap the crosshair dots with it.
2557
2700
  dataInterval: this.#X(),
2558
- padding: m,
2701
+ padding: y,
2559
2702
  crosshair: this.#f,
2560
- state: g === void 0 ? y : this.#Wt(y, g),
2561
- seriesId: u.id
2703
+ state: p === void 0 ? u : this.#Zt(u, p),
2704
+ seriesId: m.id
2562
2705
  });
2563
2706
  }
2564
- this.#de(l, d, f), this.#le(l, d, f), o && ut({
2707
+ this.#ke(l, c, f), this.#Se(l, c, f), o && kt({
2565
2708
  scope: l,
2566
- chartMediaWidth: e.media.width - this.#w(),
2709
+ chartMediaWidth: e.media.width - this.#k(),
2567
2710
  chartMediaHeight: e.media.height - this.xAxisHeight,
2568
2711
  timeScale: this.timeScale,
2569
- theme: this.#n,
2712
+ theme: this.#h,
2570
2713
  edgeStates: s,
2571
2714
  edgeExitFades: r,
2572
- edgeIndicatorFns: this.#It,
2573
- resolveBoundary: (u) => mt(u, this.#Dt[u], this.getDataBounds()),
2574
- resolveEdgeAnchor: (u, g) => this.#ve(u, g),
2575
- resolveEdgeBarSpacing: () => this.#Se(),
2576
- reportPlaceholders: (u, g) => {
2577
- this.#ht[u] = { bars: g, at: performance.now() };
2715
+ edgeIndicatorFns: this.#$t,
2716
+ resolveBoundary: (m) => Tt(m, this.#Ft[m], this.getDataBounds()),
2717
+ resolveEdgeAnchor: (m, p) => this.#Ie(m, p),
2718
+ resolveEdgeBarSpacing: () => this.#De(),
2719
+ reportPlaceholders: (m, p) => {
2720
+ this.#ct[m] = { bars: p, at: performance.now() };
2578
2721
  }
2579
2722
  }), l.context.restore();
2580
2723
  }), i) {
2581
- const { from: l, to: d } = this.timeScale.getRange();
2724
+ const { from: l, to: c } = this.timeScale.getRange();
2582
2725
  let f = !1;
2583
- for (const c of this.#t)
2584
- if (!(!c.visible || !c.renderer.overlayNeedsAnimation) && (c.renderer.hasOverlayContentInRange?.(l, d) ?? !0)) {
2726
+ for (const g of this.#t)
2727
+ if (!(!g.visible || !g.renderer.overlayNeedsAnimation) && (g.renderer.hasOverlayContentInRange?.(l, c) ?? !0)) {
2585
2728
  f = !0;
2586
2729
  break;
2587
2730
  }
2588
2731
  if (!f) {
2589
- for (const c of this.#y)
2590
- if (c.pulse && c.time >= l && c.time <= d) {
2732
+ for (const g of this.#y)
2733
+ if (g.pulse && g.time >= l && g.time <= c) {
2591
2734
  f = !0;
2592
2735
  break;
2593
2736
  }
2594
2737
  }
2595
- f && this.#c.markDirty();
2738
+ f && this.#d.markDirty();
2596
2739
  }
2597
- a && this.#c.markDirty();
2740
+ a && this.#d.markDirty();
2598
2741
  }
2599
2742
  }
2600
2743
  }
2601
2744
  export {
2602
- _e as ChartInstance
2745
+ ri as ChartInstance
2603
2746
  };