react-klinecharts-ui 0.2.0 → 0.4.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.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk47JXSAIT_cjs = require('./chunk-47JXSAIT.cjs');
3
+ var chunkPIFLJKYF_cjs = require('./chunk-PIFLJKYF.cjs');
4
4
  var react = require('react');
5
5
  var reactKlinecharts = require('react-klinecharts');
6
6
  var jsxRuntime = require('react/jsx-runtime');
@@ -58,6 +58,8 @@ function reducer(state, action) {
58
58
  return { ...state, mainIndicators: action.indicators };
59
59
  case "SET_SUB_INDICATORS":
60
60
  return { ...state, subIndicators: action.indicators };
61
+ case "SET_INDICATOR_AXES":
62
+ return { ...state, indicatorAxes: action.axes };
61
63
  case "SET_STYLES":
62
64
  return { ...state, styles: action.styles };
63
65
  case "SET_LOCALE":
@@ -120,6 +122,7 @@ function KlinechartsUIProvider({
120
122
  (acc, name) => ({ ...acc, [name]: "" }),
121
123
  {}
122
124
  ),
125
+ indicatorAxes: {},
123
126
  styles: opts.styles,
124
127
  screenshotUrl: null
125
128
  })
@@ -177,7 +180,7 @@ function KlinechartsUIProvider({
177
180
  const extraOverlaysRef = react.useRef(extraOverlays);
178
181
  react.useEffect(() => {
179
182
  if (shouldRegister) {
180
- chunk47JXSAIT_cjs.registerExtensions();
183
+ chunkPIFLJKYF_cjs.registerExtensions();
181
184
  }
182
185
  extraOverlaysRef.current?.forEach((overlay) => reactKlinecharts.registerOverlay(overlay));
183
186
  }, [shouldRegister]);
@@ -644,9 +647,12 @@ var INDICATOR_PARAMS = {
644
647
  };
645
648
 
646
649
  // src/hooks/useIndicators.ts
650
+ var COLLAPSED_HEIGHT = 30;
647
651
  function useIndicators() {
648
652
  const { state, dispatch } = useKlinechartsUI();
649
653
  const { undoRedoListenerRef } = useKlinechartsUIDispatch();
654
+ const paneHeightsRef = react.useRef({});
655
+ const collapsedPanesRef = react.useRef(/* @__PURE__ */ new Set());
650
656
  const mainIndicators = react.useMemo(() => {
651
657
  const activeNames = state.mainIndicators;
652
658
  const inactive = MAIN_INDICATORS.filter((n) => !activeNames.includes(n));
@@ -664,62 +670,95 @@ function useIndicators() {
664
670
  ];
665
671
  }, [state.subIndicators]);
666
672
  const addMainIndicator = react.useCallback(
667
- (name) => {
673
+ (name, options) => {
668
674
  if (state.mainIndicators.includes(name)) return;
675
+ const yAxis = options?.yAxis;
669
676
  state.chart?.createIndicator(
670
- { name, id: `main_${name}`, paneId: "candle_pane" },
671
- true,
672
- { id: "candle_pane" }
677
+ { name, id: `main_${name}` },
678
+ { isStack: true, pane: { id: "candle_pane" }, yAxis }
673
679
  );
674
680
  const newIndicators = [...state.mainIndicators, name];
675
681
  dispatch({ type: "SET_MAIN_INDICATORS", indicators: newIndicators });
682
+ if (yAxis?.id) {
683
+ dispatch({
684
+ type: "SET_INDICATOR_AXES",
685
+ axes: { ...state.indicatorAxes, [`main_${name}`]: yAxis.id }
686
+ });
687
+ }
676
688
  undoRedoListenerRef.current?.({
677
689
  type: "indicator_toggled",
678
- data: { name, wasActive: false, isMain: true, paneId: "candle_pane" }
690
+ data: {
691
+ name,
692
+ wasActive: false,
693
+ isMain: true,
694
+ paneId: "candle_pane",
695
+ yAxisId: yAxis?.id
696
+ }
679
697
  });
680
698
  },
681
- [state.chart, state.mainIndicators, dispatch, undoRedoListenerRef]
699
+ [state.chart, state.mainIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
682
700
  );
683
701
  const removeMainIndicator = react.useCallback(
684
702
  (name) => {
685
- state.chart?.removeIndicator({ id: `main_${name}` });
703
+ const id = `main_${name}`;
704
+ const yAxisId = state.indicatorAxes[id];
705
+ state.chart?.removeIndicator({ id });
686
706
  const newIndicators = state.mainIndicators.filter((n) => n !== name);
687
707
  dispatch({ type: "SET_MAIN_INDICATORS", indicators: newIndicators });
708
+ if (yAxisId) {
709
+ const nextAxes = { ...state.indicatorAxes };
710
+ delete nextAxes[id];
711
+ dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
712
+ }
688
713
  undoRedoListenerRef.current?.({
689
714
  type: "indicator_toggled",
690
- data: { name, wasActive: true, isMain: true, paneId: "candle_pane" }
715
+ data: { name, wasActive: true, isMain: true, paneId: "candle_pane", yAxisId }
691
716
  });
692
717
  },
693
- [state.chart, state.mainIndicators, dispatch, undoRedoListenerRef]
718
+ [state.chart, state.mainIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
694
719
  );
695
720
  const addSubIndicator = react.useCallback(
696
- (name) => {
721
+ (name, options) => {
697
722
  if (name in state.subIndicators) return;
698
723
  const id = `sub_${name}`;
699
- state.chart?.createIndicator({ name, id });
724
+ const yAxis = options?.yAxis;
725
+ state.chart?.createIndicator({ name, id }, { yAxis });
700
726
  const paneId = state.chart?.getIndicators({ id })?.[0]?.paneId ?? "";
701
727
  const newIndicators = { ...state.subIndicators, [name]: paneId };
702
728
  dispatch({ type: "SET_SUB_INDICATORS", indicators: newIndicators });
729
+ if (yAxis?.id) {
730
+ dispatch({
731
+ type: "SET_INDICATOR_AXES",
732
+ axes: { ...state.indicatorAxes, [id]: yAxis.id }
733
+ });
734
+ }
703
735
  undoRedoListenerRef.current?.({
704
736
  type: "indicator_toggled",
705
- data: { name, wasActive: false, isMain: false, paneId }
737
+ data: { name, wasActive: false, isMain: false, paneId, yAxisId: yAxis?.id }
706
738
  });
707
739
  },
708
- [state.chart, state.subIndicators, dispatch, undoRedoListenerRef]
740
+ [state.chart, state.subIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
709
741
  );
710
742
  const removeSubIndicator = react.useCallback(
711
743
  (name) => {
744
+ const id = `sub_${name}`;
712
745
  const paneId = state.subIndicators[name] ?? "";
713
- state.chart?.removeIndicator({ id: `sub_${name}` });
746
+ const yAxisId = state.indicatorAxes[id];
747
+ state.chart?.removeIndicator({ id });
714
748
  const newIndicators = { ...state.subIndicators };
715
749
  delete newIndicators[name];
716
750
  dispatch({ type: "SET_SUB_INDICATORS", indicators: newIndicators });
751
+ if (yAxisId) {
752
+ const nextAxes = { ...state.indicatorAxes };
753
+ delete nextAxes[id];
754
+ dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
755
+ }
717
756
  undoRedoListenerRef.current?.({
718
757
  type: "indicator_toggled",
719
- data: { name, wasActive: true, isMain: false, paneId }
758
+ data: { name, wasActive: true, isMain: false, paneId, yAxisId }
720
759
  });
721
760
  },
722
- [state.chart, state.subIndicators, dispatch, undoRedoListenerRef]
761
+ [state.chart, state.subIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
723
762
  );
724
763
  const toggleMainIndicator = react.useCallback(
725
764
  (name) => {
@@ -749,8 +788,10 @@ function useIndicators() {
749
788
  [state.chart]
750
789
  );
751
790
  const updateIndicatorParams = react.useCallback(
752
- (name, paneId, params) => {
753
- state.chart?.overrideIndicator({ name, paneId, calcParams: params });
791
+ // `paneId` is kept in the signature for API stability; klinecharts v10
792
+ // `overrideIndicator` no longer accepts it and targets by name/id instead.
793
+ (name, _paneId, params) => {
794
+ state.chart?.overrideIndicator({ name, calcParams: params });
754
795
  },
755
796
  [state.chart]
756
797
  );
@@ -771,11 +812,9 @@ function useIndicators() {
771
812
  {
772
813
  name,
773
814
  id: `main_${name}`,
774
- paneId: "candle_pane",
775
815
  ...prevCalcParams ? { calcParams: prevCalcParams } : {}
776
816
  },
777
- true,
778
- { id: "candle_pane" }
817
+ { isStack: true, pane: { id: "candle_pane" } }
779
818
  );
780
819
  const newSub = { ...state.subIndicators };
781
820
  delete newSub[name];
@@ -816,6 +855,128 @@ function useIndicators() {
816
855
  (name) => name in state.subIndicators,
817
856
  [state.subIndicators]
818
857
  );
858
+ const collapseSubIndicator = react.useCallback(
859
+ (name) => {
860
+ const paneId = state.subIndicators[name];
861
+ if (!state.chart || !paneId) return;
862
+ const currentSize = state.chart.getSize?.(paneId);
863
+ if (currentSize?.height && currentSize.height > COLLAPSED_HEIGHT) {
864
+ paneHeightsRef.current[paneId] = currentSize.height;
865
+ }
866
+ collapsedPanesRef.current.add(paneId);
867
+ state.chart.setPaneOptions?.({
868
+ id: paneId,
869
+ height: COLLAPSED_HEIGHT
870
+ });
871
+ state.chart.overrideIndicator({ name, id: `sub_${name}`, visible: false });
872
+ },
873
+ [state.chart, state.subIndicators]
874
+ );
875
+ const expandSubIndicator = react.useCallback(
876
+ (name) => {
877
+ const paneId = state.subIndicators[name];
878
+ if (!state.chart || !paneId) return;
879
+ const savedHeight = paneHeightsRef.current[paneId] ?? 100;
880
+ collapsedPanesRef.current.delete(paneId);
881
+ state.chart.setPaneOptions?.({
882
+ id: paneId,
883
+ height: savedHeight
884
+ });
885
+ state.chart.overrideIndicator({ name, id: `sub_${name}`, visible: true });
886
+ },
887
+ [state.chart, state.subIndicators]
888
+ );
889
+ const isSubIndicatorCollapsed = react.useCallback(
890
+ (name) => {
891
+ const paneId = state.subIndicators[name];
892
+ return paneId ? collapsedPanesRef.current.has(paneId) : false;
893
+ },
894
+ [state.subIndicators]
895
+ );
896
+ const reorderSubIndicator = react.useCallback(
897
+ (name, direction) => {
898
+ if (!state.chart) return;
899
+ const subNames = Object.keys(state.subIndicators);
900
+ const idx = subNames.indexOf(name);
901
+ if (idx === -1) return;
902
+ const swapIdx = direction === "up" ? idx - 1 : idx + 1;
903
+ if (swapIdx < 0 || swapIdx >= subNames.length) return;
904
+ const subStates = subNames.map((n) => {
905
+ const id = `sub_${n}`;
906
+ const indicator = state.chart.getIndicators({ id })?.[0];
907
+ return {
908
+ name: n,
909
+ calcParams: indicator?.calcParams,
910
+ visible: indicator?.visible ?? true,
911
+ styles: indicator?.styles,
912
+ paneId: state.subIndicators[n]
913
+ };
914
+ });
915
+ [subStates[idx], subStates[swapIdx]] = [subStates[swapIdx], subStates[idx]];
916
+ for (const n of subNames) {
917
+ state.chart.removeIndicator({ id: `sub_${n}` });
918
+ }
919
+ const newSubIndicators = {};
920
+ for (const sub of subStates) {
921
+ const id = `sub_${sub.name}`;
922
+ state.chart.createIndicator({
923
+ name: sub.name,
924
+ id,
925
+ ...sub.calcParams ? { calcParams: sub.calcParams } : {},
926
+ visible: sub.visible
927
+ });
928
+ const paneId = state.chart.getIndicators({ id })?.[0]?.paneId ?? "";
929
+ newSubIndicators[sub.name] = paneId;
930
+ if (sub.styles) {
931
+ state.chart.overrideIndicator({
932
+ name: sub.name,
933
+ id,
934
+ styles: sub.styles
935
+ });
936
+ }
937
+ }
938
+ dispatch({ type: "SET_SUB_INDICATORS", indicators: newSubIndicators });
939
+ },
940
+ [state.chart, state.subIndicators, dispatch]
941
+ );
942
+ const getIndicatorAxis = react.useCallback(
943
+ (name, isMain) => state.indicatorAxes[isMain ? `main_${name}` : `sub_${name}`],
944
+ [state.indicatorAxes]
945
+ );
946
+ const bindIndicatorToNewAxis = react.useCallback(
947
+ (name, isMain, yAxis) => {
948
+ if (!state.chart) return;
949
+ const id = isMain ? `main_${name}` : `sub_${name}`;
950
+ const current = state.chart.getIndicators({ id })?.[0];
951
+ if (!current) return;
952
+ const calcParams = current.calcParams;
953
+ const styles = current.styles;
954
+ const visible = current.visible ?? true;
955
+ const paneId = isMain ? "candle_pane" : current.paneId ?? state.subIndicators[name] ?? "";
956
+ state.chart.removeIndicator({ id });
957
+ state.chart.createIndicator(
958
+ {
959
+ name,
960
+ id,
961
+ ...calcParams ? { calcParams } : {},
962
+ visible
963
+ },
964
+ {
965
+ isStack: isMain,
966
+ ...paneId ? { pane: { id: paneId } } : {},
967
+ yAxis
968
+ }
969
+ );
970
+ if (styles) {
971
+ state.chart.overrideIndicator({ name, id, styles });
972
+ }
973
+ const nextAxes = { ...state.indicatorAxes };
974
+ if (yAxis?.id) nextAxes[id] = yAxis.id;
975
+ else delete nextAxes[id];
976
+ dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
977
+ },
978
+ [state.chart, state.indicatorAxes, state.subIndicators, dispatch]
979
+ );
819
980
  return {
820
981
  mainIndicators,
821
982
  subIndicators,
@@ -835,7 +996,14 @@ function useIndicators() {
835
996
  updateIndicatorParams,
836
997
  getIndicatorParams,
837
998
  isMainIndicatorActive,
838
- isSubIndicatorActive
999
+ isSubIndicatorActive,
1000
+ collapseSubIndicator,
1001
+ expandSubIndicator,
1002
+ isSubIndicatorCollapsed,
1003
+ reorderSubIndicator,
1004
+ indicatorAxes: state.indicatorAxes,
1005
+ getIndicatorAxis,
1006
+ bindIndicatorToNewAxis
839
1007
  };
840
1008
  }
841
1009
 
@@ -934,6 +1102,17 @@ function useDrawingTools() {
934
1102
  const [magnetMode, setMagnetModeState] = react.useState("normal");
935
1103
  const [isLocked, setIsLocked] = react.useState(false);
936
1104
  const [isVisible, setIsVisible] = react.useState(true);
1105
+ const [autoRetrigger, setAutoRetrigger] = react.useState(true);
1106
+ const activeToolRef = react.useRef(activeTool);
1107
+ activeToolRef.current = activeTool;
1108
+ const autoRetriggerRef = react.useRef(autoRetrigger);
1109
+ autoRetriggerRef.current = autoRetrigger;
1110
+ const isLockedRef = react.useRef(isLocked);
1111
+ isLockedRef.current = isLocked;
1112
+ const isVisibleRef = react.useRef(isVisible);
1113
+ isVisibleRef.current = isVisible;
1114
+ const magnetModeRef = react.useRef(magnetMode);
1115
+ magnetModeRef.current = magnetMode;
937
1116
  const categories = react.useMemo(
938
1117
  () => DRAWING_CATEGORIES.map((cat) => ({
939
1118
  key: cat.key,
@@ -944,15 +1123,15 @@ function useDrawingTools() {
944
1123
  })),
945
1124
  []
946
1125
  );
947
- const selectTool = react.useCallback(
1126
+ const createOverlayForTool = react.useCallback(
948
1127
  (name) => {
949
- setActiveTool(name);
1128
+ const mode = magnetModeRef.current === "strong" ? "strong_magnet" : magnetModeRef.current === "weak" ? "weak_magnet" : "normal";
950
1129
  state.chart?.createOverlay({
951
1130
  name,
952
1131
  groupId: DRAWING_GROUP_ID,
953
- lock: isLocked,
954
- visible: isVisible,
955
- mode: magnetMode === "strong" ? "strong_magnet" : magnetMode === "weak" ? "weak_magnet" : "normal",
1132
+ lock: isLockedRef.current,
1133
+ visible: isVisibleRef.current,
1134
+ mode,
956
1135
  onDrawEnd: (event) => {
957
1136
  const o = event.overlay;
958
1137
  undoRedoListenerRef.current?.({
@@ -967,10 +1146,22 @@ function useDrawingTools() {
967
1146
  }
968
1147
  }
969
1148
  });
1149
+ if (autoRetriggerRef.current && activeToolRef.current === name) {
1150
+ requestAnimationFrame(() => {
1151
+ createOverlayForTool(name);
1152
+ });
1153
+ }
970
1154
  }
971
1155
  });
972
1156
  },
973
- [state.chart, isLocked, isVisible, magnetMode, undoRedoListenerRef]
1157
+ [state.chart, undoRedoListenerRef]
1158
+ );
1159
+ const selectTool = react.useCallback(
1160
+ (name) => {
1161
+ setActiveTool(name);
1162
+ createOverlayForTool(name);
1163
+ },
1164
+ [createOverlayForTool]
974
1165
  );
975
1166
  const clearActiveTool = react.useCallback(() => {
976
1167
  setActiveTool(null);
@@ -1041,12 +1232,14 @@ function useDrawingTools() {
1041
1232
  magnetMode,
1042
1233
  isLocked,
1043
1234
  isVisible,
1235
+ autoRetrigger,
1044
1236
  selectTool,
1045
1237
  clearActiveTool,
1046
1238
  setMagnetMode,
1047
1239
  toggleLock,
1048
1240
  toggleVisibility,
1049
- removeAllDrawings
1241
+ removeAllDrawings,
1242
+ setAutoRetrigger
1050
1243
  };
1051
1244
  }
1052
1245
 
@@ -1120,20 +1313,23 @@ function useKlinechartsUISettings() {
1120
1313
  () => TOOLTIP_SHOW_RULES.map((r) => ({ key: r, localeKey: r })),
1121
1314
  []
1122
1315
  );
1316
+ const applyPaneAxis = react.useCallback(
1317
+ (axis) => {
1318
+ state.chart?.overrideYAxis?.({ paneId: "candle_pane", ...axis });
1319
+ },
1320
+ [state.chart]
1321
+ );
1123
1322
  const hasAppliedInitial = react.useRef(false);
1124
1323
  react.useEffect(() => {
1125
1324
  if (!state.chart || hasAppliedInitial.current) return;
1126
1325
  hasAppliedInitial.current = true;
1127
- const needsPaneOptions = settings.reverseCoordinate || settings.priceAxisType !== "normal" || settings.yAxisPosition !== "right" || settings.yAxisInside;
1128
- if (needsPaneOptions) {
1129
- state.chart.setPaneOptions({
1130
- id: "candle_pane",
1131
- axis: {
1132
- ...settings.priceAxisType !== "normal" && { name: settings.priceAxisType },
1133
- ...settings.reverseCoordinate && { reverse: true },
1134
- ...settings.yAxisPosition !== "right" && { position: settings.yAxisPosition },
1135
- ...settings.yAxisInside && { inside: true }
1136
- }
1326
+ const needsAxisOverride = settings.reverseCoordinate || settings.priceAxisType !== "normal" || settings.yAxisPosition !== "right" || settings.yAxisInside;
1327
+ if (needsAxisOverride) {
1328
+ applyPaneAxis({
1329
+ ...settings.priceAxisType !== "normal" && { name: settings.priceAxisType },
1330
+ ...settings.reverseCoordinate && { reverse: true },
1331
+ ...settings.yAxisPosition !== "right" && { position: settings.yAxisPosition },
1332
+ ...settings.yAxisInside && { inside: true }
1137
1333
  });
1138
1334
  }
1139
1335
  if (settings.showIndicatorLastValue) {
@@ -1156,12 +1352,6 @@ function useKlinechartsUISettings() {
1156
1352
  },
1157
1353
  [state.chart]
1158
1354
  );
1159
- const applyPaneAxis = react.useCallback(
1160
- (axis) => {
1161
- state.chart?.setPaneOptions({ id: "candle_pane", axis });
1162
- },
1163
- [state.chart]
1164
- );
1165
1355
  const setCandleType = react.useCallback(
1166
1356
  (type) => {
1167
1357
  applyStyle("candle.type", type);
@@ -1309,11 +1499,8 @@ function useKlinechartsUISettings() {
1309
1499
  const resetToDefaults = react.useCallback(() => {
1310
1500
  setSettings(defaultSettings);
1311
1501
  state.chart?.setStyles(state.theme);
1312
- state.chart?.setPaneOptions({
1313
- id: "candle_pane",
1314
- axis: { name: "normal", reverse: false, position: "right", inside: false }
1315
- });
1316
- }, [state.chart, state.theme]);
1502
+ applyPaneAxis({ name: "normal", reverse: false, position: "right", inside: false });
1503
+ }, [state.chart, state.theme, applyPaneAxis]);
1317
1504
  return {
1318
1505
  ...settings,
1319
1506
  candleTypes,
@@ -1570,21 +1757,28 @@ function useUndoRedo() {
1570
1757
  break;
1571
1758
  }
1572
1759
  case "indicator_toggled": {
1573
- const { name, wasActive, isMain, paneId } = action.data;
1760
+ const { name, wasActive, isMain, paneId, yAxisId } = action.data;
1761
+ const id = isMain ? `main_${name}` : `sub_${name}`;
1574
1762
  if (wasActive) {
1575
1763
  if (isMain) {
1576
1764
  state.chart.createIndicator(
1577
- { name, id: `main_${name}`, paneId: "candle_pane" },
1578
- true,
1579
- { id: "candle_pane" }
1765
+ { name, id },
1766
+ {
1767
+ isStack: true,
1768
+ pane: { id: "candle_pane" },
1769
+ ...yAxisId ? { yAxis: { id: yAxisId } } : {}
1770
+ }
1580
1771
  );
1581
1772
  dispatch({
1582
1773
  type: "SET_MAIN_INDICATORS",
1583
1774
  indicators: [...state.mainIndicators, name]
1584
1775
  });
1585
1776
  } else {
1586
- state.chart.createIndicator({ name, id: `sub_${name}` });
1587
- const newPaneId = state.chart.getIndicators({ id: `sub_${name}` })?.[0]?.paneId ?? "";
1777
+ state.chart.createIndicator(
1778
+ { name, id },
1779
+ yAxisId ? { yAxis: { id: yAxisId } } : void 0
1780
+ );
1781
+ const newPaneId = state.chart.getIndicators({ id })?.[0]?.paneId ?? "";
1588
1782
  dispatch({
1589
1783
  type: "SET_SUB_INDICATORS",
1590
1784
  indicators: {
@@ -1593,9 +1787,15 @@ function useUndoRedo() {
1593
1787
  }
1594
1788
  });
1595
1789
  }
1790
+ if (yAxisId) {
1791
+ dispatch({
1792
+ type: "SET_INDICATOR_AXES",
1793
+ axes: { ...state.indicatorAxes, [id]: yAxisId }
1794
+ });
1795
+ }
1596
1796
  } else {
1797
+ state.chart.removeIndicator({ id });
1597
1798
  if (isMain) {
1598
- state.chart.removeIndicator({ id: `main_${name}` });
1599
1799
  dispatch({
1600
1800
  type: "SET_MAIN_INDICATORS",
1601
1801
  indicators: state.mainIndicators.filter(
@@ -1603,7 +1803,6 @@ function useUndoRedo() {
1603
1803
  )
1604
1804
  });
1605
1805
  } else {
1606
- state.chart.removeIndicator({ id: `sub_${name}` });
1607
1806
  const newSub = { ...state.subIndicators };
1608
1807
  delete newSub[name];
1609
1808
  dispatch({
@@ -1611,6 +1810,11 @@ function useUndoRedo() {
1611
1810
  indicators: newSub
1612
1811
  });
1613
1812
  }
1813
+ if (state.indicatorAxes[id]) {
1814
+ const nextAxes = { ...state.indicatorAxes };
1815
+ delete nextAxes[id];
1816
+ dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
1817
+ }
1614
1818
  }
1615
1819
  setRedoStack((prev) => [
1616
1820
  ...prev,
@@ -1620,7 +1824,8 @@ function useUndoRedo() {
1620
1824
  name,
1621
1825
  wasActive: !wasActive,
1622
1826
  isMain,
1623
- paneId
1827
+ paneId,
1828
+ yAxisId
1624
1829
  }
1625
1830
  }
1626
1831
  ]);
@@ -1630,7 +1835,7 @@ function useUndoRedo() {
1630
1835
  } finally {
1631
1836
  isProcessingRef.current = false;
1632
1837
  }
1633
- }, [undoStack, state.chart, state.mainIndicators, state.subIndicators, dispatch]);
1838
+ }, [undoStack, state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
1634
1839
  const redo = react.useCallback(() => {
1635
1840
  if (redoStack.length === 0 || !state.chart || isProcessingRef.current)
1636
1841
  return;
@@ -1682,21 +1887,28 @@ function useUndoRedo() {
1682
1887
  break;
1683
1888
  }
1684
1889
  case "indicator_toggled": {
1685
- const { name, wasActive, isMain } = action.data;
1890
+ const { name, wasActive, isMain, paneId, yAxisId } = action.data;
1891
+ const id = isMain ? `main_${name}` : `sub_${name}`;
1686
1892
  if (wasActive) {
1687
1893
  if (isMain) {
1688
1894
  state.chart.createIndicator(
1689
- { name, id: `main_${name}`, paneId: "candle_pane" },
1690
- true,
1691
- { id: "candle_pane" }
1895
+ { name, id },
1896
+ {
1897
+ isStack: true,
1898
+ pane: { id: "candle_pane" },
1899
+ ...yAxisId ? { yAxis: { id: yAxisId } } : {}
1900
+ }
1692
1901
  );
1693
1902
  dispatch({
1694
1903
  type: "SET_MAIN_INDICATORS",
1695
1904
  indicators: [...state.mainIndicators, name]
1696
1905
  });
1697
1906
  } else {
1698
- state.chart.createIndicator({ name, id: `sub_${name}` });
1699
- const newPaneId = state.chart.getIndicators({ id: `sub_${name}` })?.[0]?.paneId ?? "";
1907
+ state.chart.createIndicator(
1908
+ { name, id },
1909
+ yAxisId ? { yAxis: { id: yAxisId } } : void 0
1910
+ );
1911
+ const newPaneId = state.chart.getIndicators({ id })?.[0]?.paneId ?? "";
1700
1912
  dispatch({
1701
1913
  type: "SET_SUB_INDICATORS",
1702
1914
  indicators: {
@@ -1705,9 +1917,15 @@ function useUndoRedo() {
1705
1917
  }
1706
1918
  });
1707
1919
  }
1920
+ if (yAxisId) {
1921
+ dispatch({
1922
+ type: "SET_INDICATOR_AXES",
1923
+ axes: { ...state.indicatorAxes, [id]: yAxisId }
1924
+ });
1925
+ }
1708
1926
  } else {
1927
+ state.chart.removeIndicator({ id });
1709
1928
  if (isMain) {
1710
- state.chart.removeIndicator({ id: `main_${name}` });
1711
1929
  dispatch({
1712
1930
  type: "SET_MAIN_INDICATORS",
1713
1931
  indicators: state.mainIndicators.filter(
@@ -1715,7 +1933,6 @@ function useUndoRedo() {
1715
1933
  )
1716
1934
  });
1717
1935
  } else {
1718
- state.chart.removeIndicator({ id: `sub_${name}` });
1719
1936
  const newSub = { ...state.subIndicators };
1720
1937
  delete newSub[name];
1721
1938
  dispatch({
@@ -1723,6 +1940,11 @@ function useUndoRedo() {
1723
1940
  indicators: newSub
1724
1941
  });
1725
1942
  }
1943
+ if (state.indicatorAxes[id]) {
1944
+ const nextAxes = { ...state.indicatorAxes };
1945
+ delete nextAxes[id];
1946
+ dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
1947
+ }
1726
1948
  }
1727
1949
  setUndoStack((prev) => [
1728
1950
  ...prev,
@@ -1731,7 +1953,9 @@ function useUndoRedo() {
1731
1953
  data: {
1732
1954
  name,
1733
1955
  wasActive: !wasActive,
1734
- isMain
1956
+ isMain,
1957
+ paneId,
1958
+ yAxisId
1735
1959
  }
1736
1960
  }
1737
1961
  ]);
@@ -1741,7 +1965,7 @@ function useUndoRedo() {
1741
1965
  } finally {
1742
1966
  isProcessingRef.current = false;
1743
1967
  }
1744
- }, [redoStack, state.chart, state.mainIndicators, state.subIndicators, dispatch]);
1968
+ }, [redoStack, state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
1745
1969
  react.useEffect(() => {
1746
1970
  const handleKeyDown = (e) => {
1747
1971
  const isCtrlOrMeta = e.ctrlKey || e.metaKey;
@@ -1815,12 +2039,14 @@ function useLayoutManager() {
1815
2039
  if (indicatorMap) {
1816
2040
  indicatorMap.forEach((paneIndicators, paneId) => {
1817
2041
  paneIndicators.forEach((indicator) => {
2042
+ const yAxisId = state.indicatorAxes[indicator.id];
1818
2043
  indicators2.push({
1819
2044
  paneId,
1820
2045
  name: indicator.name,
1821
2046
  calcParams: indicator.calcParams,
1822
2047
  visible: indicator.visible,
1823
- ...indicator.styles ? { styles: indicator.styles } : {}
2048
+ ...indicator.styles ? { styles: indicator.styles } : {},
2049
+ ...yAxisId ? { yAxisId } : {}
1824
2050
  });
1825
2051
  });
1826
2052
  });
@@ -1848,7 +2074,7 @@ function useLayoutManager() {
1848
2074
  indicators: indicators2,
1849
2075
  drawings
1850
2076
  };
1851
- }, [state.chart, state.symbol, state.period]);
2077
+ }, [state.chart, state.symbol, state.period, state.indicatorAxes]);
1852
2078
  const saveLayout = react.useCallback(
1853
2079
  (name) => {
1854
2080
  const chartState = serializeState();
@@ -1896,25 +2122,35 @@ function useLayoutManager() {
1896
2122
  }
1897
2123
  const newMainIndicators = [];
1898
2124
  const newSubIndicators = {};
2125
+ const restoredAxes = {};
1899
2126
  if (chartState.indicators) {
1900
2127
  for (const ind of chartState.indicators) {
2128
+ const isMain = ind.paneId === "candle_pane";
2129
+ const id2 = isMain ? `main_${ind.name}` : `sub_${ind.name}`;
1901
2130
  chart.createIndicator(
1902
2131
  {
1903
2132
  name: ind.name,
2133
+ id: id2,
1904
2134
  calcParams: ind.calcParams,
1905
2135
  visible: ind.visible
1906
2136
  },
1907
- ind.paneId !== "candle_pane",
1908
- { id: ind.paneId }
2137
+ {
2138
+ isStack: ind.paneId !== "candle_pane",
2139
+ pane: { id: ind.paneId },
2140
+ ...ind.yAxisId ? { yAxis: { id: ind.yAxisId } } : {}
2141
+ }
1909
2142
  );
1910
2143
  if (ind.styles) {
1911
2144
  chart.overrideIndicator({
1912
2145
  name: ind.name,
1913
- paneId: ind.paneId,
2146
+ id: id2,
1914
2147
  styles: ind.styles
1915
2148
  });
1916
2149
  }
1917
- if (ind.paneId === "candle_pane") {
2150
+ if (ind.yAxisId) {
2151
+ restoredAxes[id2] = ind.yAxisId;
2152
+ }
2153
+ if (isMain) {
1918
2154
  newMainIndicators.push(ind.name);
1919
2155
  } else {
1920
2156
  newSubIndicators[ind.name] = ind.paneId;
@@ -1929,6 +2165,10 @@ function useLayoutManager() {
1929
2165
  type: "SET_SUB_INDICATORS",
1930
2166
  indicators: newSubIndicators
1931
2167
  });
2168
+ dispatch({
2169
+ type: "SET_INDICATOR_AXES",
2170
+ axes: restoredAxes
2171
+ });
1932
2172
  if (chartState.drawings) {
1933
2173
  for (const drawing of chartState.drawings) {
1934
2174
  chart.createOverlay({
@@ -2112,7 +2352,7 @@ ${code}`
2112
2352
  ];
2113
2353
  const fn = new Function(...allArgs);
2114
2354
  const shadowValues = SHADOW_KEYS.map(() => void 0);
2115
- const result = fn(...shadowValues, chunk47JXSAIT_cjs.TA_default, dataList, parsedParams);
2355
+ const result = fn(...shadowValues, chunkPIFLJKYF_cjs.TA_default, dataList, parsedParams);
2116
2356
  if (!Array.isArray(result)) {
2117
2357
  throw new Error("Script must return an Array.");
2118
2358
  }
@@ -2154,8 +2394,7 @@ ${code}`
2154
2394
  if (placement === "main") {
2155
2395
  paneId = chart.createIndicator(
2156
2396
  { name: indicatorName },
2157
- true,
2158
- { id: "candle_pane" }
2397
+ { isStack: true, pane: { id: "candle_pane" } }
2159
2398
  );
2160
2399
  } else {
2161
2400
  paneId = chart.createIndicator({ name: indicatorName });
@@ -2245,6 +2484,749 @@ ${code}`
2245
2484
  defaultScript: DEFAULT_SCRIPT
2246
2485
  };
2247
2486
  }
2487
+ function useCrosshair() {
2488
+ const { state } = useKlinechartsUI();
2489
+ const [barData, setBarData] = react.useState(null);
2490
+ const rafRef = react.useRef(0);
2491
+ const handler = react.useCallback(
2492
+ (event) => {
2493
+ if (rafRef.current) {
2494
+ cancelAnimationFrame(rafRef.current);
2495
+ }
2496
+ rafRef.current = requestAnimationFrame(() => {
2497
+ rafRef.current = 0;
2498
+ const klineData = event?.kLineData;
2499
+ if (!klineData) {
2500
+ setBarData(null);
2501
+ return;
2502
+ }
2503
+ const pricePrecision = state.symbol?.pricePrecision ?? 2;
2504
+ const open = klineData.open ?? 0;
2505
+ const close = klineData.close ?? 0;
2506
+ const change = parseFloat((close - open).toFixed(pricePrecision));
2507
+ const changePercent = open !== 0 ? parseFloat((change / open * 100).toFixed(2)) : 0;
2508
+ setBarData({
2509
+ open,
2510
+ high: klineData.high ?? 0,
2511
+ low: klineData.low ?? 0,
2512
+ close,
2513
+ volume: klineData.volume ?? 0,
2514
+ timestamp: klineData.timestamp ?? 0,
2515
+ change,
2516
+ changePercent
2517
+ });
2518
+ });
2519
+ },
2520
+ [state.symbol?.pricePrecision]
2521
+ );
2522
+ react.useEffect(() => {
2523
+ const chart = state.chart;
2524
+ if (!chart) return;
2525
+ chart.subscribeAction?.("onCrosshairChange", handler);
2526
+ return () => {
2527
+ if (rafRef.current) {
2528
+ cancelAnimationFrame(rafRef.current);
2529
+ rafRef.current = 0;
2530
+ }
2531
+ chart.unsubscribeAction?.("onCrosshairChange", handler);
2532
+ };
2533
+ }, [state.chart, handler]);
2534
+ return { barData };
2535
+ }
2536
+ var alertCounter = 0;
2537
+ function useAlerts() {
2538
+ const { state } = useKlinechartsUI();
2539
+ const [alerts, setAlerts] = react.useState([]);
2540
+ const callbackRef = react.useRef(null);
2541
+ const prevCloseRef = react.useRef(null);
2542
+ const addAlert = react.useCallback(
2543
+ (price, condition, message) => {
2544
+ const id = `alert_${++alertCounter}`;
2545
+ const alert = {
2546
+ id,
2547
+ price,
2548
+ condition,
2549
+ message,
2550
+ triggered: false
2551
+ };
2552
+ setAlerts((prev) => [...prev, alert]);
2553
+ if (state.chart) {
2554
+ state.chart.createOverlay({
2555
+ name: "horizontalStraightLine",
2556
+ id,
2557
+ groupId: "price_alerts",
2558
+ points: [{ value: price }],
2559
+ styles: {
2560
+ line: {
2561
+ style: "dashed",
2562
+ color: "#ff9800",
2563
+ size: 1
2564
+ }
2565
+ },
2566
+ lock: true
2567
+ });
2568
+ }
2569
+ return id;
2570
+ },
2571
+ [state.chart]
2572
+ );
2573
+ const removeAlert = react.useCallback(
2574
+ (id) => {
2575
+ setAlerts((prev) => prev.filter((a) => a.id !== id));
2576
+ state.chart?.removeOverlay({ id });
2577
+ },
2578
+ [state.chart]
2579
+ );
2580
+ const clearAlerts = react.useCallback(() => {
2581
+ setAlerts((prev) => {
2582
+ for (const alert of prev) {
2583
+ state.chart?.removeOverlay({ id: alert.id });
2584
+ }
2585
+ return [];
2586
+ });
2587
+ }, [state.chart]);
2588
+ const onAlertTriggered = react.useCallback(
2589
+ (callback) => {
2590
+ callbackRef.current = callback;
2591
+ },
2592
+ []
2593
+ );
2594
+ react.useEffect(() => {
2595
+ if (!state.chart) return;
2596
+ const interval = setInterval(() => {
2597
+ const dataList = state.chart?.getDataList();
2598
+ if (!dataList || dataList.length === 0) return;
2599
+ const lastBar = dataList[dataList.length - 1];
2600
+ const currentClose = lastBar.close;
2601
+ const prevClose = prevCloseRef.current;
2602
+ if (prevClose === null) {
2603
+ prevCloseRef.current = currentClose;
2604
+ return;
2605
+ }
2606
+ prevCloseRef.current = currentClose;
2607
+ setAlerts((prev) => {
2608
+ let changed = false;
2609
+ const next = prev.map((alert) => {
2610
+ if (alert.triggered) return alert;
2611
+ let shouldTrigger = false;
2612
+ if (alert.condition === "crossing_up") {
2613
+ shouldTrigger = prevClose < alert.price && currentClose >= alert.price;
2614
+ } else if (alert.condition === "crossing_down") {
2615
+ shouldTrigger = prevClose > alert.price && currentClose <= alert.price;
2616
+ } else if (alert.condition === "crossing") {
2617
+ shouldTrigger = prevClose < alert.price && currentClose >= alert.price || prevClose > alert.price && currentClose <= alert.price;
2618
+ }
2619
+ if (shouldTrigger) {
2620
+ changed = true;
2621
+ const triggered = { ...alert, triggered: true };
2622
+ callbackRef.current?.(triggered);
2623
+ return triggered;
2624
+ }
2625
+ return alert;
2626
+ });
2627
+ return changed ? next : prev;
2628
+ });
2629
+ }, 1e3);
2630
+ return () => clearInterval(interval);
2631
+ }, [state.chart]);
2632
+ return {
2633
+ alerts,
2634
+ addAlert,
2635
+ removeAlert,
2636
+ clearAlerts,
2637
+ onAlertTriggered
2638
+ };
2639
+ }
2640
+ function useDataExport() {
2641
+ const { state } = useKlinechartsUI();
2642
+ const exportAll = react.useCallback(
2643
+ (format) => {
2644
+ if (!state.chart) return;
2645
+ const dataList = state.chart.getDataList();
2646
+ if (!dataList || dataList.length === 0) return;
2647
+ downloadData(dataList, format, state.symbol?.ticker);
2648
+ },
2649
+ [state.chart, state.symbol?.ticker]
2650
+ );
2651
+ const exportVisible = react.useCallback(
2652
+ (format) => {
2653
+ if (!state.chart) return;
2654
+ const dataList = state.chart.getDataList();
2655
+ if (!dataList || dataList.length === 0) return;
2656
+ const visibleRange = state.chart.getVisibleRange?.();
2657
+ if (!visibleRange) {
2658
+ downloadData(dataList, format, state.symbol?.ticker);
2659
+ return;
2660
+ }
2661
+ const { from, to } = visibleRange;
2662
+ const visibleData = dataList.slice(from, to);
2663
+ downloadData(visibleData, format, state.symbol?.ticker);
2664
+ },
2665
+ [state.chart, state.symbol?.ticker]
2666
+ );
2667
+ return { exportAll, exportVisible };
2668
+ }
2669
+ function formatRow(bar) {
2670
+ return {
2671
+ date: new Date(bar.timestamp).toISOString(),
2672
+ open: bar.open,
2673
+ high: bar.high,
2674
+ low: bar.low,
2675
+ close: bar.close,
2676
+ volume: bar.volume ?? 0
2677
+ };
2678
+ }
2679
+ function buildCsv(dataList) {
2680
+ const header = "Date,Open,High,Low,Close,Volume\n";
2681
+ const rows = dataList.map((bar) => {
2682
+ const r = formatRow(bar);
2683
+ return `${r.date},${r.open},${r.high},${r.low},${r.close},${r.volume}`;
2684
+ });
2685
+ return header + rows.join("\n");
2686
+ }
2687
+ function buildJson(dataList) {
2688
+ return JSON.stringify(dataList.map(formatRow), null, 2);
2689
+ }
2690
+ function downloadData(dataList, format, ticker) {
2691
+ const content = format === "csv" ? buildCsv(dataList) : buildJson(dataList);
2692
+ const mimeType = format === "csv" ? "text/csv" : "application/json";
2693
+ const blob = new Blob([content], { type: mimeType });
2694
+ const url = URL.createObjectURL(blob);
2695
+ const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2696
+ const prefix = ticker ?? "chart";
2697
+ const filename = `${prefix}_${date}.${format}`;
2698
+ const link = document.createElement("a");
2699
+ link.href = url;
2700
+ link.download = filename;
2701
+ document.body.appendChild(link);
2702
+ link.click();
2703
+ document.body.removeChild(link);
2704
+ URL.revokeObjectURL(url);
2705
+ }
2706
+ function useWatchlist() {
2707
+ const { state } = useKlinechartsUI();
2708
+ const { dispatch, datafeed } = useKlinechartsUIDispatch();
2709
+ const [items, setItems] = react.useState([]);
2710
+ const subscriptionsRef = react.useRef(/* @__PURE__ */ new Map());
2711
+ const activeSymbol = state.symbol?.ticker ?? null;
2712
+ const addSymbol = react.useCallback(
2713
+ (ticker) => {
2714
+ setItems((prev) => {
2715
+ if (prev.some((item) => item.ticker === ticker)) return prev;
2716
+ return [
2717
+ ...prev,
2718
+ { ticker, lastPrice: null, change: null, changePercent: null }
2719
+ ];
2720
+ });
2721
+ if (subscriptionsRef.current.has(ticker)) return;
2722
+ const symbolInfo = { ticker };
2723
+ const period = state.period;
2724
+ subscriptionsRef.current.set(ticker, { symbolInfo, period });
2725
+ datafeed.subscribe(symbolInfo, period, (bar) => {
2726
+ setItems(
2727
+ (prev) => prev.map((item) => {
2728
+ if (item.ticker !== ticker) return item;
2729
+ const change = bar.close - bar.open;
2730
+ const changePercent = bar.open !== 0 ? change / bar.open * 100 : null;
2731
+ return {
2732
+ ...item,
2733
+ lastPrice: bar.close,
2734
+ change,
2735
+ changePercent
2736
+ };
2737
+ })
2738
+ );
2739
+ });
2740
+ },
2741
+ [datafeed, state.period]
2742
+ );
2743
+ const removeSymbol = react.useCallback(
2744
+ (ticker) => {
2745
+ const sub = subscriptionsRef.current.get(ticker);
2746
+ if (sub) {
2747
+ datafeed.unsubscribe(sub.symbolInfo, sub.period);
2748
+ subscriptionsRef.current.delete(ticker);
2749
+ }
2750
+ setItems((prev) => prev.filter((item) => item.ticker !== ticker));
2751
+ },
2752
+ [datafeed]
2753
+ );
2754
+ const switchSymbol = react.useCallback(
2755
+ (ticker) => {
2756
+ dispatch({ type: "SET_SYMBOL", symbol: { ticker } });
2757
+ },
2758
+ [dispatch]
2759
+ );
2760
+ react.useEffect(() => {
2761
+ return () => {
2762
+ subscriptionsRef.current.forEach((sub) => {
2763
+ datafeed.unsubscribe(sub.symbolInfo, sub.period);
2764
+ });
2765
+ subscriptionsRef.current.clear();
2766
+ };
2767
+ }, [datafeed]);
2768
+ return {
2769
+ items,
2770
+ addSymbol,
2771
+ removeSymbol,
2772
+ switchSymbol,
2773
+ activeSymbol
2774
+ };
2775
+ }
2776
+ function useReplay() {
2777
+ const { state } = useKlinechartsUI();
2778
+ const [isReplaying, setIsReplaying] = react.useState(false);
2779
+ const [isPaused, setIsPaused] = react.useState(false);
2780
+ const [speed, setSpeedState] = react.useState(1);
2781
+ const [barIndex, setBarIndex] = react.useState(0);
2782
+ const [totalBars, setTotalBars] = react.useState(0);
2783
+ const intervalRef = react.useRef(null);
2784
+ const savedDataRef = react.useRef([]);
2785
+ const currentIndexRef = react.useRef(0);
2786
+ const clearInterval_ = react.useCallback(() => {
2787
+ if (intervalRef.current !== null) {
2788
+ clearInterval(intervalRef.current);
2789
+ intervalRef.current = null;
2790
+ }
2791
+ }, []);
2792
+ const addNextBar = react.useCallback(() => {
2793
+ if (!state.chart) return;
2794
+ const data = savedDataRef.current;
2795
+ const idx = currentIndexRef.current;
2796
+ if (idx >= data.length) {
2797
+ clearInterval_();
2798
+ setIsPaused(true);
2799
+ return;
2800
+ }
2801
+ const bar = data[idx];
2802
+ state.chart.updateData?.(bar);
2803
+ currentIndexRef.current = idx + 1;
2804
+ setBarIndex(idx + 1);
2805
+ }, [state.chart, clearInterval_]);
2806
+ const startInterval = react.useCallback(
2807
+ (currentSpeed) => {
2808
+ clearInterval_();
2809
+ intervalRef.current = setInterval(addNextBar, 1e3 / currentSpeed);
2810
+ },
2811
+ [addNextBar, clearInterval_]
2812
+ );
2813
+ const startReplay = react.useCallback(() => {
2814
+ if (!state.chart) return;
2815
+ const dataList = state.chart.getDataList();
2816
+ if (!dataList || dataList.length === 0) return;
2817
+ savedDataRef.current = [...dataList];
2818
+ currentIndexRef.current = 0;
2819
+ setTotalBars(dataList.length);
2820
+ setBarIndex(0);
2821
+ setIsReplaying(true);
2822
+ setIsPaused(false);
2823
+ state.chart.clearData?.();
2824
+ startInterval(speed);
2825
+ }, [state.chart, speed, startInterval]);
2826
+ const stopReplay = react.useCallback(() => {
2827
+ if (!state.chart) return;
2828
+ clearInterval_();
2829
+ const data = savedDataRef.current;
2830
+ if (data.length > 0) {
2831
+ state.chart.clearData?.();
2832
+ for (const bar of data) {
2833
+ state.chart.updateData?.(bar);
2834
+ }
2835
+ }
2836
+ savedDataRef.current = [];
2837
+ currentIndexRef.current = 0;
2838
+ setIsReplaying(false);
2839
+ setIsPaused(false);
2840
+ setBarIndex(0);
2841
+ setTotalBars(0);
2842
+ }, [state.chart, clearInterval_]);
2843
+ const togglePause = react.useCallback(() => {
2844
+ if (!isReplaying) return;
2845
+ if (isPaused) {
2846
+ startInterval(speed);
2847
+ setIsPaused(false);
2848
+ } else {
2849
+ clearInterval_();
2850
+ setIsPaused(true);
2851
+ }
2852
+ }, [isReplaying, isPaused, speed, startInterval, clearInterval_]);
2853
+ const stepForward = react.useCallback(() => {
2854
+ if (!isReplaying || !isPaused) return;
2855
+ addNextBar();
2856
+ }, [isReplaying, isPaused, addNextBar]);
2857
+ const stepBackward = react.useCallback(() => {
2858
+ if (!isReplaying || !isPaused || !state.chart) return;
2859
+ const idx = currentIndexRef.current;
2860
+ if (idx <= 1) return;
2861
+ const data = savedDataRef.current;
2862
+ state.chart.clearData?.();
2863
+ for (let i = 0; i < idx - 1; i++) {
2864
+ state.chart.updateData?.(data[i]);
2865
+ }
2866
+ currentIndexRef.current = idx - 1;
2867
+ setBarIndex(idx - 1);
2868
+ }, [isReplaying, isPaused, state.chart]);
2869
+ const seekTo = react.useCallback(
2870
+ (targetIndex) => {
2871
+ if (!isReplaying || !state.chart) return;
2872
+ const data = savedDataRef.current;
2873
+ const clamped = Math.max(0, Math.min(targetIndex, data.length));
2874
+ clearInterval_();
2875
+ setIsPaused(true);
2876
+ state.chart.clearData?.();
2877
+ for (let i = 0; i < clamped; i++) {
2878
+ state.chart.updateData?.(data[i]);
2879
+ }
2880
+ currentIndexRef.current = clamped;
2881
+ setBarIndex(clamped);
2882
+ },
2883
+ [isReplaying, state.chart, clearInterval_]
2884
+ );
2885
+ const setSpeed = react.useCallback(
2886
+ (newSpeed) => {
2887
+ setSpeedState(newSpeed);
2888
+ if (isReplaying && !isPaused) {
2889
+ startInterval(newSpeed);
2890
+ }
2891
+ },
2892
+ [isReplaying, isPaused, startInterval]
2893
+ );
2894
+ react.useEffect(() => {
2895
+ return () => {
2896
+ clearInterval_();
2897
+ };
2898
+ }, [clearInterval_]);
2899
+ return {
2900
+ isReplaying,
2901
+ isPaused,
2902
+ speed,
2903
+ barIndex,
2904
+ totalBars,
2905
+ startReplay,
2906
+ stopReplay,
2907
+ togglePause,
2908
+ stepForward,
2909
+ stepBackward,
2910
+ seekTo,
2911
+ setSpeed
2912
+ };
2913
+ }
2914
+ var DEFAULT_COLORS = [
2915
+ "#2196f3",
2916
+ "#ff9800",
2917
+ "#4caf50",
2918
+ "#e91e63",
2919
+ "#9c27b0",
2920
+ "#00bcd4",
2921
+ "#ff5722",
2922
+ "#8bc34a"
2923
+ ];
2924
+ var colorIndex = 0;
2925
+ var compareCounter = 0;
2926
+ function useCompare() {
2927
+ const { state, datafeed } = useKlinechartsUI();
2928
+ const [symbols, setSymbols] = react.useState([]);
2929
+ const indicatorsRef = react.useRef(/* @__PURE__ */ new Map());
2930
+ const addSymbol = react.useCallback(
2931
+ async (ticker, color) => {
2932
+ if (!state.chart || !datafeed) return;
2933
+ if (indicatorsRef.current.has(ticker)) return;
2934
+ const assignedColor = color ?? DEFAULT_COLORS[colorIndex++ % DEFAULT_COLORS.length];
2935
+ const mainDataList = state.chart.getDataList();
2936
+ if (!mainDataList || mainDataList.length === 0) return;
2937
+ const from = mainDataList[0].timestamp;
2938
+ const to = mainDataList[mainDataList.length - 1].timestamp;
2939
+ const compareData = await datafeed.getHistoryKLineData(
2940
+ { ticker },
2941
+ { ...state.period, label: "" },
2942
+ from,
2943
+ to
2944
+ );
2945
+ if (!compareData || compareData.length === 0) return;
2946
+ const compareMap = /* @__PURE__ */ new Map();
2947
+ for (const bar of compareData) {
2948
+ compareMap.set(bar.timestamp, bar.close);
2949
+ }
2950
+ let basePrice = null;
2951
+ for (const bar of mainDataList) {
2952
+ const close = compareMap.get(bar.timestamp);
2953
+ if (close != null) {
2954
+ basePrice = close;
2955
+ break;
2956
+ }
2957
+ }
2958
+ if (basePrice === null || basePrice === 0) return;
2959
+ const bp = basePrice;
2960
+ const normalizedData = mainDataList.map((mainBar) => {
2961
+ const close = compareMap.get(mainBar.timestamp);
2962
+ return {
2963
+ pct: close != null ? (close - bp) / bp * 100 : NaN
2964
+ };
2965
+ });
2966
+ const indicatorName = `__cmp_${++compareCounter}_${ticker}`;
2967
+ reactKlinecharts.registerIndicator({
2968
+ name: indicatorName,
2969
+ shortName: ticker,
2970
+ figures: [
2971
+ {
2972
+ key: "pct",
2973
+ title: `${ticker} %: `,
2974
+ type: "line",
2975
+ styles: () => ({ color: assignedColor })
2976
+ }
2977
+ ],
2978
+ calc: () => normalizedData
2979
+ });
2980
+ const paneId = state.chart.createIndicator(
2981
+ { name: indicatorName },
2982
+ { isStack: true, pane: { id: "candle_pane" } }
2983
+ );
2984
+ indicatorsRef.current.set(ticker, {
2985
+ name: indicatorName,
2986
+ paneId: typeof paneId === "string" ? paneId : "candle_pane"
2987
+ });
2988
+ setSymbols((prev) => {
2989
+ if (prev.some((s) => s.ticker === ticker)) return prev;
2990
+ return [
2991
+ ...prev,
2992
+ { ticker, basePrice: bp, color: assignedColor, visible: true }
2993
+ ];
2994
+ });
2995
+ },
2996
+ [state.chart, state.period, datafeed]
2997
+ );
2998
+ const removeSymbol = react.useCallback(
2999
+ (ticker) => {
3000
+ const info = indicatorsRef.current.get(ticker);
3001
+ if (info && state.chart) {
3002
+ try {
3003
+ state.chart.removeIndicator({ name: info.name });
3004
+ } catch {
3005
+ }
3006
+ indicatorsRef.current.delete(ticker);
3007
+ }
3008
+ setSymbols((prev) => prev.filter((s) => s.ticker !== ticker));
3009
+ },
3010
+ [state.chart]
3011
+ );
3012
+ const toggleSymbol = react.useCallback(
3013
+ (ticker) => {
3014
+ const info = indicatorsRef.current.get(ticker);
3015
+ if (!info || !state.chart) return;
3016
+ setSymbols((prev) => {
3017
+ const sym = prev.find((s) => s.ticker === ticker);
3018
+ if (!sym) return prev;
3019
+ const newVisible = !sym.visible;
3020
+ state.chart?.overrideIndicator({
3021
+ name: info.name,
3022
+ visible: newVisible
3023
+ });
3024
+ return prev.map(
3025
+ (s) => s.ticker === ticker ? { ...s, visible: newVisible } : s
3026
+ );
3027
+ });
3028
+ },
3029
+ [state.chart]
3030
+ );
3031
+ const clearAll = react.useCallback(() => {
3032
+ indicatorsRef.current.forEach((info) => {
3033
+ try {
3034
+ state.chart?.removeIndicator({ name: info.name });
3035
+ } catch {
3036
+ }
3037
+ });
3038
+ indicatorsRef.current.clear();
3039
+ setSymbols([]);
3040
+ }, [state.chart]);
3041
+ react.useEffect(() => {
3042
+ return () => {
3043
+ indicatorsRef.current.forEach((info) => {
3044
+ try {
3045
+ state.chart?.removeIndicator({ name: info.name });
3046
+ } catch {
3047
+ }
3048
+ });
3049
+ indicatorsRef.current.clear();
3050
+ };
3051
+ }, [state.chart]);
3052
+ return { symbols, addSymbol, removeSymbol, toggleSymbol, clearAll };
3053
+ }
3054
+ var MEASURE_OVERLAY_ID = "__measure_line__";
3055
+ function useMeasure() {
3056
+ const { state } = useKlinechartsUI();
3057
+ const [isActive, setIsActive] = react.useState(false);
3058
+ const [fromPoint, setFromPoint] = react.useState(null);
3059
+ const [result, setResult] = react.useState(null);
3060
+ const clickCountRef = react.useRef(0);
3061
+ const computeResult = react.useCallback(
3062
+ (from, to) => {
3063
+ const priceDiff = to.price - from.price;
3064
+ const pricePercent = from.price !== 0 ? priceDiff / from.price * 100 : 0;
3065
+ const bars = Math.abs(to.barIndex - from.barIndex);
3066
+ const timeDiff = Math.abs(to.timestamp - from.timestamp);
3067
+ return { from, to, priceDiff, pricePercent, bars, timeDiff };
3068
+ },
3069
+ []
3070
+ );
3071
+ const cleanup = react.useCallback(() => {
3072
+ state.chart?.removeOverlay({ id: MEASURE_OVERLAY_ID });
3073
+ }, [state.chart]);
3074
+ const startMeasure = react.useCallback(() => {
3075
+ cleanup();
3076
+ setIsActive(true);
3077
+ setFromPoint(null);
3078
+ setResult(null);
3079
+ clickCountRef.current = 0;
3080
+ if (!state.chart) return;
3081
+ state.chart.createOverlay({
3082
+ name: "segment",
3083
+ id: MEASURE_OVERLAY_ID,
3084
+ groupId: "measure",
3085
+ styles: {
3086
+ line: {
3087
+ style: "dashed",
3088
+ color: "#FFD600",
3089
+ size: 1
3090
+ }
3091
+ },
3092
+ lock: true,
3093
+ onDrawEnd: (event) => {
3094
+ const overlay = event?.overlay;
3095
+ const points = overlay?.points;
3096
+ if (!points || points.length < 2) return;
3097
+ const chart = state.chart;
3098
+ if (!chart) return;
3099
+ const dataList = chart.getDataList();
3100
+ if (!dataList || dataList.length === 0) return;
3101
+ const makePoint = (p) => {
3102
+ const idx = Math.max(
3103
+ 0,
3104
+ Math.min(p.dataIndex ?? 0, dataList.length - 1)
3105
+ );
3106
+ const bar = dataList[idx];
3107
+ return {
3108
+ price: p.value ?? bar?.close ?? 0,
3109
+ timestamp: bar?.timestamp ?? 0,
3110
+ barIndex: idx
3111
+ };
3112
+ };
3113
+ const from = makePoint(points[0]);
3114
+ const to = makePoint(points[1]);
3115
+ setFromPoint(from);
3116
+ setResult(computeResult(from, to));
3117
+ setIsActive(false);
3118
+ }
3119
+ });
3120
+ }, [state.chart, cleanup, computeResult]);
3121
+ const cancelMeasure = react.useCallback(() => {
3122
+ cleanup();
3123
+ setIsActive(false);
3124
+ setFromPoint(null);
3125
+ clickCountRef.current = 0;
3126
+ }, [cleanup]);
3127
+ const clearResult = react.useCallback(() => {
3128
+ cleanup();
3129
+ setResult(null);
3130
+ setFromPoint(null);
3131
+ }, [cleanup]);
3132
+ react.useEffect(() => {
3133
+ return () => {
3134
+ state.chart?.removeOverlay({ id: MEASURE_OVERLAY_ID });
3135
+ };
3136
+ }, [state.chart]);
3137
+ return {
3138
+ isActive,
3139
+ startMeasure,
3140
+ cancelMeasure,
3141
+ result,
3142
+ clearResult,
3143
+ fromPoint
3144
+ };
3145
+ }
3146
+ var annotationCounter = 0;
3147
+ function useAnnotations() {
3148
+ const { state } = useKlinechartsUI();
3149
+ const [annotations, setAnnotations] = react.useState([]);
3150
+ const addAnnotation = react.useCallback(
3151
+ (text, price, timestamp, color) => {
3152
+ const id = `annotation_${++annotationCounter}`;
3153
+ const annotation = {
3154
+ id,
3155
+ text,
3156
+ price,
3157
+ timestamp,
3158
+ color
3159
+ };
3160
+ setAnnotations((prev) => [...prev, annotation]);
3161
+ if (state.chart) {
3162
+ state.chart.createOverlay({
3163
+ name: "simpleAnnotation",
3164
+ id,
3165
+ groupId: "annotations",
3166
+ points: [{ timestamp, value: price }],
3167
+ extendData: text,
3168
+ styles: color ? {
3169
+ text: {
3170
+ color
3171
+ }
3172
+ } : void 0,
3173
+ lock: true
3174
+ });
3175
+ }
3176
+ return id;
3177
+ },
3178
+ [state.chart]
3179
+ );
3180
+ const removeAnnotation = react.useCallback(
3181
+ (id) => {
3182
+ setAnnotations((prev) => prev.filter((a) => a.id !== id));
3183
+ state.chart?.removeOverlay({ id });
3184
+ },
3185
+ [state.chart]
3186
+ );
3187
+ const updateAnnotation = react.useCallback(
3188
+ (id, updates) => {
3189
+ setAnnotations(
3190
+ (prev) => prev.map((a) => a.id === id ? { ...a, ...updates } : a)
3191
+ );
3192
+ if (state.chart) {
3193
+ const overrideData = { id };
3194
+ if (updates.text !== void 0) {
3195
+ overrideData.extendData = updates.text;
3196
+ }
3197
+ if (updates.color !== void 0) {
3198
+ overrideData.styles = {
3199
+ text: {
3200
+ color: updates.color
3201
+ }
3202
+ };
3203
+ }
3204
+ state.chart.overrideOverlay(overrideData);
3205
+ }
3206
+ },
3207
+ [state.chart]
3208
+ );
3209
+ const clearAnnotations = react.useCallback(() => {
3210
+ setAnnotations((prev) => {
3211
+ for (const annotation of prev) {
3212
+ state.chart?.removeOverlay({ id: annotation.id });
3213
+ }
3214
+ return [];
3215
+ });
3216
+ }, [state.chart]);
3217
+ react.useEffect(() => {
3218
+ return () => {
3219
+ state.chart?.removeOverlay({ groupId: "annotations" });
3220
+ };
3221
+ }, [state.chart]);
3222
+ return {
3223
+ annotations,
3224
+ addAnnotation,
3225
+ removeAnnotation,
3226
+ updateAnnotation,
3227
+ clearAnnotations
3228
+ };
3229
+ }
2248
3230
 
2249
3231
  // src/utils/createDataLoader.ts
2250
3232
  function createDataLoader(datafeed, dispatch) {
@@ -2312,171 +3294,175 @@ function createDataLoader(datafeed, dispatch) {
2312
3294
 
2313
3295
  Object.defineProperty(exports, "TA", {
2314
3296
  enumerable: true,
2315
- get: function () { return chunk47JXSAIT_cjs.TA_default; }
3297
+ get: function () { return chunkPIFLJKYF_cjs.TA_default; }
2316
3298
  });
2317
3299
  Object.defineProperty(exports, "abcd", {
2318
3300
  enumerable: true,
2319
- get: function () { return chunk47JXSAIT_cjs.abcd_default; }
3301
+ get: function () { return chunkPIFLJKYF_cjs.abcd_default; }
2320
3302
  });
2321
3303
  Object.defineProperty(exports, "anyWaves", {
2322
3304
  enumerable: true,
2323
- get: function () { return chunk47JXSAIT_cjs.anyWaves_default; }
3305
+ get: function () { return chunkPIFLJKYF_cjs.anyWaves_default; }
2324
3306
  });
2325
3307
  Object.defineProperty(exports, "arrow", {
2326
3308
  enumerable: true,
2327
- get: function () { return chunk47JXSAIT_cjs.arrow_default; }
3309
+ get: function () { return chunkPIFLJKYF_cjs.arrow_default; }
2328
3310
  });
2329
3311
  Object.defineProperty(exports, "bollTv", {
2330
3312
  enumerable: true,
2331
- get: function () { return chunk47JXSAIT_cjs.bollTv_default; }
3313
+ get: function () { return chunkPIFLJKYF_cjs.bollTv_default; }
2332
3314
  });
2333
3315
  Object.defineProperty(exports, "brush", {
2334
3316
  enumerable: true,
2335
- get: function () { return chunk47JXSAIT_cjs.brush_default; }
3317
+ get: function () { return chunkPIFLJKYF_cjs.brush_default; }
2336
3318
  });
2337
3319
  Object.defineProperty(exports, "cci", {
2338
3320
  enumerable: true,
2339
- get: function () { return chunk47JXSAIT_cjs.cci_default; }
3321
+ get: function () { return chunkPIFLJKYF_cjs.cci_default; }
2340
3322
  });
2341
3323
  Object.defineProperty(exports, "circle", {
2342
3324
  enumerable: true,
2343
- get: function () { return chunk47JXSAIT_cjs.circle_default; }
3325
+ get: function () { return chunkPIFLJKYF_cjs.circle_default; }
3326
+ });
3327
+ Object.defineProperty(exports, "depthOverlay", {
3328
+ enumerable: true,
3329
+ get: function () { return chunkPIFLJKYF_cjs.depthOverlay_default; }
2344
3330
  });
2345
3331
  Object.defineProperty(exports, "eightWaves", {
2346
3332
  enumerable: true,
2347
- get: function () { return chunk47JXSAIT_cjs.eightWaves_default; }
3333
+ get: function () { return chunkPIFLJKYF_cjs.eightWaves_default; }
2348
3334
  });
2349
3335
  Object.defineProperty(exports, "elliottWave", {
2350
3336
  enumerable: true,
2351
- get: function () { return chunk47JXSAIT_cjs.elliottWave_default; }
3337
+ get: function () { return chunkPIFLJKYF_cjs.elliottWave_default; }
2352
3338
  });
2353
3339
  Object.defineProperty(exports, "fibRetracement", {
2354
3340
  enumerable: true,
2355
- get: function () { return chunk47JXSAIT_cjs.fibRetracement_default; }
3341
+ get: function () { return chunkPIFLJKYF_cjs.fibRetracement_default; }
2356
3342
  });
2357
3343
  Object.defineProperty(exports, "fibonacciCircle", {
2358
3344
  enumerable: true,
2359
- get: function () { return chunk47JXSAIT_cjs.fibonacciCircle_default; }
3345
+ get: function () { return chunkPIFLJKYF_cjs.fibonacciCircle_default; }
2360
3346
  });
2361
3347
  Object.defineProperty(exports, "fibonacciExtension", {
2362
3348
  enumerable: true,
2363
- get: function () { return chunk47JXSAIT_cjs.fibonacciExtension_default; }
3349
+ get: function () { return chunkPIFLJKYF_cjs.fibonacciExtension_default; }
2364
3350
  });
2365
3351
  Object.defineProperty(exports, "fibonacciSegment", {
2366
3352
  enumerable: true,
2367
- get: function () { return chunk47JXSAIT_cjs.fibonacciSegment_default; }
3353
+ get: function () { return chunkPIFLJKYF_cjs.fibonacciSegment_default; }
2368
3354
  });
2369
3355
  Object.defineProperty(exports, "fibonacciSpeedResistanceFan", {
2370
3356
  enumerable: true,
2371
- get: function () { return chunk47JXSAIT_cjs.fibonacciSpeedResistanceFan_default; }
3357
+ get: function () { return chunkPIFLJKYF_cjs.fibonacciSpeedResistanceFan_default; }
2372
3358
  });
2373
3359
  Object.defineProperty(exports, "fibonacciSpiral", {
2374
3360
  enumerable: true,
2375
- get: function () { return chunk47JXSAIT_cjs.fibonacciSpiral_default; }
3361
+ get: function () { return chunkPIFLJKYF_cjs.fibonacciSpiral_default; }
2376
3362
  });
2377
3363
  Object.defineProperty(exports, "fiveWaves", {
2378
3364
  enumerable: true,
2379
- get: function () { return chunk47JXSAIT_cjs.fiveWaves_default; }
3365
+ get: function () { return chunkPIFLJKYF_cjs.fiveWaves_default; }
2380
3366
  });
2381
3367
  Object.defineProperty(exports, "gannBox", {
2382
3368
  enumerable: true,
2383
- get: function () { return chunk47JXSAIT_cjs.gannBox_default; }
3369
+ get: function () { return chunkPIFLJKYF_cjs.gannBox_default; }
2384
3370
  });
2385
3371
  Object.defineProperty(exports, "gannFan", {
2386
3372
  enumerable: true,
2387
- get: function () { return chunk47JXSAIT_cjs.gannFan_default; }
3373
+ get: function () { return chunkPIFLJKYF_cjs.gannFan_default; }
2388
3374
  });
2389
3375
  Object.defineProperty(exports, "hma", {
2390
3376
  enumerable: true,
2391
- get: function () { return chunk47JXSAIT_cjs.hma_default; }
3377
+ get: function () { return chunkPIFLJKYF_cjs.hma_default; }
2392
3378
  });
2393
3379
  Object.defineProperty(exports, "ichimoku", {
2394
3380
  enumerable: true,
2395
- get: function () { return chunk47JXSAIT_cjs.ichimoku_default; }
3381
+ get: function () { return chunkPIFLJKYF_cjs.ichimoku_default; }
2396
3382
  });
2397
3383
  Object.defineProperty(exports, "indicators", {
2398
3384
  enumerable: true,
2399
- get: function () { return chunk47JXSAIT_cjs.indicators; }
3385
+ get: function () { return chunkPIFLJKYF_cjs.indicators; }
2400
3386
  });
2401
3387
  Object.defineProperty(exports, "longPosition", {
2402
3388
  enumerable: true,
2403
- get: function () { return chunk47JXSAIT_cjs.longPosition_default; }
3389
+ get: function () { return chunkPIFLJKYF_cjs.longPosition_default; }
2404
3390
  });
2405
3391
  Object.defineProperty(exports, "maRibbon", {
2406
3392
  enumerable: true,
2407
- get: function () { return chunk47JXSAIT_cjs.maRibbon_default; }
3393
+ get: function () { return chunkPIFLJKYF_cjs.maRibbon_default; }
2408
3394
  });
2409
3395
  Object.defineProperty(exports, "macdTv", {
2410
3396
  enumerable: true,
2411
- get: function () { return chunk47JXSAIT_cjs.macdTv_default; }
3397
+ get: function () { return chunkPIFLJKYF_cjs.macdTv_default; }
2412
3398
  });
2413
3399
  Object.defineProperty(exports, "measure", {
2414
3400
  enumerable: true,
2415
- get: function () { return chunk47JXSAIT_cjs.measure_default; }
3401
+ get: function () { return chunkPIFLJKYF_cjs.measure_default; }
2416
3402
  });
2417
3403
  Object.defineProperty(exports, "orderLine", {
2418
3404
  enumerable: true,
2419
- get: function () { return chunk47JXSAIT_cjs.orderLine_default; }
3405
+ get: function () { return chunkPIFLJKYF_cjs.orderLine_default; }
2420
3406
  });
2421
3407
  Object.defineProperty(exports, "overlays", {
2422
3408
  enumerable: true,
2423
- get: function () { return chunk47JXSAIT_cjs.overlays; }
3409
+ get: function () { return chunkPIFLJKYF_cjs.overlays; }
2424
3410
  });
2425
3411
  Object.defineProperty(exports, "parallelChannel", {
2426
3412
  enumerable: true,
2427
- get: function () { return chunk47JXSAIT_cjs.parallelChannel_default; }
3413
+ get: function () { return chunkPIFLJKYF_cjs.parallelChannel_default; }
2428
3414
  });
2429
3415
  Object.defineProperty(exports, "parallelogram", {
2430
3416
  enumerable: true,
2431
- get: function () { return chunk47JXSAIT_cjs.parallelogram_default; }
3417
+ get: function () { return chunkPIFLJKYF_cjs.parallelogram_default; }
2432
3418
  });
2433
3419
  Object.defineProperty(exports, "pivotPoints", {
2434
3420
  enumerable: true,
2435
- get: function () { return chunk47JXSAIT_cjs.pivotPoints_default; }
3421
+ get: function () { return chunkPIFLJKYF_cjs.pivotPoints_default; }
2436
3422
  });
2437
3423
  Object.defineProperty(exports, "ray", {
2438
3424
  enumerable: true,
2439
- get: function () { return chunk47JXSAIT_cjs.ray_default; }
3425
+ get: function () { return chunkPIFLJKYF_cjs.ray_default; }
2440
3426
  });
2441
3427
  Object.defineProperty(exports, "rect", {
2442
3428
  enumerable: true,
2443
- get: function () { return chunk47JXSAIT_cjs.rect_default; }
3429
+ get: function () { return chunkPIFLJKYF_cjs.rect_default; }
2444
3430
  });
2445
3431
  Object.defineProperty(exports, "registerExtensions", {
2446
3432
  enumerable: true,
2447
- get: function () { return chunk47JXSAIT_cjs.registerExtensions; }
3433
+ get: function () { return chunkPIFLJKYF_cjs.registerExtensions; }
2448
3434
  });
2449
3435
  Object.defineProperty(exports, "rsiTv", {
2450
3436
  enumerable: true,
2451
- get: function () { return chunk47JXSAIT_cjs.rsiTv_default; }
3437
+ get: function () { return chunkPIFLJKYF_cjs.rsiTv_default; }
2452
3438
  });
2453
3439
  Object.defineProperty(exports, "shortPosition", {
2454
3440
  enumerable: true,
2455
- get: function () { return chunk47JXSAIT_cjs.shortPosition_default; }
3441
+ get: function () { return chunkPIFLJKYF_cjs.shortPosition_default; }
2456
3442
  });
2457
3443
  Object.defineProperty(exports, "stochastic", {
2458
3444
  enumerable: true,
2459
- get: function () { return chunk47JXSAIT_cjs.stochastic_default; }
3445
+ get: function () { return chunkPIFLJKYF_cjs.stochastic_default; }
2460
3446
  });
2461
3447
  Object.defineProperty(exports, "superTrend", {
2462
3448
  enumerable: true,
2463
- get: function () { return chunk47JXSAIT_cjs.superTrend_default; }
3449
+ get: function () { return chunkPIFLJKYF_cjs.superTrend_default; }
2464
3450
  });
2465
3451
  Object.defineProperty(exports, "threeWaves", {
2466
3452
  enumerable: true,
2467
- get: function () { return chunk47JXSAIT_cjs.threeWaves_default; }
3453
+ get: function () { return chunkPIFLJKYF_cjs.threeWaves_default; }
2468
3454
  });
2469
3455
  Object.defineProperty(exports, "triangle", {
2470
3456
  enumerable: true,
2471
- get: function () { return chunk47JXSAIT_cjs.triangle_default; }
3457
+ get: function () { return chunkPIFLJKYF_cjs.triangle_default; }
2472
3458
  });
2473
3459
  Object.defineProperty(exports, "vwap", {
2474
3460
  enumerable: true,
2475
- get: function () { return chunk47JXSAIT_cjs.vwap_default; }
3461
+ get: function () { return chunkPIFLJKYF_cjs.vwap_default; }
2476
3462
  });
2477
3463
  Object.defineProperty(exports, "xabcd", {
2478
3464
  enumerable: true,
2479
- get: function () { return chunk47JXSAIT_cjs.xabcd_default; }
3465
+ get: function () { return chunkPIFLJKYF_cjs.xabcd_default; }
2480
3466
  });
2481
3467
  exports.CANDLE_TYPES = CANDLE_TYPES;
2482
3468
  exports.COMPARE_RULES = COMPARE_RULES;
@@ -2493,6 +3479,11 @@ exports.TIMEZONES = TIMEZONES;
2493
3479
  exports.TOOLTIP_SHOW_RULES = TOOLTIP_SHOW_RULES;
2494
3480
  exports.YAXIS_POSITIONS = YAXIS_POSITIONS;
2495
3481
  exports.createDataLoader = createDataLoader;
3482
+ exports.useAlerts = useAlerts;
3483
+ exports.useAnnotations = useAnnotations;
3484
+ exports.useCompare = useCompare;
3485
+ exports.useCrosshair = useCrosshair;
3486
+ exports.useDataExport = useDataExport;
2496
3487
  exports.useDrawingTools = useDrawingTools;
2497
3488
  exports.useFullscreen = useFullscreen;
2498
3489
  exports.useIndicators = useIndicators;
@@ -2501,12 +3492,15 @@ exports.useKlinechartsUILoading = useKlinechartsUILoading;
2501
3492
  exports.useKlinechartsUISettings = useKlinechartsUISettings;
2502
3493
  exports.useKlinechartsUITheme = useKlinechartsUITheme;
2503
3494
  exports.useLayoutManager = useLayoutManager;
3495
+ exports.useMeasure = useMeasure;
2504
3496
  exports.useOrderLines = useOrderLines;
2505
3497
  exports.usePeriods = usePeriods;
3498
+ exports.useReplay = useReplay;
2506
3499
  exports.useScreenshot = useScreenshot;
2507
3500
  exports.useScriptEditor = useScriptEditor;
2508
3501
  exports.useSymbolSearch = useSymbolSearch;
2509
3502
  exports.useTimezone = useTimezone;
2510
3503
  exports.useUndoRedo = useUndoRedo;
3504
+ exports.useWatchlist = useWatchlist;
2511
3505
  //# sourceMappingURL=index.cjs.map
2512
3506
  //# sourceMappingURL=index.cjs.map