@wick-charts/vue 0.5.0 → 0.5.1

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.
@@ -1,15 +1,15 @@
1
- import { AnimationConfig as z, DEFAULT_LINE_PULSE as H } from "./animation/config.js";
2
- import { createViewportEngine as N } from "./animation/viewport-engine.js";
1
+ import { AnimationConfig as z, DEFAULT_LINE_PULSE as N } from "./animation/config.js";
2
+ import { createViewportEngine as H } from "./animation/viewport-engine.js";
3
3
  import { CanvasManager as W } from "./canvas-manager.js";
4
- import { drawEdgeIndicators as E, resolveEdgeBoundary as $ } from "./chart/edge-indicators.js";
4
+ import { drawEdgeIndicators as E, resolveEdgeBoundary as F } from "./chart/edge-indicators.js";
5
5
  import { computeFitToData as O } from "./chart/fit-to-data.js";
6
- import { getLastValue as B, getPreviousClose as F, getStackedLastValue as Y } from "./chart/last-value.js";
7
- import { resolveMaxVisibleBars as X, resolvePadding as D, resolvePerfOptions as _, isSameHorizontalPadding as C } from "./chart/options.js";
6
+ import { getLastValue as Y, getPreviousClose as B, getStackedLastValue as X } from "./chart/last-value.js";
7
+ import { resolveMaxVisibleBars as _, resolvePadding as D, resolvePerfOptions as $, isSameHorizontalPadding as T } from "./chart/options.js";
8
8
  import { computePan as U, computeZoom as Z } from "./chart/pan-zoom-math.js";
9
9
  import { StreamingCadence as G } from "./chart/streaming-cadence.js";
10
10
  import { computeStreamingTarget as j } from "./chart/streaming-target.js";
11
- import { resolvePaddingTime as T } from "./chart/viewport-padding.js";
12
- import { computeTargetYRange as q, resolveBound as R } from "./chart/y-target.js";
11
+ import { resolvePaddingTime as C } from "./chart/viewport-padding.js";
12
+ import { computeTargetYRange as q, resolveBound as M } from "./chart/y-target.js";
13
13
  import { renderCrosshair as J } from "./components/crosshair.js";
14
14
  import { renderGrid as K } from "./components/grid.js";
15
15
  import { renderMarker as Q } from "./components/marker.js";
@@ -17,18 +17,18 @@ import { renderReferenceLine as tt } from "./components/reference-line.js";
17
17
  import { resolveTimeRegionColors as it, renderTimeRegion as et } from "./components/time-region.js";
18
18
  import { EventEmitter as st } from "./events.js";
19
19
  import { InteractionHandler as rt } from "./interactions/handler.js";
20
- import { RenderScheduler as M } from "./render-scheduler.js";
20
+ import { RenderScheduler as R } from "./render-scheduler.js";
21
21
  import { XScale as nt } from "./scales/x-scale.js";
22
- import { YScale as ht } from "./scales/y-scale.js";
23
- import { resolveSeriesDefinition as at } from "./series/definition.js";
22
+ import { YScale as at } from "./scales/y-scale.js";
23
+ import { resolveSeriesDefinition as ht } from "./series/definition.js";
24
24
  import { catppuccin as ot } from "./theme/themes/catppuccin.js";
25
25
  import { normalizeTime as g, detectInterval as lt } from "./utils/time.js";
26
- let dt = 0, ct = 0, mt = 0, ut = 0;
27
- function I(m, i) {
28
- return m === i ? !0 : !m || !i || m.length !== i.length ? !1 : m.every((t, e) => t === i[e]);
26
+ let ct = 0, dt = 0, mt = 0, ut = 0;
27
+ function I(m, t) {
28
+ return m === t ? !0 : !m || !t || m.length !== t.length ? !1 : m.every((i, e) => i === t[e]);
29
29
  }
30
- function ft(m, i) {
31
- return m === i ? !0 : !m || !i || m.length !== i.length ? !1 : m.every((t, e) => t === i[e]);
30
+ function ft(m, t) {
31
+ return m === t ? !0 : !m || !t || m.length !== t.length ? !1 : m.every((i, e) => i === t[e]);
32
32
  }
33
33
  class Ot extends st {
34
34
  /** Canvas lifecycle and DPR-aware sizing. */
@@ -36,7 +36,7 @@ class Ot extends st {
36
36
  /** Schedules main-layer redraws (background, grid, series). */
37
37
  #i;
38
38
  /** Schedules overlay redraws (crosshair). */
39
- #d;
39
+ #l;
40
40
  /** Maps time values to horizontal pixel coordinates. */
41
41
  timeScale;
42
42
  /** Maps price/value to vertical pixel coordinates. */
@@ -46,7 +46,7 @@ class Ot extends st {
46
46
  /** All registered series (candlestick, line, bar, pie). */
47
47
  #t = [];
48
48
  /** Point annotations (event markers) drawn on the overlay layer, kept out of the series model. */
49
- #c = [];
49
+ #m = [];
50
50
  /** Time-region bands drawn on the main layer behind the series, kept out of the series model. */
51
51
  #v = [];
52
52
  /** Reference lines (horizontal threshold / vertical event) drawn on the overlay layer, kept out of the series model. */
@@ -56,32 +56,40 @@ class Ot extends st {
56
56
  /** Whether to render the background grid. */
57
57
  #E;
58
58
  /** Detected time interval between data points (milliseconds). */
59
- #h = 6e4;
59
+ #a = 6e4;
60
60
  /** Current crosshair position, null when cursor is outside the chart. */
61
- #m = null;
61
+ #d = null;
62
+ /**
63
+ * What the crosshair is anchored to, deciding which half of the position
64
+ * survives a viewport move (see {@link #syncCrosshairToViewport}):
65
+ * `'pointer'` (real hover) keeps `mediaX`/`mediaY` and re-resolves
66
+ * `time`/`y`; `'time'` (programmatic {@link setCrosshair}) keeps
67
+ * `time`/`y` and re-projects the pixel position.
68
+ */
69
+ #F = "pointer";
62
70
  /** Whether the last overlay pass painted anything — gates the full-bitmap
63
71
  * clear so an empty overlay isn't cleared again every main frame. */
64
- #G = !1;
72
+ #q = !1;
65
73
  /** User-specified Y-axis bounds (auto, fixed, percentage). */
66
- #a = {};
74
+ #h = {};
67
75
  /** Cached series ID list — invalidated on add/remove. */
68
76
  #A = null;
69
77
  /** Axis visibility and sizing configuration. */
70
78
  #I = {};
71
79
  /** Host-declared state per edge — drives the edge-indicator overlay. */
72
- #b = { left: "idle", right: "idle" };
80
+ #x = { left: "idle", right: "idle" };
73
81
  /** Cached boundary timestamps from the last `edgeReached` emission, by side. */
74
- #j = { left: null, right: null };
82
+ #J = { left: null, right: null };
75
83
  /** Host-supplied callback fired when the user releases a pan/zoom past a data edge. */
76
- #q;
84
+ #K;
77
85
  /** Nesting depth for batch updates. Suppresses recomputes while > 0. */
78
86
  #w = 0;
79
87
  /** True when batched operations include data changes (triggers full onDataChanged on end). */
80
- #$ = !1;
88
+ #O = !1;
81
89
  /** True when batched operations include visibility changes (triggers Y-range + redraw on end). */
82
- #T = !1;
90
+ #C = !1;
83
91
  /** True when batched operations bumped overlay version (emits a single overlayChange on flush). */
84
- #O = !1;
92
+ #Y = !1;
85
93
  /**
86
94
  * Monotonic counter bumped on any mutation that affects overlay output —
87
95
  * data, visibility, series options, theme. Used by snapshot helpers in
@@ -91,14 +99,14 @@ class Ot extends st {
91
99
  *
92
100
  * @internal
93
101
  */
94
- #J = 0;
102
+ #Q = 0;
95
103
  get yAxisWidth() {
96
- const i = this.#I.y;
97
- return i?.visible === !1 ? 0 : i?.width ?? 55;
104
+ const t = this.#I.y;
105
+ return t?.visible === !1 ? 0 : t?.width ?? 55;
98
106
  }
99
107
  get xAxisHeight() {
100
- const i = this.#I.x;
101
- return i?.visible === !1 ? 0 : i?.height ?? 30;
108
+ const t = this.#I.x;
109
+ return t?.visible === !1 ? 0 : t?.height ?? 30;
102
110
  }
103
111
  /** Resolved animation config derived from `options.animations` at construction. */
104
112
  #f;
@@ -126,7 +134,7 @@ class Ot extends st {
126
134
  * field carries the decision across that gap. The closure also reads
127
135
  * `#dataStart` / `#dataEnd` directly for the timestamps.
128
136
  */
129
- #K = !1;
137
+ #tt = !1;
130
138
  /** Earliest data timestamp registered across all series, `null` before any data has arrived. */
131
139
  #k = null;
132
140
  /** Latest data timestamp registered across all series, `null` before any data has arrived. */
@@ -150,7 +158,7 @@ class Ot extends st {
150
158
  * the right edge and trims the left. Resolved once at construction from
151
159
  * `options.viewport.maxVisibleBars`.
152
160
  */
153
- #Q;
161
+ #it;
154
162
  /**
155
163
  * Committed logical X range — the "where X should be" target. Engine
156
164
  * eases its visual toward this. Pan / zoom / setRange / fitContent /
@@ -166,22 +174,22 @@ class Ot extends st {
166
174
  * screen; chart's per-frame autoscroll check re-engages it when a
167
175
  * follow-up pan brings the tail back into view.
168
176
  */
169
- #p = !0;
177
+ #y = !0;
170
178
  /** Resolved viewport padding (top/bottom px + left/right pixels-or-intervals). */
171
- #l;
179
+ #c;
172
180
  /** Cached chart width — passed by interactions on every call; kept for the rare
173
181
  * call that omits it (e.g. programmatic `chart.pan(...)` without explicit width). */
174
182
  #z = 0;
175
183
  /** Active performance monitor, or `null` when instrumentation is disabled (the default). */
176
- #x;
184
+ #S;
177
185
  /** When true, `destroy()` tears down the monitor; false for caller-supplied monitors we must not destroy. */
178
186
  #B = !1;
179
187
  /** Visible HUD overlay (mounted by the perf config); non-null only when the caller requested one. */
180
- #F = null;
181
- constructor(i, t) {
182
- super(), t?.axis && (this.#I = t.axis, this.#a = { min: t.axis.y?.min, max: t.axis.y?.max }), this.#r = t?.theme ?? ot.theme, this.#E = t?.grid?.visible !== !1, this.#f = z.resolve(t?.animations), this.#Q = X(t?.viewport?.maxVisibleBars), this.#l = D(t?.padding), this.#D = new G();
188
+ #X = null;
189
+ constructor(t, i) {
190
+ super(), i?.axis && (this.#I = i.axis, this.#h = { min: i.axis.y?.min, max: i.axis.y?.max }), this.#r = i?.theme ?? ot.theme, this.#E = i?.grid?.visible !== !1, this.#f = z.resolve(i?.animations), this.#it = _(i?.viewport?.maxVisibleBars), this.#c = D(i?.padding), this.#D = new G();
183
191
  const e = this.#f.axis.y, s = this.#f.axis.x;
184
- this.#e = N({
192
+ this.#e = H({
185
193
  initial: { yRange: { min: 0, max: 0 }, xRange: { from: 0, to: 0 } },
186
194
  y: {
187
195
  curve: e.curve,
@@ -196,21 +204,21 @@ class Ot extends st {
196
204
  settleMs: s.settleMs,
197
205
  gestureMs: s.gestureMs
198
206
  },
199
- computeXTarget: () => this.#gt(),
200
- computeYTarget: ({ xTarget: a }) => this.#st(a),
207
+ computeXTarget: () => this.#pt(),
208
+ computeYTarget: ({ xTarget: h }) => this.#nt(h),
201
209
  onWake: () => this.#i?.markDirty()
202
- }), this.#q = t?.onEdgeReached, this.#H = t?.viewport?.initialRange;
203
- const r = _(t?.perf);
204
- this.#x = r.monitor, this.#B = r.ownsMonitor, this.#n = new W(i, this.#x ?? void 0), this.timeScale = new nt(), this.yScale = new ht();
210
+ }), this.#K = i?.onEdgeReached, this.#N = i?.viewport?.initialRange;
211
+ const r = $(i?.perf);
212
+ this.#S = r.monitor, this.#B = r.ownsMonitor, this.#n = new W(t, this.#S ?? void 0), this.timeScale = new nt(), this.yScale = new at();
205
213
  const n = this.#f.axis.ticksMs;
206
- this.timeScale.tickTracker.setFadeMs(n), this.yScale.tickTracker.setFadeMs(n), this.#i = new M((a) => this.#U(a)), this.#d = new M(
207
- (a) => this.#Z("overlay", a, () => this.renderOverlay(a))
208
- ), this.#x && r.hud && (this.#F = r.hud(i, this.#x));
209
- const h = t?.interactive !== !1;
210
- this.#W = h ? new rt(this.#n.canvas, this, this.timeScale, this.yScale) : null, this.#n.on("resize", () => {
211
- this.syncScales(), this.#U(), this.emit("viewportChange");
212
- }), this.syncScales(), this.#W?.on("crosshairMove", (a) => {
213
- this.#m = a, this.#d.markDirty(), this.emit("crosshairMove", a), this.#ft(a);
214
+ this.timeScale.tickTracker.setFadeMs(n), this.yScale.tickTracker.setFadeMs(n), this.#i = new R((h) => this.#G(h)), this.#l = new R(
215
+ (h) => this.#j("overlay", h, () => this.renderOverlay(h))
216
+ ), this.#S && r.hud && (this.#X = r.hud(t, this.#S));
217
+ const a = i?.interactive !== !1;
218
+ this.#W = a ? new rt(this.#n.canvas, this, this.timeScale, this.yScale) : null, this.#n.on("resize", () => {
219
+ this.syncScales(), this.#G(), this.emit("viewportChange");
220
+ }), this.syncScales(), this.#W?.on("crosshairMove", (h) => {
221
+ this.#F = "pointer", this.#d = h, this.#l.markDirty(), this.emit("crosshairMove", h), this.#_(h);
214
222
  });
215
223
  }
