@tradecanvas/chart 1.4.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +910 -858
  3. package/dist/Chart.d.ts +606 -23
  4. package/dist/Chart.d.ts.map +1 -1
  5. package/dist/DataManager.d.ts +5 -0
  6. package/dist/DataManager.d.ts.map +1 -1
  7. package/dist/HistoryPager.d.ts +58 -0
  8. package/dist/HistoryPager.d.ts.map +1 -0
  9. package/dist/LayoutSession-CTZB90NX.cjs +2 -0
  10. package/dist/LayoutSession-CTZB90NX.cjs.map +1 -0
  11. package/dist/LayoutSession-CWn3sdbs.js +3967 -0
  12. package/dist/LayoutSession-CWn3sdbs.js.map +1 -0
  13. package/dist/ThemeManager.d.ts +5 -1
  14. package/dist/ThemeManager.d.ts.map +1 -1
  15. package/dist/chartA11y.d.ts +59 -0
  16. package/dist/chartA11y.d.ts.map +1 -0
  17. package/dist/charts/ChartTypeStrategy.d.ts +5 -4
  18. package/dist/charts/ChartTypeStrategy.d.ts.map +1 -1
  19. package/dist/grid/ChartGrid.d.ts +6 -1
  20. package/dist/grid/ChartGrid.d.ts.map +1 -1
  21. package/dist/i18n-CiQ8EDVs.js +1469 -0
  22. package/dist/i18n-CiQ8EDVs.js.map +1 -0
  23. package/dist/i18n-WsLA9SmD.cjs +2 -0
  24. package/dist/i18n-WsLA9SmD.cjs.map +1 -0
  25. package/dist/index.cjs +1 -1
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +22 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +31 -31
  30. package/dist/index.js.map +1 -1
  31. package/dist/indicatorLabel.d.ts +7 -0
  32. package/dist/indicatorLabel.d.ts.map +1 -0
  33. package/dist/layout/LayoutManager.d.ts +50 -0
  34. package/dist/layout/LayoutManager.d.ts.map +1 -1
  35. package/dist/layout/priceAxisWidth.d.ts +2 -0
  36. package/dist/layout/priceAxisWidth.d.ts.map +1 -1
  37. package/dist/regularHours.d.ts +10 -0
  38. package/dist/regularHours.d.ts.map +1 -0
  39. package/dist/state/LayoutSession.d.ts +101 -0
  40. package/dist/state/LayoutSession.d.ts.map +1 -0
  41. package/dist/state/layoutStorage.d.ts +46 -0
  42. package/dist/state/layoutStorage.d.ts.map +1 -0
  43. package/dist/trading/wireExecution.d.ts +7 -3
  44. package/dist/trading/wireExecution.d.ts.map +1 -1
  45. package/dist/widget/ChartWidget.d.ts +219 -10
  46. package/dist/widget/ChartWidget.d.ts.map +1 -1
  47. package/dist/widget/ChartWidgetGrid.d.ts +166 -0
  48. package/dist/widget/ChartWidgetGrid.d.ts.map +1 -0
  49. package/dist/widget/DrawingTemplateStore.d.ts +29 -8
  50. package/dist/widget/DrawingTemplateStore.d.ts.map +1 -1
  51. package/dist/widget/WatchlistStore.d.ts +65 -0
  52. package/dist/widget/WatchlistStore.d.ts.map +1 -0
  53. package/dist/widget/WidgetAccountPanel.d.ts +72 -0
  54. package/dist/widget/WidgetAccountPanel.d.ts.map +1 -0
  55. package/dist/widget/WidgetAlertsPanel.d.ts +50 -3
  56. package/dist/widget/WidgetAlertsPanel.d.ts.map +1 -1
  57. package/dist/widget/WidgetBracketBar.d.ts +3 -1
  58. package/dist/widget/WidgetBracketBar.d.ts.map +1 -1
  59. package/dist/widget/WidgetChartNav.d.ts +36 -0
  60. package/dist/widget/WidgetChartNav.d.ts.map +1 -0
  61. package/dist/widget/WidgetCommandPalette.d.ts +3 -1
  62. package/dist/widget/WidgetCommandPalette.d.ts.map +1 -1
  63. package/dist/widget/WidgetContextMenu.d.ts +40 -0
  64. package/dist/widget/WidgetContextMenu.d.ts.map +1 -0
  65. package/dist/widget/WidgetDataWindow.d.ts +3 -1
  66. package/dist/widget/WidgetDataWindow.d.ts.map +1 -1
  67. package/dist/widget/WidgetDepthLadder.d.ts +3 -1
  68. package/dist/widget/WidgetDepthLadder.d.ts.map +1 -1
  69. package/dist/widget/WidgetDrawingSettings.d.ts +108 -0
  70. package/dist/widget/WidgetDrawingSettings.d.ts.map +1 -0
  71. package/dist/widget/WidgetDrawingSidebar.d.ts +14 -1
  72. package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
  73. package/dist/widget/WidgetDrawingStyle.d.ts +3 -1
  74. package/dist/widget/WidgetDrawingStyle.d.ts.map +1 -1
  75. package/dist/widget/WidgetDropdown.d.ts.map +1 -1
  76. package/dist/widget/WidgetGoToDate.d.ts +5 -4
  77. package/dist/widget/WidgetGoToDate.d.ts.map +1 -1
  78. package/dist/widget/WidgetHistoryPill.d.ts +23 -0
  79. package/dist/widget/WidgetHistoryPill.d.ts.map +1 -0
  80. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
  81. package/dist/widget/WidgetIndicatorLegend.d.ts +31 -1
  82. package/dist/widget/WidgetIndicatorLegend.d.ts.map +1 -1
  83. package/dist/widget/WidgetIndicatorSettings.d.ts +62 -7
  84. package/dist/widget/WidgetIndicatorSettings.d.ts.map +1 -1
  85. package/dist/widget/WidgetIntervalInput.d.ts +34 -0
  86. package/dist/widget/WidgetIntervalInput.d.ts.map +1 -0
  87. package/dist/widget/WidgetLayoutsDialog.d.ts +39 -0
  88. package/dist/widget/WidgetLayoutsDialog.d.ts.map +1 -0
  89. package/dist/widget/WidgetLayoutsUI.d.ts +37 -0
  90. package/dist/widget/WidgetLayoutsUI.d.ts.map +1 -0
  91. package/dist/widget/WidgetNamePrompt.d.ts +31 -0
  92. package/dist/widget/WidgetNamePrompt.d.ts.map +1 -0
  93. package/dist/widget/WidgetObjectTree.d.ts +21 -3
  94. package/dist/widget/WidgetObjectTree.d.ts.map +1 -1
  95. package/dist/widget/WidgetOrderTicket.d.ts +49 -0
  96. package/dist/widget/WidgetOrderTicket.d.ts.map +1 -0
  97. package/dist/widget/WidgetReplayBar.d.ts +15 -0
  98. package/dist/widget/WidgetReplayBar.d.ts.map +1 -1
  99. package/dist/widget/WidgetSettings.d.ts +13 -1
  100. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  101. package/dist/widget/WidgetStatusBar.d.ts +3 -0
  102. package/dist/widget/WidgetStatusBar.d.ts.map +1 -1
  103. package/dist/widget/WidgetStyles.d.ts +3 -1
  104. package/dist/widget/WidgetStyles.d.ts.map +1 -1
  105. package/dist/widget/WidgetSymbolInfo.d.ts +64 -0
  106. package/dist/widget/WidgetSymbolInfo.d.ts.map +1 -0
  107. package/dist/widget/WidgetSymbolSearch.d.ts +26 -5
  108. package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -1
  109. package/dist/widget/WidgetToolbar.d.ts +30 -1
  110. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  111. package/dist/widget/WidgetWatchlist.d.ts +53 -13
  112. package/dist/widget/WidgetWatchlist.d.ts.map +1 -1
  113. package/dist/widget/chartMenu.d.ts +40 -0
  114. package/dist/widget/chartMenu.d.ts.map +1 -0
  115. package/dist/widget/drawingMenu.d.ts +21 -0
  116. package/dist/widget/drawingMenu.d.ts.map +1 -0
  117. package/dist/widget/focusTrap.d.ts +8 -0
  118. package/dist/widget/focusTrap.d.ts.map +1 -0
  119. package/dist/widget/i18n.d.ts +20 -89
  120. package/dist/widget/i18n.d.ts.map +1 -1
  121. package/dist/widget/iconSet.d.ts.map +1 -1
  122. package/dist/widget/index.cjs +4294 -3028
  123. package/dist/widget/index.cjs.map +1 -1
  124. package/dist/widget/index.d.ts +15 -1
  125. package/dist/widget/index.d.ts.map +1 -1
  126. package/dist/widget/index.js +6326 -1185
  127. package/dist/widget/index.js.map +1 -1
  128. package/dist/widget/indicatorTemplates.d.ts +24 -0
  129. package/dist/widget/indicatorTemplates.d.ts.map +1 -0
  130. package/dist/widget/keyTarget.d.ts +11 -0
  131. package/dist/widget/keyTarget.d.ts.map +1 -0
  132. package/dist/widget/legendValues.d.ts +11 -6
  133. package/dist/widget/legendValues.d.ts.map +1 -1
  134. package/dist/widget/locales/ar.d.ts +4 -0
  135. package/dist/widget/locales/ar.d.ts.map +1 -0
  136. package/dist/widget/locales/de.d.ts +4 -0
  137. package/dist/widget/locales/de.d.ts.map +1 -0
  138. package/dist/widget/locales/en.d.ts +722 -0
  139. package/dist/widget/locales/en.d.ts.map +1 -0
  140. package/dist/widget/locales/es.d.ts +4 -0
  141. package/dist/widget/locales/es.d.ts.map +1 -0
  142. package/dist/widget/locales/fr.d.ts +4 -0
  143. package/dist/widget/locales/fr.d.ts.map +1 -0
  144. package/dist/widget/locales/he.d.ts +4 -0
  145. package/dist/widget/locales/he.d.ts.map +1 -0
  146. package/dist/widget/locales/id.d.ts +4 -0
  147. package/dist/widget/locales/id.d.ts.map +1 -0
  148. package/dist/widget/locales/index.cjs +2 -0
  149. package/dist/widget/locales/index.cjs.map +1 -0
  150. package/dist/widget/locales/index.d.ts +33 -0
  151. package/dist/widget/locales/index.d.ts.map +1 -0
  152. package/dist/widget/locales/index.js +10089 -0
  153. package/dist/widget/locales/index.js.map +1 -0
  154. package/dist/widget/locales/ja.d.ts +4 -0
  155. package/dist/widget/locales/ja.d.ts.map +1 -0
  156. package/dist/widget/locales/ko.d.ts +4 -0
  157. package/dist/widget/locales/ko.d.ts.map +1 -0
  158. package/dist/widget/locales/pt.d.ts +4 -0
  159. package/dist/widget/locales/pt.d.ts.map +1 -0
  160. package/dist/widget/locales/ru.d.ts +4 -0
  161. package/dist/widget/locales/ru.d.ts.map +1 -0
  162. package/dist/widget/locales/th.d.ts +4 -0
  163. package/dist/widget/locales/th.d.ts.map +1 -0
  164. package/dist/widget/locales/tr.d.ts +4 -0
  165. package/dist/widget/locales/tr.d.ts.map +1 -0
  166. package/dist/widget/locales/vi.d.ts +4 -0
  167. package/dist/widget/locales/vi.d.ts.map +1 -0
  168. package/dist/widget/locales/zh.d.ts +4 -0
  169. package/dist/widget/locales/zh.d.ts.map +1 -0
  170. package/dist/widget/locales/zhHant.d.ts +4 -0
  171. package/dist/widget/locales/zhHant.d.ts.map +1 -0
  172. package/dist/widget/orderTicket.d.ts +27 -0
  173. package/dist/widget/orderTicket.d.ts.map +1 -0
  174. package/dist/widget/settingsControls.d.ts +24 -0
  175. package/dist/widget/settingsControls.d.ts.map +1 -0
  176. package/dist/widget/types.d.ts +182 -6
  177. package/dist/widget/types.d.ts.map +1 -1
  178. package/dist/widget/widgetConfig.d.ts.map +1 -1
  179. package/dist/widget/widgetLayout.d.ts +22 -0
  180. package/dist/widget/widgetLayout.d.ts.map +1 -0
  181. package/dist/widget/widgetLocales.d.ts +17 -0
  182. package/dist/widget/widgetLocales.d.ts.map +1 -0
  183. package/dist/widget/widgetTimeframes.d.ts +8 -0
  184. package/dist/widget/widgetTimeframes.d.ts.map +1 -1
  185. package/dist/widget/widgetTimezones.d.ts +32 -0
  186. package/dist/widget/widgetTimezones.d.ts.map +1 -0
  187. package/dist/widget/widgetUI.d.ts +126 -0
  188. package/dist/widget/widgetUI.d.ts.map +1 -0
  189. package/package.json +8 -3
  190. package/dist/DragDropImporter-C5kgfbET.cjs +0 -2
  191. package/dist/DragDropImporter-C5kgfbET.cjs.map +0 -1
  192. package/dist/DragDropImporter-Dd9Mud5J.js +0 -2099
  193. package/dist/DragDropImporter-Dd9Mud5J.js.map +0 -1
  194. package/dist/charts/IndicatorPriceRange.d.ts +0 -20
  195. package/dist/charts/IndicatorPriceRange.d.ts.map +0 -1
@@ -1,2099 +0,0 @@
1
- import { DARK_THEME as e, DEFAULT_PANEL_HEIGHT as t, LIGHT_THEME as n, LayerType as r, MIN_PANEL_HEIGHT as i, PRICE_AXIS_WIDTH as a, TIME_AXIS_HEIGHT as o, autoPricePrecision as s, computePriceLimits as c, formatPrice as l, mergeBar as u, setLocale as d, timeframeToMs as f } from "@tradecanvas/commons";
2
- import { AlertDragHandler as p, AlertManager as m, Animator as ee, AreaRenderer as te, AxisDragHandler as ne, BarCountdown as re, BarRenderer as ie, BaselineRenderer as ae, CandlestickRenderer as h, ChartLegend as oe, ChartStateManager as g, CompareRenderer as se, CrosshairHandler as ce, CrosshairTooltip as le, CurrentPriceLine as ue, DataExporter as _, DepthHeatmapRenderer as de, DrawingManager as fe, DrawingRenderer as pe, EquivolumeRenderer as me, EventBus as he, GridRenderer as ge, HLCAreaRenderer as _e, HollowCandleRenderer as ve, IndicatorEngine as v, InteractionManager as ye, KagiRenderer as be, KeyboardHandler as xe, LineRenderer as Se, LineWithMarkersRenderer as Ce, MarketProfileRenderer as we, MeasureOverlay as Te, PanHandler as Ee, PaneResizeHandler as De, PeriodLevelsRenderer as Oe, PinnedTooltip as ke, PivotMarkersRenderer as Ae, PointAndFigureRenderer as je, PriceAxis as Me, RenderEngine as Ne, RenkoRenderer as y, ReplayManager as b, Screenshot as x, SelectionBoxOverlay as Pe, SessionBreaks as Fe, SessionShading as Ie, SignalMarkerManager as Le, StepLineRenderer as Re, StreamManager as ze, TimeAxis as Be, TradeZoneManager as Ve, TradingManager as He, TradingRenderer as Ue, UndoRedoManager as We, Viewport as Ge, VolumeCandleRenderer as Ke, VolumeProfileRenderer as qe, VolumeRenderer as Je, Watermark as Ye, ZoomHandler as Xe, barTimeStepMs as Ze, findDominantSwing as Qe, rangePresetStart as $e, registerBuiltInDrawingTools as et, registerBuiltInIndicators as S, timestampToBarIndex as C, toHeikinAshi as tt, toKagi as nt, toLineBreak as rt, toPointAndFigure as it, toRangeBars as at, toRenko as ot, xToBarIndex as st } from "@tradecanvas/core";
3
- //#region src/charts/ChartTypeStrategy.ts
4
- function ct(e) {
5
- switch (e) {
6
- case "candlestick":
7
- case "heikinAshi":
8
- case "lineBreak":
9
- case "rangeBars": return new h();
10
- case "line": return new Se();
11
- case "area": return new te();
12
- case "bar": return new ie();
13
- case "hollowCandle": return new ve();
14
- case "baseline": return new ae();
15
- case "renko": return new y();
16
- case "kagi": return new be();
17
- case "pointAndFigure": return new je();
18
- case "volumeCandles": return new Ke();
19
- case "equivolume": return new me();
20
- case "hlcArea": return new _e();
21
- case "stepLine": return new Re();
22
- case "lineWithMarkers": return new Ce();
23
- default: return new h();
24
- }
25
- }
26
- function lt(e, t) {
27
- if (t.length === 0) return t;
28
- switch (e) {
29
- case "heikinAshi": return tt(t);
30
- case "renko": return ot(t, {
31
- brickSize: 0,
32
- useATR: !0,
33
- atrPeriod: 14
34
- });
35
- case "lineBreak": return rt(t, 3);
36
- case "kagi": return nt(t, 4);
37
- case "pointAndFigure": return it(t, T(t) * .01, 3);
38
- case "rangeBars": return at(t, { rangeSize: T(t) * .005 });
39
- default: return t;
40
- }
41
- }
42
- function w(e) {
43
- switch (e) {
44
- case "heikinAshi":
45
- case "renko":
46
- case "lineBreak":
47
- case "kagi":
48
- case "pointAndFigure":
49
- case "rangeBars": return !0;
50
- default: return !1;
51
- }
52
- }
53
- function ut(e) {
54
- return e !== "heikinAshi" && w(e);
55
- }
56
- function T(e) {
57
- let t = 0;
58
- for (let n of e) t += n.close;
59
- return t / e.length;
60
- }
61
- function dt(e, t) {
62
- let n = t?.(e);
63
- return n ? n.createRenderer() : ct(e);
64
- }
65
- function ft(e, t, n) {
66
- if (t.length === 0) return t;
67
- let r = n?.(e);
68
- return r?.transform ? r.transform(t) : lt(e, t);
69
- }
70
- //#endregion
71
- //#region src/charts/IndicatorPriceRange.ts
72
- var E = {
73
- min: 0,
74
- max: 100
75
- }, D = .1;
76
- function pt(e, t, n) {
77
- if (!e) return { ...E };
78
- let r = Infinity, i = -Infinity;
79
- if (e.series) {
80
- let a = Math.min(n, e.series.length - 1);
81
- for (let n = Math.max(0, t); n <= a; n++) {
82
- let t = e.series[n];
83
- if (t) for (let e in t) {
84
- let n = t[e];
85
- n !== void 0 && Number.isFinite(n) && (n < r && (r = n), n > i && (i = n));
86
- }
87
- }
88
- } else {
89
- let a = 0;
90
- for (let [, o] of e.values) {
91
- if (a >= t && a <= n) for (let e in o) {
92
- let t = o[e];
93
- t !== void 0 && Number.isFinite(t) && (t < r && (r = t), t > i && (i = t));
94
- }
95
- a++;
96
- }
97
- }
98
- if (r === Infinity) return { ...E };
99
- let a = i - r || 1;
100
- return {
101
- min: r - a * D,
102
- max: i + a * D
103
- };
104
- }
105
- //#endregion
106
- //#region src/state/AutoSaveScheduler.ts
107
- var mt = class {
108
- timer = null;
109
- delayMs = 0;
110
- key = null;
111
- constructor(e) {
112
- this.save = e;
113
- }
114
- enable(e, t) {
115
- this.key = e, this.delayMs = t;
116
- }
117
- disable() {
118
- this.key = null, this.delayMs = 0, this.cancel();
119
- }
120
- schedule() {
121
- this.delayMs <= 0 || !this.key || (this.timer && clearTimeout(this.timer), this.timer = setTimeout(() => {
122
- this.timer = null, this.key && this.save(this.key);
123
- }, this.delayMs));
124
- }
125
- cancel() {
126
- this.timer &&= (clearTimeout(this.timer), null);
127
- }
128
- isEnabled() {
129
- return this.delayMs > 0 && this.key !== null;
130
- }
131
- hasPending() {
132
- return this.timer !== null;
133
- }
134
- };
135
- //#endregion
136
- //#region src/DataManager.ts
137
- function O(e) {
138
- if (!e || typeof e.time != "number") return !1;
139
- let { open: t, high: n, low: r, close: i } = e;
140
- return !(!isFinite(t) || !isFinite(n) || !isFinite(r) || !isFinite(i) || t < 0 || n < 0 || r < 0 || i < 0 || n < r || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0));
141
- }
142
- function ht(e) {
143
- return e.volume !== void 0 && e.high >= e.open && e.high >= e.close && e.low <= e.open && e.low <= e.close;
144
- }
145
- function k(e) {
146
- return {
147
- ...e,
148
- high: Math.max(e.open, e.high, e.low, e.close),
149
- low: Math.min(e.open, e.high, e.low, e.close),
150
- volume: e.volume === void 0 ? 0 : Math.max(0, e.volume)
151
- };
152
- }
153
- var A = class {
154
- data = [];
155
- getData() {
156
- return this.data;
157
- }
158
- setData(e) {
159
- let t = [];
160
- for (let n = 0; n < e.length; n++) {
161
- let r = e[n];
162
- O(r) && t.push(ht(r) ? r : k(r));
163
- }
164
- this.data = t;
165
- }
166
- appendBar(e) {
167
- O(e) && this.data.push(k(e));
168
- }
169
- updateLastBar(e) {
170
- if (!O(e)) return;
171
- let t = k(e);
172
- if (this.data.length === 0) {
173
- this.data.push(t);
174
- return;
175
- }
176
- this.data[this.data.length - 1] = t;
177
- }
178
- updateLastBarFromTick(e) {
179
- this.data.length !== 0 && (!isFinite(e.price) || e.price < 0 || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0) || (this.data[this.data.length - 1] = u(this.data[this.data.length - 1], e)));
180
- }
181
- getLength() {
182
- return this.data.length;
183
- }
184
- clear() {
185
- this.data = [];
186
- }
187
- }, j = class {
188
- theme;
189
- constructor(t) {
190
- !t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
191
- }
192
- getTheme() {
193
- return this.theme;
194
- }
195
- setTheme(t) {
196
- t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
197
- }
198
- }, M = 200, N = 80, P = class {
199
- panels = [];
200
- containerWidth = 0;
201
- containerHeight = 0;
202
- priceAxisWidth = a;
203
- resize(e, t) {
204
- this.containerWidth = e, this.containerHeight = t;
205
- }
206
- addPanel(e, n = "bottom", r) {
207
- let a = n === "left" || n === "right";
208
- this.panels.push({
209
- id: e,
210
- position: n,
211
- size: r ?? (a ? M : t),
212
- minSize: a ? N : i,
213
- content: {
214
- type: "indicator",
215
- indicatorInstanceId: e
216
- }
217
- });
218
- }
219
- removePanel(e) {
220
- this.panels = this.panels.filter((t) => t.id !== e);
221
- }
222
- setPanelPosition(e, n) {
223
- let r = this.panels.find((t) => t.id === e);
224
- if (r) {
225
- let e = r.position === "left" || r.position === "right", a = n === "left" || n === "right";
226
- r.position = n, e !== a && (r.size = a ? M : t, r.minSize = a ? N : i);
227
- }
228
- }
229
- setPanelSize(e, t) {
230
- let n = this.panels.find((t) => t.id === e);
231
- n && (n.size = Math.max(n.minSize, t));
232
- }
233
- setPriceAxisWidth(e) {
234
- this.priceAxisWidth = e;
235
- }
236
- getPanels() {
237
- return this.panels;
238
- }
239
- resolve() {
240
- let e = this.panels.filter((e) => e.position === "left"), t = this.panels.filter((e) => e.position === "right"), n = this.panels.filter((e) => e.position === "top"), r = this.panels.filter((e) => e.position === "bottom"), i = e.reduce((e, t) => e + t.size, 0), a = t.reduce((e, t) => e + t.size, 0), s = n.reduce((e, t) => e + t.size, 0), c = r.reduce((e, t) => e + t.size, 0), l = {
241
- x: i,
242
- y: s,
243
- width: Math.max(0, this.containerWidth - i - a - this.priceAxisWidth),
244
- height: Math.max(0, this.containerHeight - s - c - o)
245
- }, u = [], d = [], f = 0;
246
- for (let t of e) u.push({
247
- config: t,
248
- rect: {
249
- x: f,
250
- y: 0,
251
- width: t.size,
252
- height: this.containerHeight - o
253
- }
254
- }), d.push({
255
- panelId: t.id,
256
- rect: {
257
- x: f + t.size - 2,
258
- y: 0,
259
- width: 4,
260
- height: this.containerHeight
261
- },
262
- orientation: "vertical"
263
- }), f += t.size;
264
- let p = 0;
265
- for (let e of n) u.push({
266
- config: e,
267
- rect: {
268
- x: i,
269
- y: p,
270
- width: l.width,
271
- height: e.size
272
- }
273
- }), d.push({
274
- panelId: e.id,
275
- rect: {
276
- x: i,
277
- y: p + e.size - 2,
278
- width: l.width,
279
- height: 4
280
- },
281
- orientation: "horizontal"
282
- }), p += e.size;
283
- p = l.y + l.height;
284
- for (let e of r) u.push({
285
- config: e,
286
- rect: {
287
- x: i,
288
- y: p,
289
- width: l.width,
290
- height: e.size
291
- }
292
- }), d.push({
293
- panelId: e.id,
294
- rect: {
295
- x: i,
296
- y: p - 2,
297
- width: l.width,
298
- height: 4
299
- },
300
- orientation: "horizontal"
301
- }), p += e.size;
302
- f = i + l.width + this.priceAxisWidth;
303
- for (let e of t) u.push({
304
- config: e,
305
- rect: {
306
- x: f,
307
- y: 0,
308
- width: e.size,
309
- height: this.containerHeight - o
310
- }
311
- }), d.push({
312
- panelId: e.id,
313
- rect: {
314
- x: f - 2,
315
- y: 0,
316
- width: 4,
317
- height: this.containerHeight
318
- },
319
- orientation: "vertical"
320
- }), f += e.size;
321
- return {
322
- mainChartRect: l,
323
- panels: u,
324
- dividers: d
325
- };
326
- }
327
- getMainChartRect() {
328
- return this.resolve().mainChartRect;
329
- }
330
- }, gt = 14, _t = 14, vt = 22, F = 4;
331
- function yt(e) {
332
- let { min: t, max: n, lastPrice: r, locale: i, fontFamily: o, fontSizeSmall: c, measure: u } = e, d = s(t, n), f = e.tagPrecision ?? d, p = r === null ? [t, n] : [
333
- t,
334
- n,
335
- r
336
- ], m = a;
337
- for (let e of p) {
338
- if (!Number.isFinite(e)) continue;
339
- let t = l(e, d, i), n = l(e, f, i);
340
- m = Math.max(m, u(t, `500 ${c}px ${o}`) + gt, u(n, `bold 11px ${o}`) + _t, u(n, `600 ${c}px ${o}`) + vt);
341
- }
342
- return m <= a ? a : Math.ceil(m / F) * F;
343
- }
344
- function bt(e, t) {
345
- return t > e || t <= e - 12 ? t : e;
346
- }
347
- var xt = class {
348
- netY = 0;
349
- travelX = 0;
350
- engaged = !1;
351
- reset() {
352
- this.netY = 0, this.travelX = 0, this.engaged = !1;
353
- }
354
- step(e, t, n) {
355
- if (this.engaged) return !0;
356
- if (this.netY += t, this.travelX += Math.abs(e), !n) this.engaged = !0;
357
- else {
358
- let e = Math.abs(this.netY);
359
- this.engaged = e > 24 && e >= this.travelX * .5;
360
- }
361
- return this.engaged;
362
- }
363
- }, St = 1;
364
- function I(e, t) {
365
- return e.filter((e) => (e.descriptor.layer ?? "overlay") === t);
366
- }
367
- function L(e) {
368
- switch (e.kind) {
369
- case "indicator": return `indicator:${e.plugin.descriptor.id}`;
370
- case "drawing": return `drawing:${e.plugin.descriptor.type}`;
371
- case "chartType": return `chartType:${e.plugin.descriptor.type}`;
372
- case "overlay": return `overlay:${e.plugin.descriptor.id}`;
373
- }
374
- }
375
- //#endregion
376
- //#region src/plugins/registry.ts
377
- var R = /* @__PURE__ */ new Map();
378
- function Ct(e) {
379
- R.set(L(e), e);
380
- }
381
- function wt(e) {
382
- return R.delete(e);
383
- }
384
- function z() {
385
- return [...R.values()];
386
- }
387
- function Tt() {
388
- R.clear();
389
- }
390
- //#endregion
391
- //#region src/plugins/PluginManager.ts
392
- var B = class {
393
- plugins = /* @__PURE__ */ new Map();
394
- constructor(e, t = {}) {
395
- if (this.indicatorEngine = e, t.inheritGlobal !== !1) for (let e of z()) this.add(e);
396
- for (let e of t.plugins ?? []) this.add(e);
397
- }
398
- register(e) {
399
- this.add(e);
400
- }
401
- unregister(e) {
402
- return this.plugins.delete(e);
403
- }
404
- list() {
405
- return [...this.plugins.values()];
406
- }
407
- registerIndicator(e) {
408
- this.add({
409
- kind: "indicator",
410
- plugin: e
411
- });
412
- }
413
- getChartType(e) {
414
- let t = this.plugins.get(`chartType:${e}`);
415
- return t?.kind === "chartType" ? t.plugin : void 0;
416
- }
417
- getOverlays() {
418
- let e = [];
419
- for (let t of this.plugins.values()) t.kind === "overlay" && e.push(t.plugin);
420
- return e;
421
- }
422
- add(e) {
423
- this.plugins.set(L(e), e), e.kind === "indicator" && this.indicatorEngine.register(e.plugin);
424
- }
425
- }, V = {
426
- orderPlace: (e, t) => e.placeOrder(t),
427
- orderModify: (e, t) => e.modifyOrder(t),
428
- orderCancel: (e, t) => e.cancelOrder(t),
429
- positionModify: (e, t) => e.modifyPosition(t),
430
- positionClose: (e, t) => e.closePosition(t)
431
- };
432
- function Et(e, t) {
433
- let n = [], r = (e) => t.setOrders(e.data ?? []), i = (e) => t.setPositions(e.data ?? []), a = (e) => t.onError(e.data ?? { message: "Execution error" });
434
- e.on("orders", r), e.on("positions", i), e.on("error", a), n.push(() => e.off("orders", r), () => e.off("positions", i), () => e.off("error", a));
435
- for (let r of Object.keys(V)) {
436
- let i = V[r], a = t.onIntent(r, (n) => {
437
- Promise.resolve(i(e, n)).catch((e) => t.onError({
438
- message: `Execution command failed: ${r}`,
439
- cause: e
440
- }));
441
- });
442
- n.push(a);
443
- }
444
- return () => {
445
- for (let e of n) e();
446
- };
447
- }
448
- //#endregion
449
- //#region src/Chart.ts
450
- var Dt = 0xe8d4a51000, Ot = class {
451
- static version = "1.4.0";
452
- engine;
453
- viewport;
454
- dataManager;
455
- themeManager;
456
- layoutManager;
457
- pluginManager;
458
- indicatorEngine;
459
- drawingManager;
460
- drawingRenderer;
461
- tradingManager;
462
- tradingRenderer;
463
- eventBus;
464
- streamManager = null;
465
- executionAdapter = null;
466
- execTeardown = null;
467
- autoScrollOnNewBar = !0;
468
- displayDataCache = null;
469
- indicatorUpdateFrom = null;
470
- resolvedLayoutCache = null;
471
- panelInfoCache = null;
472
- renderScheduled = !1;
473
- priceAxisWidth = a;
474
- measureCtx;
475
- containerSizeCache = null;
476
- containerSizeCacheTime = 0;
477
- lastEmittedRange = null;
478
- lastEmittedPriceRange = null;
479
- lastEmittedBarWidth = null;
480
- chartLegend;
481
- watermark;
482
- barCountdown;
483
- unrestoredIndicators = [];
484
- displayTzOffset = null;
485
- sessionBreaks;
486
- sessionShading;
487
- compareRenderer;
488
- countdownInterval = null;
489
- volumeRenderer;
490
- volumeProfile;
491
- marketProfile;
492
- depthHeatmap;
493
- periodLevels;
494
- pivotMarkers;
495
- alertManager;
496
- signalMarkerManager;
497
- tradeZoneManager;
498
- measureOverlay;
499
- selectionBoxOverlay = new Pe();
500
- replayManager;
501
- replayBarUnsub = null;
502
- replaySeeking = !1;
503
- replaySession = null;
504
- undoRedoManager;
505
- autoSaveScheduler = new mt((e) => this.saveState(e));
506
- animator;
507
- crosshairTooltip;
508
- pinnedTooltip;
509
- interactionManager;
510
- crosshairHandler;
511
- chartRenderer;
512
- gridRenderer;
513
- priceAxis;
514
- timeAxis;
515
- options;
516
- features;
517
- marketConfig = null;
518
- container;
519
- currentPriceLine;
520
- numberLocale;
521
- marketPricePrecision = null;
522
- paneTitles = !0;
523
- defaultAutoScale;
524
- keyboardHandler = null;
525
- onWindowKeyDown = null;
526
- currentSymbol = "";
527
- constructor(e, t) {
528
- this.container = e, this.options = t, this.numberLocale = t.numberLocale ?? "en-US", this.defaultAutoScale = t.autoScale !== !1;
529
- let n = t.features ?? {};
530
- this.features = {
531
- drawings: n.drawings ?? !0,
532
- drawingTools: n.drawingTools ?? [],
533
- drawingMagnet: n.drawingMagnet ?? !0,
534
- drawingUndoRedo: n.drawingUndoRedo ?? !0,
535
- trading: n.trading ?? !0,
536
- tradingContextMenu: n.tradingContextMenu ?? !1,
537
- indicators: n.indicators ?? !0,
538
- indicatorIds: n.indicatorIds ?? [],
539
- panning: n.panning ?? !0,
540
- zooming: n.zooming ?? !0,
541
- crosshair: n.crosshair ?? !0,
542
- crosshairTooltip: n.crosshairTooltip ?? !0,
543
- keyboard: n.keyboard ?? !0,
544
- priceAxis: n.priceAxis ?? !0,
545
- timeAxis: n.timeAxis ?? !0,
546
- grid: n.grid ?? t.grid?.visible ?? !0,
547
- legend: n.legend ?? !0,
548
- volume: n.volume ?? !0,
549
- watermark: n.watermark ?? !0,
550
- saveLoad: n.saveLoad ?? !0,
551
- screenshot: n.screenshot ?? !0,
552
- alerts: n.alerts ?? !0,
553
- replay: n.replay ?? !0,
554
- sessionBreaks: n.sessionBreaks ?? !0,
555
- barCountdown: n.barCountdown ?? !0,
556
- compareSymbols: n.compareSymbols ?? !0,
557
- dataExport: n.dataExport ?? !0,
558
- logScale: n.logScale ?? !0,
559
- timeframes: n.timeframes ?? [],
560
- defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? []
561
- }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new A(), this.themeManager = new j(t.theme), this.layoutManager = new P(), this.indicatorEngine = new v(), this.pluginManager = new B(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new he(), S(this.indicatorEngine), this.drawingManager = new fe(), et(this.drawingManager), this.drawingRenderer = new pe(this.drawingManager), this.drawingManager.setRequestRender(() => {
562
- this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave();
563
- }), this.drawingManager.setEventCallback((e, t) => {
564
- this.eventBus.emit(e, t);
565
- }), this.drawingManager.setToolFilter((e) => this.features.drawings && (this.features.drawingTools.length === 0 || this.features.drawingTools.includes(e))), this.undoRedoManager = new We(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.features.drawingMagnet && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new He({
566
- enabled: this.features.trading,
567
- contextMenu: { enabled: this.features.tradingContextMenu }
568
- }), this.tradingRenderer = new Ue(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
569
- this.eventBus.emit(e, t);
570
- }), this.engine = new Ne(e);
571
- let i = this.engine.dprManager.getContainerSize();
572
- if (this.viewport = new Ge(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.viewport.setPanLimits({
573
- freePan: t.freePan ?? !0,
574
- minVisibleBars: t.panLimits?.minVisibleBars ?? 3
575
- }), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
576
- if (e.width <= 0 || e.height <= 0) return;
577
- let t = this.viewport.isAtEnd();
578
- this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t);
579
- }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new ge(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new Me(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new Be(), this.crosshairHandler = new ce(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
580
- if (e !== null && t) {
581
- let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0;
582
- this.chartLegend.setHoverBar(r ?? null);
583
- let i = this.viewport.getState(), a = t.y >= i.chartRect.y && t.y <= i.chartRect.y + i.chartRect.height;
584
- r && a && this.features.crosshairTooltip ? this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize(), {
585
- prevClose: e > 0 ? n[e - 1]?.close : void 0,
586
- priceRange: i.priceRange,
587
- plot: i.chartRect,
588
- barStepMs: Ze(n)
589
- }) : this.crosshairTooltip.hide(), this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", {
590
- point: t,
591
- bar: r,
592
- barIndex: e
593
- });
594
- } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null), this.eventBus.emit("crosshairLeave", {});
595
- }), this.chartLegend = new oe(), this.chartLegend.setChartType(t.chartType), this.chartLegend.setLocale(this.numberLocale), this.watermark = new Ye(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Je(), this.volumeProfile = new qe(), this.marketProfile = new we(), this.depthHeatmap = new de(), this.periodLevels = new Oe(), this.pivotMarkers = new Ae(), this.barCountdown = new re(), this.barCountdown.setVisible(this.features.barCountdown), this.sessionBreaks = new Fe(), this.sessionBreaks.setLocale(this.numberLocale), this.sessionShading = new Ie(), this.compareRenderer = new se(), t.sessionBreaks ? this.sessionBreaks.setConfig({
596
- visible: t.sessionBreaks.visible ?? !0,
597
- color: t.sessionBreaks.color,
598
- lineStyle: t.sessionBreaks.lineStyle,
599
- lineWidth: t.sessionBreaks.lineWidth
600
- }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.features.logScale && this.viewport.setLogScale(!0), this.animator = new ee(), this.crosshairTooltip = new le(), this.crosshairTooltip.create(e), this.crosshairTooltip.setLocale(this.numberLocale), this.pinnedTooltip = new ke(), this.pinnedTooltip.create(e), this.keyboardHandler = new xe({
601
- scrollBars: (e) => {
602
- let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
603
- this.viewport.scrollBy(e * t), this.updateViewportAndRender();
604
- },
605
- zoom: (e) => {
606
- let t = this.viewport.getState().chartRect.width;
607
- this.viewport.zoom(e, t / 2), this.updateViewportAndRender();
608
- },
609
- goToStart: () => {
610
- this.viewport.scrollBy(-Infinity), this.updateViewportAndRender();
611
- },
612
- goToEnd: () => {
613
- this.viewport.scrollToEnd(), this.updateViewportAndRender();
614
- },
615
- fitContent: () => this.fitContent()
616
- }), this.keyboardHandler.setEnabled(this.features.keyboard), this.onWindowKeyDown = (e) => {
617
- if (!this.keyboardHandler) return;
618
- let t = document.activeElement;
619
- t && t !== this.container && !this.container.contains(t) || t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable) || this.keyboardHandler.handleKey(e) && e.preventDefault();
620
- }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new ue(), this.currentPriceLine.setLocale(this.numberLocale), this.priceAxis.setReservedPriceProvider(() => this.currentPriceLine.isVisible() ? this.currentPriceLine.getPrice() : null), this.alertManager = new m(), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => {
621
- let t = {
622
- id: e.id,
623
- price: e.price,
624
- condition: e.condition,
625
- message: e.message,
626
- triggered: e.triggered
627
- };
628
- this.eventBus.emit("alertTriggered", t), this.eventBus.emit("dataUpdate", {
629
- alert: "triggered",
630
- alertId: e.id,
631
- price: e.price,
632
- message: e.message
633
- });
634
- }), this.alertManager.on("added", (e) => {
635
- this.eventBus.emit("alertAdd", {
636
- id: e.id,
637
- price: e.price,
638
- condition: e.condition,
639
- message: e.message,
640
- triggered: e.triggered
641
- });
642
- }), this.alertManager.on("removed", (e) => {
643
- this.eventBus.emit("alertRemove", { id: e });
644
- }), this.alertManager.on("updated", (e) => {
645
- this.eventBus.emit("alertUpdate", {
646
- id: e.id,
647
- price: e.price,
648
- condition: e.condition,
649
- message: e.message,
650
- triggered: e.triggered
651
- });
652
- }), this.signalMarkerManager = new Le(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
653
- this.eventBus.emit("signalMarkerAdd", {
654
- id: e.id,
655
- source: e.source,
656
- direction: e.direction
657
- });
658
- }), this.signalMarkerManager.on("removed", (e) => {
659
- this.eventBus.emit("signalMarkerRemove", { id: e });
660
- }), this.tradeZoneManager = new Ve(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
661
- this.eventBus.emit("tradeZoneAdd", {
662
- id: e.id,
663
- direction: e.direction
664
- });
665
- }), this.tradeZoneManager.on("removed", (e) => {
666
- this.eventBus.emit("tradeZoneRemove", { id: e });
667
- }), this.replayManager = new b(), this.measureOverlay = new Te(), this.interactionManager = new ye(e), this.features.panning) {
668
- let e = new xt();
669
- this.interactionManager.setPanHandler(new Ee((t, n) => {
670
- t && this.viewport.scrollBy(t), e.step(t, n, this.options.autoScale !== !1) && n && (this.options.autoScale = !1, this.viewport.panPriceRange(n)), this.updateViewportAndRender();
671
- }, () => e.reset()));
672
- }
673
- if (this.features.zooming) {
674
- this.interactionManager.setZoomHandler(new Xe((e, t) => {
675
- this.viewport.zoom(e, t), this.updateViewportAndRender();
676
- }));
677
- let e = new ne((e) => {
678
- this.options.autoScale = !1, this.viewport.scalePriceRange(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
679
- }, (e) => {
680
- let t = this.viewport.getState().chartRect.width;
681
- this.viewport.zoom(1 / e - 1, t / 2), this.updateViewportAndRender();
682
- });
683
- this.interactionManager.setAxisDragHandler(e, () => this.viewport.getState(), (e) => {
684
- e === "price" ? (this.options.autoScale = !0, this.updateViewportAndRender()) : this.fitContent();
685
- });
686
- }
687
- if (this.features.crosshair && this.interactionManager.setCrosshairHandler(this.crosshairHandler), this.features.drawings && this.interactionManager.setDrawingManager(this.drawingManager, () => ({
688
- ...this.viewport.getState(),
689
- data: this.getDisplayData()
690
- })), this.features.trading && this.interactionManager.setTradingManager(this.tradingManager, () => ({
691
- ...this.viewport.getState(),
692
- data: this.getDisplayData()
693
- })), this.features.alerts) {
694
- let e = new p(this.alertManager, () => this.viewport.getState());
695
- this.interactionManager.setAlertDragHandler(e);
696
- }
697
- let a = new De();
698
- a.configure(() => this.getResolvedLayout(), (e, t) => this.setPanelSize(e, t)), this.interactionManager.setPaneResizeHandler(a), this.interactionManager.setAltClickHandler((e) => {
699
- let t = this.getDisplayData();
700
- if (t.length === 0) return;
701
- let n = this.viewport.getState(), i = n.barWidth + n.barSpacing, a = Math.round((n.offset + e.x) / i);
702
- a < 0 || a >= t.length || (this.pinnedTooltip.isPinned() && this.pinnedTooltip.getPinnedIndex() === a ? this.pinnedTooltip.unpin() : this.pinnedTooltip.pin(t[a], a, this.themeManager.getTheme()), this.pinnedTooltip.reposition(this.viewport.getState(), this.dataManager.getData()[a] ?? null, a, this.themeManager.getTheme()), this.engine.requestRender(r.Overlay));
703
- }), this.interactionManager.setClickHandler((e) => {
704
- let t = this.getDisplayData();
705
- if (this.eventBus.emit("click", {
706
- x: e.x,
707
- y: e.y
708
- }), t.length === 0) return;
709
- let n = st(e.x, this.viewport.getState());
710
- n < 0 || n >= t.length || this.eventBus.emit("barClick", {
711
- bar: t[n],
712
- barIndex: n,
713
- point: e
714
- });
715
- }), this.interactionManager.setEscapeHandler(() => {
716
- if (this.features.trading && this.tradingManager.isBracketActive()) {
717
- this.tradingManager.cancelBracket(), this.eventBus.emit("dataUpdate", { bracket: "cancelled" });
718
- return;
719
- }
720
- this.pinnedTooltip.isPinned() && (this.pinnedTooltip.unpin(), this.engine.requestRender(r.Overlay));
721
- }), this.interactionManager.setConfirmHandler(() => this.features.trading && this.tradingManager.isBracketActive() ? (this.tradingManager.confirmBracket(), !0) : !1), this.interactionManager.setMeasureHandlers({
722
- begin: (e) => {
723
- this.measureOverlay.begin(e, this.viewport.getState(), this.getDisplayData());
724
- },
725
- move: (e) => {
726
- this.measureOverlay.update(e, this.viewport.getState(), this.getDisplayData());
727
- },
728
- end: () => {
729
- this.measureOverlay.end();
730
- }
731
- });
732
- let o = (e) => {
733
- let t = this.viewport.getState().chartRect;
734
- return {
735
- x: Math.max(t.x, Math.min(t.x + t.width, e.x)),
736
- y: Math.max(t.y, Math.min(t.y + t.height, e.y))
737
- };
738
- };
739
- this.interactionManager.setBoxSelectHandlers({
740
- begin: (e) => this.selectionBoxOverlay.begin(o(e)),
741
- move: (e) => this.selectionBoxOverlay.update(o(e)),
742
- end: () => {
743
- let e = this.selectionBoxOverlay.end();
744
- if (!e || !this.features.drawings) return;
745
- let t = {
746
- ...this.viewport.getState(),
747
- data: this.getDisplayData()
748
- };
749
- e.isClick ? this.drawingManager.toggleSelectionAt({
750
- x: e.x1,
751
- y: e.y1
752
- }, t) : this.drawingManager.selectInRect(e, t), this.engine.requestRender(r.Overlay);
753
- },
754
- cancel: () => this.selectionBoxOverlay.cancel()
755
- }), this.interactionManager.setOverlayDirtyCallback((e) => {
756
- this.engine.requestRender(e ? r.Hover : r.Overlay);
757
- }), this.interactionManager.attach(), this.syncRenderContext(), this.engine.start();
758
- }
759
- setData(e) {
760
- this.endReplaySession(), this.dataManager.setData(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.options.autoScale = this.defaultAutoScale, this.alertManager.clearLastValues(), this.recalcIndicators(this.dataManager.getData()), e.length > 0 && this.currentPriceLine.setPrice(e[e.length - 1].close), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: e.length });
761
- }
762
- appendBar(e) {
763
- if (this.replaySession) {
764
- this.replaySession.live.appendBar(e);
765
- return;
766
- }
767
- let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
768
- this.dataManager.appendBar(e);
769
- let n = this.dataManager.getData();
770
- this.crosshairHandler.setData(n), this.displayDataCache = null, this.recalcIndicatorsFrom(n, n.length - 2), this.updateViewportAndRender(t);
771
- }
772
- appendBars(e) {
773
- if (e.length === 0) return;
774
- if (this.replaySession) {
775
- for (let t of e) this.replaySession.live.appendBar(t);
776
- return;
777
- }
778
- let t = this.viewport.isAtEnd(), n = this.dataManager.getLength() - 1;
779
- for (let t of e) this.dataManager.appendBar(t);
780
- this.displayDataCache = null, this.recalcIndicatorsFrom(this.dataManager.getData(), n), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(t);
781
- }
782
- updateLastBar(e) {
783
- if (this.replaySession) {
784
- this.replaySession.live.updateLastBar(e);
785
- return;
786
- }
787
- this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null);
788
- let t = this.dataManager.getData();
789
- this.recalcIndicatorsFrom(t, t.length - 1), this.scheduleRender();
790
- }
791
- updateLastBarFromTick(e) {
792
- if (this.replaySession) {
793
- this.replaySession.live.updateLastBarFromTick(e), Number.isFinite(e.price) && (this.replaySession.price = { price: e.price });
794
- return;
795
- }
796
- this.dataManager.updateLastBarFromTick(e), this.currentPriceLine.setPrice(e.price), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null);
797
- let t = this.dataManager.getData();
798
- this.recalcIndicatorsFrom(t, t.length - 1), this.scheduleRender();
799
- }
800
- setChartType(e) {
801
- this.options.chartType = e, this.chartRenderer = this.createChartRenderer(e), this.chartLegend.setChartType(e), this.displayDataCache = null, this.updateViewportAndRender(!0);
802
- }
803
- addIndicator(e, t = {}, n = "bottom") {
804
- if (!this.features.indicators || this.features.indicatorIds.length > 0 && !this.features.indicatorIds.includes(e)) return null;
805
- let r = this.indicatorEngine.addIndicator(e, t, this.dataManager.getData());
806
- return this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e)?.placement === "panel" ? (this.layoutManager.addPanel(r, n), this.updateViewportAndRender()) : this.engine.requestRender(), this.eventBus.emit("indicatorAdd", {
807
- instanceId: r,
808
- id: e
809
- }), this.scheduleAutoSave(), r;
810
- }
811
- updateIndicator(e, t) {
812
- this.indicatorEngine.updateIndicator(e, t, this.dataManager.getData()), this.announceIndicatorUpdate(0), this.engine.requestRender(), this.scheduleAutoSave();
813
- }
814
- removeIndicator(e) {
815
- let t = this.layoutManager.getPanels().some((t) => t.id === e);
816
- this.indicatorEngine.removeIndicator(e), this.layoutManager.removePanel(e), this.eventBus.emit("indicatorRemove", { instanceId: e }), this.scheduleAutoSave(), t ? this.updateViewportAndRender() : this.engine.requestRender();
817
- }
818
- getIndicatorStyle(e) {
819
- return this.indicatorEngine.getIndicatorStyle(e);
820
- }
821
- getIndicatorOutput(e) {
822
- return this.indicatorEngine.getOutput(e);
823
- }
824
- registerIndicator(e) {
825
- this.pluginManager.registerIndicator(e);
826
- }
827
- get plugins() {
828
- return this.pluginManager;
829
- }
830
- static indicators() {
831
- let e = new v();
832
- return S(e), e.getAvailableIndicators();
833
- }
834
- setPanelPosition(e, t) {
835
- this.layoutManager.setPanelPosition(e, t), this.engine.requestRender();
836
- }
837
- setPanelSize(e, t) {
838
- this.layoutManager.setPanelSize(e, t), this.updateViewportAndRender(), this.eventBus.emit("paneResize", {
839
- instanceId: e,
840
- size: t
841
- });
842
- }
843
- getIndicatorPanes() {
844
- return this.buildPanelRenderInfos().map((e) => ({
845
- instanceId: e.instanceId,
846
- rect: { ...e.rect }
847
- }));
848
- }
849
- setPaneTitlesVisible(e) {
850
- this.paneTitles = e, this.engine.requestRender();
851
- }
852
- getLegendBottom() {
853
- let e = this.viewport.getState().chartRect.y;
854
- return this.features.legend ? e + this.chartLegend.getHeight() : e;
855
- }
856
- isTimeAligned() {
857
- return ut(this.options.chartType) ? !1 : this.getDisplayData().length === this.dataManager.getLength();
858
- }
859
- formatPrice(e) {
860
- let { min: t, max: n } = this.viewport.getState().priceRange;
861
- return l(e, this.marketPricePrecision ?? s(t, n), this.numberLocale);
862
- }
863
- setDrawingTool(e) {
864
- this.features.drawings && (e && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(e) || this.drawingManager.setActiveTool(e));
865
- }
866
- getDrawingTool() {
867
- return this.drawingManager.getActiveTool();
868
- }
869
- setStayInDrawingMode(e) {
870
- this.drawingManager.setStayInDrawingMode(e);
871
- }
872
- isStayInDrawingMode() {
873
- return this.drawingManager.isStayInDrawingMode();
874
- }
875
- copyDrawings() {
876
- return this.drawingManager.copySelection();
877
- }
878
- pasteDrawings() {
879
- return this.features.drawings ? this.drawingManager.paste() : [];
880
- }
881
- setDrawingStyle(e) {
882
- this.drawingManager.setStyle(e);
883
- }
884
- getDrawingStyle() {
885
- return this.drawingManager.getActiveStyle();
886
- }
887
- getSelectedDrawingId() {
888
- return this.drawingManager.getSelectedDrawingId();
889
- }
890
- setSelectedDrawingStyle(e, t) {
891
- return this.drawingManager.setSelectedDrawingStyle(e, t);
892
- }
893
- getDrawings() {
894
- return this.drawingManager.getDrawings();
895
- }
896
- setDrawings(e) {
897
- this.drawingManager.setDrawings(e);
898
- }
899
- addDrawing(e) {
900
- if (!this.features.drawings) return null;
901
- let t = this.drawingManager.addDrawing(e);
902
- return this.scheduleAutoSave(), t;
903
- }
904
- autoFib() {
905
- if (!this.features.drawings) return null;
906
- let e = this.getDisplayData(), t = this.viewport.getState(), n = Qe(e, t.visibleRange.from, t.visibleRange.to);
907
- return n ? this.addDrawing({
908
- type: "fibRetracement",
909
- anchors: [n[0], n[1]]
910
- }) : null;
911
- }
912
- removeDrawing(e) {
913
- this.drawingManager.removeDrawing(e);
914
- }
915
- setDrawingVisible(e, t) {
916
- this.drawingManager.setDrawingVisible(e, t);
917
- }
918
- setDrawingLocked(e, t) {
919
- this.drawingManager.setDrawingLocked(e, t);
920
- }
921
- clearDrawings() {
922
- this.drawingManager.clearDrawings();
923
- }
924
- registerDrawingTool(e) {
925
- this.drawingManager.register(e);
926
- }
927
- undo() {
928
- return this.features.drawingUndoRedo ? this.drawingManager.undo() : !1;
929
- }
930
- redo() {
931
- return this.features.drawingUndoRedo ? this.drawingManager.redo() : !1;
932
- }
933
- getUndoRedoState() {
934
- return this.undoRedoManager.getState();
935
- }
936
- setDrawingMagnet(e) {
937
- this.drawingManager.setMagnetMode(e && this.features.drawingMagnet ? "magnet" : "none");
938
- }
939
- getDrawingMagnet() {
940
- return this.drawingManager.getMagnetMode() === "magnet";
941
- }
942
- lockAllDrawings() {
943
- this.drawingManager.lockAllDrawings();
944
- }
945
- unlockAllDrawings() {
946
- this.drawingManager.unlockAllDrawings();
947
- }
948
- hideAllDrawings() {
949
- this.drawingManager.hideAllDrawings();
950
- }
951
- showAllDrawings() {
952
- this.drawingManager.showAllDrawings();
953
- }
954
- duplicateDrawing(e) {
955
- let t = e ?? this.drawingManager.getSelectedDrawingId();
956
- return t ? this.drawingManager.duplicateDrawing(t) : null;
957
- }
958
- exportVisibleData(e = "csv", t) {
959
- if (!this.features.dataExport) return;
960
- let n = this.viewport.getState(), r = this.dataManager.getData(), i = Math.max(0, n.visibleRange.from), a = Math.min(r.length - 1, n.visibleRange.to), o = r.slice(i, a + 1);
961
- if (e === "json") {
962
- let e = _.toJSON(o);
963
- _.download(e, t ?? "chart-data.json", "application/json");
964
- } else {
965
- let e = _.toCSV(o);
966
- _.download(e, t ?? "chart-data.csv", "text/csv");
967
- }
968
- }
969
- exportAllData(e = "csv", t) {
970
- if (!this.features.dataExport) return;
971
- let n = this.dataManager.getData();
972
- if (e === "json") {
973
- let e = _.toJSON(n);
974
- _.download(e, t ?? "chart-data.json", "application/json");
975
- } else {
976
- let e = _.toCSV(n);
977
- _.download(e, t ?? "chart-data.csv", "text/csv");
978
- }
979
- }
980
- setAutoSave(e, t = 5e3) {
981
- this.autoSaveScheduler.enable(e, t);
982
- }
983
- disableAutoSave() {
984
- this.autoSaveScheduler.disable();
985
- }
986
- scheduleAutoSave() {
987
- this.autoSaveScheduler.schedule();
988
- }
989
- getAvailableIndicators() {
990
- return this.indicatorEngine.getAvailableIndicators();
991
- }
992
- getIndicatorInputs(e) {
993
- let t = this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e);
994
- return t ? {
995
- id: t.id,
996
- params: t.defaultConfig
997
- } : null;
998
- }
999
- getActiveIndicators() {
1000
- return this.indicatorEngine.getActiveIndicators();
1001
- }
1002
- setIndicatorVisible(e, t) {
1003
- this.indicatorEngine.setVisible(e, t) !== null && (this.updateViewportAndRender(), this.scheduleAutoSave());
1004
- }
1005
- getIndicatorConfig(e) {
1006
- let t = this.indicatorEngine.getIndicatorConfig(e);
1007
- return t ? {
1008
- id: t.id,
1009
- params: { ...t.params }
1010
- } : null;
1011
- }
1012
- updateIndicatorStyle(e, t) {
1013
- this.indicatorEngine.updateIndicatorStyle(e, t), this.engine.requestRender(), this.scheduleAutoSave();
1014
- }
1015
- setOrders(e) {
1016
- this.features.trading && this.tradingManager.setOrders(e);
1017
- }
1018
- startBracket(e, t) {
1019
- if (!this.features.trading) return !1;
1020
- let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null);
1021
- return r === null ? !1 : (this.tradingManager.startBracket(e, r), !0);
1022
- }
1023
- cancelBracket() {
1024
- this.features.trading && this.tradingManager.cancelBracket();
1025
- }
1026
- confirmBracket() {
1027
- return this.features.trading ? this.tradingManager.confirmBracket() : !1;
1028
- }
1029
- isBracketActive() {
1030
- return this.features.trading && this.tradingManager.isBracketActive();
1031
- }
1032
- startOrderDraft(e, t) {
1033
- if (!this.features.trading) return !1;
1034
- let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null);
1035
- return r === null ? !1 : (this.tradingManager.startOrderDraft(e, r), !0);
1036
- }
1037
- cancelOrderDraft() {
1038
- this.features.trading && this.tradingManager.cancelOrderDraft();
1039
- }
1040
- confirmOrderDraft() {
1041
- return this.features.trading ? this.tradingManager.confirmOrderDraft() : !1;
1042
- }
1043
- isOrderDraftActive() {
1044
- return this.features.trading && this.tradingManager.isOrderDraftActive();
1045
- }
1046
- placeOrderIntent(e) {
1047
- this.features.trading && this.eventBus.emit("orderPlace", e);
1048
- }
1049
- setPositions(e) {
1050
- this.features.trading && this.tradingManager.setPositions(e);
1051
- }
1052
- setDepthData(e) {
1053
- this.features.trading && this.tradingManager.setDepthData(e);
1054
- }
1055
- setCurrentPrice(e, t) {
1056
- this.tradingManager.setCurrentPrice(e), this.replaySession ? this.replaySession.price = { price: e } : (this.currentPriceLine.setPrice(e), this.scheduleRender()), this.features.alerts && (this.alertManager.checkPrice(e), this.feedIndicatorAlerts());
1057
- }
1058
- feedIndicatorAlerts() {
1059
- let e = this.alertManager.getAlerts(), t = this.dataManager.getData();
1060
- if (t.length === 0) return;
1061
- let n = t.length - 1, r = /* @__PURE__ */ new Set();
1062
- for (let t of e) {
1063
- if (t.channel === "price" || r.has(t.channel)) continue;
1064
- r.add(t.channel);
1065
- let e = t.channel.indexOf(":");
1066
- if (e < 0) continue;
1067
- let i = t.channel.slice(0, e), a = t.channel.slice(e + 1), o = this.indicatorEngine.getOutput(i)?.series?.[n]?.[a];
1068
- typeof o == "number" && Number.isFinite(o) && this.alertManager.checkChannel(t.channel, o);
1069
- }
1070
- }
1071
- setTradingConfig(e) {
1072
- this.features.trading && this.tradingManager.setConfig(e);
1073
- }
1074
- async connect(e) {
1075
- this.replayStop(), this.disconnectStream(), this.streamManager = new ze(), this.streamManager.on("snapshot", (e) => {
1076
- if (this.replaySession) {
1077
- this.replaySession.live.setData(e);
1078
- return;
1079
- }
1080
- this.setData(e);
1081
- }), this.streamManager.on("barClose", (e) => {
1082
- if (this.replaySession) {
1083
- this.replaySession.live.appendBar(e);
1084
- return;
1085
- }
1086
- let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
1087
- this.dataManager.appendBar(e);
1088
- let n = this.dataManager.getData();
1089
- this.crosshairHandler.setData(n), this.displayDataCache = null, this.recalcIndicatorsFrom(n, n.length - 2), this.updateViewportAndRender(t);
1090
- }), this.streamManager.on("barUpdate", (e) => {
1091
- if (this.replaySession) {
1092
- this.replaySession.live.updateLastBar(e);
1093
- return;
1094
- }
1095
- this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close);
1096
- let t = this.dataManager.getData();
1097
- this.recalcIndicatorsFrom(t, t.length - 1), this.scheduleRender();
1098
- }), this.streamManager.on("priceChange", ({ price: e, previousClose: t }) => {
1099
- if (this.tradingManager.setCurrentPrice(e), this.replaySession) {
1100
- this.replaySession.price = {
1101
- price: e,
1102
- previousClose: t ?? void 0
1103
- };
1104
- return;
1105
- }
1106
- this.currentPriceLine.setPrice(e, t ?? void 0), this.engine.requestRender(r.Overlay);
1107
- }), this.streamManager.on("connectionChange", (e) => {
1108
- this.eventBus.emit("dataUpdate", { connection: e });
1109
- }), this.streamManager.on("error", (e) => {
1110
- this.eventBus.emit("dataUpdate", { error: e.message });
1111
- }), this.autoScrollOnNewBar = e.autoScroll !== !1, this.currentSymbol = e.symbol;
1112
- let t = this.streamManager;
1113
- if (await t.connect(e), this.streamManager !== t) return;
1114
- let n = f(e.timeframe);
1115
- this.barCountdown.setTimeframeMs(n), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => {
1116
- this.barCountdown.isVisible() && this.engine.requestRender(r.Hover);
1117
- }, 1e3);
1118
- }
1119
- async switchStream(e, t) {
1120
- this.streamManager && (this.currentSymbol = e, this.barCountdown.setTimeframeMs(f(t)), await this.streamManager.switchTo(e, t));
1121
- }
1122
- isTimeframeAllowed(e) {
1123
- let t = this.features.timeframes;
1124
- return t.length === 0 || t.includes(e);
1125
- }
1126
- async setTimeframe(e) {
1127
- if (!this.streamManager) throw Error("No active stream. Call connect() first.");
1128
- this.isTimeframeAllowed(e) && await this.switchStream(this.currentSymbol, e);
1129
- }
1130
- disconnectStream() {
1131
- this.streamManager &&= (this.streamManager.dispose(), null);
1132
- }
1133
- connectExecution(e, t = {}) {
1134
- if (!this.features.trading) throw Error("connectExecution requires features.trading to be enabled");
1135
- this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = Et(e, {
1136
- onIntent: (e, t) => {
1137
- let n = (e) => t(e.payload);
1138
- return this.eventBus.on(e, n), () => this.eventBus.off(e, n);
1139
- },
1140
- setOrders: (e) => this.setOrders(e),
1141
- setPositions: (e) => this.setPositions(e),
1142
- onError: (e) => this.eventBus.emit("executionError", e)
1143
- }), Promise.resolve(e.connect(t)).catch((e) => this.eventBus.emit("executionError", {
1144
- message: "Execution connect failed",
1145
- cause: e
1146
- }));
1147
- }
1148
- disconnectExecution() {
1149
- this.execTeardown &&= (this.execTeardown(), null), this.executionAdapter &&= (this.executionAdapter.disconnect(), null);
1150
- }
1151
- getExecutionAdapter() {
1152
- return this.executionAdapter;
1153
- }
1154
- setBarCountdownVisible(e) {
1155
- this.barCountdown.setVisible(e && this.features.barCountdown), this.engine.requestRender(r.Hover);
1156
- }
1157
- setSessionBreaksVisible(e) {
1158
- this.sessionBreaks.setVisible(e), this.engine.requestRender(r.Background);
1159
- }
1160
- addCompareSymbol(e, t, n, i) {
1161
- this.features.compareSymbols && (this.compareRenderer.addSymbol({
1162
- id: e,
1163
- label: t,
1164
- data: n,
1165
- color: i,
1166
- visible: !0
1167
- }), this.engine.requestRender(r.Main));
1168
- }
1169
- removeCompareSymbol(e) {
1170
- this.compareRenderer.removeSymbol(e), this.engine.requestRender(r.Main);
1171
- }
1172
- updateCompareData(e, t) {
1173
- this.compareRenderer.setSymbolData(e, t), this.engine.requestRender(r.Main);
1174
- }
1175
- setCompareMode(e) {
1176
- this.compareRenderer.setMode(e), this.engine.requestRender(r.Main);
1177
- }
1178
- clearCompareSymbols() {
1179
- this.compareRenderer.clear(), this.engine.requestRender(r.Main);
1180
- }
1181
- setLogScale(e) {
1182
- e && !this.features.logScale || (this.viewport.setLogScale(e), this.updateViewportAndRender());
1183
- }
1184
- isLogScale() {
1185
- return this.viewport.isLogScale();
1186
- }
1187
- setInvertScale(e) {
1188
- this.viewport.setInvertScale(e), this.updateViewportAndRender();
1189
- }
1190
- isInvertScale() {
1191
- return this.viewport.isInvertScale();
1192
- }
1193
- setScaleMode(e) {
1194
- e === "logarithmic" && !this.features.logScale || (this.viewport.setScaleMode(e), this.updateViewportAndRender());
1195
- }
1196
- getScaleMode() {
1197
- return this.viewport.getScaleMode();
1198
- }
1199
- setSessionBreaksConfig(e) {
1200
- this.sessionBreaks.setConfig(e), this.engine.requestRender(r.Background);
1201
- }
1202
- getConnectionState() {
1203
- return this.streamManager?.getConnectionState() ?? "disconnected";
1204
- }
1205
- getConnectionInfo() {
1206
- return this.streamManager?.getConnectionInfo() ?? { state: "disconnected" };
1207
- }
1208
- setAutoScroll(e) {
1209
- this.autoScrollOnNewBar = e;
1210
- }
1211
- scrollTo(e) {
1212
- let t = this.dataManager.getData();
1213
- for (let n = 0; n < t.length; n++) if (t[n].time >= e) {
1214
- let e = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
1215
- this.viewport.scrollBy(n * e - this.viewport.getState().offset), this.updateViewportAndRender();
1216
- return;
1217
- }
1218
- }
1219
- goToTime(e) {
1220
- let t = this.getDisplayData();
1221
- if (t.length === 0 || !Number.isFinite(e)) return -1;
1222
- let n = Math.max(0, Math.min(t.length - 1, Math.floor(C(e, t)))), r = this.viewport.getState(), i = n * (r.barWidth + r.barSpacing) + r.barWidth / 2 - r.chartRect.width / 2;
1223
- return this.viewport.scrollBy(i - r.offset), this.updateViewportAndRender(), n;
1224
- }
1225
- setVisibleRangePreset(e) {
1226
- let t = this.getDisplayData();
1227
- if (t.length === 0) return;
1228
- let n = t.length - 1, r = t[n].time > Dt ? 1 : 1e3, i = $e(e, t[n].time * r, this.displayTzOffset), a = i === null ? null : i / r;
1229
- if (a === null || a < t[0].time) {
1230
- this.fitContent();
1231
- return;
1232
- }
1233
- let o = Math.min(n, Math.floor(C(a, t)) + 1);
1234
- this.viewport.zoomToBarRange(o, n + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender();
1235
- }
1236
- scrollToEnd() {
1237
- this.viewport.scrollToEnd(), this.updateViewportAndRender();
1238
- }
1239
- setVisibleRange(e, t) {
1240
- let n = this.dataManager.getData();
1241
- if (n.length === 0) return;
1242
- let r = C(Math.min(e, t), n), i = C(Math.max(e, t), n);
1243
- this.viewport.zoomToBarRange(r, i), this.updateViewportAndRender();
1244
- }
1245
- setPanLimits(e) {
1246
- this.viewport.setPanLimits(e), this.updateViewportAndRender();
1247
- }
1248
- zoomIn() {
1249
- let e = this.viewport.getState().chartRect.width;
1250
- this.viewport.zoom(.2, e / 2), this.updateViewportAndRender();
1251
- }
1252
- zoomOut() {
1253
- let e = this.viewport.getState().chartRect.width;
1254
- this.viewport.zoom(-.2, e / 2), this.updateViewportAndRender();
1255
- }
1256
- fitContent() {
1257
- let e = this.dataManager.getLength();
1258
- e !== 0 && (this.viewport.zoomToBarRange(0, e - 1 + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender());
1259
- }
1260
- on(e, t) {
1261
- this.eventBus.on(e, t);
1262
- }
1263
- off(e, t) {
1264
- this.eventBus.off(e, t);
1265
- }
1266
- enableTauriBridge(e) {
1267
- this.eventBus.enableTauriBridge({
1268
- enabled: !0,
1269
- ...e
1270
- });
1271
- }
1272
- disableTauriBridge() {
1273
- this.eventBus.disableTauriBridge();
1274
- }
1275
- setTheme(e) {
1276
- this.themeManager.setTheme(e), this.syncRenderContext(), this.container.style.backgroundColor = this.themeManager.getTheme().background, this.engine.requestRender(), this.eventBus.emit("themeChange", { theme: e });
1277
- }
1278
- getTheme() {
1279
- return this.themeManager.getTheme();
1280
- }
1281
- setWatermark(e, t) {
1282
- this.watermark.setConfig({
1283
- text: e,
1284
- ...t
1285
- }), this.engine.requestRender(r.Background);
1286
- }
1287
- setAutoScale(e) {
1288
- this.options.autoScale = e, this.defaultAutoScale = e, this.updateViewportAndRender();
1289
- }
1290
- isAutoScale() {
1291
- return this.options.autoScale !== !1;
1292
- }
1293
- setCrosshairMode(e) {
1294
- this.crosshairHandler.setMode(e), this.engine.requestRender(r.Hover);
1295
- }
1296
- getCrosshairMode() {
1297
- return this.crosshairHandler.getMode();
1298
- }
1299
- setCrosshairPosition(e) {
1300
- e ? this.crosshairHandler.onPointerMove(e) : this.crosshairHandler.onPointerLeave(), this.engine.requestRender(r.Hover);
1301
- }
1302
- setCrosshairTime(e) {
1303
- let t = this.getDisplayData(), n = e === null || t.length === 0 ? null : Math.floor(C(e, t));
1304
- n !== this.crosshairHandler.getSyncedSlot() && (this.crosshairHandler.setSyncedSlot(n), this.engine.requestRender(r.Hover));
1305
- }
1306
- getData() {
1307
- return this.dataManager.getData();
1308
- }
1309
- setGridVisible(e) {
1310
- this.gridRenderer.setVisible(e), this.engine.requestRender(r.Background);
1311
- }
1312
- isGridVisible() {
1313
- return this.gridRenderer.isVisible();
1314
- }
1315
- setVolumeVisible(e) {
1316
- this.volumeRenderer.setVisible(e), this.engine.requestRender(r.Main);
1317
- }
1318
- setVolumeProfileVisible(e) {
1319
- this.volumeProfile.setVisible(e), this.engine.requestRender(r.Main);
1320
- }
1321
- isVolumeProfileVisible() {
1322
- return this.volumeProfile.isVisible();
1323
- }
1324
- setVolumeProfileConfig(e) {
1325
- e.buckets !== void 0 && this.volumeProfile.setBuckets(e.buckets), e.widthRatio !== void 0 && this.volumeProfile.setWidthRatio(e.widthRatio), e.opacity !== void 0 && this.volumeProfile.setOpacity(e.opacity), e.highlightPoC !== void 0 && this.volumeProfile.setHighlightPoC(e.highlightPoC), this.engine.requestRender(r.Main);
1326
- }
1327
- setMarketProfileVisible(e) {
1328
- this.marketProfile.setVisible(e), this.engine.requestRender(r.Main);
1329
- }
1330
- isMarketProfileVisible() {
1331
- return this.marketProfile.isVisible();
1332
- }
1333
- setMarketProfileConfig(e) {
1334
- e.buckets !== void 0 && this.marketProfile.setBuckets(e.buckets), e.widthRatio !== void 0 && this.marketProfile.setWidthRatio(e.widthRatio), e.opacity !== void 0 && this.marketProfile.setOpacity(e.opacity), e.valueAreaPct !== void 0 && this.marketProfile.setValueAreaPct(e.valueAreaPct), e.highlightPoC !== void 0 && this.marketProfile.setHighlightPoC(e.highlightPoC), e.showStats !== void 0 && this.marketProfile.setShowStats(e.showStats), e.splitBySession !== void 0 && this.marketProfile.setSplitBySession(e.splitBySession), e.letters !== void 0 && this.marketProfile.setLetters(e.letters), this.engine.requestRender(r.Main);
1335
- }
1336
- getMarketProfileStats() {
1337
- return this.marketProfile.getStats();
1338
- }
1339
- setDepthHeatmapVisible(e) {
1340
- this.depthHeatmap.setVisible(e), this.engine.requestRender(r.Main);
1341
- }
1342
- isDepthHeatmapVisible() {
1343
- return this.depthHeatmap.isVisible();
1344
- }
1345
- setDepthHeatmapConfig(e) {
1346
- e.opacity !== void 0 && this.depthHeatmap.setOpacity(e.opacity), e.capacity !== void 0 && this.depthHeatmap.setCapacity(e.capacity), this.engine.requestRender(r.Main);
1347
- }
1348
- pushDepthSnapshot(e) {
1349
- let t = this.dataManager.getData();
1350
- t.length !== 0 && (this.depthHeatmap.push(t[t.length - 1].time, e), this.depthHeatmap.isVisible() && this.engine.requestRender(r.Main));
1351
- }
1352
- clearDepthHeatmap() {
1353
- this.depthHeatmap.clear(), this.engine.requestRender(r.Main);
1354
- }
1355
- setPeriodLevelsVisible(e) {
1356
- this.periodLevels.setVisible(e), this.engine.requestRender(r.Main);
1357
- }
1358
- isPeriodLevelsVisible() {
1359
- return this.periodLevels.isVisible();
1360
- }
1361
- setPeriodLevelsPeriod(e) {
1362
- this.periodLevels.setPeriod(e), this.engine.requestRender(r.Main);
1363
- }
1364
- setTimezoneOffset(e) {
1365
- this.displayTzOffset = e, this.timeAxis.setTimezoneOffset(e), this.crosshairHandler.setTimezoneOffset(e), this.crosshairTooltip.setTimezoneOffset(e), this.engine.requestRender(r.UI);
1366
- }
1367
- setPivotMarkersVisible(e) {
1368
- this.pivotMarkers.setVisible(e), this.engine.requestRender(r.Overlay);
1369
- }
1370
- isPivotMarkersVisible() {
1371
- return this.pivotMarkers.isVisible();
1372
- }
1373
- setPivotMarkersConfig(e) {
1374
- (e.left !== void 0 || e.right !== void 0) && this.pivotMarkers.setStrength(e.left ?? 5, e.right ?? e.left ?? 5), e.showLabels !== void 0 && this.pivotMarkers.setShowLabels(e.showLabels), e.structureLabels !== void 0 && this.pivotMarkers.setStructureLabels(e.structureLabels), this.engine.requestRender(r.Overlay);
1375
- }
1376
- setSessionShadingVisible(e) {
1377
- this.sessionShading.setVisible(e), this.engine.requestRender(r.Background);
1378
- }
1379
- isSessionShadingVisible() {
1380
- return this.sessionShading.isVisible();
1381
- }
1382
- setSessionShadingConfig(e) {
1383
- this.sessionShading.setConfig(e), this.engine.requestRender(r.Background);
1384
- }
1385
- setTooltipVisible(e) {
1386
- e || this.crosshairTooltip.hide();
1387
- }
1388
- setLegend(e) {
1389
- this.chartLegend.setConfig(e), this.engine.requestRender(r.Hover);
1390
- }
1391
- setSymbolName(e) {
1392
- this.chartLegend.setSymbol(e), this.engine.requestRender(r.Hover);
1393
- }
1394
- setStatusText(e) {
1395
- this.chartLegend.setStatusText(e), this.engine.requestRender(r.Hover);
1396
- }
1397
- screenshot(e) {
1398
- this.features.screenshot && x.download(this.container, e, this.themeManager.getTheme().background);
1399
- }
1400
- async copyScreenshot() {
1401
- if (!this.features.screenshot) return !1;
1402
- try {
1403
- let e = await x.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1404
- return !e || !navigator.clipboard?.write || !t ? !1 : (await navigator.clipboard.write([new t({ "image/png": e })]), !0);
1405
- } catch {
1406
- return !1;
1407
- }
1408
- }
1409
- screenshotDataURL() {
1410
- return this.features.screenshot ? x.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1411
- }
1412
- async screenshotBlob() {
1413
- return this.features.screenshot ? x.toBlob(this.container, this.themeManager.getTheme().background) : null;
1414
- }
1415
- addAlert(e, t = "crossing", n, r = "price", i) {
1416
- if (!this.features.alerts) return null;
1417
- let a = this.alertManager.addAlert(e, t, n, !1, r, i);
1418
- return this.scheduleAutoSave(), a;
1419
- }
1420
- removeAlert(e) {
1421
- this.alertManager.removeAlert(e), this.scheduleAutoSave();
1422
- }
1423
- getAlerts() {
1424
- return this.alertManager.getAlerts();
1425
- }
1426
- clearAlerts() {
1427
- this.alertManager.clearAlerts(), this.scheduleAutoSave();
1428
- }
1429
- saveAlerts(e) {
1430
- this.alertManager.saveToStorage(e);
1431
- }
1432
- loadAlerts(e) {
1433
- this.alertManager.loadFromStorage(e), this.engine.requestRender(r.Overlay);
1434
- }
1435
- addSignalMarker(e) {
1436
- return this.signalMarkerManager.addMarker(e);
1437
- }
1438
- removeSignalMarker(e) {
1439
- this.signalMarkerManager.removeMarker(e);
1440
- }
1441
- getSignalMarkers() {
1442
- return this.signalMarkerManager.getMarkers();
1443
- }
1444
- setSignalMarkers(e) {
1445
- this.signalMarkerManager.setMarkers(e);
1446
- }
1447
- clearSignalMarkers() {
1448
- this.signalMarkerManager.clearMarkers();
1449
- }
1450
- setSignalMarkerStyle(e) {
1451
- this.signalMarkerManager.setStyle(e);
1452
- }
1453
- addTradeZone(e) {
1454
- return this.tradeZoneManager.addZone(e);
1455
- }
1456
- updateTradeZone(e, t) {
1457
- this.tradeZoneManager.updateZone(e, t);
1458
- }
1459
- removeTradeZone(e) {
1460
- this.tradeZoneManager.removeZone(e);
1461
- }
1462
- getTradeZones() {
1463
- return this.tradeZoneManager.getZones();
1464
- }
1465
- setTradeZones(e) {
1466
- this.tradeZoneManager.setZones(e);
1467
- }
1468
- clearTradeZones() {
1469
- this.tradeZoneManager.clearZones();
1470
- }
1471
- setTradeZoneStyle(e) {
1472
- this.tradeZoneManager.setStyle(e);
1473
- }
1474
- replayStart(e) {
1475
- if (!this.features.replay) return;
1476
- if (!this.replaySession) {
1477
- if (this.dataManager.getLength() === 0) return;
1478
- let e = new A();
1479
- e.setData(this.dataManager.getData()), this.replaySession = {
1480
- live: e,
1481
- price: null
1482
- };
1483
- }
1484
- let t = this.replaySession.live.getData().slice();
1485
- this.options.autoScale = !0, this.replayManager.load(t);
1486
- let n = -1;
1487
- this.replayBarUnsub?.(), this.replayBarUnsub = this.replayManager.on("bar", ({ bar: e, index: r }) => {
1488
- let i = r + 1, a = n > 0 && i > n && this.dataManager.getLength() === n, o = !(a && !this.replaySeeking) || this.autoScrollOnNewBar && this.viewport.isAtEnd();
1489
- if (a) {
1490
- for (let e = n; e < i; e++) this.dataManager.appendBar(t[e]);
1491
- this.recalcIndicatorsFrom(this.dataManager.getData(), n);
1492
- } else this.dataManager.setData(t.slice(0, i)), this.recalcIndicators(this.dataManager.getData());
1493
- n = i, this.currentPriceLine.setPrice(t[r].close, r > 0 ? t[r - 1].close : void 0), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.updateViewportAndRender(o);
1494
- }), this.replayManager.play(e);
1495
- }
1496
- replayPause() {
1497
- this.replayManager.pause();
1498
- }
1499
- replayResume() {
1500
- this.replayManager.resume();
1501
- }
1502
- replayStop() {
1503
- let e = this.replaySession;
1504
- this.endReplaySession(), e && (this.setData(e.live.getData()), e.price && this.currentPriceLine.setPrice(e.price.price, e.price.previousClose));
1505
- }
1506
- isReplayActive() {
1507
- return this.replaySession !== null;
1508
- }
1509
- getPlotRect() {
1510
- let { x: e, y: t, width: n, height: r } = this.viewport.getState().chartRect;
1511
- return {
1512
- x: e,
1513
- y: t,
1514
- width: n,
1515
- height: r
1516
- };
1517
- }
1518
- endReplaySession() {
1519
- this.replaySession && (this.replaySession = null, this.replayBarUnsub?.(), this.replayBarUnsub = null, this.replayManager.stop());
1520
- }
1521
- replaySeek(e) {
1522
- this.replaySeeking = !0;
1523
- try {
1524
- this.replayManager.seekTo(e);
1525
- } finally {
1526
- this.replaySeeking = !1;
1527
- }
1528
- }
1529
- setReplaySpeed(e) {
1530
- this.replayManager.setSpeed(e);
1531
- }
1532
- getReplayState() {
1533
- return this.replayManager.getState();
1534
- }
1535
- getReplayProgress() {
1536
- return this.replayManager.getProgress();
1537
- }
1538
- captureSnapshot() {
1539
- let e = this.layoutManager.getPanels();
1540
- return g.capture({
1541
- getDrawings: () => this.getDrawings(),
1542
- getTheme: () => this.getTheme(),
1543
- getAlerts: () => this.getAlerts(),
1544
- getIndicators: () => [...this.indicatorEngine.getActiveIndicators().map((t) => ({
1545
- id: t.id,
1546
- instanceId: t.instanceId,
1547
- params: t.params,
1548
- position: e.find((e) => e.id === t.instanceId)?.position,
1549
- style: this.indicatorEngine.getIndicatorStyle(t.instanceId) ?? void 0,
1550
- visible: t.visible
1551
- })), ...this.unrestoredIndicators]
1552
- }, {
1553
- chartType: this.options.chartType,
1554
- symbol: this.currentSymbol || void 0
1555
- });
1556
- }
1557
- saveState(e) {
1558
- if (!this.features.saveLoad) return null;
1559
- let t = this.captureSnapshot(), n = g.serialize(t);
1560
- return e && g.saveToStorage(e, t), n;
1561
- }
1562
- loadState(e) {
1563
- if (!this.features.saveLoad) return;
1564
- let t = g.deserialize(e);
1565
- t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme);
1566
- let n = /* @__PURE__ */ new Map();
1567
- if (t.version >= 2 && this.features.indicators) {
1568
- this.unrestoredIndicators = [];
1569
- let e = new Set(this.indicatorEngine.getAvailableIndicators().map((e) => e.id));
1570
- for (let e of this.indicatorEngine.getActiveIndicators()) this.removeIndicator(e.instanceId);
1571
- for (let r of t.indicators) {
1572
- let t = [
1573
- "top",
1574
- "bottom",
1575
- "left",
1576
- "right"
1577
- ].find((e) => e === r.position) ?? "bottom", i = null;
1578
- try {
1579
- if (!e.has(r.id)) throw Error("no such indicator is registered");
1580
- i = this.addIndicator(r.id, r.params, t);
1581
- } catch (e) {
1582
- console.warn(`Layout indicator "${r.id}" kept but not shown:`, e);
1583
- }
1584
- if (!i) {
1585
- this.unrestoredIndicators.push(r);
1586
- continue;
1587
- }
1588
- n.set(r.instanceId, i), r.style && this.updateIndicatorStyle(i, r.style), r.visible === !1 && this.setIndicatorVisible(i, !1);
1589
- }
1590
- }
1591
- if (t.alerts && this.features.alerts) {
1592
- this.alertManager.clearAlerts();
1593
- for (let e of t.alerts) {
1594
- if (e.triggered && !e.repeating) continue;
1595
- let t = e.channel.indexOf(":"), r = t > 0 ? n.get(e.channel.slice(0, t)) : void 0, i = r ? r + e.channel.slice(t) : e.channel;
1596
- this.alertManager.addAlert(e.price, e.condition, e.message, e.repeating, i, e.label);
1597
- }
1598
- }
1599
- this.scheduleAutoSave();
1600
- }
1601
- loadStateFromStorage(e) {
1602
- if (!this.features.saveLoad) return !1;
1603
- let t = g.loadFromStorage(e);
1604
- return t ? (this.loadState(g.serialize(t)), !0) : !1;
1605
- }
1606
- downloadState(e) {
1607
- this.features.saveLoad && g.downloadFile(this.captureSnapshot(), e);
1608
- }
1609
- async loadStateFromFile() {
1610
- if (!this.features.saveLoad) return;
1611
- let e = await g.loadFromFile();
1612
- this.loadState(g.serialize(e));
1613
- }
1614
- setLocale(e) {
1615
- d(e), this.engine.requestRender();
1616
- }
1617
- setNumberLocale(e) {
1618
- this.numberLocale = e, this.priceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.chartLegend.setLocale(e), this.crosshairTooltip.setLocale(e), this.sessionBreaks.setLocale(e), this.currentPriceLine.setLocale(e), this.updateViewportAndRender();
1619
- }
1620
- getNumberLocale() {
1621
- return this.numberLocale;
1622
- }
1623
- setMarket(e) {
1624
- if (this.marketConfig = e, e.colorScheme) {
1625
- let t = {
1626
- ...this.themeManager.getTheme(),
1627
- candleUp: e.colorScheme.up,
1628
- candleDown: e.colorScheme.down,
1629
- candleUpWick: e.colorScheme.up,
1630
- candleDownWick: e.colorScheme.down,
1631
- volumeUp: e.colorScheme.up.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.up}4D`,
1632
- volumeDown: e.colorScheme.down.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.down}4D`
1633
- };
1634
- this.themeManager.setTheme(t);
1635
- }
1636
- e.pricePrecision !== void 0 && (this.marketPricePrecision = e.pricePrecision, this.tradingManager.setConfig({ pricePrecision: e.pricePrecision }), this.alertManager.setPricePrecision(e.pricePrecision), this.streamManager?.priceLine.setPricePrecision(e.pricePrecision), this.currentPriceLine.setPricePrecision(e.pricePrecision), this.crosshairHandler.setPricePrecision(e.pricePrecision), this.chartLegend.setPricePrecision(e.pricePrecision), this.crosshairTooltip.setPricePrecision(e.pricePrecision)), this.updateViewportAndRender();
1637
- }
1638
- getMarket() {
1639
- return this.marketConfig;
1640
- }
1641
- setPriceLimits(e) {
1642
- this.marketConfig && (c(e, this.marketConfig) && (this.marketConfig.priceLimits = {
1643
- ...this.marketConfig.priceLimits,
1644
- referencePrice: e
1645
- }), this.engine.requestRender());
1646
- }
1647
- getFeatures() {
1648
- return this.features;
1649
- }
1650
- setFeatures(e) {
1651
- Object.assign(this.features, e), (e.crosshair === !1 || e.crosshairTooltip === !1) && this.crosshairTooltip.hide(), e.grid !== void 0 && this.engine.requestRender(r.Background), e.volume !== void 0 && (this.volumeRenderer.setVisible(e.volume), this.engine.requestRender(r.Main)), e.drawings === !1 && this.drawingManager.setActiveTool(null), e.trading === !1 && (this.tradingManager.setOrders([]), this.tradingManager.setPositions([])), e.keyboard !== void 0 && this.keyboardHandler?.setEnabled(e.keyboard), this.engine.requestRender();
1652
- }
1653
- resize() {
1654
- let e = this.engine.dprManager.readContainerSize();
1655
- if (e.width <= 0 || e.height <= 0) return;
1656
- this.containerSizeCache = e, this.containerSizeCacheTime = Date.now();
1657
- let t = this.engine.dprManager.getDpr();
1658
- this.engine.layerManager.resize(e, t);
1659
- let n = this.viewport.isAtEnd();
1660
- this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(n), this.eventBus.emit("resize", e);
1661
- }
1662
- destroy() {
1663
- this.countdownInterval && clearInterval(this.countdownInterval), this.disableAutoSave(), this.disconnectStream(), this.disconnectExecution(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = "";
1664
- }
1665
- createChartRenderer(e) {
1666
- return dt(e, (e) => this.pluginManager.getChartType(e));
1667
- }
1668
- getDisplayData() {
1669
- if (this.displayDataCache) return this.displayDataCache;
1670
- let e = this.dataManager.getData();
1671
- if (e.length === 0) return e;
1672
- let t = ft(this.options.chartType, e, (e) => this.pluginManager.getChartType(e));
1673
- return this.displayDataCache = t, t;
1674
- }
1675
- recalcIndicatorsFrom(e, t) {
1676
- this.indicatorEngine.recalculateFrom(e, t), this.announceIndicatorUpdate(t);
1677
- }
1678
- recalcIndicators(e) {
1679
- this.indicatorEngine.recalculateAll(e), this.announceIndicatorUpdate(0);
1680
- }
1681
- announceIndicatorUpdate(e) {
1682
- if (this.indicatorUpdateFrom !== null) {
1683
- this.indicatorUpdateFrom = Math.min(this.indicatorUpdateFrom, e);
1684
- return;
1685
- }
1686
- this.indicatorUpdateFrom = e, queueMicrotask(() => {
1687
- let e = this.indicatorUpdateFrom;
1688
- this.indicatorUpdateFrom = null, e !== null && this.eventBus.emit("indicatorUpdate", { from: e });
1689
- });
1690
- }
1691
- scheduleRender() {
1692
- this.renderScheduled || (this.renderScheduled = !0, requestAnimationFrame(() => {
1693
- this.renderScheduled = !1, this.applyDataToViewport(), this.fitPriceAxisWidth() && this.applyDataToViewport(), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1694
- }));
1695
- }
1696
- applyDataToViewport(e = !1) {
1697
- let t = this.getDisplayData(), n = this.options.autoScale !== !1;
1698
- this.viewport.updateData(t, n && !e), e && (this.viewport.scrollToEnd(), n && this.viewport.updateData(t, !0));
1699
- let r = this.viewport.getState();
1700
- if (t.length > 0) {
1701
- let e = Math.max(0, Math.min(r.visibleRange.from, t.length - 1));
1702
- this.viewport.setScaleBaseline(t[e]?.close);
1703
- }
1704
- if (n) {
1705
- let e = this.indicatorEngine.getOverlayPriceRange(r.visibleRange.from, Math.min(r.visibleRange.to, t.length - 1));
1706
- if (e) {
1707
- let t = r.priceRange, n = Math.min(t.min, e.min), i = Math.max(t.max, e.max);
1708
- if (n < t.min || i > t.max) {
1709
- let e = i - n || 1;
1710
- this.viewport.setPriceRange(n - e * .02, i + e * .02);
1711
- }
1712
- }
1713
- }
1714
- return t;
1715
- }
1716
- updateViewportAndRender(e = !1) {
1717
- this.resolvedLayoutCache = null, this.panelInfoCache = null;
1718
- let t = this.getResolvedLayout();
1719
- this.viewport.setChartRect(t.mainChartRect), this.applyDataToViewport(e), this.fitPriceAxisWidth() && this.applyDataToViewport(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1720
- }
1721
- fitPriceAxisWidth() {
1722
- if (!this.features.priceAxis) return !1;
1723
- let { priceRange: e } = this.viewport.getState(), t = this.themeManager.getTheme(), n = yt({
1724
- min: e.min,
1725
- max: e.max,
1726
- lastPrice: this.currentPriceLine.getPrice(),
1727
- tagPrecision: this.marketConfig?.pricePrecision ?? null,
1728
- locale: this.numberLocale,
1729
- fontFamily: t.font.family,
1730
- fontSizeSmall: t.font.sizeSmall,
1731
- measure: (e, t) => this.measureText(e, t)
1732
- }), r = bt(this.priceAxisWidth, n);
1733
- return r === this.priceAxisWidth ? !1 : (this.priceAxisWidth = r, this.layoutManager.setPriceAxisWidth(r), this.viewport.setPriceAxisWidth(r), this.resolvedLayoutCache = null, this.panelInfoCache = null, this.viewport.setChartRect(this.getResolvedLayout().mainChartRect), !0);
1734
- }
1735
- measureText(e, t) {
1736
- this.measureCtx === void 0 && (this.measureCtx = typeof document < "u" ? document.createElement("canvas").getContext("2d") : null);
1737
- let n = this.measureCtx;
1738
- return n ? (n.font = t, n.measureText(e).width) : e.length * 7;
1739
- }
1740
- emitViewportEvents() {
1741
- let e = this.viewport.getState(), t = Math.max(0, Math.floor(e.visibleRange.from)), n = Math.max(t, Math.ceil(e.visibleRange.to));
1742
- (!this.lastEmittedRange || this.lastEmittedRange.from !== t || this.lastEmittedRange.to !== n) && (this.lastEmittedRange = {
1743
- from: t,
1744
- to: n
1745
- }, this.eventBus.emit("visibleRangeChange", {
1746
- from: t,
1747
- to: n
1748
- }));
1749
- let { min: r, max: i } = e.priceRange;
1750
- (!this.lastEmittedPriceRange || this.lastEmittedPriceRange.min !== r || this.lastEmittedPriceRange.max !== i) && (this.lastEmittedPriceRange = {
1751
- min: r,
1752
- max: i
1753
- }, this.eventBus.emit("priceRangeChange", {
1754
- min: r,
1755
- max: i
1756
- })), this.lastEmittedBarWidth !== e.barWidth && (this.lastEmittedBarWidth = e.barWidth, this.eventBus.emit("zoomChange", { barWidth: e.barWidth }));
1757
- }
1758
- getResolvedLayout() {
1759
- return this.resolvedLayoutCache || (this.resolvedLayoutCache = this.layoutManager.resolve(), this.syncCrosshairBounds(this.resolvedLayoutCache)), this.resolvedLayoutCache;
1760
- }
1761
- syncCrosshairBounds(e) {
1762
- let t = e.mainChartRect, n = t.y, r = t.y + t.height;
1763
- for (let t of e.panels) t.config.position !== "top" && t.config.position !== "bottom" || (n = Math.min(n, t.rect.y), r = Math.max(r, t.rect.y + t.rect.height));
1764
- this.crosshairHandler.setReportBounds({
1765
- top: n,
1766
- bottom: r
1767
- });
1768
- }
1769
- cachedContainerSize() {
1770
- let e = Date.now();
1771
- return (!this.containerSizeCache || e - this.containerSizeCacheTime > 500) && (this.containerSizeCache = this.engine.dprManager.getContainerSize(), this.containerSizeCacheTime = e), this.containerSizeCache;
1772
- }
1773
- buildPanelRenderInfos() {
1774
- if (this.panelInfoCache) return this.panelInfoCache;
1775
- let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => {
1776
- let i = pt(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1777
- x: e.rect.x,
1778
- y: e.rect.y + 20,
1779
- width: e.rect.width,
1780
- height: Math.max(0, e.rect.height - 20)
1781
- };
1782
- return {
1783
- instanceId: e.config.id,
1784
- rect: e.rect,
1785
- viewport: {
1786
- ...t,
1787
- chartRect: a,
1788
- priceRange: i,
1789
- logScale: !1,
1790
- scaleMode: "regular",
1791
- invertScale: !1
1792
- }
1793
- };
1794
- });
1795
- return this.panelInfoCache = i, i;
1796
- }
1797
- syncRenderContext() {
1798
- this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), null, null, this.themeManager.getTheme());
1799
- let e = this.getResolvedLayout(), t = this.features.indicators ? this.buildPanelRenderInfos() : [], n = e.panels.filter((e) => e.config.position === "bottom").reduce((e, t) => e + t.rect.height, 0), r = e.mainChartRect.y + e.mainChartRect.height + n, i = this.getDisplayData();
1800
- this.engine.setRenderContext({
1801
- chartRenderer: this.chartRenderer,
1802
- gridRenderer: this.features.grid ? this.gridRenderer : null,
1803
- priceAxis: this.features.priceAxis ? this.priceAxis : null,
1804
- timeAxis: this.features.timeAxis ? this.timeAxis : null,
1805
- crosshairHandler: this.features.crosshair ? this.crosshairHandler : null,
1806
- indicatorEngine: this.features.indicators ? this.indicatorEngine : null,
1807
- drawingRenderer: this.features.drawings ? this.drawingRenderer : null,
1808
- tradingRenderer: this.features.trading ? this.tradingRenderer : null,
1809
- currentPriceLine: this.currentPriceLine,
1810
- chartLegend: this.features.legend ? this.chartLegend : null,
1811
- volumeRenderer: this.features.volume ? this.volumeRenderer : null,
1812
- volumeProfile: this.volumeProfile,
1813
- marketProfile: this.marketProfile,
1814
- depthHeatmap: this.depthHeatmap,
1815
- periodLevels: this.periodLevels,
1816
- pivotMarkers: this.pivotMarkers,
1817
- watermark: this.features.watermark ? this.watermark : null,
1818
- barCountdown: this.barCountdown,
1819
- sessionBreaks: this.sessionBreaks,
1820
- sessionShading: this.sessionShading,
1821
- compareRenderer: this.compareRenderer,
1822
- alertManager: this.features.alerts ? this.alertManager : null,
1823
- measureOverlay: this.measureOverlay,
1824
- selectionBoxOverlay: this.selectionBoxOverlay,
1825
- signalMarkerManager: this.signalMarkerManager,
1826
- tradeZoneManager: this.tradeZoneManager,
1827
- panels: t,
1828
- priceLimits: this.buildPriceLimits(),
1829
- timeAxisY: r,
1830
- viewport: {
1831
- ...this.viewport.getState(),
1832
- data: i
1833
- },
1834
- theme: this.themeManager.getTheme(),
1835
- data: i,
1836
- numberLocale: this.numberLocale,
1837
- paneTitles: this.paneTitles,
1838
- renderOverlayPlugins: (e, t) => this.drawOverlayPlugins(e, t)
1839
- });
1840
- }
1841
- drawOverlayPlugins(e, t) {
1842
- let n = I(this.pluginManager.getOverlays(), t);
1843
- if (n.length === 0) return;
1844
- let r = {
1845
- viewport: this.viewport.getState(),
1846
- data: this.getDisplayData(),
1847
- theme: this.themeManager.getTheme()
1848
- };
1849
- for (let t of n) t.render(e, r);
1850
- }
1851
- buildPriceLimits() {
1852
- if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null;
1853
- let e = c(this.marketConfig.priceLimits.referencePrice, this.marketConfig);
1854
- return e ? {
1855
- ...e,
1856
- colors: this.marketConfig.colorScheme ? {
1857
- ceiling: this.marketConfig.colorScheme.ceiling,
1858
- floor: this.marketConfig.colorScheme.floor,
1859
- reference: this.marketConfig.colorScheme.reference
1860
- } : void 0
1861
- } : null;
1862
- }
1863
- }, H = [
1864
- "time",
1865
- "timestamp",
1866
- "date",
1867
- "datetime",
1868
- "t"
1869
- ], U = ["open", "o"], W = ["high", "h"], G = ["low", "l"], K = ["close", "c"], q = [
1870
- "volume",
1871
- "vol",
1872
- "v"
1873
- ];
1874
- function J(e) {
1875
- let t = e.trim();
1876
- return t ? t[0] === "[" || t[0] === "{" ? kt(t) : At(t) : {
1877
- data: [],
1878
- rowCount: 0,
1879
- skipped: 0
1880
- };
1881
- }
1882
- function kt(e) {
1883
- let t;
1884
- try {
1885
- t = JSON.parse(e);
1886
- } catch (e) {
1887
- throw Error(`Invalid JSON: ${e.message}`);
1888
- }
1889
- if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows");
1890
- let n = [], r = 0;
1891
- for (let e of t) {
1892
- let t = Array.isArray(e) ? Pt(e) : Nt(e);
1893
- t ? n.push(t) : r++;
1894
- }
1895
- return Q(n, t.length, r);
1896
- }
1897
- function At(e) {
1898
- let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0);
1899
- if (t.length === 0) return {
1900
- data: [],
1901
- rowCount: 0,
1902
- skipped: 0
1903
- };
1904
- let n = jt(t[0]), r = Y(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? Mt(r) : {
1905
- time: 0,
1906
- open: 1,
1907
- high: 2,
1908
- low: 3,
1909
- close: 4,
1910
- volume: 5
1911
- };
1912
- if (a.time < 0 || a.open < 0 || a.high < 0 || a.low < 0 || a.close < 0) throw Error("CSV is missing required column(s): time, open, high, low, close");
1913
- let o = [], s = 0;
1914
- for (let e = +!!i; e < t.length; e++) {
1915
- let r = Y(t[e], n), i = Z(r[a.time]), c = X(r[a.open]), l = X(r[a.high]), u = X(r[a.low]), d = X(r[a.close]), f = a.volume >= 0 ? Number(r[a.volume]) : 0;
1916
- if (i === null || ![
1917
- c,
1918
- l,
1919
- u,
1920
- d
1921
- ].every(Number.isFinite)) {
1922
- s++;
1923
- continue;
1924
- }
1925
- o.push({
1926
- time: i,
1927
- open: c,
1928
- high: l,
1929
- low: u,
1930
- close: d,
1931
- volume: Number.isFinite(f) ? f : 0
1932
- });
1933
- }
1934
- return Q(o, t.length - +!!i, s);
1935
- }
1936
- function jt(e) {
1937
- let t = {
1938
- ",": 0,
1939
- ";": 0,
1940
- " ": 0,
1941
- "|": 0
1942
- };
1943
- for (let n of e) n in t && t[n]++;
1944
- let n = ",", r = 0;
1945
- for (let [e, i] of Object.entries(t)) i > r && (n = e, r = i);
1946
- return n;
1947
- }
1948
- function Y(e, t) {
1949
- let n = [], r = "", i = !1;
1950
- for (let a = 0; a < e.length; a++) {
1951
- let o = e[a];
1952
- o === "\"" ? i && e[a + 1] === "\"" ? (r += "\"", a++) : i = !i : o === t && !i ? (n.push(r), r = "") : r += o;
1953
- }
1954
- return n.push(r), n;
1955
- }
1956
- function Mt(e) {
1957
- let t = (t) => e.findIndex((e) => t.includes(e));
1958
- return {
1959
- time: t(H),
1960
- open: t(U),
1961
- high: t(W),
1962
- low: t(G),
1963
- close: t(K),
1964
- volume: t(q)
1965
- };
1966
- }
1967
- function Nt(e) {
1968
- let t = (t) => {
1969
- for (let n of t) {
1970
- if (e[n] !== void 0) return e[n];
1971
- let t = n.toUpperCase();
1972
- if (e[t] !== void 0) return e[t];
1973
- }
1974
- }, n = Z(String(t(H) ?? "")), r = Number(t(U)), i = Number(t(W)), a = Number(t(G)), o = Number(t(K)), s = Number(t(q) ?? 0);
1975
- return n === null || ![
1976
- r,
1977
- i,
1978
- a,
1979
- o
1980
- ].every(Number.isFinite) ? null : {
1981
- time: n,
1982
- open: r,
1983
- high: i,
1984
- low: a,
1985
- close: o,
1986
- volume: Number.isFinite(s) ? s : 0
1987
- };
1988
- }
1989
- function Pt(e) {
1990
- if (e.length < 5) return null;
1991
- let t = Z(String(e[0])), n = Number(e[1]), r = Number(e[2]), i = Number(e[3]), a = Number(e[4]), o = e.length >= 6 ? Number(e[5]) : 0;
1992
- return t === null || ![
1993
- n,
1994
- r,
1995
- i,
1996
- a
1997
- ].every(Number.isFinite) ? null : {
1998
- time: t,
1999
- open: n,
2000
- high: r,
2001
- low: i,
2002
- close: a,
2003
- volume: Number.isFinite(o) ? o : 0
2004
- };
2005
- }
2006
- function X(e) {
2007
- return e === void 0 || e.trim() === "" ? NaN : Number(e);
2008
- }
2009
- function Z(e) {
2010
- let t = e.trim();
2011
- if (!t) return null;
2012
- let n = Number(t);
2013
- if (Number.isFinite(n) && n > 0) return n < 0xe8d4a51000 ? n * 1e3 : n;
2014
- let r = Date.parse(t);
2015
- return Number.isFinite(r) ? r : null;
2016
- }
2017
- function Q(e, t, n) {
2018
- e.sort((e, t) => e.time - t.time);
2019
- let r = [];
2020
- for (let t of e) r.length > 0 && r[r.length - 1].time === t.time ? r[r.length - 1] = t : r.push(t);
2021
- return {
2022
- data: r,
2023
- rowCount: t,
2024
- skipped: n
2025
- };
2026
- }
2027
- //#endregion
2028
- //#region src/io/DragDropImporter.ts
2029
- var Ft = class {
2030
- host;
2031
- overlay = null;
2032
- callbacks;
2033
- bound;
2034
- depth = 0;
2035
- constructor(e, t) {
2036
- this.host = e, this.callbacks = t, this.bound = {
2037
- dragenter: (e) => this.onDragEnter(e),
2038
- dragover: (e) => this.onDragOver(e),
2039
- dragleave: (e) => this.onDragLeave(e),
2040
- drop: (e) => this.onDrop(e)
2041
- };
2042
- }
2043
- attach() {
2044
- this.host.addEventListener("dragenter", this.bound.dragenter), this.host.addEventListener("dragover", this.bound.dragover), this.host.addEventListener("dragleave", this.bound.dragleave), this.host.addEventListener("drop", this.bound.drop);
2045
- }
2046
- detach() {
2047
- this.host.removeEventListener("dragenter", this.bound.dragenter), this.host.removeEventListener("dragover", this.bound.dragover), this.host.removeEventListener("dragleave", this.bound.dragleave), this.host.removeEventListener("drop", this.bound.drop), this.hideOverlay();
2048
- }
2049
- onDragEnter(e) {
2050
- $(e) && (e.preventDefault(), this.depth++, this.showOverlay());
2051
- }
2052
- onDragOver(e) {
2053
- $(e) && (e.preventDefault(), e.dataTransfer && (e.dataTransfer.dropEffect = "copy"));
2054
- }
2055
- onDragLeave(e) {
2056
- $(e) && (this.depth = Math.max(0, this.depth - 1), this.depth === 0 && this.hideOverlay());
2057
- }
2058
- async onDrop(e) {
2059
- e.preventDefault(), this.depth = 0, this.hideOverlay();
2060
- let t = e.dataTransfer?.files?.[0];
2061
- if (t) try {
2062
- let e = J(await t.text());
2063
- if (e.data.length === 0) throw Error(`No valid OHLCV rows found in "${t.name}"`);
2064
- this.callbacks.onData(e.data, e, t);
2065
- } catch (e) {
2066
- this.callbacks.onError?.(e, t);
2067
- }
2068
- }
2069
- showOverlay() {
2070
- this.overlay || (this.overlay = document.createElement("div"), Object.assign(this.overlay.style, {
2071
- position: "absolute",
2072
- inset: "8px",
2073
- zIndex: "90",
2074
- pointerEvents: "none",
2075
- borderRadius: "10px",
2076
- border: "2px dashed var(--tcw-accent, #f2a93b)",
2077
- background: "rgba(79, 136, 255, 0.06)",
2078
- display: "flex",
2079
- alignItems: "center",
2080
- justifyContent: "center",
2081
- color: "var(--tcw-accent, #f2a93b)",
2082
- fontSize: "14px",
2083
- fontWeight: "600",
2084
- letterSpacing: "-0.005em",
2085
- fontFamily: "inherit",
2086
- backdropFilter: "blur(2px)"
2087
- }), this.overlay.textContent = "Drop CSV or JSON to load chart data", getComputedStyle(this.host).position === "static" && (this.host.style.position = "relative"), this.host.appendChild(this.overlay));
2088
- }
2089
- hideOverlay() {
2090
- this.overlay?.remove(), this.overlay = null;
2091
- }
2092
- };
2093
- function $(e) {
2094
- return e.dataTransfer?.types?.includes("Files") ?? !1;
2095
- }
2096
- //#endregion
2097
- export { Tt as a, wt as c, L as d, P as f, B as i, St as l, A as m, J as n, z as o, j as p, Ot as r, Ct as s, Ft as t, I as u };
2098
-
2099
- //# sourceMappingURL=DragDropImporter-Dd9Mud5J.js.map