@coderyo/renderer-lite 1.1.0 → 1.1.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { IChartApi, LineData, UTCTimestamp } from 'lightweight-charts';
1
+ import * as lightweight_charts from 'lightweight-charts';
2
+ import { IChartApi, LineData, UTCTimestamp, LogicalRange } from 'lightweight-charts';
2
3
  import { Interval, Bar } from '@coderyo/data';
3
4
  import { IndicatorConfig } from '@coderyo/indicators';
4
5
 
@@ -29,6 +30,11 @@ declare class TimeScaleBus {
29
30
  setBarSpacing(spacing: number): void;
30
31
  setVisibleTimeRange(range: ChartVisibleRange): void;
31
32
  scrollToLogicalPosition(position: number, animated?: boolean): void;
33
+ /**
34
+ * DESIGN §10.4.1: after historical prepend, shift every pane's logical range by Δ
35
+ * so canonical `visibleFromMs` / `visibleToMs` (and crosshair time mapping) stay fixed.
36
+ */
37
+ compensatePrependLogicalRange(delta: number, referenceChart?: IChartApi, sliceTimes?: readonly number[]): void;
32
38
  private syncFrom;
33
39
  private emit;
34
40
  }
@@ -206,6 +212,11 @@ declare class PaneOrchestrator {
206
212
  resetViewState(): void;
207
213
  /** Skip the next automatic fitContent after setBars (used by reloadHistory). */
208
214
  preserveViewportOnNextSetBars(): void;
215
+ /**
216
+ * DESIGN §10.4.1: after `mergeBars(..., prepend)` shift logical ranges on every sync bus
217
+ * so canonical ms viewport and crosshair `t` stay stable.
218
+ */
219
+ compensatePrependForBuses(sortedTimesBefore: readonly number[], sortedTimesAfter: readonly number[], interval: Interval): void;
209
220
  getVisibleRange(): ChartVisibleRange | null;
210
221
  getBarSpace(): number;
211
222
  setBarSpace(px: number): void;
@@ -304,6 +315,46 @@ declare function bollOverlayLines(bars: Bar[], period: number, mult: number, sou
304
315
  lower: LineData<UTCTimestamp>[];
305
316
  };
306
317
 
318
+ /** Slice of loaded bar open times for the current render window (DESIGN §10.4.1). */
319
+ declare function buildSliceTimes(sortedTimes: readonly number[], renderFromMs: number, renderToMs: number): number[];
320
+ /** Count bars newly present in slice after prepend merge. */
321
+ declare function countPrependSliceDelta(beforeSlice: readonly number[], afterSlice: readonly number[]): number;
322
+ /** Map LWC logical index (position in slice) to canonical bar time `t` (ms). */
323
+ declare function logicalIndexToBarTimeMs(sliceTimes: readonly number[], logicalIndex: number): number | null;
324
+ /** Mirrors {@link VirtualWindow.getRenderRange} for prepend slice math. */
325
+ declare function deriveRenderRange(visibleFromMs: number, visibleToMs: number, sortedTimes: readonly number[], intervalMs: number): {
326
+ renderFromMs: number;
327
+ renderToMs: number;
328
+ };
329
+ /** Logical range covering canonical visible ms within a slice (DESIGN §10.4.1 fallback). */
330
+ declare function logicalRangeForVisibleWindow(sliceTimes: readonly number[], visibleFromMs: number, visibleToMs: number): LogicalRange | null;
331
+ interface PrependSliceDeltaInput {
332
+ sortedTimesBefore: readonly number[];
333
+ sortedTimesAfter: readonly number[];
334
+ visibleFromMs: number;
335
+ visibleToMs: number;
336
+ intervalMs: number;
337
+ }
338
+ /** Δ new bars in render slice after historical prepend (canonical ms window unchanged). */
339
+ declare function computePrependSliceDeltaForViewport(input: PrependSliceDeltaInput): number;
340
+ interface CompensatePrependOnRegistryOptions {
341
+ registry: TimeScaleBusRegistry;
342
+ sortedTimesBefore: readonly number[];
343
+ sortedTimesAfter: readonly number[];
344
+ intervalMs: number;
345
+ /** Reference chart for logical range read (e.g. main pane). */
346
+ referenceChart?: lightweight_charts.IChartApi;
347
+ }
348
+ /** Apply §10.4.1 logicalRange offset on every bus with an initialized visible window. */
349
+ declare function compensatePrependOnRegistry(opts: CompensatePrependOnRegistryOptions): void;
350
+ interface CompensatePrependOnBusOptions {
351
+ sortedTimesBefore: readonly number[];
352
+ sortedTimesAfter: readonly number[];
353
+ intervalMs: number;
354
+ referenceChart?: lightweight_charts.IChartApi;
355
+ }
356
+ declare function compensatePrependOnBus(bus: TimeScaleBus, opts: CompensatePrependOnBusOptions): void;
357
+
307
358
  /**
308
359
  * Default horizontal bar spacing (px) per interval so candle width feels consistent
309
360
  * when the integrator controls how many bars are loaded / visible.
@@ -311,4 +362,4 @@ declare function bollOverlayLines(bars: Bar[], period: number, mult: number, sou
311
362
  declare function defaultBarSpacingForInterval(interval: Interval): number;
312
363
  declare function resolveBarSpacingForInterval(interval: Interval, overrides?: Partial<Record<Interval, number>>): number;
313
364
 
314
- export { type ChartPaneId, type ChartVisibleRange, type CrosshairPayload, type IndicatorPaneId, IndicatorPaneStack, type IndicatorPaneStackOptions, PaneOrchestrator, type PaneOrchestratorOptions, type PaneSyncGroupPatch, type PaneSyncKey, type PinePlotLine, type ScaleMode, TimeScaleBus, TimeScaleBusRegistry, type TransformState, attachPaneResizer, bollOverlayLines, defaultBarSpacingForInterval, detectIndicatorBarMutation, emaOverlayLine, independentBusKey, isLayeredPaneMount, maOverlayLine, normalizeSyncGroupId, resolveBarSpacingForInterval, resolveBusMapKey, shouldResizeChartPane, volMaOverlayLine };
365
+ export { type ChartPaneId, type ChartVisibleRange, type CompensatePrependOnBusOptions, type CompensatePrependOnRegistryOptions, type CrosshairPayload, type IndicatorPaneId, IndicatorPaneStack, type IndicatorPaneStackOptions, PaneOrchestrator, type PaneOrchestratorOptions, type PaneSyncGroupPatch, type PaneSyncKey, type PinePlotLine, type PrependSliceDeltaInput, type ScaleMode, TimeScaleBus, TimeScaleBusRegistry, type TransformState, attachPaneResizer, bollOverlayLines, buildSliceTimes, compensatePrependOnBus, compensatePrependOnRegistry, computePrependSliceDeltaForViewport, countPrependSliceDelta, defaultBarSpacingForInterval, deriveRenderRange, detectIndicatorBarMutation, emaOverlayLine, independentBusKey, isLayeredPaneMount, logicalIndexToBarTimeMs, logicalRangeForVisibleWindow, maOverlayLine, normalizeSyncGroupId, resolveBarSpacingForInterval, resolveBusMapKey, shouldResizeChartPane, volMaOverlayLine };
package/dist/index.js CHANGED
@@ -7,6 +7,106 @@ import {
7
7
  LineSeries as LineSeries2
8
8
  } from "lightweight-charts";
9
9
  import { intervalMs as intervalMs2 } from "@coderyo/data";
10
+
11
+ // src/time-scale-prepend.ts
12
+ function buildSliceTimes(sortedTimes, renderFromMs, renderToMs) {
13
+ return sortedTimes.filter((t) => t >= renderFromMs && t <= renderToMs);
14
+ }
15
+ function countPrependSliceDelta(beforeSlice, afterSlice) {
16
+ const before = new Set(beforeSlice);
17
+ let delta = 0;
18
+ for (const t of afterSlice) {
19
+ if (!before.has(t)) delta += 1;
20
+ }
21
+ return delta;
22
+ }
23
+ function logicalIndexToBarTimeMs(sliceTimes, logicalIndex) {
24
+ if (sliceTimes.length === 0) return null;
25
+ const idx = Math.min(Math.max(0, Math.floor(logicalIndex)), sliceTimes.length - 1);
26
+ return sliceTimes[idx] ?? null;
27
+ }
28
+ function deriveRenderRange(visibleFromMs, visibleToMs, sortedTimes, intervalMs3) {
29
+ if (visibleToMs <= visibleFromMs && sortedTimes.length > 0) {
30
+ const fromMs = sortedTimes[0];
31
+ const toMs = sortedTimes[sortedTimes.length - 1];
32
+ const bufferMs2 = intervalMs3 * 20;
33
+ return { renderFromMs: fromMs - bufferMs2, renderToMs: toMs + bufferMs2 };
34
+ }
35
+ const span = visibleToMs - visibleFromMs;
36
+ const bufferMs = Math.max(span * 0.1, intervalMs3 * 50);
37
+ return {
38
+ renderFromMs: visibleFromMs - bufferMs,
39
+ renderToMs: visibleToMs + bufferMs
40
+ };
41
+ }
42
+ function logicalRangeForVisibleWindow(sliceTimes, visibleFromMs, visibleToMs) {
43
+ if (sliceTimes.length === 0 || visibleToMs <= visibleFromMs) return null;
44
+ let fromIdx = 0;
45
+ let toIdx = sliceTimes.length - 1;
46
+ for (let i = 0; i < sliceTimes.length; i++) {
47
+ if (sliceTimes[i] >= visibleFromMs) {
48
+ fromIdx = i;
49
+ break;
50
+ }
51
+ }
52
+ for (let i = sliceTimes.length - 1; i >= 0; i--) {
53
+ if (sliceTimes[i] <= visibleToMs) {
54
+ toIdx = i;
55
+ break;
56
+ }
57
+ }
58
+ if (toIdx < fromIdx) return null;
59
+ return { from: fromIdx, to: toIdx };
60
+ }
61
+ function computePrependSliceDeltaForViewport(input) {
62
+ const { visibleFromMs, visibleToMs, intervalMs: intervalMs3, sortedTimesBefore, sortedTimesAfter } = input;
63
+ const renderBefore = deriveRenderRange(visibleFromMs, visibleToMs, sortedTimesBefore, intervalMs3);
64
+ const renderAfter = deriveRenderRange(visibleFromMs, visibleToMs, sortedTimesAfter, intervalMs3);
65
+ const beforeSlice = buildSliceTimes(
66
+ sortedTimesBefore,
67
+ renderBefore.renderFromMs,
68
+ renderBefore.renderToMs
69
+ );
70
+ const afterSlice = buildSliceTimes(
71
+ sortedTimesAfter,
72
+ renderAfter.renderFromMs,
73
+ renderAfter.renderToMs
74
+ );
75
+ return countPrependSliceDelta(beforeSlice, afterSlice);
76
+ }
77
+ function compensatePrependOnRegistry(opts) {
78
+ const { registry, sortedTimesBefore, sortedTimesAfter, intervalMs: intervalMs3, referenceChart } = opts;
79
+ registry.forEachBus((_, bus) => {
80
+ compensatePrependOnBus(bus, {
81
+ sortedTimesBefore,
82
+ sortedTimesAfter,
83
+ intervalMs: intervalMs3,
84
+ referenceChart
85
+ });
86
+ });
87
+ }
88
+ function compensatePrependOnBus(bus, opts) {
89
+ const range = bus.getVisibleRange();
90
+ if (!range) return;
91
+ const delta = computePrependSliceDeltaForViewport({
92
+ sortedTimesBefore: opts.sortedTimesBefore,
93
+ sortedTimesAfter: opts.sortedTimesAfter,
94
+ visibleFromMs: range.fromMs,
95
+ visibleToMs: range.toMs,
96
+ intervalMs: opts.intervalMs
97
+ });
98
+ if (delta <= 0) return;
99
+ const { renderFromMs, renderToMs } = deriveRenderRange(
100
+ range.fromMs,
101
+ range.toMs,
102
+ opts.sortedTimesAfter,
103
+ opts.intervalMs
104
+ );
105
+ const sliceAfter = buildSliceTimes(opts.sortedTimesAfter, renderFromMs, renderToMs);
106
+ bus.compensatePrependLogicalRange(delta, opts.referenceChart, sliceAfter);
107
+ }
108
+
109
+ // src/pane-orchestrator.ts
10
110
  import { lodDecimateBars } from "@coderyo/series";
11
111
 
12
112
  // src/chart-grid.ts
@@ -517,6 +617,35 @@ var TimeScaleBus = class {
517
617
  this.syncing = false;
518
618
  this.emit();
519
619
  }
620
+ /**
621
+ * DESIGN §10.4.1: after historical prepend, shift every pane's logical range by Δ
622
+ * so canonical `visibleFromMs` / `visibleToMs` (and crosshair time mapping) stay fixed.
623
+ */
624
+ compensatePrependLogicalRange(delta, referenceChart, sliceTimes) {
625
+ const d = Math.max(0, Math.floor(delta));
626
+ if (d === 0 || this.charts.length === 0) return;
627
+ const ref = referenceChart && this.charts.includes(referenceChart) ? referenceChart : this.charts[0];
628
+ const ts = ref.timeScale();
629
+ let current = typeof ts.getVisibleLogicalRange === "function" ? ts.getVisibleLogicalRange() : null;
630
+ if (!current && sliceTimes?.length && this.visibleToMs > this.visibleFromMs) {
631
+ current = logicalRangeForVisibleWindow(
632
+ sliceTimes,
633
+ this.visibleFromMs,
634
+ this.visibleToMs
635
+ );
636
+ }
637
+ if (!current) return;
638
+ const next = {
639
+ from: current.from + d,
640
+ to: current.to + d
641
+ };
642
+ this.syncing = true;
643
+ for (const chart of this.charts) {
644
+ chart.timeScale().setVisibleLogicalRange(next);
645
+ }
646
+ this.syncing = false;
647
+ this.emit();
648
+ }
520
649
  syncFrom(source, range) {
521
650
  this.syncing = true;
522
651
  for (const chart of this.charts) {
@@ -1294,6 +1423,19 @@ var PaneOrchestrator = class {
1294
1423
  this.skipNextInitialFit = true;
1295
1424
  this.didInitialFit = true;
1296
1425
  }
1426
+ /**
1427
+ * DESIGN §10.4.1: after `mergeBars(..., prepend)` shift logical ranges on every sync bus
1428
+ * so canonical ms viewport and crosshair `t` stay stable.
1429
+ */
1430
+ compensatePrependForBuses(sortedTimesBefore, sortedTimesAfter, interval) {
1431
+ compensatePrependOnRegistry({
1432
+ registry: this.busRegistry,
1433
+ sortedTimesBefore,
1434
+ sortedTimesAfter,
1435
+ intervalMs: intervalMs2(interval),
1436
+ referenceChart: this.mainChart
1437
+ });
1438
+ }
1297
1439
  getVisibleRange() {
1298
1440
  return this.bus.getVisibleRange();
1299
1441
  }
@@ -1454,11 +1596,19 @@ export {
1454
1596
  TimeScaleBusRegistry,
1455
1597
  attachPaneResizer,
1456
1598
  bollOverlayLines,
1599
+ buildSliceTimes,
1600
+ compensatePrependOnBus,
1601
+ compensatePrependOnRegistry,
1602
+ computePrependSliceDeltaForViewport,
1603
+ countPrependSliceDelta,
1457
1604
  defaultBarSpacingForInterval,
1605
+ deriveRenderRange,
1458
1606
  detectIndicatorBarMutation,
1459
1607
  emaOverlayLine,
1460
1608
  independentBusKey,
1461
1609
  isLayeredPaneMount,
1610
+ logicalIndexToBarTimeMs,
1611
+ logicalRangeForVisibleWindow,
1462
1612
  maOverlayLine,
1463
1613
  normalizeSyncGroupId,
1464
1614
  resolveBarSpacingForInterval,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/pane-orchestrator.ts","../src/chart-grid.ts","../src/indicator-panes.ts","../src/pane-resize.ts","../src/time-scale-bus.ts","../src/time-scale-bus-registry.ts","../src/viewport-fit.ts","../src/bar-smooth-animator.ts"],"sourcesContent":["import {\n CandlestickSeries,\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type CandlestickData,\n type HistogramData,\n type WhitespaceData,\n type IChartApi,\n type ISeriesApi,\n type IPriceLine,\n type MouseEventParams,\n type Time,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport { intervalMs, type Bar, type Interval } from '@coderyo/data';\nimport { lodDecimateBars } from '@coderyo/series';\nimport { gridOptions } from './chart-grid.js';\nimport {\n DEFAULT_INDICATOR_CONFIG,\n hasVisibleIndicatorPanes,\n type IndicatorConfig,\n} from '@coderyo/indicators';\n\nimport {\n IndicatorPaneStack,\n bollOverlayLines,\n emaOverlayLine,\n maOverlayLine,\n volMaOverlayLine,\n} from './indicator-panes.js';\nimport { attachPaneResizer } from './pane-resize.js';\nimport { type ChartVisibleRange } from './time-scale-bus.js';\nimport {\n type PaneSyncGroupPatch,\n type PaneSyncKey,\n TimeScaleBusRegistry,\n} from './time-scale-bus-registry.js';\nimport { resolveBarSpacingForInterval } from './viewport-fit.js';\n\nexport type { ChartVisibleRange };\nimport { BarSmoothAnimator } from './bar-smooth-animator.js';\n\nexport type ScaleMode = 'linear' | 'log';\n\nexport interface CrosshairPayload {\n time: number;\n price: number | null;\n ohlcv: { o: number; h: number; l: number; c: number; v?: number } | null;\n}\n\nexport interface PinePlotLine {\n title: string;\n color?: string;\n values: (number | null)[];\n}\n\nexport type ChartPaneId = 'main' | 'volume' | 'indicator';\n\nexport function isLayeredPaneMount(opts: Pick<PaneOrchestratorOptions, 'volumeMount'>): boolean {\n return !!opts.volumeMount;\n}\n\nexport function shouldResizeChartPane(\n focus: Set<ChartPaneId> | null,\n pane: ChartPaneId,\n): boolean {\n if (!focus) return true;\n return focus.has(pane);\n}\n\nexport interface PaneOrchestratorOptions {\n /** Main candlestick mount (required). */\n container: HTMLElement;\n /**\n * P2: separate volume layer host; when set, no flex column in container.\n * Mount order: create empty `chartMain` + `chartVolume` nodes first, pass to compositor widgets,\n * then `createChart(chartMain, { volumeMount: chartVolume })` so LWC mounts after layer frames apply.\n */\n volumeMount?: HTMLElement;\n indicatorRoot?: HTMLElement;\n theme?: 'dark' | 'light';\n scaleMode?: ScaleMode;\n maxRenderPoints?: number;\n /** Show chart grid lines (default false). */\n showGrid?: boolean;\n /** null = no MA overlays and no MACD/RSI/KDJ panes. */\n indicatorConfig?: IndicatorConfig | null;\n /** Pine-lite plot lines on main chart (when pineEnabled). */\n pinePlots?: PinePlotLine[] | null;\n /** Animate last candle + price line toward new OHLC (~150ms). */\n smoothPriceUpdate?: boolean;\n smoothPriceDurationMs?: number;\n onIndicatorConfigChange?: (config: IndicatorConfig) => void;\n /** When true (default), set bar spacing on interval reload — does not change visible bar count. */\n autoBarSpacingOnInterval?: boolean;\n barSpacingByInterval?: Partial<Record<Interval, number>>;\n /**\n * When false, do not listen for `tradview:pane-resize` (ChartController owns that path).\n * @default true for standalone orchestrator use; ChartController passes false.\n */\n listenPaneResizeEvents?: boolean;\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\nfunction barToCandle(b: Bar): CandlestickData {\n return { time: toUtcSeconds(b.t), open: b.o, high: b.h, low: b.l, close: b.c };\n}\n\nfunction barToVolume(b: Bar): HistogramData<UTCTimestamp> {\n return { time: toUtcSeconds(b.t), value: b.v ?? 0 };\n}\n\nexport class PaneOrchestrator {\n readonly busRegistry = new TimeScaleBusRegistry();\n /** Active sync group bus (last-focused pane); used by ChartController viewport APIs. */\n get bus() {\n return this.busRegistry.activeBus;\n }\n private readonly layeredPanes: boolean;\n private readonly mainEl: HTMLElement;\n private readonly volWrap: HTMLElement;\n private detachMainVolResizer: () => void = () => {};\n private resizeFocusPanes: Set<ChartPaneId> | null = null;\n private readonly listenPaneResizeEvents: boolean;\n private readonly mainChart: IChartApi;\n private readonly volumeChart: IChartApi;\n private readonly mainSeries: ISeriesApi<'Candlestick'>;\n private readonly volumeSeries: ISeriesApi<'Histogram'>;\n private readonly maSeries: ISeriesApi<'Line'>;\n private readonly emaSeries: ISeriesApi<'Line'>;\n private readonly bollUpper: ISeriesApi<'Line'>;\n private readonly bollMiddle: ISeriesApi<'Line'>;\n private readonly bollLower: ISeriesApi<'Line'>;\n private readonly volMaSeries: ISeriesApi<'Line'>;\n private readonly indicatorRoot?: HTMLElement;\n private indicators: IndicatorPaneStack | null;\n private pinePlotSeries: ISeriesApi<'Line'>[] = [];\n private pinePlots: PinePlotLine[] | null = null;\n private overlayCanvas: HTMLCanvasElement | null = null;\n private dark = true;\n private showGrid = false;\n private readonly maxRenderPoints: number;\n private barByTime = new Map<number, Bar>();\n private barTimesOrdered: number[] = [];\n private didInitialFit = false;\n private skipNextInitialFit = false;\n /** setBars ran before the pane had layout size; refit on first real resize. */\n private pendingViewportFit = false;\n private pendingViewportBars: Bar[] | null = null;\n private indicatorConfig: IndicatorConfig | null = null;\n private onIndicatorConfigChange?: (config: IndicatorConfig) => void;\n private currentInterval: Interval = '1h';\n private autoBarSpacingOnInterval = true;\n private barSpacingByInterval?: Partial<Record<Interval, number>>;\n private priceLine: IPriceLine | null = null;\n private barAnimator: BarSmoothAnimator | null = null;\n private smoothPriceDurationMs = 150;\n\n constructor(opts: PaneOrchestratorOptions) {\n this.maxRenderPoints = opts.maxRenderPoints ?? 4000;\n this.listenPaneResizeEvents = opts.listenPaneResizeEvents !== false;\n this.dark = opts.theme !== 'light';\n this.showGrid = opts.showGrid ?? false;\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n\n this.layeredPanes = !!opts.volumeMount;\n const volEl = document.createElement('div');\n volEl.style.cssText = 'width:100%;height:100%;min-height:0;position:relative;';\n\n if (this.layeredPanes) {\n this.mainEl = opts.container;\n this.mainEl.style.cssText =\n 'width:100%;height:100%;min-height:80px;position:relative;overflow:hidden;';\n this.volWrap = opts.volumeMount!;\n this.volWrap.dataset.paneId = 'volume';\n this.volWrap.className = 'tv-volume-pane tv-volume-pane--layered';\n this.volWrap.replaceChildren();\n this.volWrap.style.cssText =\n 'width:100%;height:100%;min-height:48px;position:relative;overflow:hidden;box-sizing:border-box;';\n const volTag = document.createElement('span');\n volTag.textContent = 'Volume';\n volTag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const volClose = document.createElement('button');\n volClose.type = 'button';\n volClose.textContent = '×';\n volClose.title = '關閉成交量';\n volClose.setAttribute('aria-label', 'Close volume');\n volClose.style.cssText =\n 'position:absolute;right:6px;top:4px;z-index:3;width:22px;height:22px;padding:0;border:1px solid #30363d;border-radius:4px;background:#21262d;color:#8b949e;cursor:pointer;font-size:14px;line-height:1;';\n volClose.onclick = () => this.closeVolumePane();\n this.volWrap.append(volTag, volClose, volEl);\n } else {\n this.mainEl = document.createElement('div');\n this.mainEl.style.cssText = 'flex:7;min-height:120px;width:100%;position:relative;';\n volEl.style.cssText = 'flex:1;min-height:0;width:100%;height:100%;position:relative;';\n\n this.volWrap = document.createElement('div');\n this.volWrap.dataset.paneId = 'volume';\n this.volWrap.className = 'tv-volume-pane';\n this.volWrap.style.cssText =\n 'flex:2;min-height:48px;width:100%;position:relative;display:flex;flex-direction:column;border-top:1px solid #30363d;';\n const volTag = document.createElement('span');\n volTag.textContent = 'Volume';\n volTag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const volClose = document.createElement('button');\n volClose.type = 'button';\n volClose.textContent = '×';\n volClose.title = '關閉成交量';\n volClose.setAttribute('aria-label', 'Close volume');\n volClose.style.cssText =\n 'position:absolute;right:6px;top:4px;z-index:3;width:22px;height:22px;padding:0;border:1px solid #30363d;border-radius:4px;background:#21262d;color:#8b949e;cursor:pointer;font-size:14px;line-height:1;';\n volClose.onclick = () => this.closeVolumePane();\n this.volWrap.append(volTag, volClose, volEl);\n\n opts.container.style.cssText =\n 'display:flex;flex-direction:column;height:100%;width:100%;min-height:200px;overflow:hidden;';\n opts.container.append(this.mainEl, this.volWrap);\n this.rebuildMainVolumeResizer();\n }\n\n this.mainChart = createChart(this.mainEl, { layout, grid, autoSize: true });\n this.volumeChart = createChart(volEl, {\n layout,\n grid,\n autoSize: true,\n rightPriceScale: { scaleMargins: { top: 0.8, bottom: 0 } },\n });\n\n if (opts.scaleMode === 'log') {\n this.mainChart.priceScale('right').applyOptions({ mode: 1 });\n }\n\n this.mainSeries = this.mainChart.addSeries(CandlestickSeries, {\n upColor: '#26a69a',\n downColor: '#ef5350',\n borderVisible: false,\n wickUpColor: '#26a69a',\n wickDownColor: '#ef5350',\n });\n this.maSeries = this.mainChart.addSeries(LineSeries, {\n color: '#f0b429',\n lineWidth: 1,\n title: 'MA',\n });\n this.emaSeries = this.mainChart.addSeries(LineSeries, {\n color: '#7ee787',\n lineWidth: 1,\n title: 'EMA',\n visible: false,\n });\n this.bollUpper = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↑',\n visible: false,\n });\n this.bollMiddle = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e88',\n lineWidth: 1,\n lineStyle: 2,\n title: 'BOLL',\n visible: false,\n });\n this.bollLower = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↓',\n visible: false,\n });\n this.volumeSeries = this.volumeChart.addSeries(HistogramSeries, {\n color: '#26a69a55',\n priceFormat: { type: 'volume' },\n });\n this.volMaSeries = this.volumeChart.addSeries(LineSeries, {\n color: '#58a6ff',\n lineWidth: 1,\n title: 'VolMA5',\n });\n\n this.busRegistry.getBusForPane('main').register(this.mainChart);\n this.busRegistry.getBusForPane('volume').register(this.volumeChart);\n\n this.indicatorRoot = opts.indicatorRoot;\n this.indicatorConfig = opts.indicatorConfig ?? null;\n this.onIndicatorConfigChange = opts.onIndicatorConfigChange;\n this.autoBarSpacingOnInterval = opts.autoBarSpacingOnInterval ?? true;\n this.barSpacingByInterval = opts.barSpacingByInterval;\n this.pinePlots = opts.pinePlots ?? null;\n this.indicators = this.createIndicatorStack();\n\n this.initOverlay(this.mainEl);\n this.setSmoothPriceUpdate(opts.smoothPriceUpdate ?? false, opts.smoothPriceDurationMs);\n this.applyVolumeVisibility();\n if (opts.listenPaneResizeEvents !== false) {\n window.addEventListener('tradview:pane-resize', this.onPaneResize);\n }\n }\n\n private readonly onPaneResize = () => {\n this.resize();\n };\n\n setSmoothPriceUpdate(enabled: boolean, durationMs = 150): void {\n this.smoothPriceDurationMs = durationMs;\n if (enabled) {\n if (!this.barAnimator) {\n this.barAnimator = new BarSmoothAnimator(durationMs, (bar) => this.applyLastBarToSeries(bar));\n } else {\n this.barAnimator.setDuration(durationMs);\n }\n return;\n }\n this.barAnimator?.cancel();\n this.barAnimator = null;\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n }\n\n /** Update the last candle (and price line); optional smooth interpolation. */\n updateLastBar(target: Bar, opts?: { smooth?: boolean; durationMs?: number }): void {\n const prev = this.barByTime.get(target.t);\n const smooth = opts?.smooth ?? !!this.barAnimator;\n const duration = opts?.durationMs ?? this.smoothPriceDurationMs;\n if (smooth && this.barAnimator) {\n this.barAnimator.setDuration(duration);\n this.barAnimator.animateTo(target, prev ?? target);\n return;\n }\n this.barAnimator?.cancel();\n this.applyLastBarToSeries(target);\n }\n\n private applyLastBarToSeries(bar: Bar): void {\n this.barByTime.set(bar.t, bar);\n this.mainSeries.update(barToCandle(bar));\n if (this.isVolumeVisible()) {\n this.volumeSeries.update(barToVolume(bar));\n }\n this.ensurePriceLine(bar.c);\n if (this.indicatorConfig) {\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.applyMainOverlays(bars);\n if (hasVisibleIndicatorPanes(this.indicatorConfig)) {\n this.indicators?.setBars(bars);\n }\n }\n }\n\n private ensurePriceLine(price: number): void {\n if (!this.priceLine) {\n this.priceLine = this.mainSeries.createPriceLine({\n price,\n color: '#58a6ff',\n lineWidth: 1,\n lineStyle: 2,\n axisLabelVisible: true,\n title: '',\n });\n } else {\n this.priceLine.applyOptions({ price });\n }\n }\n\n setIntervalContext(interval: Interval): void {\n this.currentInterval = interval;\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.mainChart.applyOptions({ layout, grid });\n this.volumeChart.applyOptions({ layout, grid });\n this.indicators?.setTheme(theme);\n }\n\n setIndicatorConfig(config: IndicatorConfig | null): void {\n this.indicatorConfig = config;\n if (!config) {\n this.teardownIndicatorStack();\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.volumeSeries.setData([]);\n this.emaSeries.applyOptions({ visible: false });\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n this.applyVolumeVisibility();\n return;\n }\n if (!this.indicators) this.indicators = this.createIndicatorStack();\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.indicators?.setConfig(config);\n if (bars.length > 0) {\n this.applyMainOverlays(bars);\n if (hasVisibleIndicatorPanes(config)) {\n this.indicators?.setBars(bars);\n }\n }\n this.applyVolumeVisibility();\n }\n\n private isVolumeVisible(): boolean {\n return this.indicatorConfig?.showVolume ?? true;\n }\n\n private closeVolumePane(): void {\n if (!this.indicatorConfig) {\n this.indicatorConfig = { ...DEFAULT_INDICATOR_CONFIG, showVolume: false };\n } else {\n this.indicatorConfig = { ...this.indicatorConfig, showVolume: false };\n }\n this.applyVolumeVisibility();\n this.onIndicatorConfigChange?.(this.indicatorConfig);\n }\n\n private applyVolumeVisibility(): void {\n const show = this.isVolumeVisible();\n this.volWrap.style.display = show ? '' : 'none';\n this.rebuildMainVolumeResizer();\n if (!show) {\n this.volumeSeries.setData([]);\n this.volMaSeries.setData([]);\n }\n this.syncChartSize();\n }\n\n /** Assign per-pane sync group ids (`''` / omit = independent). Re-registers LWC charts on group change. */\n setPaneSyncGroups(patch: PaneSyncGroupPatch): void {\n const apply = (pane: PaneSyncKey, groupId: string | null | undefined) => {\n const prevKey = this.busRegistry.setPaneSyncGroup(pane, groupId);\n const nextKey = this.busRegistry.getBusKeyForPane(pane);\n if (pane === 'main') {\n this.busRegistry.moveChart(this.mainChart, prevKey, nextKey);\n } else if (pane === 'volume') {\n this.busRegistry.moveChart(this.volumeChart, prevKey, nextKey);\n } else if (this.indicators) {\n for (const chart of this.indicators.getCharts()) {\n this.busRegistry.moveChart(chart, prevKey, nextKey);\n }\n }\n };\n if (patch.main !== undefined) apply('main', patch.main);\n if (patch.volume !== undefined) apply('volume', patch.volume);\n if (patch.indicator !== undefined) apply('indicator', patch.indicator);\n }\n\n setActiveSyncPane(pane: ChartPaneId): void {\n const key: PaneSyncKey =\n pane === 'volume' ? 'volume' : pane === 'indicator' ? 'indicator' : 'main';\n this.busRegistry.setActivePane(key);\n }\n\n /** P2: when set, only these panes get LWC resize (panes in the same sync group still share TimeScaleBus). */\n setResizeFocusPanes(panes: ChartPaneId[] | null): void {\n this.resizeFocusPanes = panes?.length ? new Set(panes) : null;\n this.resize();\n }\n\n /** Current resize focus (null = all panes). @internal — not part of public package API. */\n getResizeFocusPanes(): ChartPaneId[] | null {\n return this.resizeFocusPanes ? [...this.resizeFocusPanes] : null;\n }\n\n private shouldResizePane(pane: ChartPaneId): boolean {\n return shouldResizeChartPane(this.resizeFocusPanes, pane);\n }\n\n private rebuildMainVolumeResizer(): void {\n if (this.layeredPanes) return;\n this.detachMainVolResizer();\n const parent = this.mainEl.parentElement;\n parent\n ?.querySelectorAll(':scope > [data-pane-resizer]')\n .forEach((el) => el.remove());\n\n if (!this.isVolumeVisible()) {\n this.mainEl.style.flex = '1';\n return;\n }\n this.mainEl.style.flex = '';\n this.volWrap.style.flex = '';\n this.detachMainVolResizer = attachPaneResizer(this.mainEl, this.volWrap, {\n storageKey: 'tradview:pane:main-volume',\n minTopPx: 120,\n minBottomPx: 48,\n });\n }\n\n setPinePlots(plots: PinePlotLine[] | null): void {\n this.pinePlots = plots;\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.syncPinePlotSeries(bars);\n }\n\n private teardownIndicatorStack(): void {\n this.indicators?.destroy();\n this.indicators = null;\n }\n\n private applyMainOverlays(bars: Bar[]): void {\n const cfg = this.indicatorConfig;\n if (!cfg) return;\n if (cfg.showMa) {\n this.maSeries.applyOptions({ visible: true, title: `MA${cfg.maPeriod}` });\n this.maSeries.setData(maOverlayLine(bars, cfg.maPeriod, cfg.source));\n } else {\n this.maSeries.applyOptions({ visible: false });\n this.maSeries.setData([]);\n }\n if (cfg.showVolMa) {\n this.volMaSeries.applyOptions({ visible: true });\n this.volMaSeries.setData(volMaOverlayLine(bars, cfg.volMaPeriod));\n } else {\n this.volMaSeries.applyOptions({ visible: false });\n this.volMaSeries.setData([]);\n }\n\n if (cfg.showEma) {\n this.emaSeries.applyOptions({ visible: true, title: `EMA${cfg.emaPeriod}` });\n this.emaSeries.setData(emaOverlayLine(bars, cfg.emaPeriod, cfg.source));\n } else {\n this.emaSeries.applyOptions({ visible: false });\n this.emaSeries.setData([]);\n }\n\n if (cfg.showBoll) {\n const bands = bollOverlayLines(bars, cfg.bollPeriod, cfg.bollMult, cfg.source);\n this.bollUpper.applyOptions({ visible: true });\n this.bollMiddle.applyOptions({ visible: true });\n this.bollLower.applyOptions({ visible: true });\n this.bollUpper.setData(bands.upper);\n this.bollMiddle.setData(bands.middle);\n this.bollLower.setData(bands.lower);\n } else {\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n }\n this.syncPinePlotSeries(bars);\n }\n\n private syncPinePlotSeries(bars: Bar[]): void {\n for (const s of this.pinePlotSeries) this.mainChart.removeSeries(s);\n this.pinePlotSeries = [];\n if (!this.pinePlots?.length || bars.length === 0) return;\n\n const palette = ['#58a6ff', '#d2a8ff', '#ff7b72', '#ffa657'];\n for (let i = 0; i < this.pinePlots.length; i++) {\n const plot = this.pinePlots[i]!;\n const series = this.mainChart.addSeries(LineSeries, {\n color: plot.color ?? palette[i % palette.length]!,\n lineWidth: 1,\n title: plot.title,\n });\n const out: { time: UTCTimestamp; value: number }[] = [];\n for (let j = 0; j < bars.length; j++) {\n const v = plot.values[j];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[j]!.t), value: v });\n }\n series.setData(out);\n this.pinePlotSeries.push(series);\n }\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.mainChart.applyOptions({ grid });\n this.volumeChart.applyOptions({ grid });\n this.indicators?.setShowGrid(show);\n }\n\n setBars(bars: Bar[], gaps?: number[]): void {\n const renderBars = lodDecimateBars(bars, this.maxRenderPoints);\n this.barByTime = new Map(renderBars.map((b) => [b.t, b]));\n this.barTimesOrdered = renderBars.map((b) => b.t);\n\n const gapSet = new Set(gaps ?? []);\n const seenTimes = new Set<number>();\n type CandlePoint = CandlestickData | WhitespaceData<UTCTimestamp>;\n const candles: CandlePoint[] = [];\n const vols: HistogramData<UTCTimestamp>[] = [];\n\n for (let i = 0; i < renderBars.length; i++) {\n const b = renderBars[i]!;\n const time = toUtcSeconds(b.t);\n if (seenTimes.has(time)) continue;\n seenTimes.add(time);\n if (gapSet.has(b.t)) {\n candles.push({ time });\n }\n candles.push(barToCandle(b));\n vols.push(barToVolume(b));\n }\n\n this.mainSeries.setData(candles);\n if (this.isVolumeVisible()) {\n this.volumeSeries.setData(vols);\n } else {\n this.volumeSeries.setData([]);\n }\n if (this.indicatorConfig) {\n this.applyMainOverlays(renderBars);\n if (hasVisibleIndicatorPanes(this.indicatorConfig)) {\n this.indicators?.setBars(renderBars);\n }\n } else {\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.syncPinePlotSeries(renderBars);\n }\n\n if (renderBars.length > 0) {\n this.syncChartSize();\n this.tryInitialViewportFit(renderBars);\n this.skipNextInitialFit = false;\n }\n }\n\n private mainPaneHasSize(): boolean {\n const el = this.mainChart.chartElement().parentElement;\n return (el?.clientWidth ?? 0) > 0 && (el?.clientHeight ?? 0) > 0;\n }\n\n private tryInitialViewportFit(renderBars: Bar[]): void {\n if (this.didInitialFit || this.skipNextInitialFit) return;\n if (!this.mainPaneHasSize()) {\n this.pendingViewportFit = true;\n this.pendingViewportBars = renderBars;\n return;\n }\n this.applyViewAfterDataReload(renderBars);\n this.didInitialFit = true;\n this.pendingViewportFit = false;\n this.pendingViewportBars = null;\n }\n\n private flushPendingViewportFit(): void {\n if (!this.pendingViewportFit || this.skipNextInitialFit || this.didInitialFit) return;\n const bars =\n this.pendingViewportBars ??\n [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n if (bars.length === 0 || !this.mainPaneHasSize()) return;\n this.applyViewAfterDataReload(bars);\n this.didInitialFit = true;\n this.pendingViewportFit = false;\n this.pendingViewportBars = null;\n }\n\n subscribeCrosshair(listener: (payload: CrosshairPayload | null) => void): () => void {\n const handler = (param: MouseEventParams<Time>) => {\n if (param.time == null || !param.point) {\n listener(null);\n return;\n }\n const tMs = typeof param.time === 'number' ? param.time * 1000 : null;\n if (tMs == null) {\n listener(null);\n return;\n }\n const price = this.mainSeries.coordinateToPrice(param.point.y) ?? null;\n const bar = this.barByTime.get(tMs) ?? this.findNearestBar(tMs);\n listener({\n time: tMs,\n price,\n ohlcv: bar\n ? { o: bar.o, h: bar.h, l: bar.l, c: bar.c, v: bar.v }\n : null,\n });\n };\n this.mainChart.subscribeCrosshairMove(handler);\n return () => this.mainChart.unsubscribeCrosshairMove(handler);\n }\n\n private findNearestBar(tMs: number): Bar | null {\n let best: Bar | null = null;\n let bestDt = Infinity;\n for (const b of this.barByTime.values()) {\n const dt = Math.abs(b.t - tMs);\n if (dt < bestDt) {\n bestDt = dt;\n best = b;\n }\n }\n return bestDt < 120_000 ? best : null;\n }\n\n private createIndicatorStack(): IndicatorPaneStack | null {\n if (!this.indicatorRoot || !this.indicatorConfig) return null;\n return new IndicatorPaneStack(this.indicatorRoot, this.busRegistry.getBusForPane('indicator'), {\n theme: this.dark ? 'dark' : 'light',\n showGrid: this.showGrid,\n config: this.indicatorConfig,\n onConfigChange: (config) => {\n this.indicatorConfig = config;\n this.onIndicatorConfigChange?.(config);\n },\n });\n }\n\n /** After symbol/interval reload: bar spacing for interval + show integrator-loaded span. */\n applyIntervalBarSpacing(interval?: Interval): void {\n if (!this.autoBarSpacingOnInterval) return;\n const iv = interval ?? this.currentInterval;\n const spacing = resolveBarSpacingForInterval(iv, this.barSpacingByInterval);\n this.busRegistry.forEachBus((_, bus) => bus.setBarSpacing(spacing));\n }\n\n setBarSpacingPolicy(opts: {\n autoBarSpacingOnInterval?: boolean;\n barSpacingByInterval?: Partial<Record<Interval, number>>;\n }): void {\n if (opts.autoBarSpacingOnInterval !== undefined) {\n this.autoBarSpacingOnInterval = opts.autoBarSpacingOnInterval;\n }\n if (opts.barSpacingByInterval !== undefined) {\n this.barSpacingByInterval = opts.barSpacingByInterval;\n }\n }\n\n /** Sync time scale to loaded bars (integrator history); adjust bar spacing only, not bar count. */\n private applyViewAfterDataReload(renderBars: Bar[]): void {\n if (this.autoBarSpacingOnInterval) {\n this.applyIntervalBarSpacing();\n } else {\n this.mainChart.timeScale().fitContent();\n if (this.isVolumeVisible()) this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n }\n\n if (renderBars.length > 0) {\n const fromMs = renderBars[0]!.t;\n const toMs = renderBars[renderBars.length - 1]!.t + intervalMs(this.currentInterval);\n this.bus.setVisibleTimeRange({ fromMs, toMs });\n }\n this.scrollToRealtime();\n }\n\n resetViewState(): void {\n this.didInitialFit = false;\n this.skipNextInitialFit = false;\n this.pendingViewportFit = false;\n this.pendingViewportBars = null;\n this.busRegistry.forEachBus((_, bus) => {\n bus.visibleFromMs = 0;\n bus.visibleToMs = 0;\n });\n }\n\n /** Skip the next automatic fitContent after setBars (used by reloadHistory). */\n preserveViewportOnNextSetBars(): void {\n this.skipNextInitialFit = true;\n this.didInitialFit = true;\n }\n\n getVisibleRange(): ChartVisibleRange | null {\n return this.bus.getVisibleRange();\n }\n\n getBarSpace(): number {\n return this.bus.getBarSpacing();\n }\n\n setBarSpace(px: number): void {\n this.bus.setBarSpacing(px);\n }\n\n setVisibleRange(range: ChartVisibleRange): void {\n this.bus.setVisibleTimeRange(range);\n this.didInitialFit = true;\n }\n\n scrollToTimestamp(tsMs: number, animationMs?: number): void {\n const time = toUtcSeconds(tsMs);\n const idx = this.mainChart.timeScale().timeToIndex(time, true);\n if (idx == null) {\n const nearest = this.findNearestBar(tsMs);\n if (nearest == null) return;\n const i = this.barTimesOrdered.indexOf(nearest.t);\n if (i < 0) return;\n this.busRegistry.getBusForPane('main').scrollToLogicalPosition(i, (animationMs ?? 0) > 0);\n return;\n }\n this.busRegistry.getBusForPane('main').scrollToLogicalPosition(idx as number, (animationMs ?? 0) > 0);\n }\n\n /** Clear series while symbol/interval data reloads (avoids overlapping candles). */\n clearBars(): void {\n this.barAnimator?.cancel();\n this.barByTime = new Map();\n this.barTimesOrdered = [];\n this.mainSeries.setData([]);\n this.maSeries.setData([]);\n this.volumeSeries.setData([]);\n this.volMaSeries.setData([]);\n this.indicators?.clearBars();\n }\n\n fitContent(): void {\n this.mainChart.timeScale().fitContent();\n if (this.isVolumeVisible()) this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n this.didInitialFit = true;\n }\n\n scrollToRealtime(): void {\n this.mainChart.timeScale().scrollToRealTime();\n if (this.isVolumeVisible()) this.volumeChart.timeScale().scrollToRealTime();\n this.indicators?.scrollToRealtime();\n }\n\n setLogScale(enabled: boolean): void {\n this.mainChart.priceScale('right').applyOptions({ mode: enabled ? 1 : 0 });\n }\n\n resize(): void {\n this.syncChartSize();\n this.syncOverlaySize();\n if (this.shouldResizePane('indicator')) this.indicators?.resize();\n this.flushPendingViewportFit();\n }\n\n /**\n * Resize every LWC pane once for viewport fit; does **not** change {@link resizeFocusPanes}.\n * @internal Used by ChartController data refresh paths.\n */\n resizeAllPanes(): void {\n this.syncChartSize({ allPanes: true });\n this.syncOverlaySize();\n this.indicators?.resize();\n this.flushPendingViewportFit();\n }\n\n getOverlayCanvas(): HTMLCanvasElement | null {\n return this.overlayCanvas;\n }\n\n timeToX(tMs: number): number | null {\n const coord = this.mainChart.timeScale().timeToCoordinate(toUtcSeconds(tMs));\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n priceToY(price: number): number | null {\n const coord = this.mainSeries.priceToCoordinate(price);\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n xToTime(x: number): number | null {\n const t = this.mainChart.timeScale().coordinateToTime(x / devicePixelRatio);\n if (t == null) return null;\n return Number(t) * 1000;\n }\n\n yToPrice(y: number): number | null {\n const p = this.mainSeries.coordinateToPrice(y / devicePixelRatio);\n return p ?? null;\n }\n\n destroy(): void {\n if (this.listenPaneResizeEvents) {\n window.removeEventListener('tradview:pane-resize', this.onPaneResize);\n }\n this.detachMainVolResizer();\n this.barAnimator?.cancel();\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n this.mainChart.remove();\n this.volumeChart.remove();\n this.indicators?.destroy();\n this.overlayCanvas?.remove();\n }\n\n private initOverlay(parent: HTMLElement) {\n const canvas = document.createElement('canvas');\n canvas.style.cssText =\n 'position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10;';\n parent.style.position = 'relative';\n parent.appendChild(canvas);\n this.overlayCanvas = canvas;\n this.syncOverlaySize();\n this.busRegistry.forEachBus((_, bus) => {\n bus.subscribeTransform(() => {\n this.syncOverlaySize();\n });\n });\n }\n\n /** Let drawing overlay receive clicks; cursor mode keeps pan/zoom on LWC. */\n setOverlayPointerEvents(mode: 'auto' | 'none'): void {\n if (this.overlayCanvas) this.overlayCanvas.style.pointerEvents = mode;\n }\n\n private syncOverlaySize() {\n if (!this.overlayCanvas?.parentElement) return;\n const parent = this.overlayCanvas.parentElement;\n if (parent.lastElementChild !== this.overlayCanvas) {\n parent.appendChild(this.overlayCanvas);\n }\n const rect = parent.getBoundingClientRect();\n this.overlayCanvas.width = rect.width * devicePixelRatio;\n this.overlayCanvas.height = rect.height * devicePixelRatio;\n }\n\n private syncChartSize(opts?: { allPanes?: boolean }): void {\n const all = opts?.allPanes === true;\n const mainEl = this.mainChart.chartElement().parentElement;\n const volEl = this.volumeChart.chartElement().parentElement;\n if (mainEl && (all || this.shouldResizePane('main'))) {\n const w = mainEl.clientWidth;\n const h = mainEl.clientHeight;\n if (w > 0 && h > 0) this.mainChart.resize(w, h);\n }\n if (this.isVolumeVisible() && volEl && (all || this.shouldResizePane('volume'))) {\n const w = volEl.clientWidth;\n const h = volEl.clientHeight;\n if (w > 0 && h > 0) this.volumeChart.resize(w, h);\n }\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n}","/** LWC grid line options — default off per product spec. */\nexport function gridOptions(showGrid: boolean, dark: boolean) {\n const color = dark ? '#21262d' : '#d0d7de';\n return {\n vertLines: { visible: showGrid, color },\n horzLines: { visible: showGrid, color },\n };\n}","import {\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type HistogramData,\n type IChartApi,\n type ISeriesApi,\n type LineData,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport type { Bar } from '@coderyo/data';\nimport {\n type IndicatorConfig,\n DEFAULT_INDICATOR_CONFIG,\n hasVisibleIndicatorPanes,\n boll,\n kdj,\n macd,\n rsi,\n sma,\n ema,\n} from '@coderyo/indicators';\nimport { gridOptions } from './chart-grid.js';\nimport { attachPaneResizer } from './pane-resize.js';\nimport type { TimeScaleBus } from './time-scale-bus.js';\n\nexport type IndicatorPaneId = 'macd' | 'rsi' | 'kdj';\n\nexport interface IndicatorPaneStackOptions {\n theme?: 'dark' | 'light';\n showGrid?: boolean;\n config?: IndicatorConfig;\n onConfigChange?: (config: IndicatorConfig) => void;\n}\n\nfunction barsForSource(bars: Bar[], source: IndicatorConfig['source']): Bar[] {\n if (source === 'close') return bars;\n return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\n/** PR-21: detect in-place tail updates vs full recompute. */\nexport function detectIndicatorBarMutation(\n prevTimes: number[],\n bars: Bar[],\n): 'full' | 'tail-append' | 'tail-update' {\n if (prevTimes.length === 0 || bars.length < prevTimes.length) return 'full';\n const prefixLen = Math.min(prevTimes.length, bars.length);\n for (let i = 0; i < prefixLen - 1; i++) {\n if (bars[i]!.t !== prevTimes[i]) return 'full';\n }\n if (bars.length === prevTimes.length) {\n return bars.length > 0 && bars[bars.length - 1]!.t === prevTimes[prevTimes.length - 1]\n ? 'tail-update'\n : 'full';\n }\n if (bars.length - prevTimes.length > 8) return 'full';\n for (let i = 0; i < prevTimes.length; i++) {\n if (bars[i]!.t !== prevTimes[i]) return 'full';\n }\n return 'tail-append';\n}\n\nfunction lineData(bars: Bar[], values: (number | null)[]): LineData<UTCTimestamp>[] {\n const out: LineData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[i]!.t), value: v });\n }\n return out;\n}\n\nfunction histData(bars: Bar[], values: (number | null)[]): HistogramData<UTCTimestamp>[] {\n const out: HistogramData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({\n time: toUtcSeconds(bars[i]!.t),\n value: v,\n color: v >= 0 ? '#26a69a88' : '#ef535088',\n });\n }\n return out;\n}\n\nexport class IndicatorPaneStack {\n private readonly macdChart: IChartApi;\n private readonly rsiChart: IChartApi;\n private readonly kdjChart: IChartApi;\n private readonly macdLine: ISeriesApi<'Line'>;\n private readonly macdSignal: ISeriesApi<'Line'>;\n private readonly macdHist: ISeriesApi<'Histogram'>;\n private readonly rsiLine: ISeriesApi<'Line'>;\n private readonly kdjK: ISeriesApi<'Line'>;\n private readonly kdjD: ISeriesApi<'Line'>;\n private readonly kdjJ: ISeriesApi<'Line'>;\n private dark = true;\n private showGrid = false;\n private config: IndicatorConfig = DEFAULT_INDICATOR_CONFIG;\n private readonly macdWrap: HTMLElement;\n private readonly rsiWrap: HTMLElement;\n private readonly kdjWrap: HTMLElement;\n private readonly detachResizers: Array<() => void> = [];\n private lastBarTimes: number[] = [];\n private onConfigChange?: (config: IndicatorConfig) => void;\n\n constructor(\n private readonly root: HTMLElement,\n bus: TimeScaleBus,\n opts: IndicatorPaneStackOptions | 'dark' | 'light' = 'dark',\n ) {\n const o = typeof opts === 'string' ? { theme: opts, showGrid: false } : opts;\n this.dark = o.theme !== 'light';\n this.showGrid = o.showGrid ?? false;\n this.config = o.config ?? DEFAULT_INDICATOR_CONFIG;\n this.onConfigChange = o.onConfigChange;\n this.root.style.display = 'flex';\n this.root.style.flexDirection = 'column';\n this.root.style.flex = '2';\n this.root.style.minHeight = '0';\n this.root.style.overflow = 'hidden';\n\n const macdPane = this.createPaneWrap('MACD', 'macd');\n const rsiPane = this.createPaneWrap('RSI', 'rsi');\n const kdjPane = this.createPaneWrap('KDJ', 'kdj');\n this.macdWrap = macdPane.wrap;\n this.rsiWrap = rsiPane.wrap;\n this.kdjWrap = kdjPane.wrap;\n\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart = createChart(macdPane.el, { layout, grid, autoSize: true });\n this.rsiChart = createChart(rsiPane.el, { layout, grid, autoSize: true });\n this.kdjChart = createChart(kdjPane.el, { layout, grid, autoSize: true });\n\n for (const c of [this.macdChart, this.rsiChart, this.kdjChart]) bus.register(c);\n\n this.macdLine = this.macdChart.addSeries(LineSeries, { color: '#2962ff', lineWidth: 1 });\n this.macdSignal = this.macdChart.addSeries(LineSeries, { color: '#ff9800', lineWidth: 1 });\n this.macdHist = this.macdChart.addSeries(HistogramSeries, {\n priceFormat: { type: 'price', precision: 4, minMove: 0.0001 },\n });\n this.rsiLine = this.rsiChart.addSeries(LineSeries, { color: '#ab47bc', lineWidth: 1 });\n this.kdjK = this.kdjChart.addSeries(LineSeries, { color: '#42a5f5', lineWidth: 1 });\n this.kdjD = this.kdjChart.addSeries(LineSeries, { color: '#ffa726', lineWidth: 1 });\n this.kdjJ = this.kdjChart.addSeries(LineSeries, { color: '#ef5350', lineWidth: 1 });\n\n this.applyPaneVisibility();\n }\n\n setConfig(config: IndicatorConfig): void {\n this.config = config;\n this.lastBarTimes = [];\n this.applyPaneVisibility();\n if (!this.config.showMacd && !this.config.showRsi && !this.config.showKdj) {\n this.clearBars();\n }\n }\n\n private closePane(id: IndicatorPaneId): void {\n const patch: Partial<IndicatorConfig> =\n id === 'macd' ? { showMacd: false } : id === 'rsi' ? { showRsi: false } : { showKdj: false };\n this.config = { ...this.config, ...patch };\n this.applyPaneVisibility();\n this.onConfigChange?.(this.config);\n }\n\n private applyPaneVisibility(): void {\n const anyVisible = this.config.showMacd || this.config.showRsi || this.config.showKdj;\n this.root.style.display = anyVisible ? 'flex' : 'none';\n this.rebuildPaneLayout();\n }\n\n /** Rebuild flex children and drag handles only between visible panes. */\n private rebuildPaneLayout(): void {\n for (const detach of this.detachResizers) detach();\n this.detachResizers.length = 0;\n this.root.querySelectorAll('[data-pane-resizer]').forEach((el) => el.remove());\n\n const panes: Array<{ id: IndicatorPaneId; el: HTMLElement }> = [];\n if (this.config.showMacd) panes.push({ id: 'macd', el: this.macdWrap });\n if (this.config.showRsi) panes.push({ id: 'rsi', el: this.rsiWrap });\n if (this.config.showKdj) panes.push({ id: 'kdj', el: this.kdjWrap });\n\n this.root.replaceChildren(...panes.map((p) => p.el));\n\n for (let i = 0; i < panes.length - 1; i++) {\n const top = panes[i]!;\n const bottom = panes[i + 1]!;\n this.detachResizers.push(\n attachPaneResizer(top.el, bottom.el, {\n storageKey: `tradview:pane:${top.id}-${bottom.id}`,\n minTopPx: 72,\n minBottomPx: 72,\n }),\n );\n }\n this.resize();\n }\n\n clearBars(): void {\n this.macdLine.setData([]);\n this.macdSignal.setData([]);\n this.macdHist.setData([]);\n this.rsiLine.setData([]);\n this.kdjK.setData([]);\n this.kdjD.setData([]);\n this.kdjJ.setData([]);\n this.lastBarTimes = [];\n }\n\n private warmupLookback(): number {\n const c = this.config;\n return (\n Math.max(\n c.macdSlow + c.macdSignal,\n c.rsiPeriod,\n c.kdjPeriod + c.kdjKSmooth + c.kdjDSmooth,\n ) + 5\n );\n }\n\n private detectBarMutation(bars: Bar[]): 'full' | 'tail-append' | 'tail-update' {\n return detectIndicatorBarMutation(this.lastBarTimes, bars);\n }\n\n private pushSeriesUpdates(\n series: ISeriesApi<'Line'>,\n bars: Bar[],\n values: (number | null)[],\n fromIndex: number,\n ): void {\n for (let i = fromIndex; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n series.update({ time: toUtcSeconds(bars[i]!.t), value: v });\n }\n }\n\n private pushHistUpdates(\n series: ISeriesApi<'Histogram'>,\n bars: Bar[],\n values: (number | null)[],\n fromIndex: number,\n ): void {\n for (let i = fromIndex; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n series.update({\n time: toUtcSeconds(bars[i]!.t),\n value: v,\n color: v >= 0 ? '#26a69a88' : '#ef535088',\n });\n }\n }\n\n setBars(bars: Bar[]): void {\n if (bars.length === 0) {\n this.clearBars();\n return;\n }\n\n const needMacd = this.config.showMacd;\n const needRsi = this.config.showRsi;\n const needKdj = this.config.showKdj;\n if (!hasVisibleIndicatorPanes(this.config)) {\n return;\n }\n\n const mutation = this.detectBarMutation(bars);\n this.lastBarTimes = bars.map((b) => b.t);\n const src = barsForSource(bars, this.config.source);\n const m = needMacd\n ? macd(src, this.config.macdFast, this.config.macdSlow, this.config.macdSignal)\n : null;\n const r = needRsi ? rsi(src, this.config.rsiPeriod) : null;\n const k = needKdj\n ? kdj(src, this.config.kdjPeriod, this.config.kdjKSmooth, this.config.kdjDSmooth)\n : null;\n\n if (mutation === 'full') {\n if (needMacd && m) {\n this.macdLine.setData(lineData(bars, m.macd));\n this.macdSignal.setData(lineData(bars, m.signal));\n this.macdHist.setData(histData(bars, m.histogram));\n this.macdChart.timeScale().fitContent();\n }\n if (needRsi && r) {\n this.rsiLine.setData(lineData(bars, r));\n this.rsiChart.timeScale().fitContent();\n }\n if (needKdj && k) {\n this.kdjK.setData(lineData(bars, k.k));\n this.kdjD.setData(lineData(bars, k.d));\n this.kdjJ.setData(lineData(bars, k.j));\n this.kdjChart.timeScale().fitContent();\n }\n } else {\n const from =\n mutation === 'tail-update' ? Math.max(0, bars.length - 1) : Math.max(0, bars.length - this.warmupLookback());\n if (needMacd && m) {\n this.pushSeriesUpdates(this.macdLine, bars, m.macd, from);\n this.pushSeriesUpdates(this.macdSignal, bars, m.signal, from);\n this.pushHistUpdates(this.macdHist, bars, m.histogram, from);\n }\n if (needRsi && r) {\n this.pushSeriesUpdates(this.rsiLine, bars, r, from);\n }\n if (needKdj && k) {\n this.pushSeriesUpdates(this.kdjK, bars, k.k, from);\n this.pushSeriesUpdates(this.kdjD, bars, k.d, from);\n this.pushSeriesUpdates(this.kdjJ, bars, k.j, from);\n }\n }\n\n this.resize();\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart.applyOptions({ layout, grid });\n this.rsiChart.applyOptions({ layout, grid });\n this.kdjChart.applyOptions({ layout, grid });\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.macdChart.applyOptions({ grid });\n this.rsiChart.applyOptions({ grid });\n this.kdjChart.applyOptions({ grid });\n }\n\n fitContent(): void {\n this.macdChart.timeScale().fitContent();\n this.rsiChart.timeScale().fitContent();\n this.kdjChart.timeScale().fitContent();\n }\n\n scrollToRealtime(): void {\n this.macdChart.timeScale().scrollToRealTime();\n this.rsiChart.timeScale().scrollToRealTime();\n this.kdjChart.timeScale().scrollToRealTime();\n }\n\n resize(): void {\n const panes: Array<{ show: boolean; chart: IChartApi }> = [\n { show: this.config.showMacd, chart: this.macdChart },\n { show: this.config.showRsi, chart: this.rsiChart },\n { show: this.config.showKdj, chart: this.kdjChart },\n ];\n for (const { show, chart } of panes) {\n if (!show || !chart) continue;\n const el = chart.chartElement()?.parentElement;\n if (!el) continue;\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) chart.resize(w, h);\n }\n }\n\n destroy(): void {\n for (const detach of this.detachResizers) detach();\n this.detachResizers.length = 0;\n this.macdChart.remove();\n this.rsiChart.remove();\n this.kdjChart.remove();\n this.root.replaceChildren();\n }\n\n private createPaneWrap(\n label: string,\n paneId: IndicatorPaneId,\n ): { wrap: HTMLElement; el: HTMLElement } {\n const wrap = document.createElement('div');\n wrap.className = `tv-indicator-pane tv-indicator-pane--${paneId}`;\n wrap.dataset.paneId = paneId;\n wrap.style.cssText =\n 'flex:1;min-height:72px;width:100%;position:relative;border-top:1px solid #30363d;';\n const tag = document.createElement('span');\n tag.textContent = label;\n tag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = '×';\n closeBtn.title = `關閉 ${label}`;\n closeBtn.setAttribute('aria-label', `Close ${label}`);\n closeBtn.style.cssText =\n 'position:absolute;right:6px;top:4px;z-index:3;width:22px;height:22px;padding:0;border:1px solid #30363d;border-radius:4px;background:#21262d;color:#8b949e;cursor:pointer;font-size:14px;line-height:1;';\n closeBtn.onmouseenter = () => {\n closeBtn.style.color = '#e6edf3';\n closeBtn.style.borderColor = '#484f58';\n };\n closeBtn.onmouseleave = () => {\n closeBtn.style.color = '#8b949e';\n closeBtn.style.borderColor = '#30363d';\n };\n closeBtn.onclick = () => this.closePane(paneId);\n const el = document.createElement('div');\n el.style.cssText = 'width:100%;height:100%;';\n wrap.append(tag, closeBtn, el);\n return { wrap, el };\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n\n /** LWC instances for sync-group reassignment. */\n getCharts(): IChartApi[] {\n return [this.macdChart, this.rsiChart, this.kdjChart];\n }\n}\n\nexport function maOverlayLine(\n bars: Bar[],\n period = 20,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, sma(src, period));\n}\n\nexport function volMaOverlayLine(bars: Bar[], period = 5): LineData<UTCTimestamp>[] {\n const volBars = bars.map((b) => ({ ...b, c: b.v ?? 0 }));\n return lineData(bars, sma(volBars, period, 'close'));\n}\n\nexport function emaOverlayLine(\n bars: Bar[],\n period: number,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, ema(src, period));\n}\n\nexport function bollOverlayLines(\n bars: Bar[],\n period: number,\n mult: number,\n source: IndicatorConfig['source'] = 'close',\n): {\n upper: LineData<UTCTimestamp>[];\n middle: LineData<UTCTimestamp>[];\n lower: LineData<UTCTimestamp>[];\n} {\n const src = barsForSource(bars, source);\n const bands = boll(src, period, mult);\n return {\n upper: lineData(bars, bands.upper),\n middle: lineData(bars, bands.middle),\n lower: lineData(bars, bands.lower),\n };\n}","export function attachPaneResizer(\n topPane: HTMLElement,\n bottomPane: HTMLElement,\n opts: { minTopPx?: number; minBottomPx?: number; storageKey?: string } = {},\n): () => void {\n const minTop = opts.minTopPx ?? 120;\n const minBottom = opts.minBottomPx ?? 60;\n const parent = topPane.parentElement;\n if (!parent) return () => {};\n\n let dragging = false;\n\n const handle = document.createElement('div');\n handle.dataset.paneResizer = '1';\n handle.style.cssText =\n 'height:6px;cursor:row-resize;background:#30363d;flex-shrink:0;touch-action:none;z-index:5;';\n handle.onmouseenter = () => {\n handle.style.background = '#388bfd';\n };\n handle.onmouseleave = () => {\n if (!dragging) handle.style.background = '#30363d';\n };\n bottomPane.insertAdjacentElement('beforebegin', handle);\n\n const saved = opts.storageKey ? localStorage.getItem(opts.storageKey) : null;\n if (saved) {\n const ratio = Number(saved);\n if (Number.isFinite(ratio) && ratio >= 0.15 && ratio <= 0.85) {\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n }\n }\n\n const onMove = (clientY: number) => {\n const rect = parent.getBoundingClientRect();\n const y = clientY - rect.top;\n const ratio = Math.min(0.85, Math.max(0.15, y / rect.height));\n const topPx = ratio * rect.height;\n const bottomPx = rect.height - topPx - handle.offsetHeight;\n if (topPx < minTop || bottomPx < minBottom) return;\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n if (opts.storageKey) localStorage.setItem(opts.storageKey, String(ratio));\n };\n\n const stop = () => {\n const wasDragging = dragging;\n dragging = false;\n document.body.style.cursor = '';\n handle.style.background = '#30363d';\n if (wasDragging) window.dispatchEvent(new CustomEvent('tradview:pane-resize'));\n };\n\n handle.addEventListener('pointerdown', (e) => {\n dragging = true;\n handle.setPointerCapture(e.pointerId);\n document.body.style.cursor = 'row-resize';\n });\n handle.addEventListener('pointermove', (e) => {\n if (dragging) {\n onMove(e.clientY);\n window.dispatchEvent(new CustomEvent('tradview:pane-resize'));\n }\n });\n handle.addEventListener('pointerup', stop);\n handle.addEventListener('pointercancel', stop);\n\n return () => handle.remove();\n}","import type { IChartApi, LogicalRange, UTCTimestamp } from 'lightweight-charts';\n\nexport interface ChartVisibleRange {\n fromMs: number;\n toMs: number;\n}\n\nexport interface TransformState {\n visibleFromMs: number;\n visibleToMs: number;\n width: number;\n height: number;\n}\n\ntype TransformListener = (state: TransformState) => void;\n\n/** Sync visible logical range across multiple LWC panes (§10.4.1). */\nexport class TimeScaleBus {\n private charts: IChartApi[] = [];\n private listeners = new Set<TransformListener>();\n private syncing = false;\n visibleFromMs = 0;\n visibleToMs = 0;\n\n register(chart: IChartApi): void {\n if (this.charts.includes(chart)) return;\n this.charts.push(chart);\n chart.timeScale().subscribeVisibleLogicalRangeChange((range) => {\n if (!this.charts.includes(chart)) return;\n if (this.syncing || !range) return;\n const tr = chart.timeScale().getVisibleRange();\n if (tr && typeof tr.from === 'number' && typeof tr.to === 'number') {\n this.visibleFromMs = tr.from * 1000;\n this.visibleToMs = tr.to * 1000;\n }\n this.syncFrom(chart, range);\n });\n }\n\n unregister(chart: IChartApi): void {\n const i = this.charts.indexOf(chart);\n if (i >= 0) this.charts.splice(i, 1);\n }\n\n subscribeTransform(listener: TransformListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n setBarsTimeRange(fromMs: number, toMs: number): void {\n this.visibleFromMs = fromMs;\n this.visibleToMs = toMs;\n this.emit();\n }\n\n getVisibleRange(): ChartVisibleRange | null {\n if (this.visibleToMs <= this.visibleFromMs) return null;\n return { fromMs: this.visibleFromMs, toMs: this.visibleToMs };\n }\n\n getBarSpacing(): number {\n const chart = this.charts[0];\n return chart ? chart.timeScale().options().barSpacing : 6;\n }\n\n setBarSpacing(spacing: number): void {\n if (!Number.isFinite(spacing) || spacing <= 0) return;\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().applyOptions({ barSpacing: spacing });\n }\n this.syncing = false;\n this.emit();\n }\n\n setVisibleTimeRange(range: ChartVisibleRange): void {\n const from = Math.floor(range.fromMs / 1000) as UTCTimestamp;\n const to = Math.floor(range.toMs / 1000) as UTCTimestamp;\n if (to <= from) return;\n this.visibleFromMs = range.fromMs;\n this.visibleToMs = range.toMs;\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().setVisibleRange({ from, to });\n }\n this.syncing = false;\n this.emit();\n }\n\n scrollToLogicalPosition(position: number, animated = false): void {\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().scrollToPosition(position, animated);\n }\n this.syncing = false;\n this.emit();\n }\n\n private syncFrom(source: IChartApi, range: LogicalRange) {\n this.syncing = true;\n for (const chart of this.charts) {\n if (chart !== source) {\n chart.timeScale().setVisibleLogicalRange(range);\n }\n }\n this.syncing = false;\n this.emit();\n }\n\n private emit(): void {\n const state: TransformState = {\n visibleFromMs: this.visibleFromMs,\n visibleToMs: this.visibleToMs,\n width: 0,\n height: 0,\n };\n for (const l of this.listeners) l(state);\n }\n}","import type { IChartApi } from 'lightweight-charts';\nimport { TimeScaleBus } from './time-scale-bus.js';\n\n/** Trim; empty / whitespace → independent pane (no cross-pane sync). */\nexport function normalizeSyncGroupId(id?: string | null): string | null {\n if (id == null) return null;\n const trimmed = String(id).trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport type PaneSyncKey = 'main' | 'volume' | 'indicator';\n\nconst INDEP_PREFIX = '@independent:';\n\nexport function independentBusKey(pane: PaneSyncKey): string {\n return `${INDEP_PREFIX}${pane}`;\n}\n\nexport function resolveBusMapKey(\n groupId: string | null | undefined,\n pane: PaneSyncKey,\n): string {\n const norm = normalizeSyncGroupId(groupId);\n return norm ?? independentBusKey(pane);\n}\n\nexport interface PaneSyncGroupPatch {\n main?: string | null;\n volume?: string | null;\n indicator?: string | null;\n}\n\n/**\n * One {@link TimeScaleBus} per sync group id; empty group id → per-pane independent bus.\n */\nexport class TimeScaleBusRegistry {\n private readonly buses = new Map<string, TimeScaleBus>();\n private readonly paneKeys = new Map<PaneSyncKey, string>();\n private activeKey: string;\n\n constructor() {\n for (const pane of ['main', 'volume', 'indicator'] as const) {\n const key = independentBusKey(pane);\n this.paneKeys.set(pane, key);\n this.getOrCreateBus(key);\n }\n this.activeKey = this.paneKeys.get('main')!;\n }\n\n getOrCreateBus(key: string): TimeScaleBus {\n let bus = this.buses.get(key);\n if (!bus) {\n bus = new TimeScaleBus();\n this.buses.set(key, bus);\n }\n return bus;\n }\n\n getBusKeyForPane(pane: PaneSyncKey): string {\n return this.paneKeys.get(pane)!;\n }\n\n getBusForPane(pane: PaneSyncKey): TimeScaleBus {\n return this.getOrCreateBus(this.getBusKeyForPane(pane));\n }\n\n /** Active bus for IChart viewport APIs (follows last-focused chart pane). */\n get activeBus(): TimeScaleBus {\n return this.getOrCreateBus(this.activeKey);\n }\n\n getActiveBusKey(): string {\n return this.activeKey;\n }\n\n setActivePane(pane: PaneSyncKey): void {\n this.activeKey = this.paneKeys.get(pane)!;\n }\n\n setPaneSyncGroup(pane: PaneSyncKey, groupId: string | null | undefined): string {\n const nextKey = resolveBusMapKey(groupId, pane);\n const prevKey = this.paneKeys.get(pane)!;\n this.paneKeys.set(pane, nextKey);\n this.getOrCreateBus(nextKey);\n if (this.activeKey === prevKey) this.activeKey = nextKey;\n return prevKey;\n }\n\n forEachBus(fn: (key: string, bus: TimeScaleBus) => void): void {\n for (const [key, bus] of this.buses) fn(key, bus);\n }\n\n moveChart(chart: IChartApi, fromKey: string, toKey: string, copyRange = true): void {\n if (fromKey === toKey) return;\n const from = this.getOrCreateBus(fromKey);\n const to = this.getOrCreateBus(toKey);\n const range = copyRange ? from.getVisibleRange() : null;\n from.unregister(chart);\n to.register(chart);\n if (range) to.setVisibleTimeRange(range);\n }\n}","import { intervalMs, type Interval } from '@coderyo/data';\n\n/**\n * Default horizontal bar spacing (px) per interval so candle width feels consistent\n * when the integrator controls how many bars are loaded / visible.\n */\nexport function defaultBarSpacingForInterval(interval: Interval): number {\n const ms = intervalMs(interval);\n if (ms <= 1_000) return 3;\n if (ms <= 5_000) return 4;\n if (ms <= 15_000) return 5;\n if (ms <= 30_000) return 6;\n if (ms <= 60_000) return 7;\n if (ms <= 300_000) return 8;\n if (ms <= 900_000) return 9;\n if (ms <= 3_600_000) return 10;\n if (ms <= 14_400_000) return 11;\n return 12;\n}\n\nexport function resolveBarSpacingForInterval(\n interval: Interval,\n overrides?: Partial<Record<Interval, number>>,\n): number {\n const custom = overrides?.[interval];\n if (custom != null && Number.isFinite(custom) && custom > 0) {\n return Math.min(24, Math.max(2, custom));\n }\n return defaultBarSpacingForInterval(interval);\n}","import type { Bar } from '@coderyo/data';\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - Math.pow(1 - t, 3);\n}\n\n/** Interpolate last candle OHLC toward target over `durationMs` (interrupts on new target). */\nexport class BarSmoothAnimator {\n private raf = 0;\n private start = 0;\n private from: Bar | null = null;\n private to: Bar | null = null;\n\n constructor(\n private durationMs: number,\n private readonly onFrame: (bar: Bar) => void,\n ) {}\n\n setDuration(ms: number): void {\n this.durationMs = ms;\n }\n\n animateTo(target: Bar, from?: Bar): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n const base = from ?? this.to ?? target;\n this.from = { ...base, t: target.t };\n this.to = { ...target };\n this.start = performance.now();\n\n const step = (now: number) => {\n const raw = Math.min(1, (now - this.start) / this.durationMs);\n const p = easeOutCubic(raw);\n const f = this.from!;\n const t = this.to!;\n const frame: Bar = {\n t: t.t,\n o: lerp(f.o, t.o, p),\n h: lerp(f.h, t.h, p),\n l: lerp(f.l, t.l, p),\n c: lerp(f.c, t.c, p),\n v: t.v,\n };\n this.onFrame(frame);\n if (raw < 1) {\n this.raf = requestAnimationFrame(step);\n } else {\n this.raf = 0;\n this.onFrame(t);\n }\n };\n this.raf = requestAnimationFrame(step);\n }\n\n cancel(): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n this.raf = 0;\n }\n}"],"mappings":"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","names":["ColorType","createChart","HistogramSeries","LineSeries","intervalMs","DEFAULT_INDICATOR_CONFIG","hasVisibleIndicatorPanes","toUtcSeconds","createChart","LineSeries","HistogramSeries","hasVisibleIndicatorPanes","DEFAULT_INDICATOR_CONFIG","intervalMs","ColorType"]}
1
+ {"version":3,"sources":["../src/pane-orchestrator.ts","../src/time-scale-prepend.ts","../src/chart-grid.ts","../src/indicator-panes.ts","../src/pane-resize.ts","../src/time-scale-bus.ts","../src/time-scale-bus-registry.ts","../src/viewport-fit.ts","../src/bar-smooth-animator.ts"],"sourcesContent":["import {\n CandlestickSeries,\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type CandlestickData,\n type HistogramData,\n type WhitespaceData,\n type IChartApi,\n type ISeriesApi,\n type IPriceLine,\n type MouseEventParams,\n type Time,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport { intervalMs, type Bar, type Interval } from '@coderyo/data';\nimport { compensatePrependOnRegistry } from './time-scale-prepend.js';\nimport { lodDecimateBars } from '@coderyo/series';\nimport { gridOptions } from './chart-grid.js';\nimport {\n DEFAULT_INDICATOR_CONFIG,\n hasVisibleIndicatorPanes,\n type IndicatorConfig,\n} from '@coderyo/indicators';\n\nimport {\n IndicatorPaneStack,\n bollOverlayLines,\n emaOverlayLine,\n maOverlayLine,\n volMaOverlayLine,\n} from './indicator-panes.js';\nimport { attachPaneResizer } from './pane-resize.js';\nimport { type ChartVisibleRange } from './time-scale-bus.js';\nimport {\n type PaneSyncGroupPatch,\n type PaneSyncKey,\n TimeScaleBusRegistry,\n} from './time-scale-bus-registry.js';\nimport { resolveBarSpacingForInterval } from './viewport-fit.js';\n\nexport type { ChartVisibleRange };\nimport { BarSmoothAnimator } from './bar-smooth-animator.js';\n\nexport type ScaleMode = 'linear' | 'log';\n\nexport interface CrosshairPayload {\n time: number;\n price: number | null;\n ohlcv: { o: number; h: number; l: number; c: number; v?: number } | null;\n}\n\nexport interface PinePlotLine {\n title: string;\n color?: string;\n values: (number | null)[];\n}\n\nexport type ChartPaneId = 'main' | 'volume' | 'indicator';\n\nexport function isLayeredPaneMount(opts: Pick<PaneOrchestratorOptions, 'volumeMount'>): boolean {\n return !!opts.volumeMount;\n}\n\nexport function shouldResizeChartPane(\n focus: Set<ChartPaneId> | null,\n pane: ChartPaneId,\n): boolean {\n if (!focus) return true;\n return focus.has(pane);\n}\n\nexport interface PaneOrchestratorOptions {\n /** Main candlestick mount (required). */\n container: HTMLElement;\n /**\n * P2: separate volume layer host; when set, no flex column in container.\n * Mount order: create empty `chartMain` + `chartVolume` nodes first, pass to compositor widgets,\n * then `createChart(chartMain, { volumeMount: chartVolume })` so LWC mounts after layer frames apply.\n */\n volumeMount?: HTMLElement;\n indicatorRoot?: HTMLElement;\n theme?: 'dark' | 'light';\n scaleMode?: ScaleMode;\n maxRenderPoints?: number;\n /** Show chart grid lines (default false). */\n showGrid?: boolean;\n /** null = no MA overlays and no MACD/RSI/KDJ panes. */\n indicatorConfig?: IndicatorConfig | null;\n /** Pine-lite plot lines on main chart (when pineEnabled). */\n pinePlots?: PinePlotLine[] | null;\n /** Animate last candle + price line toward new OHLC (~150ms). */\n smoothPriceUpdate?: boolean;\n smoothPriceDurationMs?: number;\n onIndicatorConfigChange?: (config: IndicatorConfig) => void;\n /** When true (default), set bar spacing on interval reload — does not change visible bar count. */\n autoBarSpacingOnInterval?: boolean;\n barSpacingByInterval?: Partial<Record<Interval, number>>;\n /**\n * When false, do not listen for `tradview:pane-resize` (ChartController owns that path).\n * @default true for standalone orchestrator use; ChartController passes false.\n */\n listenPaneResizeEvents?: boolean;\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\nfunction barToCandle(b: Bar): CandlestickData {\n return { time: toUtcSeconds(b.t), open: b.o, high: b.h, low: b.l, close: b.c };\n}\n\nfunction barToVolume(b: Bar): HistogramData<UTCTimestamp> {\n return { time: toUtcSeconds(b.t), value: b.v ?? 0 };\n}\n\nexport class PaneOrchestrator {\n readonly busRegistry = new TimeScaleBusRegistry();\n /** Active sync group bus (last-focused pane); used by ChartController viewport APIs. */\n get bus() {\n return this.busRegistry.activeBus;\n }\n private readonly layeredPanes: boolean;\n private readonly mainEl: HTMLElement;\n private readonly volWrap: HTMLElement;\n private detachMainVolResizer: () => void = () => {};\n private resizeFocusPanes: Set<ChartPaneId> | null = null;\n private readonly listenPaneResizeEvents: boolean;\n private readonly mainChart: IChartApi;\n private readonly volumeChart: IChartApi;\n private readonly mainSeries: ISeriesApi<'Candlestick'>;\n private readonly volumeSeries: ISeriesApi<'Histogram'>;\n private readonly maSeries: ISeriesApi<'Line'>;\n private readonly emaSeries: ISeriesApi<'Line'>;\n private readonly bollUpper: ISeriesApi<'Line'>;\n private readonly bollMiddle: ISeriesApi<'Line'>;\n private readonly bollLower: ISeriesApi<'Line'>;\n private readonly volMaSeries: ISeriesApi<'Line'>;\n private readonly indicatorRoot?: HTMLElement;\n private indicators: IndicatorPaneStack | null;\n private pinePlotSeries: ISeriesApi<'Line'>[] = [];\n private pinePlots: PinePlotLine[] | null = null;\n private overlayCanvas: HTMLCanvasElement | null = null;\n private dark = true;\n private showGrid = false;\n private readonly maxRenderPoints: number;\n private barByTime = new Map<number, Bar>();\n private barTimesOrdered: number[] = [];\n private didInitialFit = false;\n private skipNextInitialFit = false;\n /** setBars ran before the pane had layout size; refit on first real resize. */\n private pendingViewportFit = false;\n private pendingViewportBars: Bar[] | null = null;\n private indicatorConfig: IndicatorConfig | null = null;\n private onIndicatorConfigChange?: (config: IndicatorConfig) => void;\n private currentInterval: Interval = '1h';\n private autoBarSpacingOnInterval = true;\n private barSpacingByInterval?: Partial<Record<Interval, number>>;\n private priceLine: IPriceLine | null = null;\n private barAnimator: BarSmoothAnimator | null = null;\n private smoothPriceDurationMs = 150;\n\n constructor(opts: PaneOrchestratorOptions) {\n this.maxRenderPoints = opts.maxRenderPoints ?? 4000;\n this.listenPaneResizeEvents = opts.listenPaneResizeEvents !== false;\n this.dark = opts.theme !== 'light';\n this.showGrid = opts.showGrid ?? false;\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n\n this.layeredPanes = !!opts.volumeMount;\n const volEl = document.createElement('div');\n volEl.style.cssText = 'width:100%;height:100%;min-height:0;position:relative;';\n\n if (this.layeredPanes) {\n this.mainEl = opts.container;\n this.mainEl.style.cssText =\n 'width:100%;height:100%;min-height:80px;position:relative;overflow:hidden;';\n this.volWrap = opts.volumeMount!;\n this.volWrap.dataset.paneId = 'volume';\n this.volWrap.className = 'tv-volume-pane tv-volume-pane--layered';\n this.volWrap.replaceChildren();\n this.volWrap.style.cssText =\n 'width:100%;height:100%;min-height:48px;position:relative;overflow:hidden;box-sizing:border-box;';\n const volTag = document.createElement('span');\n volTag.textContent = 'Volume';\n volTag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const volClose = document.createElement('button');\n volClose.type = 'button';\n volClose.textContent = '×';\n volClose.title = '關閉成交量';\n volClose.setAttribute('aria-label', 'Close volume');\n volClose.style.cssText =\n 'position:absolute;right:6px;top:4px;z-index:3;width:22px;height:22px;padding:0;border:1px solid #30363d;border-radius:4px;background:#21262d;color:#8b949e;cursor:pointer;font-size:14px;line-height:1;';\n volClose.onclick = () => this.closeVolumePane();\n this.volWrap.append(volTag, volClose, volEl);\n } else {\n this.mainEl = document.createElement('div');\n this.mainEl.style.cssText = 'flex:7;min-height:120px;width:100%;position:relative;';\n volEl.style.cssText = 'flex:1;min-height:0;width:100%;height:100%;position:relative;';\n\n this.volWrap = document.createElement('div');\n this.volWrap.dataset.paneId = 'volume';\n this.volWrap.className = 'tv-volume-pane';\n this.volWrap.style.cssText =\n 'flex:2;min-height:48px;width:100%;position:relative;display:flex;flex-direction:column;border-top:1px solid #30363d;';\n const volTag = document.createElement('span');\n volTag.textContent = 'Volume';\n volTag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const volClose = document.createElement('button');\n volClose.type = 'button';\n volClose.textContent = '×';\n volClose.title = '關閉成交量';\n volClose.setAttribute('aria-label', 'Close volume');\n volClose.style.cssText =\n 'position:absolute;right:6px;top:4px;z-index:3;width:22px;height:22px;padding:0;border:1px solid #30363d;border-radius:4px;background:#21262d;color:#8b949e;cursor:pointer;font-size:14px;line-height:1;';\n volClose.onclick = () => this.closeVolumePane();\n this.volWrap.append(volTag, volClose, volEl);\n\n opts.container.style.cssText =\n 'display:flex;flex-direction:column;height:100%;width:100%;min-height:200px;overflow:hidden;';\n opts.container.append(this.mainEl, this.volWrap);\n this.rebuildMainVolumeResizer();\n }\n\n this.mainChart = createChart(this.mainEl, { layout, grid, autoSize: true });\n this.volumeChart = createChart(volEl, {\n layout,\n grid,\n autoSize: true,\n rightPriceScale: { scaleMargins: { top: 0.8, bottom: 0 } },\n });\n\n if (opts.scaleMode === 'log') {\n this.mainChart.priceScale('right').applyOptions({ mode: 1 });\n }\n\n this.mainSeries = this.mainChart.addSeries(CandlestickSeries, {\n upColor: '#26a69a',\n downColor: '#ef5350',\n borderVisible: false,\n wickUpColor: '#26a69a',\n wickDownColor: '#ef5350',\n });\n this.maSeries = this.mainChart.addSeries(LineSeries, {\n color: '#f0b429',\n lineWidth: 1,\n title: 'MA',\n });\n this.emaSeries = this.mainChart.addSeries(LineSeries, {\n color: '#7ee787',\n lineWidth: 1,\n title: 'EMA',\n visible: false,\n });\n this.bollUpper = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↑',\n visible: false,\n });\n this.bollMiddle = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e88',\n lineWidth: 1,\n lineStyle: 2,\n title: 'BOLL',\n visible: false,\n });\n this.bollLower = this.mainChart.addSeries(LineSeries, {\n color: '#8b949e',\n lineWidth: 1,\n title: 'BOLL↓',\n visible: false,\n });\n this.volumeSeries = this.volumeChart.addSeries(HistogramSeries, {\n color: '#26a69a55',\n priceFormat: { type: 'volume' },\n });\n this.volMaSeries = this.volumeChart.addSeries(LineSeries, {\n color: '#58a6ff',\n lineWidth: 1,\n title: 'VolMA5',\n });\n\n this.busRegistry.getBusForPane('main').register(this.mainChart);\n this.busRegistry.getBusForPane('volume').register(this.volumeChart);\n\n this.indicatorRoot = opts.indicatorRoot;\n this.indicatorConfig = opts.indicatorConfig ?? null;\n this.onIndicatorConfigChange = opts.onIndicatorConfigChange;\n this.autoBarSpacingOnInterval = opts.autoBarSpacingOnInterval ?? true;\n this.barSpacingByInterval = opts.barSpacingByInterval;\n this.pinePlots = opts.pinePlots ?? null;\n this.indicators = this.createIndicatorStack();\n\n this.initOverlay(this.mainEl);\n this.setSmoothPriceUpdate(opts.smoothPriceUpdate ?? false, opts.smoothPriceDurationMs);\n this.applyVolumeVisibility();\n if (opts.listenPaneResizeEvents !== false) {\n window.addEventListener('tradview:pane-resize', this.onPaneResize);\n }\n }\n\n private readonly onPaneResize = () => {\n this.resize();\n };\n\n setSmoothPriceUpdate(enabled: boolean, durationMs = 150): void {\n this.smoothPriceDurationMs = durationMs;\n if (enabled) {\n if (!this.barAnimator) {\n this.barAnimator = new BarSmoothAnimator(durationMs, (bar) => this.applyLastBarToSeries(bar));\n } else {\n this.barAnimator.setDuration(durationMs);\n }\n return;\n }\n this.barAnimator?.cancel();\n this.barAnimator = null;\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n }\n\n /** Update the last candle (and price line); optional smooth interpolation. */\n updateLastBar(target: Bar, opts?: { smooth?: boolean; durationMs?: number }): void {\n const prev = this.barByTime.get(target.t);\n const smooth = opts?.smooth ?? !!this.barAnimator;\n const duration = opts?.durationMs ?? this.smoothPriceDurationMs;\n if (smooth && this.barAnimator) {\n this.barAnimator.setDuration(duration);\n this.barAnimator.animateTo(target, prev ?? target);\n return;\n }\n this.barAnimator?.cancel();\n this.applyLastBarToSeries(target);\n }\n\n private applyLastBarToSeries(bar: Bar): void {\n this.barByTime.set(bar.t, bar);\n this.mainSeries.update(barToCandle(bar));\n if (this.isVolumeVisible()) {\n this.volumeSeries.update(barToVolume(bar));\n }\n this.ensurePriceLine(bar.c);\n if (this.indicatorConfig) {\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.applyMainOverlays(bars);\n if (hasVisibleIndicatorPanes(this.indicatorConfig)) {\n this.indicators?.setBars(bars);\n }\n }\n }\n\n private ensurePriceLine(price: number): void {\n if (!this.priceLine) {\n this.priceLine = this.mainSeries.createPriceLine({\n price,\n color: '#58a6ff',\n lineWidth: 1,\n lineStyle: 2,\n axisLabelVisible: true,\n title: '',\n });\n } else {\n this.priceLine.applyOptions({ price });\n }\n }\n\n setIntervalContext(interval: Interval): void {\n this.currentInterval = interval;\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.mainChart.applyOptions({ layout, grid });\n this.volumeChart.applyOptions({ layout, grid });\n this.indicators?.setTheme(theme);\n }\n\n setIndicatorConfig(config: IndicatorConfig | null): void {\n this.indicatorConfig = config;\n if (!config) {\n this.teardownIndicatorStack();\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.volumeSeries.setData([]);\n this.emaSeries.applyOptions({ visible: false });\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n this.applyVolumeVisibility();\n return;\n }\n if (!this.indicators) this.indicators = this.createIndicatorStack();\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.indicators?.setConfig(config);\n if (bars.length > 0) {\n this.applyMainOverlays(bars);\n if (hasVisibleIndicatorPanes(config)) {\n this.indicators?.setBars(bars);\n }\n }\n this.applyVolumeVisibility();\n }\n\n private isVolumeVisible(): boolean {\n return this.indicatorConfig?.showVolume ?? true;\n }\n\n private closeVolumePane(): void {\n if (!this.indicatorConfig) {\n this.indicatorConfig = { ...DEFAULT_INDICATOR_CONFIG, showVolume: false };\n } else {\n this.indicatorConfig = { ...this.indicatorConfig, showVolume: false };\n }\n this.applyVolumeVisibility();\n this.onIndicatorConfigChange?.(this.indicatorConfig);\n }\n\n private applyVolumeVisibility(): void {\n const show = this.isVolumeVisible();\n this.volWrap.style.display = show ? '' : 'none';\n this.rebuildMainVolumeResizer();\n if (!show) {\n this.volumeSeries.setData([]);\n this.volMaSeries.setData([]);\n }\n this.syncChartSize();\n }\n\n /** Assign per-pane sync group ids (`''` / omit = independent). Re-registers LWC charts on group change. */\n setPaneSyncGroups(patch: PaneSyncGroupPatch): void {\n const apply = (pane: PaneSyncKey, groupId: string | null | undefined) => {\n const prevKey = this.busRegistry.setPaneSyncGroup(pane, groupId);\n const nextKey = this.busRegistry.getBusKeyForPane(pane);\n if (pane === 'main') {\n this.busRegistry.moveChart(this.mainChart, prevKey, nextKey);\n } else if (pane === 'volume') {\n this.busRegistry.moveChart(this.volumeChart, prevKey, nextKey);\n } else if (this.indicators) {\n for (const chart of this.indicators.getCharts()) {\n this.busRegistry.moveChart(chart, prevKey, nextKey);\n }\n }\n };\n if (patch.main !== undefined) apply('main', patch.main);\n if (patch.volume !== undefined) apply('volume', patch.volume);\n if (patch.indicator !== undefined) apply('indicator', patch.indicator);\n }\n\n setActiveSyncPane(pane: ChartPaneId): void {\n const key: PaneSyncKey =\n pane === 'volume' ? 'volume' : pane === 'indicator' ? 'indicator' : 'main';\n this.busRegistry.setActivePane(key);\n }\n\n /** P2: when set, only these panes get LWC resize (panes in the same sync group still share TimeScaleBus). */\n setResizeFocusPanes(panes: ChartPaneId[] | null): void {\n this.resizeFocusPanes = panes?.length ? new Set(panes) : null;\n this.resize();\n }\n\n /** Current resize focus (null = all panes). @internal — not part of public package API. */\n getResizeFocusPanes(): ChartPaneId[] | null {\n return this.resizeFocusPanes ? [...this.resizeFocusPanes] : null;\n }\n\n private shouldResizePane(pane: ChartPaneId): boolean {\n return shouldResizeChartPane(this.resizeFocusPanes, pane);\n }\n\n private rebuildMainVolumeResizer(): void {\n if (this.layeredPanes) return;\n this.detachMainVolResizer();\n const parent = this.mainEl.parentElement;\n parent\n ?.querySelectorAll(':scope > [data-pane-resizer]')\n .forEach((el) => el.remove());\n\n if (!this.isVolumeVisible()) {\n this.mainEl.style.flex = '1';\n return;\n }\n this.mainEl.style.flex = '';\n this.volWrap.style.flex = '';\n this.detachMainVolResizer = attachPaneResizer(this.mainEl, this.volWrap, {\n storageKey: 'tradview:pane:main-volume',\n minTopPx: 120,\n minBottomPx: 48,\n });\n }\n\n setPinePlots(plots: PinePlotLine[] | null): void {\n this.pinePlots = plots;\n const bars = [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n this.syncPinePlotSeries(bars);\n }\n\n private teardownIndicatorStack(): void {\n this.indicators?.destroy();\n this.indicators = null;\n }\n\n private applyMainOverlays(bars: Bar[]): void {\n const cfg = this.indicatorConfig;\n if (!cfg) return;\n if (cfg.showMa) {\n this.maSeries.applyOptions({ visible: true, title: `MA${cfg.maPeriod}` });\n this.maSeries.setData(maOverlayLine(bars, cfg.maPeriod, cfg.source));\n } else {\n this.maSeries.applyOptions({ visible: false });\n this.maSeries.setData([]);\n }\n if (cfg.showVolMa) {\n this.volMaSeries.applyOptions({ visible: true });\n this.volMaSeries.setData(volMaOverlayLine(bars, cfg.volMaPeriod));\n } else {\n this.volMaSeries.applyOptions({ visible: false });\n this.volMaSeries.setData([]);\n }\n\n if (cfg.showEma) {\n this.emaSeries.applyOptions({ visible: true, title: `EMA${cfg.emaPeriod}` });\n this.emaSeries.setData(emaOverlayLine(bars, cfg.emaPeriod, cfg.source));\n } else {\n this.emaSeries.applyOptions({ visible: false });\n this.emaSeries.setData([]);\n }\n\n if (cfg.showBoll) {\n const bands = bollOverlayLines(bars, cfg.bollPeriod, cfg.bollMult, cfg.source);\n this.bollUpper.applyOptions({ visible: true });\n this.bollMiddle.applyOptions({ visible: true });\n this.bollLower.applyOptions({ visible: true });\n this.bollUpper.setData(bands.upper);\n this.bollMiddle.setData(bands.middle);\n this.bollLower.setData(bands.lower);\n } else {\n this.bollUpper.applyOptions({ visible: false });\n this.bollMiddle.applyOptions({ visible: false });\n this.bollLower.applyOptions({ visible: false });\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n }\n this.syncPinePlotSeries(bars);\n }\n\n private syncPinePlotSeries(bars: Bar[]): void {\n for (const s of this.pinePlotSeries) this.mainChart.removeSeries(s);\n this.pinePlotSeries = [];\n if (!this.pinePlots?.length || bars.length === 0) return;\n\n const palette = ['#58a6ff', '#d2a8ff', '#ff7b72', '#ffa657'];\n for (let i = 0; i < this.pinePlots.length; i++) {\n const plot = this.pinePlots[i]!;\n const series = this.mainChart.addSeries(LineSeries, {\n color: plot.color ?? palette[i % palette.length]!,\n lineWidth: 1,\n title: plot.title,\n });\n const out: { time: UTCTimestamp; value: number }[] = [];\n for (let j = 0; j < bars.length; j++) {\n const v = plot.values[j];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[j]!.t), value: v });\n }\n series.setData(out);\n this.pinePlotSeries.push(series);\n }\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.mainChart.applyOptions({ grid });\n this.volumeChart.applyOptions({ grid });\n this.indicators?.setShowGrid(show);\n }\n\n setBars(bars: Bar[], gaps?: number[]): void {\n const renderBars = lodDecimateBars(bars, this.maxRenderPoints);\n this.barByTime = new Map(renderBars.map((b) => [b.t, b]));\n this.barTimesOrdered = renderBars.map((b) => b.t);\n\n const gapSet = new Set(gaps ?? []);\n const seenTimes = new Set<number>();\n type CandlePoint = CandlestickData | WhitespaceData<UTCTimestamp>;\n const candles: CandlePoint[] = [];\n const vols: HistogramData<UTCTimestamp>[] = [];\n\n for (let i = 0; i < renderBars.length; i++) {\n const b = renderBars[i]!;\n const time = toUtcSeconds(b.t);\n if (seenTimes.has(time)) continue;\n seenTimes.add(time);\n if (gapSet.has(b.t)) {\n candles.push({ time });\n }\n candles.push(barToCandle(b));\n vols.push(barToVolume(b));\n }\n\n this.mainSeries.setData(candles);\n if (this.isVolumeVisible()) {\n this.volumeSeries.setData(vols);\n } else {\n this.volumeSeries.setData([]);\n }\n if (this.indicatorConfig) {\n this.applyMainOverlays(renderBars);\n if (hasVisibleIndicatorPanes(this.indicatorConfig)) {\n this.indicators?.setBars(renderBars);\n }\n } else {\n this.maSeries.setData([]);\n this.emaSeries.setData([]);\n this.bollUpper.setData([]);\n this.bollMiddle.setData([]);\n this.bollLower.setData([]);\n this.volMaSeries.setData([]);\n this.syncPinePlotSeries(renderBars);\n }\n\n if (renderBars.length > 0) {\n this.syncChartSize();\n this.tryInitialViewportFit(renderBars);\n this.skipNextInitialFit = false;\n }\n }\n\n private mainPaneHasSize(): boolean {\n const el = this.mainChart.chartElement().parentElement;\n return (el?.clientWidth ?? 0) > 0 && (el?.clientHeight ?? 0) > 0;\n }\n\n private tryInitialViewportFit(renderBars: Bar[]): void {\n if (this.didInitialFit || this.skipNextInitialFit) return;\n if (!this.mainPaneHasSize()) {\n this.pendingViewportFit = true;\n this.pendingViewportBars = renderBars;\n return;\n }\n this.applyViewAfterDataReload(renderBars);\n this.didInitialFit = true;\n this.pendingViewportFit = false;\n this.pendingViewportBars = null;\n }\n\n private flushPendingViewportFit(): void {\n if (!this.pendingViewportFit || this.skipNextInitialFit || this.didInitialFit) return;\n const bars =\n this.pendingViewportBars ??\n [...this.barByTime.values()].sort((a, b) => a.t - b.t);\n if (bars.length === 0 || !this.mainPaneHasSize()) return;\n this.applyViewAfterDataReload(bars);\n this.didInitialFit = true;\n this.pendingViewportFit = false;\n this.pendingViewportBars = null;\n }\n\n subscribeCrosshair(listener: (payload: CrosshairPayload | null) => void): () => void {\n const handler = (param: MouseEventParams<Time>) => {\n if (param.time == null || !param.point) {\n listener(null);\n return;\n }\n const tMs = typeof param.time === 'number' ? param.time * 1000 : null;\n if (tMs == null) {\n listener(null);\n return;\n }\n const price = this.mainSeries.coordinateToPrice(param.point.y) ?? null;\n const bar = this.barByTime.get(tMs) ?? this.findNearestBar(tMs);\n listener({\n time: tMs,\n price,\n ohlcv: bar\n ? { o: bar.o, h: bar.h, l: bar.l, c: bar.c, v: bar.v }\n : null,\n });\n };\n this.mainChart.subscribeCrosshairMove(handler);\n return () => this.mainChart.unsubscribeCrosshairMove(handler);\n }\n\n private findNearestBar(tMs: number): Bar | null {\n let best: Bar | null = null;\n let bestDt = Infinity;\n for (const b of this.barByTime.values()) {\n const dt = Math.abs(b.t - tMs);\n if (dt < bestDt) {\n bestDt = dt;\n best = b;\n }\n }\n return bestDt < 120_000 ? best : null;\n }\n\n private createIndicatorStack(): IndicatorPaneStack | null {\n if (!this.indicatorRoot || !this.indicatorConfig) return null;\n return new IndicatorPaneStack(this.indicatorRoot, this.busRegistry.getBusForPane('indicator'), {\n theme: this.dark ? 'dark' : 'light',\n showGrid: this.showGrid,\n config: this.indicatorConfig,\n onConfigChange: (config) => {\n this.indicatorConfig = config;\n this.onIndicatorConfigChange?.(config);\n },\n });\n }\n\n /** After symbol/interval reload: bar spacing for interval + show integrator-loaded span. */\n applyIntervalBarSpacing(interval?: Interval): void {\n if (!this.autoBarSpacingOnInterval) return;\n const iv = interval ?? this.currentInterval;\n const spacing = resolveBarSpacingForInterval(iv, this.barSpacingByInterval);\n this.busRegistry.forEachBus((_, bus) => bus.setBarSpacing(spacing));\n }\n\n setBarSpacingPolicy(opts: {\n autoBarSpacingOnInterval?: boolean;\n barSpacingByInterval?: Partial<Record<Interval, number>>;\n }): void {\n if (opts.autoBarSpacingOnInterval !== undefined) {\n this.autoBarSpacingOnInterval = opts.autoBarSpacingOnInterval;\n }\n if (opts.barSpacingByInterval !== undefined) {\n this.barSpacingByInterval = opts.barSpacingByInterval;\n }\n }\n\n /** Sync time scale to loaded bars (integrator history); adjust bar spacing only, not bar count. */\n private applyViewAfterDataReload(renderBars: Bar[]): void {\n if (this.autoBarSpacingOnInterval) {\n this.applyIntervalBarSpacing();\n } else {\n this.mainChart.timeScale().fitContent();\n if (this.isVolumeVisible()) this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n }\n\n if (renderBars.length > 0) {\n const fromMs = renderBars[0]!.t;\n const toMs = renderBars[renderBars.length - 1]!.t + intervalMs(this.currentInterval);\n this.bus.setVisibleTimeRange({ fromMs, toMs });\n }\n this.scrollToRealtime();\n }\n\n resetViewState(): void {\n this.didInitialFit = false;\n this.skipNextInitialFit = false;\n this.pendingViewportFit = false;\n this.pendingViewportBars = null;\n this.busRegistry.forEachBus((_, bus) => {\n bus.visibleFromMs = 0;\n bus.visibleToMs = 0;\n });\n }\n\n /** Skip the next automatic fitContent after setBars (used by reloadHistory). */\n preserveViewportOnNextSetBars(): void {\n this.skipNextInitialFit = true;\n this.didInitialFit = true;\n }\n\n /**\n * DESIGN §10.4.1: after `mergeBars(..., prepend)` shift logical ranges on every sync bus\n * so canonical ms viewport and crosshair `t` stay stable.\n */\n compensatePrependForBuses(\n sortedTimesBefore: readonly number[],\n sortedTimesAfter: readonly number[],\n interval: Interval,\n ): void {\n compensatePrependOnRegistry({\n registry: this.busRegistry,\n sortedTimesBefore,\n sortedTimesAfter,\n intervalMs: intervalMs(interval),\n referenceChart: this.mainChart,\n });\n }\n\n getVisibleRange(): ChartVisibleRange | null {\n return this.bus.getVisibleRange();\n }\n\n getBarSpace(): number {\n return this.bus.getBarSpacing();\n }\n\n setBarSpace(px: number): void {\n this.bus.setBarSpacing(px);\n }\n\n setVisibleRange(range: ChartVisibleRange): void {\n this.bus.setVisibleTimeRange(range);\n this.didInitialFit = true;\n }\n\n scrollToTimestamp(tsMs: number, animationMs?: number): void {\n const time = toUtcSeconds(tsMs);\n const idx = this.mainChart.timeScale().timeToIndex(time, true);\n if (idx == null) {\n const nearest = this.findNearestBar(tsMs);\n if (nearest == null) return;\n const i = this.barTimesOrdered.indexOf(nearest.t);\n if (i < 0) return;\n this.busRegistry.getBusForPane('main').scrollToLogicalPosition(i, (animationMs ?? 0) > 0);\n return;\n }\n this.busRegistry.getBusForPane('main').scrollToLogicalPosition(idx as number, (animationMs ?? 0) > 0);\n }\n\n /** Clear series while symbol/interval data reloads (avoids overlapping candles). */\n clearBars(): void {\n this.barAnimator?.cancel();\n this.barByTime = new Map();\n this.barTimesOrdered = [];\n this.mainSeries.setData([]);\n this.maSeries.setData([]);\n this.volumeSeries.setData([]);\n this.volMaSeries.setData([]);\n this.indicators?.clearBars();\n }\n\n fitContent(): void {\n this.mainChart.timeScale().fitContent();\n if (this.isVolumeVisible()) this.volumeChart.timeScale().fitContent();\n this.indicators?.fitContent();\n this.didInitialFit = true;\n }\n\n scrollToRealtime(): void {\n this.mainChart.timeScale().scrollToRealTime();\n if (this.isVolumeVisible()) this.volumeChart.timeScale().scrollToRealTime();\n this.indicators?.scrollToRealtime();\n }\n\n setLogScale(enabled: boolean): void {\n this.mainChart.priceScale('right').applyOptions({ mode: enabled ? 1 : 0 });\n }\n\n resize(): void {\n this.syncChartSize();\n this.syncOverlaySize();\n if (this.shouldResizePane('indicator')) this.indicators?.resize();\n this.flushPendingViewportFit();\n }\n\n /**\n * Resize every LWC pane once for viewport fit; does **not** change {@link resizeFocusPanes}.\n * @internal Used by ChartController data refresh paths.\n */\n resizeAllPanes(): void {\n this.syncChartSize({ allPanes: true });\n this.syncOverlaySize();\n this.indicators?.resize();\n this.flushPendingViewportFit();\n }\n\n getOverlayCanvas(): HTMLCanvasElement | null {\n return this.overlayCanvas;\n }\n\n timeToX(tMs: number): number | null {\n const coord = this.mainChart.timeScale().timeToCoordinate(toUtcSeconds(tMs));\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n priceToY(price: number): number | null {\n const coord = this.mainSeries.priceToCoordinate(price);\n if (coord == null) return null;\n return coord * devicePixelRatio;\n }\n\n xToTime(x: number): number | null {\n const t = this.mainChart.timeScale().coordinateToTime(x / devicePixelRatio);\n if (t == null) return null;\n return Number(t) * 1000;\n }\n\n yToPrice(y: number): number | null {\n const p = this.mainSeries.coordinateToPrice(y / devicePixelRatio);\n return p ?? null;\n }\n\n destroy(): void {\n if (this.listenPaneResizeEvents) {\n window.removeEventListener('tradview:pane-resize', this.onPaneResize);\n }\n this.detachMainVolResizer();\n this.barAnimator?.cancel();\n if (this.priceLine) {\n this.mainSeries.removePriceLine(this.priceLine);\n this.priceLine = null;\n }\n this.mainChart.remove();\n this.volumeChart.remove();\n this.indicators?.destroy();\n this.overlayCanvas?.remove();\n }\n\n private initOverlay(parent: HTMLElement) {\n const canvas = document.createElement('canvas');\n canvas.style.cssText =\n 'position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10;';\n parent.style.position = 'relative';\n parent.appendChild(canvas);\n this.overlayCanvas = canvas;\n this.syncOverlaySize();\n this.busRegistry.forEachBus((_, bus) => {\n bus.subscribeTransform(() => {\n this.syncOverlaySize();\n });\n });\n }\n\n /** Let drawing overlay receive clicks; cursor mode keeps pan/zoom on LWC. */\n setOverlayPointerEvents(mode: 'auto' | 'none'): void {\n if (this.overlayCanvas) this.overlayCanvas.style.pointerEvents = mode;\n }\n\n private syncOverlaySize() {\n if (!this.overlayCanvas?.parentElement) return;\n const parent = this.overlayCanvas.parentElement;\n if (parent.lastElementChild !== this.overlayCanvas) {\n parent.appendChild(this.overlayCanvas);\n }\n const rect = parent.getBoundingClientRect();\n this.overlayCanvas.width = rect.width * devicePixelRatio;\n this.overlayCanvas.height = rect.height * devicePixelRatio;\n }\n\n private syncChartSize(opts?: { allPanes?: boolean }): void {\n const all = opts?.allPanes === true;\n const mainEl = this.mainChart.chartElement().parentElement;\n const volEl = this.volumeChart.chartElement().parentElement;\n if (mainEl && (all || this.shouldResizePane('main'))) {\n const w = mainEl.clientWidth;\n const h = mainEl.clientHeight;\n if (w > 0 && h > 0) this.mainChart.resize(w, h);\n }\n if (this.isVolumeVisible() && volEl && (all || this.shouldResizePane('volume'))) {\n const w = volEl.clientWidth;\n const h = volEl.clientHeight;\n if (w > 0 && h > 0) this.volumeChart.resize(w, h);\n }\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n}","import type { LogicalRange } from 'lightweight-charts';\nimport type { TimeScaleBus } from './time-scale-bus.js';\nimport type { TimeScaleBusRegistry } from './time-scale-bus-registry.js';\n\n/** Slice of loaded bar open times for the current render window (DESIGN §10.4.1). */\nexport function buildSliceTimes(\n sortedTimes: readonly number[],\n renderFromMs: number,\n renderToMs: number,\n): number[] {\n return sortedTimes.filter((t) => t >= renderFromMs && t <= renderToMs);\n}\n\n/** Count bars newly present in slice after prepend merge. */\nexport function countPrependSliceDelta(beforeSlice: readonly number[], afterSlice: readonly number[]): number {\n const before = new Set(beforeSlice);\n let delta = 0;\n for (const t of afterSlice) {\n if (!before.has(t)) delta += 1;\n }\n return delta;\n}\n\n/** Map LWC logical index (position in slice) to canonical bar time `t` (ms). */\nexport function logicalIndexToBarTimeMs(sliceTimes: readonly number[], logicalIndex: number): number | null {\n if (sliceTimes.length === 0) return null;\n const idx = Math.min(Math.max(0, Math.floor(logicalIndex)), sliceTimes.length - 1);\n return sliceTimes[idx] ?? null;\n}\n\n/** Mirrors {@link VirtualWindow.getRenderRange} for prepend slice math. */\nexport function deriveRenderRange(\n visibleFromMs: number,\n visibleToMs: number,\n sortedTimes: readonly number[],\n intervalMs: number,\n): { renderFromMs: number; renderToMs: number } {\n if (visibleToMs <= visibleFromMs && sortedTimes.length > 0) {\n const fromMs = sortedTimes[0]!;\n const toMs = sortedTimes[sortedTimes.length - 1]!;\n const bufferMs = intervalMs * 20;\n return { renderFromMs: fromMs - bufferMs, renderToMs: toMs + bufferMs };\n }\n const span = visibleToMs - visibleFromMs;\n const bufferMs = Math.max(span * 0.1, intervalMs * 50);\n return {\n renderFromMs: visibleFromMs - bufferMs,\n renderToMs: visibleToMs + bufferMs,\n };\n}\n\n/** Logical range covering canonical visible ms within a slice (DESIGN §10.4.1 fallback). */\nexport function logicalRangeForVisibleWindow(\n sliceTimes: readonly number[],\n visibleFromMs: number,\n visibleToMs: number,\n): LogicalRange | null {\n if (sliceTimes.length === 0 || visibleToMs <= visibleFromMs) return null;\n let fromIdx = 0;\n let toIdx = sliceTimes.length - 1;\n for (let i = 0; i < sliceTimes.length; i++) {\n if (sliceTimes[i]! >= visibleFromMs) {\n fromIdx = i;\n break;\n }\n }\n for (let i = sliceTimes.length - 1; i >= 0; i--) {\n if (sliceTimes[i]! <= visibleToMs) {\n toIdx = i;\n break;\n }\n }\n if (toIdx < fromIdx) return null;\n return { from: fromIdx, to: toIdx } as LogicalRange;\n}\n\nexport interface PrependSliceDeltaInput {\n sortedTimesBefore: readonly number[];\n sortedTimesAfter: readonly number[];\n visibleFromMs: number;\n visibleToMs: number;\n intervalMs: number;\n}\n\n/** Δ new bars in render slice after historical prepend (canonical ms window unchanged). */\nexport function computePrependSliceDeltaForViewport(input: PrependSliceDeltaInput): number {\n const { visibleFromMs, visibleToMs, intervalMs, sortedTimesBefore, sortedTimesAfter } = input;\n const renderBefore = deriveRenderRange(visibleFromMs, visibleToMs, sortedTimesBefore, intervalMs);\n const renderAfter = deriveRenderRange(visibleFromMs, visibleToMs, sortedTimesAfter, intervalMs);\n const beforeSlice = buildSliceTimes(\n sortedTimesBefore,\n renderBefore.renderFromMs,\n renderBefore.renderToMs,\n );\n const afterSlice = buildSliceTimes(\n sortedTimesAfter,\n renderAfter.renderFromMs,\n renderAfter.renderToMs,\n );\n return countPrependSliceDelta(beforeSlice, afterSlice);\n}\n\nexport interface CompensatePrependOnRegistryOptions {\n registry: TimeScaleBusRegistry;\n sortedTimesBefore: readonly number[];\n sortedTimesAfter: readonly number[];\n intervalMs: number;\n /** Reference chart for logical range read (e.g. main pane). */\n referenceChart?: import('lightweight-charts').IChartApi;\n}\n\n/** Apply §10.4.1 logicalRange offset on every bus with an initialized visible window. */\nexport function compensatePrependOnRegistry(opts: CompensatePrependOnRegistryOptions): void {\n const { registry, sortedTimesBefore, sortedTimesAfter, intervalMs, referenceChart } = opts;\n registry.forEachBus((_, bus) => {\n compensatePrependOnBus(bus, {\n sortedTimesBefore,\n sortedTimesAfter,\n intervalMs,\n referenceChart,\n });\n });\n}\n\nexport interface CompensatePrependOnBusOptions {\n sortedTimesBefore: readonly number[];\n sortedTimesAfter: readonly number[];\n intervalMs: number;\n referenceChart?: import('lightweight-charts').IChartApi;\n}\n\nexport function compensatePrependOnBus(bus: TimeScaleBus, opts: CompensatePrependOnBusOptions): void {\n const range = bus.getVisibleRange();\n if (!range) return;\n const delta = computePrependSliceDeltaForViewport({\n sortedTimesBefore: opts.sortedTimesBefore,\n sortedTimesAfter: opts.sortedTimesAfter,\n visibleFromMs: range.fromMs,\n visibleToMs: range.toMs,\n intervalMs: opts.intervalMs,\n });\n if (delta <= 0) return;\n const { renderFromMs, renderToMs } = deriveRenderRange(\n range.fromMs,\n range.toMs,\n opts.sortedTimesAfter,\n opts.intervalMs,\n );\n const sliceAfter = buildSliceTimes(opts.sortedTimesAfter, renderFromMs, renderToMs);\n bus.compensatePrependLogicalRange(delta, opts.referenceChart, sliceAfter);\n}","/** LWC grid line options — default off per product spec. */\nexport function gridOptions(showGrid: boolean, dark: boolean) {\n const color = dark ? '#21262d' : '#d0d7de';\n return {\n vertLines: { visible: showGrid, color },\n horzLines: { visible: showGrid, color },\n };\n}","import {\n ColorType,\n createChart,\n HistogramSeries,\n LineSeries,\n type HistogramData,\n type IChartApi,\n type ISeriesApi,\n type LineData,\n type UTCTimestamp,\n} from 'lightweight-charts';\nimport type { Bar } from '@coderyo/data';\nimport {\n type IndicatorConfig,\n DEFAULT_INDICATOR_CONFIG,\n hasVisibleIndicatorPanes,\n boll,\n kdj,\n macd,\n rsi,\n sma,\n ema,\n} from '@coderyo/indicators';\nimport { gridOptions } from './chart-grid.js';\nimport { attachPaneResizer } from './pane-resize.js';\nimport type { TimeScaleBus } from './time-scale-bus.js';\n\nexport type IndicatorPaneId = 'macd' | 'rsi' | 'kdj';\n\nexport interface IndicatorPaneStackOptions {\n theme?: 'dark' | 'light';\n showGrid?: boolean;\n config?: IndicatorConfig;\n onConfigChange?: (config: IndicatorConfig) => void;\n}\n\nfunction barsForSource(bars: Bar[], source: IndicatorConfig['source']): Bar[] {\n if (source === 'close') return bars;\n return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));\n}\n\nfunction toUtcSeconds(tMs: number): UTCTimestamp {\n return Math.floor(tMs / 1000) as UTCTimestamp;\n}\n\n/** PR-21: detect in-place tail updates vs full recompute. */\nexport function detectIndicatorBarMutation(\n prevTimes: number[],\n bars: Bar[],\n): 'full' | 'tail-append' | 'tail-update' {\n if (prevTimes.length === 0 || bars.length < prevTimes.length) return 'full';\n const prefixLen = Math.min(prevTimes.length, bars.length);\n for (let i = 0; i < prefixLen - 1; i++) {\n if (bars[i]!.t !== prevTimes[i]) return 'full';\n }\n if (bars.length === prevTimes.length) {\n return bars.length > 0 && bars[bars.length - 1]!.t === prevTimes[prevTimes.length - 1]\n ? 'tail-update'\n : 'full';\n }\n if (bars.length - prevTimes.length > 8) return 'full';\n for (let i = 0; i < prevTimes.length; i++) {\n if (bars[i]!.t !== prevTimes[i]) return 'full';\n }\n return 'tail-append';\n}\n\nfunction lineData(bars: Bar[], values: (number | null)[]): LineData<UTCTimestamp>[] {\n const out: LineData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({ time: toUtcSeconds(bars[i]!.t), value: v });\n }\n return out;\n}\n\nfunction histData(bars: Bar[], values: (number | null)[]): HistogramData<UTCTimestamp>[] {\n const out: HistogramData<UTCTimestamp>[] = [];\n for (let i = 0; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n out.push({\n time: toUtcSeconds(bars[i]!.t),\n value: v,\n color: v >= 0 ? '#26a69a88' : '#ef535088',\n });\n }\n return out;\n}\n\nexport class IndicatorPaneStack {\n private readonly macdChart: IChartApi;\n private readonly rsiChart: IChartApi;\n private readonly kdjChart: IChartApi;\n private readonly macdLine: ISeriesApi<'Line'>;\n private readonly macdSignal: ISeriesApi<'Line'>;\n private readonly macdHist: ISeriesApi<'Histogram'>;\n private readonly rsiLine: ISeriesApi<'Line'>;\n private readonly kdjK: ISeriesApi<'Line'>;\n private readonly kdjD: ISeriesApi<'Line'>;\n private readonly kdjJ: ISeriesApi<'Line'>;\n private dark = true;\n private showGrid = false;\n private config: IndicatorConfig = DEFAULT_INDICATOR_CONFIG;\n private readonly macdWrap: HTMLElement;\n private readonly rsiWrap: HTMLElement;\n private readonly kdjWrap: HTMLElement;\n private readonly detachResizers: Array<() => void> = [];\n private lastBarTimes: number[] = [];\n private onConfigChange?: (config: IndicatorConfig) => void;\n\n constructor(\n private readonly root: HTMLElement,\n bus: TimeScaleBus,\n opts: IndicatorPaneStackOptions | 'dark' | 'light' = 'dark',\n ) {\n const o = typeof opts === 'string' ? { theme: opts, showGrid: false } : opts;\n this.dark = o.theme !== 'light';\n this.showGrid = o.showGrid ?? false;\n this.config = o.config ?? DEFAULT_INDICATOR_CONFIG;\n this.onConfigChange = o.onConfigChange;\n this.root.style.display = 'flex';\n this.root.style.flexDirection = 'column';\n this.root.style.flex = '2';\n this.root.style.minHeight = '0';\n this.root.style.overflow = 'hidden';\n\n const macdPane = this.createPaneWrap('MACD', 'macd');\n const rsiPane = this.createPaneWrap('RSI', 'rsi');\n const kdjPane = this.createPaneWrap('KDJ', 'kdj');\n this.macdWrap = macdPane.wrap;\n this.rsiWrap = rsiPane.wrap;\n this.kdjWrap = kdjPane.wrap;\n\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart = createChart(macdPane.el, { layout, grid, autoSize: true });\n this.rsiChart = createChart(rsiPane.el, { layout, grid, autoSize: true });\n this.kdjChart = createChart(kdjPane.el, { layout, grid, autoSize: true });\n\n for (const c of [this.macdChart, this.rsiChart, this.kdjChart]) bus.register(c);\n\n this.macdLine = this.macdChart.addSeries(LineSeries, { color: '#2962ff', lineWidth: 1 });\n this.macdSignal = this.macdChart.addSeries(LineSeries, { color: '#ff9800', lineWidth: 1 });\n this.macdHist = this.macdChart.addSeries(HistogramSeries, {\n priceFormat: { type: 'price', precision: 4, minMove: 0.0001 },\n });\n this.rsiLine = this.rsiChart.addSeries(LineSeries, { color: '#ab47bc', lineWidth: 1 });\n this.kdjK = this.kdjChart.addSeries(LineSeries, { color: '#42a5f5', lineWidth: 1 });\n this.kdjD = this.kdjChart.addSeries(LineSeries, { color: '#ffa726', lineWidth: 1 });\n this.kdjJ = this.kdjChart.addSeries(LineSeries, { color: '#ef5350', lineWidth: 1 });\n\n this.applyPaneVisibility();\n }\n\n setConfig(config: IndicatorConfig): void {\n this.config = config;\n this.lastBarTimes = [];\n this.applyPaneVisibility();\n if (!this.config.showMacd && !this.config.showRsi && !this.config.showKdj) {\n this.clearBars();\n }\n }\n\n private closePane(id: IndicatorPaneId): void {\n const patch: Partial<IndicatorConfig> =\n id === 'macd' ? { showMacd: false } : id === 'rsi' ? { showRsi: false } : { showKdj: false };\n this.config = { ...this.config, ...patch };\n this.applyPaneVisibility();\n this.onConfigChange?.(this.config);\n }\n\n private applyPaneVisibility(): void {\n const anyVisible = this.config.showMacd || this.config.showRsi || this.config.showKdj;\n this.root.style.display = anyVisible ? 'flex' : 'none';\n this.rebuildPaneLayout();\n }\n\n /** Rebuild flex children and drag handles only between visible panes. */\n private rebuildPaneLayout(): void {\n for (const detach of this.detachResizers) detach();\n this.detachResizers.length = 0;\n this.root.querySelectorAll('[data-pane-resizer]').forEach((el) => el.remove());\n\n const panes: Array<{ id: IndicatorPaneId; el: HTMLElement }> = [];\n if (this.config.showMacd) panes.push({ id: 'macd', el: this.macdWrap });\n if (this.config.showRsi) panes.push({ id: 'rsi', el: this.rsiWrap });\n if (this.config.showKdj) panes.push({ id: 'kdj', el: this.kdjWrap });\n\n this.root.replaceChildren(...panes.map((p) => p.el));\n\n for (let i = 0; i < panes.length - 1; i++) {\n const top = panes[i]!;\n const bottom = panes[i + 1]!;\n this.detachResizers.push(\n attachPaneResizer(top.el, bottom.el, {\n storageKey: `tradview:pane:${top.id}-${bottom.id}`,\n minTopPx: 72,\n minBottomPx: 72,\n }),\n );\n }\n this.resize();\n }\n\n clearBars(): void {\n this.macdLine.setData([]);\n this.macdSignal.setData([]);\n this.macdHist.setData([]);\n this.rsiLine.setData([]);\n this.kdjK.setData([]);\n this.kdjD.setData([]);\n this.kdjJ.setData([]);\n this.lastBarTimes = [];\n }\n\n private warmupLookback(): number {\n const c = this.config;\n return (\n Math.max(\n c.macdSlow + c.macdSignal,\n c.rsiPeriod,\n c.kdjPeriod + c.kdjKSmooth + c.kdjDSmooth,\n ) + 5\n );\n }\n\n private detectBarMutation(bars: Bar[]): 'full' | 'tail-append' | 'tail-update' {\n return detectIndicatorBarMutation(this.lastBarTimes, bars);\n }\n\n private pushSeriesUpdates(\n series: ISeriesApi<'Line'>,\n bars: Bar[],\n values: (number | null)[],\n fromIndex: number,\n ): void {\n for (let i = fromIndex; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n series.update({ time: toUtcSeconds(bars[i]!.t), value: v });\n }\n }\n\n private pushHistUpdates(\n series: ISeriesApi<'Histogram'>,\n bars: Bar[],\n values: (number | null)[],\n fromIndex: number,\n ): void {\n for (let i = fromIndex; i < bars.length; i++) {\n const v = values[i];\n if (v == null) continue;\n series.update({\n time: toUtcSeconds(bars[i]!.t),\n value: v,\n color: v >= 0 ? '#26a69a88' : '#ef535088',\n });\n }\n }\n\n setBars(bars: Bar[]): void {\n if (bars.length === 0) {\n this.clearBars();\n return;\n }\n\n const needMacd = this.config.showMacd;\n const needRsi = this.config.showRsi;\n const needKdj = this.config.showKdj;\n if (!hasVisibleIndicatorPanes(this.config)) {\n return;\n }\n\n const mutation = this.detectBarMutation(bars);\n this.lastBarTimes = bars.map((b) => b.t);\n const src = barsForSource(bars, this.config.source);\n const m = needMacd\n ? macd(src, this.config.macdFast, this.config.macdSlow, this.config.macdSignal)\n : null;\n const r = needRsi ? rsi(src, this.config.rsiPeriod) : null;\n const k = needKdj\n ? kdj(src, this.config.kdjPeriod, this.config.kdjKSmooth, this.config.kdjDSmooth)\n : null;\n\n if (mutation === 'full') {\n if (needMacd && m) {\n this.macdLine.setData(lineData(bars, m.macd));\n this.macdSignal.setData(lineData(bars, m.signal));\n this.macdHist.setData(histData(bars, m.histogram));\n this.macdChart.timeScale().fitContent();\n }\n if (needRsi && r) {\n this.rsiLine.setData(lineData(bars, r));\n this.rsiChart.timeScale().fitContent();\n }\n if (needKdj && k) {\n this.kdjK.setData(lineData(bars, k.k));\n this.kdjD.setData(lineData(bars, k.d));\n this.kdjJ.setData(lineData(bars, k.j));\n this.kdjChart.timeScale().fitContent();\n }\n } else {\n const from =\n mutation === 'tail-update' ? Math.max(0, bars.length - 1) : Math.max(0, bars.length - this.warmupLookback());\n if (needMacd && m) {\n this.pushSeriesUpdates(this.macdLine, bars, m.macd, from);\n this.pushSeriesUpdates(this.macdSignal, bars, m.signal, from);\n this.pushHistUpdates(this.macdHist, bars, m.histogram, from);\n }\n if (needRsi && r) {\n this.pushSeriesUpdates(this.rsiLine, bars, r, from);\n }\n if (needKdj && k) {\n this.pushSeriesUpdates(this.kdjK, bars, k.k, from);\n this.pushSeriesUpdates(this.kdjD, bars, k.d, from);\n this.pushSeriesUpdates(this.kdjJ, bars, k.j, from);\n }\n }\n\n this.resize();\n }\n\n setTheme(theme: 'dark' | 'light'): void {\n this.dark = theme === 'dark';\n const layout = this.layoutForTheme(this.dark);\n const grid = gridOptions(this.showGrid, this.dark);\n this.macdChart.applyOptions({ layout, grid });\n this.rsiChart.applyOptions({ layout, grid });\n this.kdjChart.applyOptions({ layout, grid });\n }\n\n setShowGrid(show: boolean): void {\n this.showGrid = show;\n const grid = gridOptions(show, this.dark);\n this.macdChart.applyOptions({ grid });\n this.rsiChart.applyOptions({ grid });\n this.kdjChart.applyOptions({ grid });\n }\n\n fitContent(): void {\n this.macdChart.timeScale().fitContent();\n this.rsiChart.timeScale().fitContent();\n this.kdjChart.timeScale().fitContent();\n }\n\n scrollToRealtime(): void {\n this.macdChart.timeScale().scrollToRealTime();\n this.rsiChart.timeScale().scrollToRealTime();\n this.kdjChart.timeScale().scrollToRealTime();\n }\n\n resize(): void {\n const panes: Array<{ show: boolean; chart: IChartApi }> = [\n { show: this.config.showMacd, chart: this.macdChart },\n { show: this.config.showRsi, chart: this.rsiChart },\n { show: this.config.showKdj, chart: this.kdjChart },\n ];\n for (const { show, chart } of panes) {\n if (!show || !chart) continue;\n const el = chart.chartElement()?.parentElement;\n if (!el) continue;\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) chart.resize(w, h);\n }\n }\n\n destroy(): void {\n for (const detach of this.detachResizers) detach();\n this.detachResizers.length = 0;\n this.macdChart.remove();\n this.rsiChart.remove();\n this.kdjChart.remove();\n this.root.replaceChildren();\n }\n\n private createPaneWrap(\n label: string,\n paneId: IndicatorPaneId,\n ): { wrap: HTMLElement; el: HTMLElement } {\n const wrap = document.createElement('div');\n wrap.className = `tv-indicator-pane tv-indicator-pane--${paneId}`;\n wrap.dataset.paneId = paneId;\n wrap.style.cssText =\n 'flex:1;min-height:72px;width:100%;position:relative;border-top:1px solid #30363d;';\n const tag = document.createElement('span');\n tag.textContent = label;\n tag.style.cssText =\n 'position:absolute;left:6px;top:4px;z-index:2;font-size:10px;color:#8b949e;pointer-events:none;';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = '×';\n closeBtn.title = `關閉 ${label}`;\n closeBtn.setAttribute('aria-label', `Close ${label}`);\n closeBtn.style.cssText =\n 'position:absolute;right:6px;top:4px;z-index:3;width:22px;height:22px;padding:0;border:1px solid #30363d;border-radius:4px;background:#21262d;color:#8b949e;cursor:pointer;font-size:14px;line-height:1;';\n closeBtn.onmouseenter = () => {\n closeBtn.style.color = '#e6edf3';\n closeBtn.style.borderColor = '#484f58';\n };\n closeBtn.onmouseleave = () => {\n closeBtn.style.color = '#8b949e';\n closeBtn.style.borderColor = '#30363d';\n };\n closeBtn.onclick = () => this.closePane(paneId);\n const el = document.createElement('div');\n el.style.cssText = 'width:100%;height:100%;';\n wrap.append(tag, closeBtn, el);\n return { wrap, el };\n }\n\n private layoutForTheme(dark: boolean) {\n return {\n background: { type: ColorType.Solid, color: dark ? '#0d1117' : '#ffffff' },\n textColor: dark ? '#e6edf3' : '#24292f',\n };\n }\n\n /** LWC instances for sync-group reassignment. */\n getCharts(): IChartApi[] {\n return [this.macdChart, this.rsiChart, this.kdjChart];\n }\n}\n\nexport function maOverlayLine(\n bars: Bar[],\n period = 20,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, sma(src, period));\n}\n\nexport function volMaOverlayLine(bars: Bar[], period = 5): LineData<UTCTimestamp>[] {\n const volBars = bars.map((b) => ({ ...b, c: b.v ?? 0 }));\n return lineData(bars, sma(volBars, period, 'close'));\n}\n\nexport function emaOverlayLine(\n bars: Bar[],\n period: number,\n source: IndicatorConfig['source'] = 'close',\n): LineData<UTCTimestamp>[] {\n const src = barsForSource(bars, source);\n return lineData(bars, ema(src, period));\n}\n\nexport function bollOverlayLines(\n bars: Bar[],\n period: number,\n mult: number,\n source: IndicatorConfig['source'] = 'close',\n): {\n upper: LineData<UTCTimestamp>[];\n middle: LineData<UTCTimestamp>[];\n lower: LineData<UTCTimestamp>[];\n} {\n const src = barsForSource(bars, source);\n const bands = boll(src, period, mult);\n return {\n upper: lineData(bars, bands.upper),\n middle: lineData(bars, bands.middle),\n lower: lineData(bars, bands.lower),\n };\n}","export function attachPaneResizer(\n topPane: HTMLElement,\n bottomPane: HTMLElement,\n opts: { minTopPx?: number; minBottomPx?: number; storageKey?: string } = {},\n): () => void {\n const minTop = opts.minTopPx ?? 120;\n const minBottom = opts.minBottomPx ?? 60;\n const parent = topPane.parentElement;\n if (!parent) return () => {};\n\n let dragging = false;\n\n const handle = document.createElement('div');\n handle.dataset.paneResizer = '1';\n handle.style.cssText =\n 'height:6px;cursor:row-resize;background:#30363d;flex-shrink:0;touch-action:none;z-index:5;';\n handle.onmouseenter = () => {\n handle.style.background = '#388bfd';\n };\n handle.onmouseleave = () => {\n if (!dragging) handle.style.background = '#30363d';\n };\n bottomPane.insertAdjacentElement('beforebegin', handle);\n\n const saved = opts.storageKey ? localStorage.getItem(opts.storageKey) : null;\n if (saved) {\n const ratio = Number(saved);\n if (Number.isFinite(ratio) && ratio >= 0.15 && ratio <= 0.85) {\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n }\n }\n\n const onMove = (clientY: number) => {\n const rect = parent.getBoundingClientRect();\n const y = clientY - rect.top;\n const ratio = Math.min(0.85, Math.max(0.15, y / rect.height));\n const topPx = ratio * rect.height;\n const bottomPx = rect.height - topPx - handle.offsetHeight;\n if (topPx < minTop || bottomPx < minBottom) return;\n topPane.style.flex = `${ratio * 10}`;\n bottomPane.style.flex = `${(1 - ratio) * 10}`;\n if (opts.storageKey) localStorage.setItem(opts.storageKey, String(ratio));\n };\n\n const stop = () => {\n const wasDragging = dragging;\n dragging = false;\n document.body.style.cursor = '';\n handle.style.background = '#30363d';\n if (wasDragging) window.dispatchEvent(new CustomEvent('tradview:pane-resize'));\n };\n\n handle.addEventListener('pointerdown', (e) => {\n dragging = true;\n handle.setPointerCapture(e.pointerId);\n document.body.style.cursor = 'row-resize';\n });\n handle.addEventListener('pointermove', (e) => {\n if (dragging) {\n onMove(e.clientY);\n window.dispatchEvent(new CustomEvent('tradview:pane-resize'));\n }\n });\n handle.addEventListener('pointerup', stop);\n handle.addEventListener('pointercancel', stop);\n\n return () => handle.remove();\n}","import type { IChartApi, LogicalRange, UTCTimestamp } from 'lightweight-charts';\nimport { logicalRangeForVisibleWindow } from './time-scale-prepend.js';\n\nexport interface ChartVisibleRange {\n fromMs: number;\n toMs: number;\n}\n\nexport interface TransformState {\n visibleFromMs: number;\n visibleToMs: number;\n width: number;\n height: number;\n}\n\ntype TransformListener = (state: TransformState) => void;\n\n/** Sync visible logical range across multiple LWC panes (§10.4.1). */\nexport class TimeScaleBus {\n private charts: IChartApi[] = [];\n private listeners = new Set<TransformListener>();\n private syncing = false;\n visibleFromMs = 0;\n visibleToMs = 0;\n\n register(chart: IChartApi): void {\n if (this.charts.includes(chart)) return;\n this.charts.push(chart);\n chart.timeScale().subscribeVisibleLogicalRangeChange((range) => {\n if (!this.charts.includes(chart)) return;\n if (this.syncing || !range) return;\n const tr = chart.timeScale().getVisibleRange();\n if (tr && typeof tr.from === 'number' && typeof tr.to === 'number') {\n this.visibleFromMs = tr.from * 1000;\n this.visibleToMs = tr.to * 1000;\n }\n this.syncFrom(chart, range);\n });\n }\n\n unregister(chart: IChartApi): void {\n const i = this.charts.indexOf(chart);\n if (i >= 0) this.charts.splice(i, 1);\n }\n\n subscribeTransform(listener: TransformListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n setBarsTimeRange(fromMs: number, toMs: number): void {\n this.visibleFromMs = fromMs;\n this.visibleToMs = toMs;\n this.emit();\n }\n\n getVisibleRange(): ChartVisibleRange | null {\n if (this.visibleToMs <= this.visibleFromMs) return null;\n return { fromMs: this.visibleFromMs, toMs: this.visibleToMs };\n }\n\n getBarSpacing(): number {\n const chart = this.charts[0];\n return chart ? chart.timeScale().options().barSpacing : 6;\n }\n\n setBarSpacing(spacing: number): void {\n if (!Number.isFinite(spacing) || spacing <= 0) return;\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().applyOptions({ barSpacing: spacing });\n }\n this.syncing = false;\n this.emit();\n }\n\n setVisibleTimeRange(range: ChartVisibleRange): void {\n const from = Math.floor(range.fromMs / 1000) as UTCTimestamp;\n const to = Math.floor(range.toMs / 1000) as UTCTimestamp;\n if (to <= from) return;\n this.visibleFromMs = range.fromMs;\n this.visibleToMs = range.toMs;\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().setVisibleRange({ from, to });\n }\n this.syncing = false;\n this.emit();\n }\n\n scrollToLogicalPosition(position: number, animated = false): void {\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().scrollToPosition(position, animated);\n }\n this.syncing = false;\n this.emit();\n }\n\n /**\n * DESIGN §10.4.1: after historical prepend, shift every pane's logical range by Δ\n * so canonical `visibleFromMs` / `visibleToMs` (and crosshair time mapping) stay fixed.\n */\n compensatePrependLogicalRange(\n delta: number,\n referenceChart?: IChartApi,\n sliceTimes?: readonly number[],\n ): void {\n const d = Math.max(0, Math.floor(delta));\n if (d === 0 || this.charts.length === 0) return;\n const ref =\n referenceChart && this.charts.includes(referenceChart)\n ? referenceChart\n : this.charts[0]!;\n const ts = ref.timeScale();\n let current: LogicalRange | null =\n typeof ts.getVisibleLogicalRange === 'function'\n ? ts.getVisibleLogicalRange()\n : null;\n if (\n !current &&\n sliceTimes?.length &&\n this.visibleToMs > this.visibleFromMs\n ) {\n current = logicalRangeForVisibleWindow(\n sliceTimes,\n this.visibleFromMs,\n this.visibleToMs,\n );\n }\n if (!current) return;\n const next = {\n from: (current.from as number) + d,\n to: (current.to as number) + d,\n } as LogicalRange;\n this.syncing = true;\n for (const chart of this.charts) {\n chart.timeScale().setVisibleLogicalRange(next);\n }\n this.syncing = false;\n this.emit();\n }\n\n private syncFrom(source: IChartApi, range: LogicalRange) {\n this.syncing = true;\n for (const chart of this.charts) {\n if (chart !== source) {\n chart.timeScale().setVisibleLogicalRange(range);\n }\n }\n this.syncing = false;\n this.emit();\n }\n\n private emit(): void {\n const state: TransformState = {\n visibleFromMs: this.visibleFromMs,\n visibleToMs: this.visibleToMs,\n width: 0,\n height: 0,\n };\n for (const l of this.listeners) l(state);\n }\n}","import type { IChartApi } from 'lightweight-charts';\nimport { TimeScaleBus } from './time-scale-bus.js';\n\n/** Trim; empty / whitespace → independent pane (no cross-pane sync). */\nexport function normalizeSyncGroupId(id?: string | null): string | null {\n if (id == null) return null;\n const trimmed = String(id).trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport type PaneSyncKey = 'main' | 'volume' | 'indicator';\n\nconst INDEP_PREFIX = '@independent:';\n\nexport function independentBusKey(pane: PaneSyncKey): string {\n return `${INDEP_PREFIX}${pane}`;\n}\n\nexport function resolveBusMapKey(\n groupId: string | null | undefined,\n pane: PaneSyncKey,\n): string {\n const norm = normalizeSyncGroupId(groupId);\n return norm ?? independentBusKey(pane);\n}\n\nexport interface PaneSyncGroupPatch {\n main?: string | null;\n volume?: string | null;\n indicator?: string | null;\n}\n\n/**\n * One {@link TimeScaleBus} per sync group id; empty group id → per-pane independent bus.\n */\nexport class TimeScaleBusRegistry {\n private readonly buses = new Map<string, TimeScaleBus>();\n private readonly paneKeys = new Map<PaneSyncKey, string>();\n private activeKey: string;\n\n constructor() {\n for (const pane of ['main', 'volume', 'indicator'] as const) {\n const key = independentBusKey(pane);\n this.paneKeys.set(pane, key);\n this.getOrCreateBus(key);\n }\n this.activeKey = this.paneKeys.get('main')!;\n }\n\n getOrCreateBus(key: string): TimeScaleBus {\n let bus = this.buses.get(key);\n if (!bus) {\n bus = new TimeScaleBus();\n this.buses.set(key, bus);\n }\n return bus;\n }\n\n getBusKeyForPane(pane: PaneSyncKey): string {\n return this.paneKeys.get(pane)!;\n }\n\n getBusForPane(pane: PaneSyncKey): TimeScaleBus {\n return this.getOrCreateBus(this.getBusKeyForPane(pane));\n }\n\n /** Active bus for IChart viewport APIs (follows last-focused chart pane). */\n get activeBus(): TimeScaleBus {\n return this.getOrCreateBus(this.activeKey);\n }\n\n getActiveBusKey(): string {\n return this.activeKey;\n }\n\n setActivePane(pane: PaneSyncKey): void {\n this.activeKey = this.paneKeys.get(pane)!;\n }\n\n setPaneSyncGroup(pane: PaneSyncKey, groupId: string | null | undefined): string {\n const nextKey = resolveBusMapKey(groupId, pane);\n const prevKey = this.paneKeys.get(pane)!;\n this.paneKeys.set(pane, nextKey);\n this.getOrCreateBus(nextKey);\n if (this.activeKey === prevKey) this.activeKey = nextKey;\n return prevKey;\n }\n\n forEachBus(fn: (key: string, bus: TimeScaleBus) => void): void {\n for (const [key, bus] of this.buses) fn(key, bus);\n }\n\n moveChart(chart: IChartApi, fromKey: string, toKey: string, copyRange = true): void {\n if (fromKey === toKey) return;\n const from = this.getOrCreateBus(fromKey);\n const to = this.getOrCreateBus(toKey);\n const range = copyRange ? from.getVisibleRange() : null;\n from.unregister(chart);\n to.register(chart);\n if (range) to.setVisibleTimeRange(range);\n }\n}","import { intervalMs, type Interval } from '@coderyo/data';\n\n/**\n * Default horizontal bar spacing (px) per interval so candle width feels consistent\n * when the integrator controls how many bars are loaded / visible.\n */\nexport function defaultBarSpacingForInterval(interval: Interval): number {\n const ms = intervalMs(interval);\n if (ms <= 1_000) return 3;\n if (ms <= 5_000) return 4;\n if (ms <= 15_000) return 5;\n if (ms <= 30_000) return 6;\n if (ms <= 60_000) return 7;\n if (ms <= 300_000) return 8;\n if (ms <= 900_000) return 9;\n if (ms <= 3_600_000) return 10;\n if (ms <= 14_400_000) return 11;\n return 12;\n}\n\nexport function resolveBarSpacingForInterval(\n interval: Interval,\n overrides?: Partial<Record<Interval, number>>,\n): number {\n const custom = overrides?.[interval];\n if (custom != null && Number.isFinite(custom) && custom > 0) {\n return Math.min(24, Math.max(2, custom));\n }\n return defaultBarSpacingForInterval(interval);\n}","import type { Bar } from '@coderyo/data';\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - Math.pow(1 - t, 3);\n}\n\n/** Interpolate last candle OHLC toward target over `durationMs` (interrupts on new target). */\nexport class BarSmoothAnimator {\n private raf = 0;\n private start = 0;\n private from: Bar | null = null;\n private to: Bar | null = null;\n\n constructor(\n private durationMs: number,\n private readonly onFrame: (bar: Bar) => void,\n ) {}\n\n setDuration(ms: number): void {\n this.durationMs = ms;\n }\n\n animateTo(target: Bar, from?: Bar): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n const base = from ?? this.to ?? target;\n this.from = { ...base, t: target.t };\n this.to = { ...target };\n this.start = performance.now();\n\n const step = (now: number) => {\n const raw = Math.min(1, (now - this.start) / this.durationMs);\n const p = easeOutCubic(raw);\n const f = this.from!;\n const t = this.to!;\n const frame: Bar = {\n t: t.t,\n o: lerp(f.o, t.o, p),\n h: lerp(f.h, t.h, p),\n l: lerp(f.l, t.l, p),\n c: lerp(f.c, t.c, p),\n v: t.v,\n };\n this.onFrame(frame);\n if (raw < 1) {\n this.raf = requestAnimationFrame(step);\n } else {\n this.raf = 0;\n this.onFrame(t);\n }\n };\n this.raf = requestAnimationFrame(step);\n }\n\n cancel(): void {\n if (this.raf) cancelAnimationFrame(this.raf);\n this.raf = 0;\n }\n}"],"mappings":"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","names":["ColorType","createChart","HistogramSeries","LineSeries","intervalMs","intervalMs","bufferMs","DEFAULT_INDICATOR_CONFIG","hasVisibleIndicatorPanes","toUtcSeconds","createChart","LineSeries","HistogramSeries","hasVisibleIndicatorPanes","DEFAULT_INDICATOR_CONFIG","intervalMs","ColorType"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coderyo/renderer-lite",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {