@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 +53 -2
- package/dist/index.js +150 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
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"]}
|