216
224
  /**
@@ -225,9 +233,9 @@ class Ot extends st {
225
233
  * `setSeriesVisible` / `setLayerVisible` calls — produce one overlay
226
234
  * render instead of N.
227
235
  */
228
- #S() {
229
- if (this.#J++, this.#w > 0) {
230
- this.#O = !0;
236
+ #b() {
237
+ if (this.#Q++, this.#w > 0) {
238
+ this.#Y = !0;
231
239
  return;
232
240
  }
233
241
  this.emit("overlayChange");
@@ -241,39 +249,39 @@ class Ot extends st {
241
249
  * @internal
242
250
  */
243
251
  getOverlayVersion() {
244
- return this.#J;
252
+ return this.#Q;
245
253
  }
246
254
  /**
247
255
  * Return a series ID: use the provided hint if it's non-empty and not already taken,
248
256
  * otherwise generate a new auto ID. Auto-generated IDs never collide with each other
249
257
  * or with user-provided IDs because they use a monotonically increasing counter.
250
258
  */
251
- #at(i) {
252
- if (i && !this.#t.some((e) => e.id === i))
253
- return i;
254
- let t;
259
+ #lt(t) {
260
+ if (t && !this.#t.some((e) => e.id === t))
261
+ return t;
262
+ let i;
255
263
  do
256
- t = `series_${++dt}`;
257
- while (this.#t.some((e) => e.id === t));
258
- return t;
264
+ i = `series_${++ct}`;
265
+ while (this.#t.some((e) => e.id === i));
266
+ return i;
259
267
  }
260
- addSeries(i, t = {}) {
261
- const e = typeof i == "string" ? at(i) : i;
268
+ addSeries(t, i = {}) {
269
+ const e = typeof t == "string" ? ht(t) : t;
262
270
  if (!e)
263
271
  throw new Error(
264
- `[wick-charts] Unknown series type '${String(i)}'. The string form of addSeries resolves through the series registry — call registerBuiltinSeries() once at startup, or pass the definition directly: chart.addSeries(LineSeriesDef, options).`
272
+ `[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).`
265
273
  );
266
- const { layers: s, id: r, label: n, labels: h, ...a } = t, d = s ?? 1, l = {
274
+ const { layers: s, id: r, label: n, labels: a, ...h } = i, l = s ?? 1, o = {
267
275
  ...this.#f.defaults(e.type),
268
- ...a,
276
+ ...h,
269
277
  ...this.#f.overrides(e.type)
270
- }, u = e.create({ theme: this.#r, layerCount: d }, l), c = h ?? (typeof n == "string" ? [n] : void 0), o = this.#at(r);
271
- return u.onDataChanged?.(() => this.onDataChanged()), this.#t.push({ id: o, labels: c, renderer: u, visible: !0 }), this.#A = null, this.emit("seriesChange"), this.#S(), o;
278
+ }, u = e.create({ theme: this.#r, layerCount: l }, o), d = a ?? (typeof n == "string" ? [n] : void 0), c = this.#lt(r);
279
+ return u.onDataChanged?.(() => this.onDataChanged()), this.#t.push({ id: c, labels: d, renderer: u, visible: !0 }), this.#A = null, this.emit("seriesChange"), this.#b(), c;
272
280
  }
273
281
  /** Remove a series by ID and clean up its resources. */
274
- removeSeries(i) {
275
- const t = this.#t.findIndex((e) => e.id === i);
276
- t >= 0 && (this.#t[t].renderer.dispose(), this.#t.splice(t, 1), this.#A = null, this.#i.markDirty(), this.emit("seriesChange"), this.#S());
282
+ removeSeries(t) {
283
+ const i = this.#t.findIndex((e) => e.id === t);
284
+ i >= 0 && (this.#t[i].renderer.dispose(), this.#t.splice(i, 1), this.#A = null, this.#i.markDirty(), this.emit("seriesChange"), this.#b());
277
285
  }
278
286
  // --- Markers (point annotations) -----------------------------------------
279
287
  /**
@@ -285,71 +293,71 @@ class Ot extends st {
285
293
  * are excluded from tooltips, the legend, and the Y-range autoscale, and never
286
294
  * appear in series queries.
287
295
  */
288
- addMarker(i) {
289
- const t = `marker_${++ct}`;
290
- return this.#c.push(this.#tt(t, i)), this.#d.markDirty(), t;
296
+ addMarker(t) {
297
+ const i = `marker_${++dt}`;
298
+ return this.#m.push(this.#et(i, t)), this.#l.markDirty(), i;
291
299
  }
292
300
  /** Replace a marker's config in place. No-op when the id is unknown. */
293
- updateMarker(i, t) {
294
- const e = this.#c.findIndex((s) => s.id === i);
295
- e !== -1 && (this.#c[e] = this.#tt(i, t), this.#d.markDirty());
301
+ updateMarker(t, i) {
302
+ const e = this.#m.findIndex((s) => s.id === t);
303
+ e !== -1 && (this.#m[e] = this.#et(t, i), this.#l.markDirty());
296
304
  }
297
305
  /** Remove a marker by id. No-op when the id is unknown. */
298
- removeMarker(i) {
299
- const t = this.#c.findIndex((e) => e.id === i);
300
- t !== -1 && (this.#c.splice(t, 1), this.#d.markDirty());
306
+ removeMarker(t) {
307
+ const i = this.#m.findIndex((e) => e.id === t);
308
+ i !== -1 && (this.#m.splice(i, 1), this.#l.markDirty());
301
309
  }
302
310
  /** Read-only snapshot of the registered markers (normalized). Mutate via add / update / removeMarker. */
303
311
  getMarkers() {
304
- return this.#c;
312
+ return this.#m;
305
313
  }
306
- #tt(i, t) {
314
+ #et(t, i) {
307
315
  return {
308
- id: i,
309
- time: g(t.time),
310
- value: t.value,
311
- seriesId: t.seriesId,
312
- shape: t.shape ?? "dot",
313
- pulse: t.pulse ?? !1,
314
- label: t.label,
315
- color: t.color
316
+ id: t,
317
+ time: g(i.time),
318
+ value: i.value,
319
+ seriesId: i.seriesId,
320
+ shape: i.shape ?? "dot",
321
+ pulse: i.pulse ?? !1,
322
+ label: i.label,
323
+ color: i.color
316
324
  };
317
325
  }
318
326
  /** Resolve a marker's Y value: explicit `value`, else snapped to its series at `time`. Null when neither resolves. */
319
- #ot(i) {
320
- if (i.value !== void 0 && Number.isFinite(i.value)) return i.value;
321
- if (i.seriesId === void 0) return null;
322
- const t = this.getDataAtTime(i.seriesId, i.time);
323
- return t ? "close" in t ? t.close : t.value : null;
327
+ #ct(t) {
328
+ if (t.value !== void 0 && Number.isFinite(t.value)) return t.value;
329
+ if (t.seriesId === void 0) return null;
330
+ const i = this.getDataAtTime(t.seriesId, t.time);
331
+ return i ? "close" in i ? i.close : i.value : null;
324
332
  }
325
333
  /** Resolve a marker's color: explicit `color`, else the series color, else the theme line color. */
326
- #lt(i) {
327
- if (i.color !== void 0) return i.color;
328
- if (i.seriesId !== void 0) {
329
- const t = this.getSeriesColor(i.seriesId);
330
- if (t !== null) return t;
334
+ #dt(t) {
335
+ if (t.color !== void 0) return t.color;
336
+ if (t.seriesId !== void 0) {
337
+ const i = this.getSeriesColor(t.seriesId);
338
+ if (i !== null) return i;
331
339
  }
332
340
  return this.#r.line.color;
333
341
  }
334
- #dt(i) {
335
- if (this.#c.length === 0) return;
336
- const t = performance.now() / (H * 2 * Math.PI) % 1;
337
- for (const e of this.#c) {
338
- const s = this.#ot(e);
342
+ #mt(t) {
343
+ if (this.#m.length === 0) return;
344
+ const i = performance.now() / (N * 2 * Math.PI) % 1;
345
+ for (const e of this.#m) {
346
+ const s = this.#ct(e);
339
347
  s !== null && Q({
340
- scope: i,
348
+ scope: t,
341
349
  timeScale: this.timeScale,
342
350
  yScale: this.yScale,
343
351
  theme: this.#r,
344
352
  marker: {
345
353
  time: e.time,
346
354
  value: s,
347
- color: this.#lt(e),
355
+ color: this.#dt(e),
348
356
  shape: e.shape,
349
357
  pulse: e.pulse,
350
358
  label: e.label
351
359
  },
352
- phase: t
360
+ phase: i
353
361
  });
354
362
  }
355
363
  }
@@ -365,45 +373,45 @@ class Ot extends st {
365
373
  * series model — they never affect the Y-range autoscale, tooltips, or the
366
374
  * legend.
367
375
  */
368
- addRegion(i) {
369
- const t = `region_${++mt}`;
370
- return this.#v.push(this.#it(t, i)), this.#i.markDirty(), t;
376
+ addRegion(t) {
377
+ const i = `region_${++mt}`;
378
+ return this.#v.push(this.#st(i, t)), this.#i.markDirty(), i;
371
379
  }
372
380
  /** Replace a region's config in place. No-op when the id is unknown. */
373
- updateRegion(i, t) {
374
- const e = this.#v.findIndex((s) => s.id === i);
375
- e !== -1 && (this.#v[e] = this.#it(i, t), this.#i.markDirty());
381
+ updateRegion(t, i) {
382
+ const e = this.#v.findIndex((s) => s.id === t);
383
+ e !== -1 && (this.#v[e] = this.#st(t, i), this.#i.markDirty());
376
384
  }
377
385
  /** Remove a region by id. No-op when the id is unknown. */
378
- removeRegion(i) {
379
- const t = this.#v.findIndex((e) => e.id === i);
380
- t !== -1 && (this.#v.splice(t, 1), this.#i.markDirty());
386
+ removeRegion(t) {
387
+ const i = this.#v.findIndex((e) => e.id === t);
388
+ i !== -1 && (this.#v.splice(i, 1), this.#i.markDirty());
381
389
  }
382
390
  /** Read-only snapshot of the registered regions (normalized). Mutate via add / update / removeRegion. */
383
391
  getRegions() {
384
392
  return this.#v;
385
393
  }
386
- #it(i, t) {
387
- const { to: e } = t, s = e === void 0 || e === "now" ? null : g(e);
394
+ #st(t, i) {
395
+ const { to: e } = i, s = e === void 0 || e === "now" ? null : g(e);
388
396
  return {
389
- id: i,
390
- from: g(t.from),
397
+ id: t,
398
+ from: g(i.from),
391
399
  to: s,
392
- fill: t.fill,
393
- color: t.color,
394
- label: t.label
400
+ fill: i.fill,
401
+ color: i.color,
402
+ label: i.label
395
403
  };
396
404
  }
397
- #ct(i, t, e) {
405
+ #ut(t, i, e) {
398
406
  if (this.#v.length !== 0)
399
407
  for (const s of this.#v) {
400
408
  const { color: r, fill: n } = it(s, this.#r);
401
409
  et({
402
- scope: i,
410
+ scope: t,
403
411
  timeScale: this.timeScale,
404
412
  theme: this.#r,
405
413
  region: { from: s.from, to: s.to, fill: n, color: r, label: s.label },
406
- plotWidth: t,
414
+ plotWidth: i,
407
415
  plotHeight: e
408
416
  });
409
417
  }
@@ -419,39 +427,39 @@ class Ot extends st {
419
427
  * series model — they never affect the Y-range autoscale, tooltips, or the
420
428
  * legend.
421
429
  */
422
- addLine(i) {
423
- const t = `line_${++ut}`;
424
- return this.#g.push(this.#et(t, i)), this.#d.markDirty(), t;
430
+ addLine(t) {
431
+ const i = `line_${++ut}`;
432
+ return this.#g.push(this.#rt(i, t)), this.#l.markDirty(), i;
425
433
  }
426
434
  /** Replace a reference line's config in place. No-op when the id is unknown. */
427
- updateLine(i, t) {
428
- const e = this.#g.findIndex((s) => s.id === i);
429
- e !== -1 && (this.#g[e] = this.#et(i, t), this.#d.markDirty());
435
+ updateLine(t, i) {
436
+ const e = this.#g.findIndex((s) => s.id === t);
437
+ e !== -1 && (this.#g[e] = this.#rt(t, i), this.#l.markDirty());
430
438
  }
431
439
  /** Remove a reference line by id. No-op when the id is unknown. */
432
- removeLine(i) {
433
- const t = this.#g.findIndex((e) => e.id === i);
434
- t !== -1 && (this.#g.splice(t, 1), this.#d.markDirty());
440
+ removeLine(t) {
441
+ const i = this.#g.findIndex((e) => e.id === t);
442
+ i !== -1 && (this.#g.splice(i, 1), this.#l.markDirty());
435
443
  }
436
444
  /** Read-only snapshot of the registered reference lines (normalized). Mutate via add / update / removeLine. */
437
445
  getLines() {
438
446
  return this.#g;
439
447
  }
440
- #et(i, t) {
441
- const { time: e, value: s } = t, r = {
442
- id: i,
443
- color: t.color,
444
- label: t.label,
445
- style: t.style ?? "dashed",
446
- width: t.width ?? 1
448
+ #rt(t, i) {
449
+ const { time: e, value: s } = i, r = {
450
+ id: t,
451
+ color: i.color,
452
+ label: i.label,
453
+ style: i.style ?? "dashed",
454
+ width: i.width ?? 1
447
455
  };
448
456
  return e !== void 0 ? { ...r, orientation: "vertical", coord: g(e) } : { ...r, orientation: "horizontal", coord: s ?? Number.NaN };
449
457
  }
450
- #mt(i, t, e) {
458
+ #ft(t, i, e) {
451
459
  if (this.#g.length !== 0)
452
460
  for (const s of this.#g)
453
461
  tt({
454
- scope: i,
462
+ scope: t,
455
463
  timeScale: this.timeScale,
456
464
  yScale: this.yScale,
457
465
  theme: this.#r,
@@ -463,7 +471,7 @@ class Ot extends st {
463
471
  width: s.width,
464
472
  label: s.label
465
473
  },
466
- plotWidth: t,
474
+ plotWidth: i,
467
475
  plotHeight: e
468
476
  });
469
477
  }
@@ -485,18 +493,18 @@ class Ot extends st {
485
493
  * For line/bar accepts `TimePointInput[]` (time may be `Date`); for candlestick accepts `OHLCInput[]`;
486
494
  * for pie accepts `PieSliceData[]`. Time fields are normalized internally.
487
495
  */
488
- setSeriesData(i, t, e) {
489
- const s = this.#t.find((r) => r.id === i);
490
- s && (this.#Y = !0, s.renderer.setData(t, e));
496
+ setSeriesData(t, i, e) {
497
+ const s = this.#t.find((r) => r.id === t);
498
+ s && (this.#$ = !0, s.renderer.setData(i, e));
491
499
  }
492
500
  /** Append a new data point to the end of a series (real-time tick). */
493
- appendData(i, t, e) {
494
- const s = this.#t.find((r) => r.id === i);
495
- s === void 0 || s.renderer.appendPoint === void 0 || s.renderer.appendPoint(t, e);
501
+ appendData(t, i, e) {
502
+ const s = this.#t.find((r) => r.id === t);
503
+ s === void 0 || s.renderer.appendPoint === void 0 || s.renderer.appendPoint(i, e);
496
504
  }
497
505
  /** Update the last data point of a series in place (e.g. live candle update). */
498
- updateData(i, t, e) {
499
- this.#t.find((s) => s.id === i)?.renderer.updateLastPoint?.(t, e);
506
+ updateData(t, i, e) {
507
+ this.#t.find((s) => s.id === t)?.renderer.updateLastPoint?.(i, e);
500
508
  }
501
509
  /**
502
510
  * Keep only the most recent `count` points of a series — drop the oldest
@@ -511,36 +519,36 @@ class Ot extends st {
511
519
  * chart.keepLast('feed', 100);
512
520
  * ```
513
521
  */
514
- keepLast(i, t, e) {
515
- this.#t.find((s) => s.id === i)?.renderer.keepLast?.(t, e);
522
+ keepLast(t, i, e) {
523
+ this.#t.find((s) => s.id === t)?.renderer.keepLast?.(i, e);
516
524
  }
517
525
  /** Update visual options (color, width, etc.) for an existing series. */
518
- updateSeriesOptions(i, t) {
519
- const e = this.#t.find((l) => l.id === i);
526
+ updateSeriesOptions(t, i) {
527
+ const e = this.#t.find((o) => o.id === t);
520
528
  if (!e) return;
521
529
  const s = e.labels, r = e.renderer.getLayerColors().slice(), n = this.#f.overrides(e.renderer.kind);
522
- e.renderer.updateOptions({ ...t, ...n }), "label" in t && typeof t.label == "string" && (e.labels = [t.label]), this.#i.markDirty();
523
- const h = e.renderer.getLayerColors(), a = r.length !== h.length || r.some((l, u) => l !== h[u]), d = !I(s, e.labels);
524
- (a || d) && this.#S();
530
+ e.renderer.updateOptions({ ...i, ...n }), "label" in i && typeof i.label == "string" && (e.labels = [i.label]), this.#i.markDirty();
531
+ const a = e.renderer.getLayerColors(), h = r.length !== a.length || r.some((o, u) => o !== a[u]), l = !I(s, e.labels);
532
+ (h || l) && this.#b();
525
533
  }
526
534
  /**
527
535
  * Batch multiple updates: suppress recomputes until `fn` returns. Exceptions
528
536
  * inside `fn` still flush the batch so counters don't leak across calls.
529
537
  */
530
- batch(i) {
538
+ batch(t) {
531
539
  this.#w++;
532
540
  try {
533
- i();
541
+ t();
534
542
  } finally {
535
543
  if (--this.#w <= 0) {
536
- if (this.#w = 0, this.#$)
537
- this.#$ = !1, this.#T = !1, this.onDataChanged();
538
- else if (this.#T) {
539
- this.#T = !1, this.#u = !0;
540
- const t = performance.now();
541
- this.#e.onAxisReconfig(t), this.#y(t), this.#i.markDirty();
544
+ if (this.#w = 0, this.#O)
545
+ this.#O = !1, this.#C = !1, this.onDataChanged();
546
+ else if (this.#C) {
547
+ this.#C = !1, this.#u = !0;
548
+ const i = performance.now();
549
+ this.#e.onAxisReconfig(i), this.#p(i), this.#i.markDirty();
542
550
  }
543
- this.#O && (this.#O = !1, this.emit("overlayChange"));
551
+ this.#Y && (this.#Y = !1, this.emit("overlayChange"));
544
552
  }
545
553
  }
546
554
  }
@@ -551,18 +559,18 @@ class Ot extends st {
551
559
  * computation immediately so the axis can start moving while the line
552
560
  * fades out in parallel.
553
561
  */
554
- setSeriesVisible(i, t) {
555
- const e = this.#t.find((n) => n.id === i);
556
- if (!e || e.visible === t) return;
557
- e.visible = t, this.#S();
562
+ setSeriesVisible(t, i) {
563
+ const e = this.#t.find((n) => n.id === t);
564
+ if (!e || e.visible === i) return;
565
+ e.visible = i, this.#b();
558
566
  const s = this.#f.toggleMs;
559
- if (e.renderer.setAlpha?.(t ? 1 : 0, s), this.#i.markDirty(), this.#w > 0) {
560
- this.#T = !0;
567
+ if (e.renderer.setAlpha?.(i ? 1 : 0, s), this.#i.markDirty(), this.#w > 0) {
568
+ this.#C = !0;
561
569
  return;
562
570
  }
563
571
  this.#u = !0;
564
572
  const r = performance.now();
565
- this.#e.onSeriesVisibilityChanged(r), this.#y(r);
573
+ this.#e.onSeriesVisibilityChanged(r), this.#p(r);
566
574
  }
567
575
  /**
568
576
  * Whether streaming ticks slide the visible range to track the data tail.
@@ -572,10 +580,10 @@ class Ot extends st {
572
580
  * containing the tail.
573
581
  */
574
582
  getAutoScroll() {
575
- return this.#p;
583
+ return this.#y;
576
584
  }
577
- isSeriesVisible(i) {
578
- return this.#t.find((t) => t.id === i)?.visible ?? !0;
585
+ isSeriesVisible(t) {
586
+ return this.#t.find((i) => i.id === t)?.visible ?? !0;
579
587
  }
580
588
  /**
581
589
  * Show or hide a specific layer within a multi-layer series.
@@ -587,28 +595,28 @@ class Ot extends st {
587
595
  * `getValueRange` reading `store.isVisible()`); the alpha fade keeps the
588
596
  * layer's geometry on screen until the engine's Y ease settles.
589
597
  */
590
- setLayerVisible(i, t, e) {
591
- const s = this.#t.find((h) => h.id === i);
592
- if (!s || s.renderer.getLayerCount() <= 1 || s.renderer.isLayerVisible(t) === e) return;
593
- s.renderer.setLayerVisible(t, e), this.#S();
598
+ setLayerVisible(t, i, e) {
599
+ const s = this.#t.find((a) => a.id === t);
600
+ if (!s || s.renderer.getLayerCount() <= 1 || s.renderer.isLayerVisible(i) === e) return;
601
+ s.renderer.setLayerVisible(i, e), this.#b();
594
602
  const r = this.#f.toggleMs;
595
- if (s.renderer.setLayerAlpha?.(t, e ? 1 : 0, r), this.#i.markDirty(), this.#w > 0) {
596
- this.#T = !0;
603
+ if (s.renderer.setLayerAlpha?.(i, e ? 1 : 0, r), this.#i.markDirty(), this.#w > 0) {
604
+ this.#C = !0;
597
605
  return;
598
606
  }
599
607
  this.#u = !0;
600
608
  const n = performance.now();
601
- this.#e.onSeriesVisibilityChanged(n), this.#y(n);
609
+ this.#e.onSeriesVisibilityChanged(n), this.#p(n);
602
610
  }
603
- isLayerVisible(i, t) {
604
- return this.#t.find((e) => e.id === i)?.renderer.isLayerVisible(t) ?? !0;
611
+ isLayerVisible(t, i) {
612
+ return this.#t.find((e) => e.id === t)?.renderer.isLayerVisible(i) ?? !0;
605
613
  }
606
614
  /** Auto-fit the viewport to show all data across every series. */
607
615
  fitContent() {
608
- const { first: i, last: t } = this.getDataBounds();
609
- if (i === void 0 || t === void 0) return;
616
+ const { first: t, last: i } = this.getDataBounds();
617
+ if (t === void 0 || i === void 0) return;
610
618
  const e = this.#n.size.media.width - this.yAxisWidth;
611
- this.#M(i, t, e), this.#N({ xEase: !0 });
619
+ this.#R(t, i, e), this.#H({ xEase: !0 });
612
620
  }
613
621
  getVisibleRange() {
614
622
  return this.#o.from === 0 && this.#o.to === 0 ? this.#e.getAnimationState().xRange : this.#o;
@@ -645,35 +653,35 @@ class Ot extends st {
645
653
  * multi-chart sync so a synced pane tracks the originating gesture in
646
654
  * lockstep rather than lagging behind on the long sticky contract.
647
655
  */
648
- setVisibleRange(i, t) {
649
- if (typeof i == "number") {
650
- if (!Number.isInteger(i) || i < 2) return;
651
- const { first: n, last: h } = this.getDataBounds();
652
- if (n === void 0 || h === void 0) return;
653
- const a = Math.max(n, h - (i - 1) * this.#h), d = this.#n.size.media.width - this.yAxisWidth;
654
- this.#M(a, h, d), this.#N();
656
+ setVisibleRange(t, i) {
657
+ if (typeof t == "number") {
658
+ if (!Number.isInteger(t) || t < 2) return;
659
+ const { first: n, last: a } = this.getDataBounds();
660
+ if (n === void 0 || a === void 0) return;
661
+ const h = Math.max(n, a - (t - 1) * this.#a), l = this.#n.size.media.width - this.yAxisWidth;
662
+ this.#R(h, a, l), this.#H();
655
663
  return;
656
664
  }
657
- if ("bars" in i) {
658
- if (!Number.isInteger(i.bars) || i.bars < 2) return;
659
- const n = g(i.from), h = n + i.bars * this.#h;
660
- this.#p = this.#s !== null && this.#s >= n && this.#s <= h, this.#C({ from: n, to: h }, { emitChange: !0 }), this.#L = !0, this.#N();
665
+ if ("bars" in t) {
666
+ if (!Number.isInteger(t.bars) || t.bars < 2) return;
667
+ const n = g(t.from), a = n + t.bars * this.#a;
668
+ this.#y = this.#s !== null && this.#s >= n && this.#s <= a, this.#T({ from: n, to: a }, { emitChange: !0 }), this.#L = !0, this.#H();
661
669
  return;
662
670
  }
663
- const e = g(i.from), s = g(i.to);
664
- this.#p = this.#s !== null && this.#s >= e && this.#s <= s, this.#L = !1;
665
- const r = this.#C({ from: e, to: s }, { emitChange: !0 });
666
- if (t?.gesture) {
667
- r && this.#pt();
671
+ const e = g(t.from), s = g(t.to);
672
+ this.#y = this.#s !== null && this.#s >= e && this.#s <= s, this.#L = !1;
673
+ const r = this.#T({ from: e, to: s }, { emitChange: !0 });
674
+ if (i?.gesture) {
675
+ r && this.#vt();
668
676
  return;
669
677
  }
670
- this.#N();
678
+ this.#H();
671
679
  }
672
680
  getYRange() {
673
681
  return this.#V;
674
682
  }
675
683
  getCrosshairPosition() {
676
- return this.#m;
684
+ return this.#d;
677
685
  }
678
686
  /**
679
687
  * Programmatically set or clear the crosshair. Same effect as the user
@@ -700,45 +708,52 @@ class Ot extends st {
700
708
  * current crosshair is a no-op (no emit). Combined with the y-preservation
701
709
  * above, this lets N charts broadcast their hover to each other without
702
710
  * a feedback-loop guard.
711
+ *
712
+ * The echo protection assumes the broadcast is **synchronous** (call
713
+ * `setCrosshair` directly from the `crosshairMove` listener). An echo
714
+ * routed through an async hop — a state store, a React render — can
715
+ * arrive with a stale `time` while the origin chart streams, miss the
716
+ * idempotency check, and flip that chart to time-anchored until the next
717
+ * real pointer move (see {@link #syncCrosshairToViewport}).
703
718
  */
704
- setCrosshair(i) {
705
- if (i === null) {
706
- if (this.#m === null) return;
707
- this.#m = null, this.#d.markDirty(), this.emit("crosshairMove", null);
719
+ setCrosshair(t) {
720
+ if (t === null) {
721
+ if (this.#d === null) return;
722
+ this.#d = null, this.#l.markDirty(), this.emit("crosshairMove", null);
708
723
  return;
709
724
  }
710
- const { time: t } = i;
711
- if (!Number.isFinite(t)) return;
712
- const e = this.#m;
725
+ const { time: i } = t;
726
+ if (!Number.isFinite(i)) return;
727
+ const e = this.#d;
713
728
  let s;
714
- if (i.y !== void 0)
715
- s = i.y;
729
+ if (t.y !== void 0)
730
+ s = t.y;
716
731
  else if (e !== null)
717
732
  s = e.y;
718
733
  else {
719
- const h = this.#V;
720
- s = (h.min + h.max) / 2;
734
+ const a = this.#V;
735
+ s = (a.min + a.max) / 2;
721
736
  }
722
- if (!Number.isFinite(s) || e !== null && e.time === t && e.y === s) return;
723
- const r = this.timeScale.timeToX(t), n = this.yScale.valueToY(s);
724
- this.#m = { mediaX: r, mediaY: n, time: t, y: s }, this.#d.markDirty(), this.emit("crosshairMove", this.#m);
737
+ if (!Number.isFinite(s) || e !== null && e.time === i && e.y === s) return;
738
+ const r = this.timeScale.timeToX(i), n = this.yScale.valueToY(s);
739
+ this.#F = "time", this.#d = { mediaX: r, mediaY: n, time: i, y: s }, this.#l.markDirty(), this.emit("crosshairMove", this.#d);
725
740
  }
726
741
  /** Get the last visible value and whether the absolute last point is on screen. */
727
- getLastValue(i) {
728
- return B(i, this.#t, this.#e.getAnimationState().xRange);
742
+ getLastValue(t) {
743
+ return Y(t, this.#t, this.#e.getAnimationState().xRange);
729
744
  }
730
745
  /** Get the second-to-last value, useful for computing change. */
731
- getPreviousClose(i) {
732
- return F(i, this.#t);
746
+ getPreviousClose(t) {
747
+ return B(t, this.#t);
733
748
  }
734
- getLastData(i) {
735
- const t = this.#t.find((e) => e.id === i);
736
- return !t || t.renderer.kind === "pie" ? null : t.renderer.getLastDataPoint();
749
+ getLastData(t) {
750
+ const i = this.#t.find((e) => e.id === t);
751
+ return !i || i.renderer.kind === "pie" ? null : i.renderer.getLastDataPoint();
737
752
  }
738
753
  /** Find the data point closest to the given timestamp within one data interval. */
739
- getDataAtTime(i, t) {
740
- const e = this.#t.find((s) => s.id === i);
741
- return e ? e.renderer.getDataAtTime?.(t, this.#h) ?? null : null;
754
+ getDataAtTime(t, i) {
755
+ const e = this.#t.find((s) => s.id === t);
756
+ return e ? e.renderer.getDataAtTime?.(i, this.#a) ?? null : null;
742
757
  }
743
758
  /**
744
759
  * Get all layers' data at a given time for multi-layer series (Bar/Line
@@ -746,21 +761,21 @@ class Ot extends st {
746
761
  * snapped sample time — callers must not derive layer identity from the
747
762
  * array index, because hidden layers are filtered out.
748
763
  */
749
- getLayerSnapshots(i, t) {
750
- const e = this.#t.find((s) => s.id === i);
751
- return e?.visible ? e.renderer.getLayerSnapshots?.(t, this.#h) ?? null : null;
764
+ getLayerSnapshots(t, i) {
765
+ const e = this.#t.find((s) => s.id === t);
766
+ return e?.visible ? e.renderer.getLayerSnapshots?.(i, this.#a) ?? null : null;
752
767
  }
753
768
  getSeriesIds() {
754
- return this.#A || (this.#A = this.#t.map((i) => i.id)), this.#A.slice();
769
+ return this.#A || (this.#A = this.#t.map((t) => t.id)), this.#A.slice();
755
770
  }
756
771
  /**
757
772
  * True if any visible series is non-pie (line / bar / candlestick). Used
758
773
  * to gate crosshair rendering — a pie-only chart has no meaningful x/y
759
774
  * coordinate system, so the dashed hairlines would just be visual noise.
760
775
  */
761
- #ut() {
762
- for (const i of this.#t)
763
- if (i.visible && i.renderer.kind !== "pie")
776
+ #gt() {
777
+ for (const t of this.#t)
778
+ if (t.visible && t.renderer.kind !== "pie")
764
779
  return !0;
765
780
  return !1;
766
781
  }
@@ -773,23 +788,23 @@ class Ot extends st {
773
788
  * - `opts.singleLayerOnly` — exclude series with more than one layer.
774
789
  * Useful for YLabel fallback priority (stick to a single line first).
775
790
  */
776
- getSeriesIdsByType(i, t) {
777
- const e = t?.visibleOnly === !0, s = t?.singleLayerOnly === !0, r = [];
791
+ getSeriesIdsByType(t, i) {
792
+ const e = i?.visibleOnly === !0, s = i?.singleLayerOnly === !0, r = [];
778
793
  for (const n of this.#t) {
779
- const h = n.renderer.kind === "pie";
780
- if (i === "pie" && !h || i === "time" && h) continue;
781
- const a = n.renderer.getLayerCount();
782
- if (!(s && a > 1)) {
794
+ const a = n.renderer.kind === "pie";
795
+ if (t === "pie" && !a || t === "time" && a) continue;
796
+ const h = n.renderer.getLayerCount();
797
+ if (!(s && h > 1)) {
783
798
  if (e) {
784
799
  if (!n.visible) continue;
785
- if (a > 1) {
786
- let d = !1;
787
- for (let l = 0; l < a; l++)
788
- if (n.renderer.isLayerVisible(l)) {
789
- d = !0;
800
+ if (h > 1) {
801
+ let l = !1;
802
+ for (let o = 0; o < h; o++)
803
+ if (n.renderer.isLayerVisible(o)) {
804
+ l = !0;
790
805
  break;
791
806
  }
792
- if (!d) continue;
807
+ if (!l) continue;
793
808
  }
794
809
  }
795
810
  r.push(n.id);
@@ -803,8 +818,8 @@ class Ot extends st {
803
818
  * series without stacked concepts (Candlestick, single-layer Line/Bar).
804
819
  * Returns `null` for unknown ids or empty series.
805
820
  */
806
- getStackedLastValue(i) {
807
- return Y(i, this.#t, this.#e.getAnimationState().xRange);
821
+ getStackedLastValue(t) {
822
+ return X(t, this.#t, this.#e.getAnimationState().xRange);
808
823
  }
809
824
  /**
810
825
  * Per-layer last snapshots with each layer's own `time`. Returns `null`
@@ -812,8 +827,8 @@ class Ot extends st {
812
827
  * overlay components that must display every layer in last-mode even
813
828
  * when layers advance at different rates (ragged streams).
814
829
  */
815
- getLayerLastSnapshots(i) {
816
- return this.#t.find((t) => t.id === i)?.renderer.getLayerLastSnapshots?.() ?? null;
830
+ getLayerLastSnapshots(t) {
831
+ return this.#t.find((i) => i.id === t)?.renderer.getLayerLastSnapshots?.() ?? null;
817
832
  }
818
833
  /**
819
834
  * Shallow view of the internal series entries so unit tests can introspect
@@ -823,20 +838,20 @@ class Ot extends st {
823
838
  * @internal
824
839
  */
825
840
  listSeriesForTest() {
826
- return this.#t.map((i) => ({ id: i.id, renderer: i.renderer }));
841
+ return this.#t.map((t) => ({ id: t.id, renderer: t.renderer }));
827
842
  }
828
843
  /** Get the primary display color for a series. */
829
- getSeriesColor(i) {
830
- const t = this.#t.find((e) => e.id === i);
831
- return t ? t.renderer.getLayerColors()[0] ?? this.#r.line.color : null;
844
+ getSeriesColor(t) {
845
+ const i = this.#t.find((e) => e.id === t);
846
+ return i ? i.renderer.getLayerColors()[0] ?? this.#r.line.color : null;
832
847
  }
833
848
  /** The series' primary name (first layer). Used for single-layer overlays. */
834
- getSeriesLabel(i) {
835
- return this.#t.find((t) => t.id === i)?.labels?.[0];
849
+ getSeriesLabel(t) {
850
+ return this.#t.find((i) => i.id === t)?.labels?.[0];
836
851
  }
837
852
  /** The display name of one layer, or `undefined` when that layer is unnamed. */
838
- getLayerLabel(i, t) {
839
- return this.#t.find((e) => e.id === i)?.labels?.[t];
853
+ getLayerLabel(t, i) {
854
+ return this.#t.find((e) => e.id === t)?.labels?.[i];
840
855
  }
841
856
  /**
842
857
  * Set every layer's display name at once (index = layer). Drives the tooltip,
@@ -844,9 +859,9 @@ class Ot extends st {
844
859
  * per-layer labels in `data` change. No-ops (and skips the overlay bump) when
845
860
  * the labels are unchanged, so it's safe to call on every data tick.
846
861
  */
847
- setSeriesLabels(i, t) {
848
- const e = this.#t.find((s) => s.id === i);
849
- !e || I(e.labels, t) || (e.labels = t, this.#S());
862
+ setSeriesLabels(t, i) {
863
+ const e = this.#t.find((s) => s.id === t);
864
+ !e || I(e.labels, i) || (e.labels = i, this.#b());
850
865
  }
851
866
  /**
852
867
  * Set the per-layer color overrides carried in `data` (sparse — `undefined`
@@ -855,44 +870,44 @@ class Ot extends st {
855
870
  * the renderer, which keeps them separate from the theme base so a theme swap
856
871
  * preserves them. Called by the framework wrappers; no-ops when unchanged.
857
872
  */
858
- setLayerColors(i, t) {
859
- const e = this.#t.find((s) => s.id === i);
860
- !e || ft(e.colorOverrides, t) || (e.colorOverrides = t, e.renderer.setColorOverrides?.(t), this.#i.markDirty(), this.#S());
873
+ setLayerColors(t, i) {
874
+ const e = this.#t.find((s) => s.id === t);
875
+ !e || ft(e.colorOverrides, i) || (e.colorOverrides = i, e.renderer.setColorOverrides?.(i), this.#i.markDirty(), this.#b());
861
876
  }
862
877
  /** Get per-layer colors for a series. Returns null for single-layer non-bar/line series. */
863
- getSeriesLayers(i) {
864
- const t = this.#t.find((r) => r.id === i);
865
- if (!t) return null;
866
- const e = t.renderer.getLayerCount();
878
+ getSeriesLayers(t) {
879
+ const i = this.#t.find((r) => r.id === t);
880
+ if (!i) return null;
881
+ const e = i.renderer.getLayerCount();
867
882
  if (e <= 1) return null;
868
- const s = t.renderer.getLayerColors();
883
+ const s = i.renderer.getLayerColors();
869
884
  return Array.from({ length: e }, (r, n) => ({ color: s[n % s.length] }));
870
885
  }
871
886
  /** Get all slices with computed colors and percentages. Returns null for series without slice data (e.g. candlestick, line, bar). */
872
- getSliceInfo(i) {
873
- return this.#t.find((t) => t.id === i)?.renderer.getSliceInfo?.(this.#r) ?? null;
887
+ getSliceInfo(t) {
888
+ return this.#t.find((i) => i.id === t)?.renderer.getSliceInfo?.(this.#r) ?? null;
874
889
  }
875
890
  /** Get hover info (label/value/percent/color) for the currently hovered element, or null. */
876
- getHoverInfo(i) {
877
- return this.#t.find((t) => t.id === i)?.renderer.getHoverInfo?.(this.#r) ?? null;
891
+ getHoverInfo(t) {
892
+ return this.#t.find((i) => i.id === t)?.renderer.getHoverInfo?.(this.#r) ?? null;
878
893
  }
879
894
  /** Apply a new theme and update series colors where appropriate. */
880
- setTheme(i) {
881
- const t = this.#r;
882
- this.#r = i;
895
+ setTheme(t) {
896
+ const i = this.#r;
897
+ this.#r = t;
883
898
  for (const e of this.#t)
884
- e.renderer.applyTheme(i, t);
885
- this.#i.markDirty(), this.#S();
899
+ e.renderer.applyTheme(t, i);
900
+ this.#i.markDirty(), this.#b();
886
901
  }
887
902
  getTheme() {
888
903
  return this.#r;
889
904
  }
890
905
  /** Update axis configuration and re-render. */
891
- setAxis(i) {
892
- const t = this.yAxisWidth, e = this.xAxisHeight;
893
- this.#I = i, this.#a = { min: i.y?.min, max: i.y?.max }, this.#u = !0;
906
+ setAxis(t) {
907
+ const i = this.yAxisWidth, e = this.xAxisHeight;
908
+ this.#I = t, this.#h = { min: t.y?.min, max: t.y?.max }, this.#u = !0;
894
909
  const s = performance.now();
895
- this.#e.onAxisReconfig(s), this.#y(s), (this.yAxisWidth !== t || this.xAxisHeight !== e) && this.syncScales(), this.#i.markDirty();
910
+ this.#e.onAxisReconfig(s), this.#p(s), (this.yAxisWidth !== i || this.xAxisHeight !== e) && this.syncScales(), this.#i.markDirty();
896
911
  }
897
912
  /**
898
913
  * Apply label-density knobs driven by `<YAxis labelCount=… minLabelSpacing=…>`
@@ -900,29 +915,29 @@ class Ot extends st {
900
915
  * Y-animation reset. Triggers a viewportChange + repaint so static charts
901
916
  * react without waiting for pan/zoom.
902
917
  */
903
- setYAxisLabelDensity(i) {
904
- let t = !1;
905
- "labelCount" in i && (this.yScale.setLabelCount(i.labelCount ?? null), t = !0), "minLabelSpacing" in i && (this.yScale.setMinSpacing(i.minLabelSpacing ?? null), t = !0), t && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
918
+ setYAxisLabelDensity(t) {
919
+ let i = !1;
920
+ "labelCount" in t && (this.yScale.setLabelCount(t.labelCount ?? null), i = !0), "minLabelSpacing" in t && (this.yScale.setMinSpacing(t.minLabelSpacing ?? null), i = !0), i && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
906
921
  }
907
922
  /** Label-density knobs for the time axis — mirror of {@link setYAxisLabelDensity}. */
908
- setTimeAxisLabelDensity(i) {
909
- let t = !1;
910
- "labelCount" in i && (this.timeScale.setLabelCount(i.labelCount ?? null), t = !0), "minLabelSpacing" in i && (this.timeScale.setMinSpacing(i.minLabelSpacing ?? null), t = !0), t && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
923
+ setTimeAxisLabelDensity(t) {
924
+ let i = !1;
925
+ "labelCount" in t && (this.timeScale.setLabelCount(t.labelCount ?? null), i = !0), "minLabelSpacing" in t && (this.timeScale.setMinSpacing(t.minLabelSpacing ?? null), i = !0), i && (this.syncScales(), this.emit("viewportChange"), this.#i.markDirty());
911
926
  }
912
927
  getMediaSize() {
913
928
  return this.#n.size.media;
914
929
  }
915
930
  /** Returns layout metrics for the chart area, Y axis, and time axis. */
916
931
  getLayout() {
917
- const i = this.#n.size.media, t = this.yAxisWidth, e = this.xAxisHeight;
932
+ const t = this.#n.size.media, i = this.yAxisWidth, e = this.xAxisHeight;
918
933
  return {
919
- chartArea: { x: 0, y: 0, width: i.width - t, height: i.height - e },
920
- yAxisWidth: t,
934
+ chartArea: { x: 0, y: 0, width: t.width - i, height: t.height - e },
935
+ yAxisWidth: i,
921
936
  xAxisHeight: e
922
937
  };
923
938
  }
924
939
  getDataInterval() {
925
- return this.#h;
940
+ return this.#a;
926
941
  }
927
942
  /**
928
943
  * Update viewport padding at runtime. Refits the visible time range to
@@ -932,27 +947,27 @@ class Ot extends st {
932
947
  * a wrapper re-applies padding reactively (e.g. in response to a Title /
933
948
  * InfoBar ResizeObserver).
934
949
  */
935
- setPadding(i) {
936
- const t = this.#l;
937
- this.#l = D(i);
938
- const e = this.#l, s = !C(t.left, e.left) || !C(t.right, e.right), r = t.top !== e.top || t.bottom !== e.bottom;
950
+ setPadding(t) {
951
+ const i = this.#c;
952
+ this.#c = D(t);
953
+ const e = this.#c, s = !T(i.left, e.left) || !T(i.right, e.right), r = i.top !== e.top || i.bottom !== e.bottom;
939
954
  if (s) {
940
- const { first: n, last: h } = this.getDataBounds();
941
- if (n !== void 0 && h !== void 0) {
942
- const a = this.#n.size.media.width - this.yAxisWidth;
943
- this.#M(n, h, a);
955
+ const { first: n, last: a } = this.getDataBounds();
956
+ if (n !== void 0 && a !== void 0) {
957
+ const h = this.#n.size.media.width - this.yAxisWidth;
958
+ this.#R(n, a, h);
944
959
  }
945
960
  }
946
961
  if (s || r) {
947
962
  this.#u = !0;
948
963
  const n = performance.now();
949
- this.#e.onAxisReconfig(n), this.#y(n);
964
+ this.#e.onAxisReconfig(n), this.#p(n);
950
965
  }
951
966
  this.syncScales(), this.#i.markDirty(), r && this.emit("viewportChange");
952
967
  }
953
968
  /** Show or hide the background grid. Takes effect on the next render frame. */
954
- setGrid(i) {
955
- this.#E = i.visible, this.#i.markDirty();
969
+ setGrid(t) {
970
+ this.#E = t.visible, this.#i.markDirty();
956
971
  }
957
972
  /**
958
973
  * Set the visual state for one side of the chart. Typically called in
@@ -963,12 +978,12 @@ class Ot extends st {
963
978
  * The state persists until replaced. `has-more` is accepted for API
964
979
  * symmetry and currently renders identically to `idle`.
965
980
  */
966
- setEdgeState(i, t) {
967
- this.#b[i] !== t && (this.#b[i] = t, this.#d.markDirty());
981
+ setEdgeState(t, i) {
982
+ this.#x[t] !== i && (this.#x[t] = i, this.#l.markDirty());
968
983
  }
969
984
  /** Read the current host-declared state for a given edge. */
970
- getEdgeState(i) {
971
- return this.#b[i];
985
+ getEdgeState(t) {
986
+ return this.#x[t];
972
987
  }
973
988
  /**
974
989
  * Notify chart that a YLabel overlay is mounted / unmounted. Currently a
@@ -976,73 +991,113 @@ class Ot extends st {
976
991
  * chart area to make room for the badge.
977
992
  * TODO: implement reflow.
978
993
  */
979
- setYLabel(i) {
994
+ setYLabel(t) {
980
995
  }
981
996
  /**
982
997
  * Dispatch a crosshair move to every renderer that supports spatial hover
983
998
  * (currently: pie). Any change in hover index schedules a main-layer redraw.
984
999
  */
985
- #ft(i) {
986
- const t = this.#n.size, e = this.#l, s = {
987
- top: e.top * t.verticalPixelRatio,
988
- bottom: e.bottom * t.verticalPixelRatio
1000
+ #_(t) {
1001
+ const i = this.#n.size, e = this.#c, s = {
1002
+ top: e.top * i.verticalPixelRatio,
1003
+ bottom: e.bottom * i.verticalPixelRatio
989
1004
  };
990
1005
  let r = !1;
991
1006
  for (const n of this.#t) {
992
1007
  if (!n.renderer.hitTest || !n.renderer.setHoverIndex) continue;
993
- let h = -1;
994
- if (i) {
995
- const a = i.mediaX * t.horizontalPixelRatio, d = i.mediaY * t.verticalPixelRatio;
996
- h = n.renderer.hitTest(a, d, t.bitmap.width, t.bitmap.height, s);
1008
+ let a = -1;
1009
+ if (t) {
1010
+ const h = t.mediaX * i.horizontalPixelRatio, l = t.mediaY * i.verticalPixelRatio;
1011
+ a = n.renderer.hitTest(h, l, i.bitmap.width, i.bitmap.height, s);
997
1012
  }
998
- n.renderer.setHoverIndex(h) && (r = !0);
1013
+ n.renderer.setHoverIndex(a) && (r = !0);
999
1014
  }
1000
1015
  r && this.#i.markDirty();
1001
1016
  }
1017
+ /**
1018
+ * Re-derive the crosshair after the viewport moved beneath it. A streaming
1019
+ * auto-scroll, wheel zoom, or animated Y re-fit shifts the pixel↔data
1020
+ * mapping while the cursor stays put — without this, the stored position
1021
+ * goes stale: the tooltip freezes on the old time/values while the data
1022
+ * (and any snap dots anchored to it) slides away underneath.
1023
+ *
1024
+ * Which half of the position is truth depends on {@link #crosshairAnchor}:
1025
+ * a pointer-anchored crosshair stays under the cursor and re-resolves
1026
+ * `time`/`y`; a time-anchored one keeps `time`/`y` and re-projects the
1027
+ * pixel position so it tracks its data point across the screen. A
1028
+ * time-anchored point whose time scrolls out of the visible range clears
1029
+ * the crosshair entirely (mirroring pointer-leave) — otherwise the
1030
+ * edge-clamped tooltip would pin to the chart border, live-updating for
1031
+ * an invisible point.
1032
+ *
1033
+ * Called once per painted main frame (after `syncScales`). When the
1034
+ * viewport didn't move, the re-derived values are bit-identical and the
1035
+ * method exits without emitting.
1036
+ */
1037
+ #yt() {
1038
+ const t = this.#d;
1039
+ if (t === null) return;
1040
+ const { from: i, to: e } = this.timeScale.getRange(), s = this.yScale.getRange(), r = Math.abs(e - i) * 1e-9, n = Math.abs(s.max - s.min) * 1e-9, a = 1e-6;
1041
+ let h;
1042
+ if (this.#F === "pointer") {
1043
+ const l = this.timeScale.xToTime(t.mediaX), o = this.yScale.yToValue(t.mediaY);
1044
+ if (!Number.isFinite(l) || !Number.isFinite(o) || Math.abs(l - t.time) <= r && Math.abs(o - t.y) <= n) return;
1045
+ h = { mediaX: t.mediaX, mediaY: t.mediaY, time: l, y: o };
1046
+ } else {
1047
+ if (t.time < i || t.time > e) {
1048
+ this.#d = null, this.#l.markDirty(), this.emit("crosshairMove", null), this.#_(null);
1049
+ return;
1050
+ }
1051
+ const l = this.timeScale.timeToX(t.time), o = this.yScale.valueToY(t.y);
1052
+ if (!Number.isFinite(l) || !Number.isFinite(o) || Math.abs(l - t.mediaX) <= a && Math.abs(o - t.mediaY) <= a) return;
1053
+ h = { mediaX: l, mediaY: o, time: t.time, y: t.y };
1054
+ }
1055
+ this.#d = h, this.#l.markDirty(), this.emit("crosshairMove", h), this.#_(h);
1056
+ }
1002
1057
  /** Tear down the chart: cancel animations, remove listeners, and detach the canvas. */
1003
1058
  destroy() {
1004
- for (const i of this.#t) i.renderer.dispose();
1005
- this.#t = [], this.#c = [], this.#v = [], this.#g = [], this.#A = null, this.#i.destroy(), this.#d.destroy(), this.#W?.destroy(), this.#n.destroy(), this.#F?.destroy(), this.#F = null, this.#B && this.#x?.destroy(), this.#x = null, this.#B = !1, this.removeAllListeners();
1059
+ for (const t of this.#t) t.renderer.dispose();
1060
+ this.#t = [], this.#m = [], this.#v = [], this.#g = [], this.#A = null, this.#i.destroy(), this.#l.destroy(), this.#W?.destroy(), this.#n.destroy(), this.#X?.destroy(), this.#X = null, this.#B && this.#S?.destroy(), this.#S = null, this.#B = !1, this.removeAllListeners();
1006
1061
  }
1007
1062
  /** The attached performance monitor, or `null` when instrumentation is disabled. */
1008
1063
  getPerfMonitor() {
1009
- return this.#x;
1064
+ return this.#S;
1010
1065
  }
1011
1066
  /** Compute the earliest and latest timestamps across all series. */
1012
1067
  getDataBounds() {
1013
- let i, t;
1068
+ let t, i;
1014
1069
  for (const e of this.#t) {
1015
1070
  if (!e.visible || e.renderer.kind === "pie") continue;
1016
1071
  const s = e.renderer.getTimeBounds();
1017
- s !== null && ((i === void 0 || s.first < i) && (i = s.first), (t === void 0 || s.last > t) && (t = s.last));
1072
+ s !== null && ((t === void 0 || s.first < t) && (t = s.first), (i === void 0 || s.last > i) && (i = s.last));
1018
1073
  }
1019
- return { first: i, last: t };
1074
+ return { first: t, last: i };
1020
1075
  }
1021
1076
  /** Set by `setSeriesData`/bulk-replace paths so the next `onDataChanged`
1022
1077
  * snaps the Y range (instead of easing) and `yScale.getRange()` reflects
1023
1078
  * the new domain synchronously. Cleared by `onDataChanged` after each run. */
1024
- #Y = !1;
1079
+ #$ = !1;
1025
1080
  onDataChanged() {
1026
1081
  if (this.#w > 0) {
1027
- this.#$ = !0;
1082
+ this.#O = !0;
1028
1083
  return;
1029
1084
  }
1030
1085
  this.updateDataInterval();
1031
- const { first: i, last: t } = this.getDataBounds();
1032
- i !== void 0 && (this.#k = i), t !== void 0 && (this.#P = this.#s, this.#s = t);
1033
- const e = this.#Y;
1034
- this.#Y = !1;
1035
- const s = !this.#u && i !== void 0;
1036
- e && (this.yScale.tickTracker.reset(), this.timeScale.tickTracker.reset()), this.#K = e;
1086
+ const { first: t, last: i } = this.getDataBounds();
1087
+ t !== void 0 && (this.#k = t), i !== void 0 && (this.#P = this.#s, this.#s = i);
1088
+ const e = this.#$;
1089
+ this.#$ = !1;
1090
+ const s = !this.#u && t !== void 0;
1091
+ e && (this.yScale.tickTracker.reset(), this.timeScale.tickTracker.reset()), this.#tt = e;
1037
1092
  const r = performance.now();
1038
- e || s ? (this.#D.seed(r), this.#e.onDataReplaced(r)) : this.#e.onPointAppended(r), this.#e.lastXTarget !== null && (this.#R = !0), i !== void 0 && (this.#u = !0), this.#y(r), this.syncScales(), s ? this.#U() : this.#i.markDirty(), this.emit("dataUpdate"), this.#S();
1093
+ e || s ? (this.#D.seed(r), this.#e.onDataReplaced(r)) : this.#e.onPointAppended(r), this.#e.lastXTarget !== null && (this.#M = !0), t !== void 0 && (this.#u = !0), this.#p(r), this.syncScales(), s ? this.#G() : this.#i.markDirty(), this.emit("dataUpdate"), this.#b();
1039
1094
  }
1040
1095
  updateDataInterval() {
1041
- for (const i of this.#t) {
1042
- if (i.renderer.kind === "pie") continue;
1043
- const t = i.renderer.sampleTimes(20);
1044
- if (t.length >= 2) {
1045
- this.#h = lt(t);
1096
+ for (const t of this.#t) {
1097
+ if (t.renderer.kind === "pie") continue;
1098
+ const i = t.renderer.sampleTimes(20);
1099
+ if (i.length >= 2) {
1100
+ this.#a = lt(i);
1046
1101
  break;
1047
1102
  }
1048
1103
  }
@@ -1058,22 +1113,22 @@ class Ot extends st {
1058
1113
  * range — without this guard the engine would ease from `{0,0}` into
1059
1114
  * the new target and the very first frame would render with a
1060
1115
  * zero-width X domain. */
1061
- #R = !1;
1116
+ #M = !1;
1062
1117
  /**
1063
1118
  * One-shot `setVisibleRange` argument applied on the first data arrival.
1064
1119
  * Captured at chart construction from {@link ChartOptions.viewport.initialRange};
1065
1120
  * cleared the moment it's consumed so subsequent data swaps don't snap
1066
1121
  * back to the initial window.
1067
1122
  */
1068
- #H;
1123
+ #N;
1069
1124
  /** Last Y bounds the engine resolved into {@link AnimationState.yRange}.
1070
1125
  * Used by {@link renderMain} to detect Y movement frame-to-frame so
1071
1126
  * `viewportChange` only emits when the Y range actually shifted — DOM
1072
1127
  * axis labels subscribe to that event and re-renders on every tick are
1073
1128
  * expensive. Initialised to NaN so the first real Y emit always passes
1074
1129
  * the change check. */
1075
- #X = Number.NaN;
1076
- #_ = Number.NaN;
1130
+ #U = Number.NaN;
1131
+ #Z = Number.NaN;
1077
1132
  /**
1078
1133
  * Sample the visible data window and return the resolved Y bounds, or
1079
1134
  * `null` when no series has data inside the X destination range.
@@ -1082,11 +1137,11 @@ class Ot extends st {
1082
1137
  * converge together. Clears {@link #yInited} on empty so the next emit
1083
1138
  * with valid data lands as an instant snap.
1084
1139
  */
1085
- #st(i) {
1086
- const t = i ?? this.#o, e = this.#a.min !== void 0 && this.#a.min !== "auto" && typeof this.#a.min != "number" || this.#a.max !== void 0 && this.#a.max !== "auto" && typeof this.#a.max != "number" ? [] : null, s = q(t, this.#t, e);
1140
+ #nt(t) {
1141
+ const i = t ?? this.#o, e = this.#h.min !== void 0 && this.#h.min !== "auto" && typeof this.#h.min != "number" || this.#h.max !== void 0 && this.#h.max !== "auto" && typeof this.#h.max != "number" ? [] : null, s = q(i, this.#t, e);
1087
1142
  if (s === null)
1088
1143
  return this.#u = !1, null;
1089
- const r = R(this.#a.min, s.min, s.max, e ?? [], "min"), n = R(this.#a.max, s.max, s.min, e ?? [], "max");
1144
+ const r = M(this.#h.min, s.min, s.max, e ?? [], "min"), n = M(this.#h.max, s.max, s.min, e ?? [], "max");
1090
1145
  return { min: r, max: n };
1091
1146
  }
1092
1147
  /**
@@ -1107,24 +1162,24 @@ class Ot extends st {
1107
1162
  * - **autoscroll off** → `null` (no X retarget; user has panned away
1108
1163
  * from the tail).
1109
1164
  */
1110
- #gt() {
1165
+ #pt() {
1111
1166
  if (this.#k === null || this.#s === null) return null;
1112
- const { from: i, to: t } = this.#o, e = i === 0 && t === 0, s = this.#n.size.media.width - this.yAxisWidth;
1167
+ const { from: t, to: i } = this.#o, e = t === 0 && i === 0, s = this.#n.size.media.width - this.yAxisWidth;
1113
1168
  if (e)
1114
- return this.#M(this.#k, this.#s, s), this.#H !== void 0 && (this.setVisibleRange(this.#H), this.#H = void 0), this.#o;
1115
- if (!this.#p) return null;
1116
- if (this.#K)
1117
- return this.#M(this.#k, this.#s, s), this.#o;
1169
+ return this.#R(this.#k, this.#s, s), this.#N !== void 0 && (this.setVisibleRange(this.#N), this.#N = void 0), this.#o;
1170
+ if (!this.#y) return null;
1171
+ if (this.#tt)
1172
+ return this.#R(this.#k, this.#s, s), this.#o;
1118
1173
  const r = j({
1119
1174
  currentLogical: this.#o,
1120
1175
  lastTime: this.#s,
1121
1176
  prevDataEnd: this.#P,
1122
- dataInterval: this.#h,
1123
- paddingRight: this.#l.right,
1177
+ dataInterval: this.#a,
1178
+ paddingRight: this.#c.right,
1124
1179
  chartWidth: s,
1125
1180
  holdUntilFilled: this.#L
1126
1181
  });
1127
- return r.releaseHold && (this.#L = !1), r.reengageAutoScroll && (this.#p = !0), r.newLogical === null ? null : (this.#D.observe(performance.now()), this.#e.setXSettleMs(this.#D.pickSettleMs(this.#f.axis.x.settleMs)), this.#C(r.newLogical, { emitChange: !1, skipValidation: !0 }), this.#P = this.#s, r.newLogical);
1182
+ return r.releaseHold && (this.#L = !1), r.reengageAutoScroll && (this.#y = !0), r.newLogical === null ? null : (this.#D.observe(performance.now()), this.#e.setXSettleMs(this.#D.pickSettleMs(this.#f.axis.x.settleMs)), this.#T(r.newLogical, { emitChange: !1, skipValidation: !0 }), this.#P = this.#s, r.newLogical);
1128
1183
  }
1129
1184
  /**
1130
1185
  * Fit the viewport's logical X range around a data span. Mirrors the
@@ -1132,16 +1187,16 @@ class Ot extends st {
1132
1187
  * forces autoscroll on (data tail is in the new window by construction),
1133
1188
  * commits the new range via `viewport.setRange` (which emits `change`).
1134
1189
  */
1135
- #M(i, t, e) {
1136
- const s = this.#l, r = O({
1137
- firstTime: i,
1138
- lastTime: t,
1139
- dataInterval: this.#h,
1140
- maxVisibleBars: this.#Q,
1190
+ #R(t, i, e) {
1191
+ const s = this.#c, r = O({
1192
+ firstTime: t,
1193
+ lastTime: i,
1194
+ dataInterval: this.#a,
1195
+ maxVisibleBars: this.#it,
1141
1196
  chartWidth: e,
1142
1197
  padding: { left: s.left, right: s.right }
1143
1198
  });
1144
- this.#L = !1, this.#p = !0, this.#C(r, { emitChange: !0 });
1199
+ this.#L = !1, this.#y = !0, this.#T(r, { emitChange: !0 });
1145
1200
  }
1146
1201
  /**
1147
1202
  * Commit a programmatic zoom — `fitContent` or `setVisibleRange`. Reads
@@ -1157,15 +1212,15 @@ class Ot extends st {
1157
1212
  * passes `xEase: true` so X eases instead — viewport and axis converge
1158
1213
  * on the same frame.
1159
1214
  */
1160
- #N(i) {
1161
- const t = this.#o;
1162
- if (t.to <= t.from) return;
1215
+ #H(t) {
1216
+ const i = this.#o;
1217
+ if (i.to <= i.from) return;
1163
1218
  const e = performance.now();
1164
- if (!this.#R || !this.#u) {
1165
- this.#rt(e);
1219
+ if (!this.#M || !this.#u) {
1220
+ this.#at(e);
1166
1221
  return;
1167
1222
  }
1168
- this.#e.onProgrammaticZoom({ xTarget: t, xEase: i?.xEase }, e), this.#y(e);
1223
+ this.#e.onProgrammaticZoom({ xTarget: i, xEase: t?.xEase }, e), this.#p(e);
1169
1224
  }
1170
1225
  /**
1171
1226
  * Commit the current logical X to the engine on the *gesture* profile:
@@ -1179,15 +1234,15 @@ class Ot extends st {
1179
1234
  * instead of lagging on the long sticky contract. First paint still snaps
1180
1235
  * (same as the programmatic path) so synchronous readers see final values.
1181
1236
  */
1182
- #pt() {
1183
- const i = this.#o;
1184
- if (i.to <= i.from) return;
1185
- const t = performance.now();
1186
- if (!this.#R || !this.#u) {
1187
- this.#rt(t);
1237
+ #vt() {
1238
+ const t = this.#o;
1239
+ if (t.to <= t.from) return;
1240
+ const i = performance.now();
1241
+ if (!this.#M || !this.#u) {
1242
+ this.#at(i);
1188
1243
  return;
1189
1244
  }
1190
- this.#e.onPanZoom({ xTarget: i, yAuto: !0 }, t), this.#y(t);
1245
+ this.#e.onPanZoom({ xTarget: t, yAuto: !0 }, i), this.#p(i);
1191
1246
  }
1192
1247
  /**
1193
1248
  * First-paint snap: land both axes on the current logical X immediately
@@ -1196,9 +1251,9 @@ class Ot extends st {
1196
1251
  * commits — both must snap before the chart has painted once so a
1197
1252
  * synchronous `getYRange()` / `getVisibleRange()` read sees final values.
1198
1253
  */
1199
- #rt(i) {
1200
- const t = this.#o, e = this.#st(t);
1201
- this.#R = !0, e !== null && (this.#u = !0), this.#e.snap({ x: t, y: e ?? void 0 }, i), this.#y(i);
1254
+ #at(t) {
1255
+ const i = this.#o, e = this.#nt(i);
1256
+ this.#M = !0, e !== null && (this.#u = !0), this.#e.snap({ x: i, y: e ?? void 0 }, t), this.#p(t);
1202
1257
  }
1203
1258
  /**
1204
1259
  * Validate and commit a new logical X range. Mirrors the old
@@ -1218,9 +1273,9 @@ class Ot extends st {
1218
1273
  * see `setVisibleRange`'s gesture path, where a per-frame echo would
1219
1274
  * otherwise re-arm and stall the in-flight Y ease.
1220
1275
  */
1221
- #C(i, t) {
1222
- const { from: e, to: s } = i;
1223
- return !Number.isFinite(e) || !Number.isFinite(s) || s <= e || !t.skipValidation && (s - e) / this.#h < 2 || this.#o.from === e && this.#o.to === s ? !1 : (this.#o = { from: e, to: s }, t.emitChange && (this.syncScales(), this.#i?.markDirty(), this.emit("viewportChange")), !0);
1276
+ #T(t, i) {
1277
+ const { from: e, to: s } = t;
1278
+ return !Number.isFinite(e) || !Number.isFinite(s) || s <= e || !i.skipValidation && (s - e) / this.#a < 2 || this.#o.from === e && this.#o.to === s ? !1 : (this.#o = { from: e, to: s }, i.emitChange && (this.syncScales(), this.#i?.markDirty(), this.emit("viewportChange")), !0);
1224
1279
  }
1225
1280
  /**
1226
1281
  * Apply pixel-padding to the engine's raw Y target and store the
@@ -1228,11 +1283,11 @@ class Ot extends st {
1228
1283
  * symmetric pad top / bottom from `#padding`, suppressed on the side
1229
1284
  * that has an explicit (fixed) axis bound.
1230
1285
  */
1231
- #nt(i, t, e, s, r) {
1232
- const n = t - i, h = e > 0 ? this.#l.top / e * n : 0, a = e > 0 ? this.#l.bottom / e * n : 0;
1286
+ #ht(t, i, e, s, r) {
1287
+ const n = i - t, a = e > 0 ? this.#c.top / e * n : 0, h = e > 0 ? this.#c.bottom / e * n : 0;
1233
1288
  this.#V = {
1234
- min: s ? i : i - a,
1235
- max: r ? t : t + h
1289
+ min: s ? t : t - h,
1290
+ max: r ? i : i + a
1236
1291
  };
1237
1292
  }
1238
1293
  /**
@@ -1245,18 +1300,18 @@ class Ot extends st {
1245
1300
  * as a gesture for visual easing. Public so consumers can drive pan
1246
1301
  * programmatically.
1247
1302
  */
1248
- pan(i, t = this.#z) {
1249
- t > 0 && (this.#z = t), this.#L = !1;
1303
+ pan(t, i = this.#z) {
1304
+ i > 0 && (this.#z = i), this.#L = !1;
1250
1305
  const e = U({
1251
1306
  currentLogical: this.#o,
1252
- timeDelta: i,
1253
- chartWidth: t,
1254
- dataInterval: this.#h,
1255
- padding: { left: this.#l.left, right: this.#l.right },
1307
+ timeDelta: t,
1308
+ chartWidth: i,
1309
+ dataInterval: this.#a,
1310
+ padding: { left: this.#c.left, right: this.#c.right },
1256
1311
  dataStart: this.#k,
1257
1312
  dataEnd: this.#s
1258
1313
  });
1259
- e.newLogical !== null && (this.#p = !e.autoScrollOff, this.#C(e.newLogical, { emitChange: !0 }), e.edgeReached !== null && (this.#j[e.edgeReached.side] = e.edgeReached.boundaryTime, this.#q?.(e.edgeReached)), this.#D.pause(), this.#ht());
1314
+ e.newLogical !== null && (this.#y = !e.autoScrollOff, this.#T(e.newLogical, { emitChange: !0 }), e.edgeReached !== null && (this.#J[e.edgeReached.side] = e.edgeReached.boundaryTime, this.#K?.(e.edgeReached)), this.#D.pause(), this.#ot());
1260
1315
  }
1261
1316
  /**
1262
1317
  * Zoom around a time anchor. `factor < 1` zooms in, `> 1` zooms out.
@@ -1273,37 +1328,37 @@ class Ot extends st {
1273
1328
  * and produce a visible jump). Cursor-anchored zoom is intentionally
1274
1329
  * sacrificed in follow-live mode — pan first to inspect history.
1275
1330
  */
1276
- zoomAt(i, t, e = this.#z) {
1331
+ zoomAt(t, i, e = this.#z) {
1277
1332
  e > 0 && (this.#z = e), this.#L = !1;
1278
1333
  const s = Z({
1279
1334
  currentLogical: this.#o,
1280
- centerTime: i,
1281
- factor: t,
1335
+ centerTime: t,
1336
+ factor: i,
1282
1337
  chartWidth: e,
1283
- dataInterval: this.#h,
1284
- padding: { left: this.#l.left, right: this.#l.right },
1338
+ dataInterval: this.#a,
1339
+ padding: { left: this.#c.left, right: this.#c.right },
1285
1340
  dataStart: this.#k,
1286
1341
  dataEnd: this.#s
1287
1342
  });
1288
1343
  if (s.newLogical === null) return;
1289
1344
  let r = s.newLogical;
1290
- if (this.#p && this.#s !== null) {
1291
- const n = r.to - r.from, h = T(this.#l.right, n, this.#h, e), a = this.#s + h;
1292
- r = { from: a - n, to: a }, this.#P = this.#s;
1345
+ if (this.#y && this.#s !== null) {
1346
+ const n = r.to - r.from, a = C(this.#c.right, n, this.#a, e), h = this.#s + a;
1347
+ r = { from: h - n, to: h }, this.#P = this.#s;
1293
1348
  }
1294
- this.#C(r, { emitChange: !0 }), this.#D.pause(), this.#ht();
1349
+ this.#T(r, { emitChange: !0 }), this.#D.pause(), this.#ot();
1295
1350
  }
1296
1351
  /**
1297
1352
  * Common tail for `pan` / `zoomAt`: routes the just-committed `#logical`
1298
1353
  * to the engine as a gesture so the X spring retargets and the Y spring
1299
1354
  * eases over `animations.axis.y.gesture`.
1300
1355
  */
1301
- #ht() {
1302
- const i = this.#o;
1303
- if (i.to <= i.from) return;
1304
- this.#R = !0, this.#u = !0;
1305
- const t = performance.now();
1306
- this.#e.onPanZoom({ xTarget: i, yAuto: !0 }, t), this.#y(t);
1356
+ #ot() {
1357
+ const t = this.#o;
1358
+ if (t.to <= t.from) return;
1359
+ this.#M = !0, this.#u = !0;
1360
+ const i = performance.now();
1361
+ this.#e.onPanZoom({ xTarget: t, yAuto: !0 }, i), this.#p(i);
1307
1362
  }
1308
1363
  /**
1309
1364
  * Tick the engine at the given wall clock and push the resolved X / Y
@@ -1318,11 +1373,11 @@ class Ot extends st {
1318
1373
  * `effectiveNow === startWall` and the prune step keeps zero-duration
1319
1374
  * events long enough for the slot processor to snap them.
1320
1375
  */
1321
- #y(i) {
1322
- const t = this.#e.tick(i), e = this.#n.size;
1376
+ #p(t) {
1377
+ const i = this.#e.tick(t), e = this.#n.size;
1323
1378
  if (e.media.width === 0 || e.media.height === 0) return;
1324
- const s = this.#a.min !== void 0 && this.#a.min !== "auto", r = this.#a.max !== void 0 && this.#a.max !== "auto", n = e.media.height - this.xAxisHeight;
1325
- this.#nt(t.yRange.min, t.yRange.max, n, s, r), this.#X = t.yRange.min, this.#_ = t.yRange.max, this.syncScales();
1379
+ const s = this.#h.min !== void 0 && this.#h.min !== "auto", r = this.#h.max !== void 0 && this.#h.max !== "auto", n = e.media.height - this.xAxisHeight;
1380
+ this.#ht(i.yRange.min, i.yRange.max, n, s, r), this.#U = i.yRange.min, this.#Z = i.yRange.max, this.syncScales();
1326
1381
  }
1327
1382
  /**
1328
1383
  * Lightweight scale sync: updates timeScale/yScale from current viewport state
@@ -1330,79 +1385,79 @@ class Ot extends st {
1330
1385
  * handler, so DOM axis components always read fresh coordinates on re-render.
1331
1386
  */
1332
1387
  syncScales() {
1333
- const i = this.#n.size;
1334
- if (i.media.width === 0 || i.media.height === 0) return;
1335
- const t = i.media.width - this.yAxisWidth, e = i.media.height - this.xAxisHeight;
1388
+ const t = this.#n.size;
1389
+ if (t.media.width === 0 || t.media.height === 0) return;
1390
+ const i = t.media.width - this.yAxisWidth, e = t.media.height - this.xAxisHeight;
1336
1391
  this.timeScale.update(
1337
1392
  this.#e.getAnimationState().xRange,
1338
- t,
1339
- i.horizontalPixelRatio,
1340
- this.#h
1341
- ), this.yScale.update(this.#V, e, i.verticalPixelRatio);
1393
+ i,
1394
+ t.horizontalPixelRatio,
1395
+ this.#a
1396
+ ), this.yScale.update(this.#V, e, t.verticalPixelRatio);
1342
1397
  }
1343
1398
  /** Expensive: background, grid, all series. Only on data/viewport/resize change. */
1344
- renderMain(i) {
1345
- const t = this.#n.size;
1346
- if (t.media.width === 0 || t.media.height === 0) return;
1347
- const e = typeof i == "number" ? i : performance.now(), s = this.#e.tick(e);
1399
+ renderMain(t) {
1400
+ const i = this.#n.size;
1401
+ if (i.media.width === 0 || i.media.height === 0) return;
1402
+ const e = typeof t == "number" ? t : performance.now(), s = this.#e.tick(e);
1348
1403
  s.animating && this.#i.markDirty();
1349
- const r = s.yRange.min, n = s.yRange.max, h = r !== this.#X || n !== this.#_;
1350
- if (h) {
1351
- const c = this.#a.min !== void 0 && this.#a.min !== "auto", o = this.#a.max !== void 0 && this.#a.max !== "auto", f = t.media.height - this.xAxisHeight;
1352
- this.#nt(r, n, f, c, o), this.#X = r, this.#_ = n;
1404
+ const r = s.yRange.min, n = s.yRange.max, a = r !== this.#U || n !== this.#Z;
1405
+ if (a) {
1406
+ const d = this.#h.min !== void 0 && this.#h.min !== "auto", c = this.#h.max !== void 0 && this.#h.max !== "auto", f = i.media.height - this.xAxisHeight;
1407
+ this.#ht(r, n, f, d, c), this.#U = r, this.#Z = n;
1353
1408
  }
1354
- if (this.syncScales(), this.#s !== null && !this.#p) {
1355
- const c = this.#e.lastXTarget ?? this.#o, o = c.to - c.from;
1356
- if (o > 0) {
1357
- const f = this.#n.size.media.width - this.yAxisWidth, y = T(this.#l.right, o, this.#h, f), v = this.#h * 0.5;
1358
- Math.abs(c.to - (this.#s + y)) < v && (this.#p = !0);
1409
+ if (this.syncScales(), this.#yt(), this.#s !== null && !this.#y) {
1410
+ const d = this.#e.lastXTarget ?? this.#o, c = d.to - d.from;
1411
+ if (c > 0) {
1412
+ const f = this.#n.size.media.width - this.yAxisWidth, p = C(this.#c.right, c, this.#a, f), v = this.#a * 0.5;
1413
+ Math.abs(d.to - (this.#s + p)) < v && (this.#y = !0);
1359
1414
  }
1360
1415
  }
1361
- h && this.emit("viewportChange");
1362
- let a = !1, d = !1;
1363
- this.#n.useMainLayer((c) => {
1364
- const { context: o, bitmapSize: f } = c, y = (t.media.width - this.yAxisWidth) * t.horizontalPixelRatio, v = (t.media.height - this.xAxisHeight) * t.verticalPixelRatio;
1365
- o.clearRect(0, 0, f.width, f.height), o.save(), o.beginPath(), o.rect(0, 0, y, v), o.clip(), this.yScale.tickTracker.setCurrentTicks(this.yScale.niceTickValues()), this.timeScale.tickTracker.setCurrentTicks(this.timeScale.niceTickValues(this.#h).ticks), this.yScale.tickTracker.tick(e), this.timeScale.tickTracker.tick(e);
1366
- const S = this.yScale.tickTracker.snapshot(), b = this.timeScale.tickTracker.snapshot();
1367
- a = S.isAnimating, d = b.isAnimating, (S.isAnimating || b.isAnimating || s.animating) && this.emit("tickFrame"), this.#E && K({
1368
- scope: c,
1416
+ a && this.emit("viewportChange");
1417
+ let h = !1, l = !1;
1418
+ this.#n.useMainLayer((d) => {
1419
+ const { context: c, bitmapSize: f } = d, p = (i.media.width - this.yAxisWidth) * i.horizontalPixelRatio, v = (i.media.height - this.xAxisHeight) * i.verticalPixelRatio;
1420
+ c.clearRect(0, 0, f.width, f.height), c.save(), c.beginPath(), c.rect(0, 0, p, v), c.clip(), this.yScale.tickTracker.setCurrentTicks(this.yScale.niceTickValues()), this.timeScale.tickTracker.setCurrentTicks(this.timeScale.niceTickValues(this.#a).ticks), this.yScale.tickTracker.tick(e), this.timeScale.tickTracker.tick(e);
1421
+ const b = this.yScale.tickTracker.snapshot(), x = this.timeScale.tickTracker.snapshot();
1422
+ h = b.isAnimating, l = x.isAnimating, (b.isAnimating || x.isAnimating || s.animating) && this.emit("tickFrame"), this.#E && K({
1423
+ scope: d,
1369
1424
  timeScale: this.timeScale,
1370
1425
  yScale: this.yScale,
1371
1426
  theme: this.#r,
1372
- yTicks: S,
1373
- timeTicks: b
1374
- }), this.#ct(c, y, v);
1375
- const k = this.#l, P = { top: k.top, bottom: k.bottom }, w = this.#x;
1376
- for (const p of this.#t) {
1377
- const x = p.renderer.getAlpha?.() ?? (p.visible ? 1 : 0);
1378
- if (x <= 0) continue;
1427
+ yTicks: b,
1428
+ timeTicks: x
1429
+ }), this.#ut(d, p, v);
1430
+ const k = this.#c, P = { top: k.top, bottom: k.bottom }, w = this.#S;
1431
+ for (const y of this.#t) {
1432
+ const S = y.renderer.getAlpha?.() ?? (y.visible ? 1 : 0);
1433
+ if (S <= 0) continue;
1379
1434
  const L = {
1380
- scope: c,
1435
+ scope: d,
1381
1436
  timeScale: this.timeScale,
1382
1437
  yScale: this.yScale,
1383
1438
  theme: this.#r,
1384
- dataInterval: this.#h,
1439
+ dataInterval: this.#a,
1385
1440
  padding: P,
1386
1441
  state: s,
1387
- seriesId: p.id
1388
- }, A = o.globalAlpha;
1389
- if (x < 1 && (o.globalAlpha = A * x), w) {
1442
+ seriesId: y.id
1443
+ }, A = c.globalAlpha;
1444
+ if (S < 1 && (c.globalAlpha = A * S), w) {
1390
1445
  const V = performance.now();
1391
- p.renderer.render(L), w.recordSeries(p.id, performance.now() - V, e);
1446
+ y.renderer.render(L), w.recordSeries(y.id, performance.now() - V, e);
1392
1447
  } else
1393
- p.renderer.render(L);
1394
- x < 1 && (o.globalAlpha = A);
1448
+ y.renderer.render(L);
1449
+ S < 1 && (c.globalAlpha = A);
1395
1450
  }
1396
- o.restore();
1451
+ c.restore();
1397
1452
  });
1398
- let l = !1;
1399
- for (const c of this.#t)
1400
- if (c.renderer.needsAnimation) {
1401
- l = !0, this.#i.markDirty();
1453
+ let o = !1;
1454
+ for (const d of this.#t)
1455
+ if (d.renderer.needsAnimation) {
1456
+ o = !0, this.#i.markDirty();
1402
1457
  break;
1403
1458
  }
1404
- const u = a || d;
1405
- !s.animating && !l && !u && (this.yScale.tickTracker.markArmed(), this.timeScale.tickTracker.markArmed());
1459
+ const u = h || l;
1460
+ !s.animating && !o && !u && (this.yScale.tickTracker.markArmed(), this.timeScale.tickTracker.markArmed());
1406
1461
  }
1407
1462
  /**
1408
1463
  * Paint a full frame: the main layer, then the overlay synchronously on
@@ -1413,80 +1468,80 @@ class Ot extends st {
1413
1468
  * `markDirty` calls made *during* `renderOverlay` (pulse, edge spinner)
1414
1469
  * land after the consume and re-arm cleanly for the next frame.
1415
1470
  */
1416
- #U(i) {
1417
- this.#Z("main", i, () => this.renderMain(i)), this.#d.consume(), this.#Z("overlay", i, () => this.renderOverlay(i));
1471
+ #G(t) {
1472
+ this.#j("main", t, () => this.renderMain(t)), this.#l.consume(), this.#j("overlay", t, () => this.renderOverlay(t));
1418
1473
  }
1419
1474
  /** Run a layer's paint, booking duration + draw calls to the perf monitor
1420
1475
  * when one is attached — keeps overlay time out of the `main` samples. */
1421
- #Z(i, t, e) {
1422
- const s = this.#x;
1476
+ #j(t, i, e) {
1477
+ const s = this.#S;
1423
1478
  if (!s) {
1424
1479
  e();
1425
1480
  return;
1426
1481
  }
1427
- s.resetDrawCalls(i);
1482
+ s.resetDrawCalls(t);
1428
1483
  const r = performance.now();
1429
- e(), s.recordFrame(i, performance.now() - r, t ?? r);
1484
+ e(), s.recordFrame(t, performance.now() - r, i ?? r);
1430
1485
  }
1431
1486
  /** Cheap overlay: crosshair, nearest-point dots, pulse animation, edge indicator. */
1432
- renderOverlay(i) {
1433
- const t = this.#n.size;
1434
- if (t.media.width === 0 || t.media.height === 0) return;
1487
+ renderOverlay(t) {
1488
+ const i = this.#n.size;
1489
+ if (i.media.width === 0 || i.media.height === 0) return;
1435
1490
  let e = !1;
1436
- for (const h of this.#t)
1437
- if (h.visible && h.renderer.overlayNeedsAnimation) {
1491
+ for (const a of this.#t)
1492
+ if (a.visible && a.renderer.overlayNeedsAnimation) {
1438
1493
  e = !0;
1439
1494
  break;
1440
1495
  }
1441
- this.#c.some((h) => h.pulse) && (e = !0);
1442
- const s = this.#b.left === "loading" || this.#b.right === "loading", r = this.#b.left !== "idle" || this.#b.right !== "idle", n = !!this.#m || e || r || this.#c.length > 0 || this.#g.length > 0;
1443
- if (!(!n && !this.#G)) {
1444
- if (this.#G = n, this.#n.useOverlayLayer((h) => {
1496
+ this.#m.some((a) => a.pulse) && (e = !0);
1497
+ const s = this.#x.left === "loading" || this.#x.right === "loading", r = this.#x.left !== "idle" || this.#x.right !== "idle", n = !!this.#d || e || r || this.#m.length > 0 || this.#g.length > 0;
1498
+ if (!(!n && !this.#q)) {
1499
+ if (this.#q = n, this.#n.useOverlayLayer((a) => {
1445
1500
  if (!n) return;
1446
- const a = (t.media.width - this.yAxisWidth) * t.horizontalPixelRatio, d = (t.media.height - this.xAxisHeight) * t.verticalPixelRatio;
1447
- if (h.context.save(), h.context.beginPath(), h.context.rect(0, 0, a, d), h.context.clip(), this.#m && this.#ut()) {
1448
- const o = this.#m.mediaX * t.horizontalPixelRatio, f = this.#m.mediaY * t.verticalPixelRatio;
1449
- J(h, o, f, this.#r);
1501
+ const h = (i.media.width - this.yAxisWidth) * i.horizontalPixelRatio, l = (i.media.height - this.xAxisHeight) * i.verticalPixelRatio;
1502
+ if (a.context.save(), a.context.beginPath(), a.context.rect(0, 0, h, l), a.context.clip(), this.#d && this.#gt()) {
1503
+ const c = this.#d.mediaX * i.horizontalPixelRatio, f = this.#d.mediaY * i.verticalPixelRatio;
1504
+ J(a, c, f, this.#r);
1450
1505
  }
1451
- const l = this.#l, u = { top: l.top, bottom: l.bottom }, c = this.#e.getAnimationState();
1452
- for (const o of this.#t)
1453
- o.visible && o.renderer.drawOverlay?.({
1454
- scope: h,
1506
+ const o = this.#c, u = { top: o.top, bottom: o.bottom }, d = this.#e.getAnimationState();
1507
+ for (const c of this.#t)
1508
+ c.visible && c.renderer.drawOverlay?.({
1509
+ scope: a,
1455
1510
  timeScale: this.timeScale,
1456
1511
  yScale: this.yScale,
1457
1512
  theme: this.#r,
1458
- dataInterval: this.#h,
1513
+ dataInterval: this.#a,
1459
1514
  padding: u,
1460
- crosshair: this.#m,
1461
- state: c,
1462
- seriesId: o.id
1515
+ crosshair: this.#d,
1516
+ state: d,
1517
+ seriesId: c.id
1463
1518
  });
1464
- this.#mt(h, a, d), this.#dt(h), r && E({
1465
- scope: h,
1466
- chartMediaHeight: t.media.height - this.xAxisHeight,
1519
+ this.#ft(a, h, l), this.#mt(a), r && E({
1520
+ scope: a,
1521
+ chartMediaHeight: i.media.height - this.xAxisHeight,
1467
1522
  timeScale: this.timeScale,
1468
1523
  theme: this.#r,
1469
- edgeStates: this.#b,
1470
- resolveBoundary: (o) => $(o, this.#j[o], this.getDataBounds())
1471
- }), h.context.restore();
1524
+ edgeStates: this.#x,
1525
+ resolveBoundary: (c) => F(c, this.#J[c], this.getDataBounds())
1526
+ }), a.context.restore();
1472
1527
  }), e) {
1473
- const { from: h, to: a } = this.timeScale.getRange();
1474
- let d = !1;
1475
- for (const l of this.#t)
1476
- if (!(!l.visible || !l.renderer.overlayNeedsAnimation) && (l.renderer.hasOverlayContentInRange?.(h, a) ?? !0)) {
1477
- d = !0;
1528
+ const { from: a, to: h } = this.timeScale.getRange();
1529
+ let l = !1;
1530
+ for (const o of this.#t)
1531
+ if (!(!o.visible || !o.renderer.overlayNeedsAnimation) && (o.renderer.hasOverlayContentInRange?.(a, h) ?? !0)) {
1532
+ l = !0;
1478
1533
  break;
1479
1534
  }
1480
- if (!d) {
1481
- for (const l of this.#c)
1482
- if (l.pulse && l.time >= h && l.time <= a) {
1483
- d = !0;
1535
+ if (!l) {
1536
+ for (const o of this.#m)
1537
+ if (o.pulse && o.time >= a && o.time <= h) {
1538
+ l = !0;
1484
1539
  break;
1485
1540
  }
1486
1541
  }
1487
- d && this.#d.markDirty();
1542
+ l && this.#l.markDirty();
1488
1543
  }
1489
- s && this.#d.markDirty();
1544
+ s && this.#l.markDirty();
1490
1545
  }
1491
1546
  }
1492
1547
  }