dipping-charts 0.1.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 (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +216 -0
  3. package/dist/__tests__/FullFeaturedChart.test.d.ts +2 -0
  4. package/dist/__tests__/FullFeaturedChart.test.d.ts.map +1 -0
  5. package/dist/__tests__/indicators-accuracy.test.d.ts +2 -0
  6. package/dist/__tests__/indicators-accuracy.test.d.ts.map +1 -0
  7. package/dist/__tests__/indicators.test.d.ts +2 -0
  8. package/dist/__tests__/indicators.test.d.ts.map +1 -0
  9. package/dist/__tests__/setup.d.ts +1 -0
  10. package/dist/__tests__/setup.d.ts.map +1 -0
  11. package/dist/__tests__/validateCandle.test.d.ts +2 -0
  12. package/dist/__tests__/validateCandle.test.d.ts.map +1 -0
  13. package/dist/chart/index.d.ts +2 -0
  14. package/dist/chart/index.js +5 -0
  15. package/dist/chart/index.js.map +1 -0
  16. package/dist/components/TradingChart.d.ts +24 -0
  17. package/dist/components/TradingChart.d.ts.map +1 -0
  18. package/dist/components/TradingChart.js +100 -0
  19. package/dist/components/TradingChart.js.map +1 -0
  20. package/dist/components/index.d.ts +3 -0
  21. package/dist/components/index.d.ts.map +1 -0
  22. package/dist/dipping-charts.css +1 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +28 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/indicators/atr.d.ts +15 -0
  28. package/dist/indicators/atr.d.ts.map +1 -0
  29. package/dist/indicators/atr.js +30 -0
  30. package/dist/indicators/atr.js.map +1 -0
  31. package/dist/indicators/bollingerBands.d.ts +11 -0
  32. package/dist/indicators/bollingerBands.d.ts.map +1 -0
  33. package/dist/indicators/bollingerBands.js +39 -0
  34. package/dist/indicators/bollingerBands.js.map +1 -0
  35. package/dist/indicators/currencyStrength.d.ts +43 -0
  36. package/dist/indicators/currencyStrength.d.ts.map +1 -0
  37. package/dist/indicators/currencyStrength.js +53 -0
  38. package/dist/indicators/currencyStrength.js.map +1 -0
  39. package/dist/indicators/ema.d.ts +11 -0
  40. package/dist/indicators/ema.d.ts.map +1 -0
  41. package/dist/indicators/ema.js +24 -0
  42. package/dist/indicators/ema.js.map +1 -0
  43. package/dist/indicators/index.d.ts +19 -0
  44. package/dist/indicators/index.d.ts.map +1 -0
  45. package/dist/indicators/index.js +23 -0
  46. package/dist/indicators/index.js.map +1 -0
  47. package/dist/indicators/macd.d.ts +11 -0
  48. package/dist/indicators/macd.d.ts.map +1 -0
  49. package/dist/indicators/macd.js +52 -0
  50. package/dist/indicators/macd.js.map +1 -0
  51. package/dist/indicators/rsi.d.ts +11 -0
  52. package/dist/indicators/rsi.d.ts.map +1 -0
  53. package/dist/indicators/rsi.js +29 -0
  54. package/dist/indicators/rsi.js.map +1 -0
  55. package/dist/indicators/sma.d.ts +13 -0
  56. package/dist/indicators/sma.d.ts.map +1 -0
  57. package/dist/indicators/sma.js +22 -0
  58. package/dist/indicators/sma.js.map +1 -0
  59. package/dist/indicators/stochastic.d.ts +15 -0
  60. package/dist/indicators/stochastic.d.ts.map +1 -0
  61. package/dist/indicators/stochastic.js +34 -0
  62. package/dist/indicators/stochastic.js.map +1 -0
  63. package/dist/indicators/types.d.ts +102 -0
  64. package/dist/indicators/types.d.ts.map +1 -0
  65. package/dist/indicators/vwap.d.ts +14 -0
  66. package/dist/indicators/vwap.d.ts.map +1 -0
  67. package/dist/indicators/vwap.js +17 -0
  68. package/dist/indicators/vwap.js.map +1 -0
  69. package/dist/indicators/williamsR.d.ts +17 -0
  70. package/dist/indicators/williamsR.d.ts.map +1 -0
  71. package/dist/indicators/williamsR.js +19 -0
  72. package/dist/indicators/williamsR.js.map +1 -0
  73. package/dist/react/FullFeaturedChart.d.ts +3 -0
  74. package/dist/react/FullFeaturedChart.d.ts.map +1 -0
  75. package/dist/react/FullFeaturedChart.js +640 -0
  76. package/dist/react/FullFeaturedChart.js.map +1 -0
  77. package/dist/react/components/IndicatorSettings.d.ts +20 -0
  78. package/dist/react/components/IndicatorSettings.d.ts.map +1 -0
  79. package/dist/react/components/IndicatorSettings.js +748 -0
  80. package/dist/react/components/IndicatorSettings.js.map +1 -0
  81. package/dist/react/hooks/useChart.d.ts +15 -0
  82. package/dist/react/hooks/useChart.d.ts.map +1 -0
  83. package/dist/react/hooks/useChart.js +155 -0
  84. package/dist/react/hooks/useChart.js.map +1 -0
  85. package/dist/react/hooks/useIndicators.d.ts +10 -0
  86. package/dist/react/hooks/useIndicators.d.ts.map +1 -0
  87. package/dist/react/hooks/useIndicators.js +264 -0
  88. package/dist/react/hooks/useIndicators.js.map +1 -0
  89. package/dist/react/hooks/useLineTools.d.ts +26 -0
  90. package/dist/react/hooks/useLineTools.d.ts.map +1 -0
  91. package/dist/react/hooks/useLineTools.js +189 -0
  92. package/dist/react/hooks/useLineTools.js.map +1 -0
  93. package/dist/react/hooks/useShiftSnap.d.ts +12 -0
  94. package/dist/react/hooks/useShiftSnap.d.ts.map +1 -0
  95. package/dist/react/hooks/useShiftSnap.js +54 -0
  96. package/dist/react/hooks/useShiftSnap.js.map +1 -0
  97. package/dist/react/index.d.ts +14 -0
  98. package/dist/react/index.d.ts.map +1 -0
  99. package/dist/react/index.js +18 -0
  100. package/dist/react/index.js.map +1 -0
  101. package/dist/react/loadLightweightCharts.d.ts +18 -0
  102. package/dist/react/loadLightweightCharts.d.ts.map +1 -0
  103. package/dist/react/loadLightweightCharts.js +32 -0
  104. package/dist/react/loadLightweightCharts.js.map +1 -0
  105. package/dist/react/locale.d.ts +79 -0
  106. package/dist/react/locale.d.ts.map +1 -0
  107. package/dist/react/locale.js +158 -0
  108. package/dist/react/locale.js.map +1 -0
  109. package/dist/react/types.d.ts +130 -0
  110. package/dist/react/types.d.ts.map +1 -0
  111. package/dist/types/index.d.ts +24 -0
  112. package/dist/types/index.d.ts.map +1 -0
  113. package/dist/utils/getToolId.d.ts +9 -0
  114. package/dist/utils/getToolId.d.ts.map +1 -0
  115. package/dist/utils/getToolId.js +12 -0
  116. package/dist/utils/getToolId.js.map +1 -0
  117. package/dist/utils/mockData.d.ts +10 -0
  118. package/dist/utils/mockData.d.ts.map +1 -0
  119. package/dist/utils/mockData.js +61 -0
  120. package/dist/utils/mockData.js.map +1 -0
  121. package/dist/utils/snapCrosshair.d.ts +25 -0
  122. package/dist/utils/snapCrosshair.d.ts.map +1 -0
  123. package/dist/utils/validateCandle.d.ts +30 -0
  124. package/dist/utils/validateCandle.d.ts.map +1 -0
  125. package/dist/utils/validateCandle.js +21 -0
  126. package/dist/utils/validateCandle.js.map +1 -0
  127. package/examples/css/base.css +209 -0
  128. package/examples/css/chart.css +282 -0
  129. package/examples/css/indicators.css +255 -0
  130. package/examples/index.html +163 -0
  131. package/examples/js/chart.js +370 -0
  132. package/examples/js/indicators.js +27 -0
  133. package/examples/js/main.js +6 -0
  134. package/examples/js/ui.js +1641 -0
  135. package/lib/lightweight-charts.standalone.production.js +7 -0
  136. package/package.json +106 -0
  137. package/src/react/FullFeaturedChart.css +1007 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIndicators.js","sources":["../../../src/react/hooks/useIndicators.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport type { IChartApi, ISeriesApi, Time } from 'lightweight-charts';\nimport type { CandleData } from '../../types';\nimport type { IndicatorConfigs, IndicatorConfig, BollingerBandsConfig, MACDConfig, StochasticConfig, VWAPConfig } from '../types';\nimport {\n calculateSMA,\n calculateEMA,\n calculateRSI,\n calculateMACD,\n calculateBollingerBands,\n calculateStochastic,\n calculateATR,\n calculateVWAP,\n calculateWilliamsR,\n} from '../../indicators';\nimport { filterValidIndicatorPoints } from '../../utils/validateCandle';\n\nexport function useIndicators(chart: IChartApi | null, candles: CandleData[]) {\n const seriesRef = useRef<ISeriesApi<any>[]>([]);\n\n const applyIndicators = useCallback((configs: IndicatorConfigs, macdColors?: { line: string; signal: string }) => {\n if (!chart || !candles || candles.length === 0) return;\n\n // 기존 지표 제거\n seriesRef.current.forEach(series => {\n try {\n chart.removeSeries(series);\n } catch (e) {\n // 이미 제거된 시리즈\n }\n });\n seriesRef.current = [];\n\n const filterIndicatorData = filterValidIndicatorPoints;\n\n // 동적 scaleMargins 계산 (하단 오실레이터 겹침 방지)\n // 이전 버전 호환: 새 키가 없을 수 있으므로 방어적 접근\n const hasRsi = (configs.rsi?.length ?? 0) > 0;\n const hasMacd = (configs.macd?.length ?? 0) > 0;\n const hasStochastic = (configs.stochastic?.length ?? 0) > 0;\n const hasAtr = (configs.atr?.length ?? 0) > 0;\n const hasWilliamsR = (configs.williamsR?.length ?? 0) > 0;\n\n // 하단 오실레이터 개수에 따라 scaleMargins 동적 조정\n const oscillatorPanes = [hasRsi, hasMacd, hasStochastic, hasAtr, hasWilliamsR].filter(Boolean).length;\n const paneHeight = oscillatorPanes > 0 ? Math.min(0.2, 0.5 / oscillatorPanes) : 0;\n\n let nextPaneTop = 1 - (paneHeight * oscillatorPanes);\n const assignMargins = () => {\n const top = nextPaneTop;\n nextPaneTop += paneHeight;\n return { top, bottom: 1 - nextPaneTop };\n };\n\n const rsiMargins = hasRsi ? assignMargins() : { top: 0.75, bottom: 0 };\n const macdMargins = hasMacd ? assignMargins() : { top: 0.75, bottom: 0 };\n const stochasticMargins = hasStochastic ? assignMargins() : { top: 0.75, bottom: 0 };\n const atrMargins = hasAtr ? assignMargins() : { top: 0.75, bottom: 0 };\n const williamsRMargins = hasWilliamsR ? assignMargins() : { top: 0.75, bottom: 0 };\n\n // SMA\n configs.sma.forEach((config: IndicatorConfig) => {\n const data = calculateSMA(candles, { period: config.value });\n const validData = filterIndicatorData(data || []);\n if (validData.length > 0) {\n const series = chart.addLineSeries({\n color: config.color,\n lineWidth: config.thickness as any,\n title: `SMA ${config.value}`,\n lastValueVisible: false,\n priceLineVisible: false,\n });\n series.setData(validData.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(series);\n }\n });\n\n // EMA\n configs.ema.forEach((config: IndicatorConfig) => {\n const data = calculateEMA(candles, { period: config.value });\n const validData = filterIndicatorData(data || []);\n if (validData.length > 0) {\n const series = chart.addLineSeries({\n color: config.color,\n lineWidth: config.thickness as any,\n title: `EMA ${config.value}`,\n lastValueVisible: false,\n priceLineVisible: false,\n });\n series.setData(validData.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(series);\n }\n });\n\n // RSI\n configs.rsi.forEach((config: IndicatorConfig) => {\n const data = calculateRSI(candles, { period: config.value });\n const validData = filterIndicatorData(data || []);\n if (validData.length > 0) {\n const series = chart.addLineSeries({\n color: config.color,\n lineWidth: config.thickness as any,\n title: `RSI ${config.value}`,\n priceScaleId: 'rsi',\n lastValueVisible: true,\n priceLineVisible: false,\n });\n series.priceScale().applyOptions({\n scaleMargins: rsiMargins,\n });\n series.setData(validData.map(d => ({ ...d, time: d.time as Time })));\n // RSI 과매수/과매도 기준선\n const oversold = config.oversold ?? 30;\n const overbought = config.overbought ?? 70;\n series.createPriceLine({\n price: oversold, color: 'rgba(150,150,150,0.4)', lineWidth: 1, lineStyle: 1,\n axisLabelVisible: false, title: '', lineVisible: true,\n });\n series.createPriceLine({\n price: overbought, color: 'rgba(150,150,150,0.4)', lineWidth: 1, lineStyle: 1,\n axisLabelVisible: false, title: '', lineVisible: true,\n });\n seriesRef.current.push(series);\n }\n });\n\n // MACD\n configs.macd.forEach((config: MACDConfig) => {\n const macdData = calculateMACD(candles, {\n fastPeriod: config.fastPeriod,\n slowPeriod: config.slowPeriod,\n signalPeriod: config.signalPeriod\n });\n const validMacd = filterIndicatorData(macdData.macd || []);\n const validSignal = filterIndicatorData(macdData.signal || []);\n const validHistogram = filterIndicatorData(macdData.histogram || []);\n\n if (validMacd.length > 0) {\n const macdSeries = chart.addLineSeries({\n color: macdColors?.line || '#2962FF',\n lineWidth: config.thickness as any,\n title: 'MACD',\n priceScaleId: 'macd',\n lastValueVisible: true,\n priceLineVisible: false,\n });\n macdSeries.priceScale().applyOptions({\n scaleMargins: macdMargins,\n });\n macdSeries.setData(validMacd.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(macdSeries);\n\n if (validSignal.length > 0) {\n const signalSeries = chart.addLineSeries({\n color: macdColors?.signal || '#FF6D00',\n lineWidth: config.thickness as any,\n title: 'Signal',\n priceScaleId: 'macd',\n lastValueVisible: true,\n priceLineVisible: false,\n });\n signalSeries.setData(validSignal.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(signalSeries);\n }\n\n if (validHistogram.length > 0) {\n const histSeries = chart.addHistogramSeries({\n priceScaleId: 'macd',\n });\n const histUp = config.histUpColor || '#26a69a';\n const histDown = config.histDownColor || '#ef5350';\n histSeries.setData(validHistogram.map(d => ({\n time: d.time as Time,\n value: d.value,\n color: d.value >= 0 ? histUp : histDown,\n })));\n seriesRef.current.push(histSeries);\n }\n }\n });\n\n // Bollinger Bands\n configs.bbands.forEach((config: BollingerBandsConfig) => {\n const bbData = calculateBollingerBands(candles, { period: config.value, stdDev: config.stdDev || 2 });\n const validUpper = filterIndicatorData(bbData.upper || []);\n const validMiddle = filterIndicatorData(bbData.middle || []);\n const validLower = filterIndicatorData(bbData.lower || []);\n\n if (validUpper.length > 0) {\n const upperSeries = chart.addLineSeries({\n color: config.upperColor || '#F23645',\n lineWidth: 1,\n lineStyle: 1,\n title: 'BB Upper',\n crosshairMarkerVisible: false,\n lastValueVisible: false,\n priceLineVisible: false,\n });\n upperSeries.setData(validUpper.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(upperSeries);\n\n if (validMiddle.length > 0) {\n const middleSeries = chart.addLineSeries({\n color: config.middleColor || '#2962FF',\n lineWidth: config.thickness as any,\n lineStyle: 0,\n title: 'BB Middle',\n lastValueVisible: false,\n priceLineVisible: false,\n });\n middleSeries.setData(validMiddle.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(middleSeries);\n }\n\n if (validLower.length > 0) {\n const lowerSeries = chart.addLineSeries({\n color: config.lowerColor || '#089981',\n lineWidth: 1,\n lineStyle: 1,\n title: 'BB Lower',\n crosshairMarkerVisible: false,\n lastValueVisible: false,\n priceLineVisible: false,\n });\n lowerSeries.setData(validLower.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(lowerSeries);\n }\n }\n });\n\n // Stochastic\n (configs.stochastic ?? []).forEach((config: StochasticConfig) => {\n const stochData = calculateStochastic(candles, {\n kPeriod: config.kPeriod,\n dPeriod: config.dPeriod,\n smooth: config.smooth,\n });\n const validK = filterIndicatorData(stochData.k || []);\n const validD = filterIndicatorData(stochData.d || []);\n\n if (validK.length > 0) {\n const kSeries = chart.addLineSeries({\n color: config.kColor || '#2962FF',\n lineWidth: config.thickness as any,\n title: '%K',\n priceScaleId: 'stochastic',\n lastValueVisible: true,\n priceLineVisible: false,\n });\n kSeries.priceScale().applyOptions({ scaleMargins: stochasticMargins });\n kSeries.setData(validK.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(kSeries);\n\n // Overbought/Oversold lines\n kSeries.createPriceLine({\n price: 80, color: 'rgba(150,150,150,0.4)', lineWidth: 1, lineStyle: 1,\n axisLabelVisible: false, title: '', lineVisible: true,\n });\n kSeries.createPriceLine({\n price: 20, color: 'rgba(150,150,150,0.4)', lineWidth: 1, lineStyle: 1,\n axisLabelVisible: false, title: '', lineVisible: true,\n });\n\n if (validD.length > 0) {\n const dSeries = chart.addLineSeries({\n color: config.dColor || '#FF6D00',\n lineWidth: config.thickness as any,\n title: '%D',\n priceScaleId: 'stochastic',\n lastValueVisible: true,\n priceLineVisible: false,\n });\n dSeries.setData(validD.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(dSeries);\n }\n }\n });\n\n // ATR\n (configs.atr ?? []).forEach((config: IndicatorConfig) => {\n const data = calculateATR(candles, { period: config.value });\n const validData = filterIndicatorData(data || []);\n if (validData.length > 0) {\n const series = chart.addLineSeries({\n color: config.color,\n lineWidth: config.thickness as any,\n title: `ATR ${config.value}`,\n priceScaleId: 'atr',\n lastValueVisible: true,\n priceLineVisible: false,\n });\n series.priceScale().applyOptions({ scaleMargins: atrMargins });\n series.setData(validData.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(series);\n }\n });\n\n // VWAP (overlay — same price scale as candles)\n (configs.vwap ?? []).forEach((config: VWAPConfig) => {\n const data = calculateVWAP(candles);\n const validData = filterIndicatorData(data || []);\n if (validData.length > 0) {\n const series = chart.addLineSeries({\n color: config.color || '#E040FB',\n lineWidth: config.thickness as any,\n title: 'VWAP',\n lastValueVisible: false,\n priceLineVisible: false,\n });\n series.setData(validData.map(d => ({ ...d, time: d.time as Time })));\n seriesRef.current.push(series);\n }\n });\n\n // Williams %R\n (configs.williamsR ?? []).forEach((config: IndicatorConfig) => {\n const data = calculateWilliamsR(candles, { period: config.value });\n const validData = filterIndicatorData(data || []);\n if (validData.length > 0) {\n const series = chart.addLineSeries({\n color: config.color,\n lineWidth: config.thickness as any,\n title: `W%R ${config.value}`,\n priceScaleId: 'williamsR',\n lastValueVisible: true,\n priceLineVisible: false,\n });\n series.priceScale().applyOptions({ scaleMargins: williamsRMargins });\n series.setData(validData.map(d => ({ ...d, time: d.time as Time })));\n\n // Overbought/Oversold lines\n series.createPriceLine({\n price: -20, color: 'rgba(150,150,150,0.4)', lineWidth: 1, lineStyle: 1,\n axisLabelVisible: false, title: '', lineVisible: true,\n });\n series.createPriceLine({\n price: -80, color: 'rgba(150,150,150,0.4)', lineWidth: 1, lineStyle: 1,\n axisLabelVisible: false, title: '', lineVisible: true,\n });\n seriesRef.current.push(series);\n }\n });\n }, [chart, candles]);\n\n return { applyIndicators };\n}\n"],"names":["useIndicators","chart","candles","seriesRef","useRef","useCallback","configs","macdColors","series","filterIndicatorData","filterValidIndicatorPoints","hasRsi","_a","hasMacd","_b","hasStochastic","_c","hasAtr","_d","hasWilliamsR","_e","oscillatorPanes","paneHeight","nextPaneTop","assignMargins","top","rsiMargins","macdMargins","stochasticMargins","atrMargins","williamsRMargins","config","data","calculateSMA","validData","d","calculateEMA","calculateRSI","oversold","overbought","macdData","calculateMACD","validMacd","validSignal","validHistogram","macdSeries","signalSeries","histSeries","histUp","histDown","bbData","calculateBollingerBands","validUpper","validMiddle","validLower","upperSeries","middleSeries","lowerSeries","stochData","calculateStochastic","validK","validD","kSeries","dSeries","calculateATR","calculateVWAP","calculateWilliamsR"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { IChartApi } from 'lightweight-charts';
2
+ import { LineToolType, LineTool } from '../types';
3
+ export interface UseLineToolsOptions {
4
+ onToolFinished?: (tool: LineTool) => void;
5
+ onToolsChange?: (tools: LineTool[]) => void;
6
+ initialTools?: LineTool[];
7
+ }
8
+ export declare function useLineTools(chart: IChartApi | null, options?: UseLineToolsOptions): {
9
+ activeToolType: LineToolType | null;
10
+ selectedToolId: string | null;
11
+ selectedTool: LineTool | null | undefined;
12
+ currentWidth: number;
13
+ currentColor: string;
14
+ tools: Map<string, LineTool>;
15
+ activateTool: (toolType: LineToolType) => void;
16
+ addTextTool: (text: string) => void;
17
+ removeAllTools: () => void;
18
+ removeSelectedTool: () => void;
19
+ updateLineWidth: (newWidth: number) => void;
20
+ updateColor: (color: string) => void;
21
+ updateText: (newText: string) => void;
22
+ setSelectedToolId: import('react').Dispatch<import('react').SetStateAction<string | null>>;
23
+ exportTools: () => LineTool[];
24
+ loadTools: (savedTools: LineTool[]) => void;
25
+ };
26
+ //# sourceMappingURL=useLineTools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLineTools.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useLineTools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAmB,MAAM,UAAU,CAAC;AAGxE,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,mBAAmB;;;;;;;6BA4HrC,YAAY;wBAwBjB,MAAM;;;gCAkCE,MAAM;yBAmCb,MAAM;0BAmCL,MAAM;;uBA3KX,QAAQ,EAAE;4BAKH,QAAQ,EAAE;EA6PtD"}
@@ -0,0 +1,189 @@
1
+ import { useState as E, useRef as v, useCallback as d, useEffect as M } from "react";
2
+ import { getToolIdFromResult as b } from "../../utils/getToolId.js";
3
+ function _(o, l) {
4
+ var S, k, U, W, h, j, q;
5
+ const [A, L] = E(null), [s, p] = E(null), [B, y] = E(/* @__PURE__ */ new Map()), r = v(/* @__PURE__ */ new Map()), T = v({
6
+ line: { width: 2, color: "#2962FF" }
7
+ }), I = v(l == null ? void 0 : l.onToolFinished), C = v(l == null ? void 0 : l.onToolsChange), z = v(!1), F = d(() => {
8
+ if (C.current) {
9
+ const n = Array.from(r.current.values());
10
+ C.current(n);
11
+ }
12
+ }, []), x = d((n, e) => {
13
+ if (!o) return null;
14
+ const t = Array.from(r.current.values());
15
+ o.removeAllLineTools(), r.current.clear();
16
+ let i = null;
17
+ return t.forEach((u) => {
18
+ const c = u.id === n ? e : u.options, w = o.addLineTool(u.toolType, u.points, c), a = b(w);
19
+ a && (r.current.set(a, {
20
+ id: a,
21
+ toolType: u.toolType,
22
+ points: u.points,
23
+ options: c
24
+ }), u.id === n && (i = a));
25
+ }), y(new Map(r.current)), i;
26
+ }, [o]), O = d((n) => {
27
+ if (!o) return null;
28
+ const t = Array.from(r.current.values()).filter((i) => i.id !== n);
29
+ return o.removeAllLineTools(), r.current.clear(), t.forEach((i) => {
30
+ const u = o.addLineTool(i.toolType, i.points, i.options), c = b(u);
31
+ c && r.current.set(c, {
32
+ id: c,
33
+ toolType: i.toolType,
34
+ points: i.points,
35
+ options: i.options
36
+ });
37
+ }), y(new Map(r.current)), r.current.size > 0 ? Array.from(r.current.keys())[0] : null;
38
+ }, [o]), D = d(() => Array.from(r.current.values()), []), R = d((n) => {
39
+ !o || !n || n.length === 0 || (o.removeAllLineTools(), r.current.clear(), n.forEach((e) => {
40
+ const t = o.addLineTool(e.toolType, e.points, e.options), i = b(t);
41
+ i && r.current.set(i, {
42
+ id: i,
43
+ toolType: e.toolType,
44
+ points: e.points,
45
+ options: e.options
46
+ });
47
+ }), y(new Map(r.current)), p(null));
48
+ }, [o]);
49
+ M(() => {
50
+ !o || z.current || l != null && l.initialTools && l.initialTools.length > 0 && (z.current = !0, setTimeout(() => {
51
+ R(l.initialTools);
52
+ }, 100));
53
+ }, [o, l == null ? void 0 : l.initialTools, R]);
54
+ const G = d((n) => {
55
+ var e, t;
56
+ if (o) {
57
+ if (A === n) {
58
+ L(null);
59
+ return;
60
+ }
61
+ L(n), n !== "Text" && o.addLineTool(n, [], {
62
+ line: {
63
+ width: ((e = T.current.line) == null ? void 0 : e.width) || 2,
64
+ color: ((t = T.current.line) == null ? void 0 : t.color) || "#2962FF"
65
+ }
66
+ });
67
+ }
68
+ }, [o, A]), H = d((n) => {
69
+ var e, t;
70
+ !o || !n || o.addLineTool("Text", [], {
71
+ text: {
72
+ value: n,
73
+ font: {
74
+ color: ((e = T.current.line) == null ? void 0 : e.color) || "#2962FF",
75
+ size: (((t = T.current.line) == null ? void 0 : t.width) || 2) * 10
76
+ }
77
+ }
78
+ });
79
+ }, [o]), J = d(() => {
80
+ o && (o.removeAllLineTools(), r.current.clear(), y(/* @__PURE__ */ new Map()), p(null), L(null), F());
81
+ }, [o, F]), K = d(() => {
82
+ if (!o || !s) return;
83
+ const n = O(s);
84
+ p(n), F();
85
+ }, [o, s, O, F]), N = d((n) => {
86
+ var u, c, w, a, g, m;
87
+ if (!o || !s || !r.current.has(s)) return;
88
+ const e = r.current.get(s);
89
+ let t;
90
+ e.toolType === "Text" ? t = {
91
+ ...e.options,
92
+ text: {
93
+ value: ((u = e.options.text) == null ? void 0 : u.value) || "",
94
+ font: {
95
+ ...(c = e.options.text) == null ? void 0 : c.font,
96
+ color: ((a = (w = e.options.text) == null ? void 0 : w.font) == null ? void 0 : a.color) || "#2962FF",
97
+ size: n * 10
98
+ }
99
+ }
100
+ } : t = {
101
+ ...e.options,
102
+ line: {
103
+ ...e.options.line,
104
+ width: n,
105
+ color: ((g = e.options.line) == null ? void 0 : g.color) || "#2962FF"
106
+ }
107
+ };
108
+ const i = x(s, t);
109
+ p(i), T.current.line = { ...T.current.line, width: n, color: ((m = T.current.line) == null ? void 0 : m.color) || "#2962FF" };
110
+ }, [o, s, x]), P = d((n) => {
111
+ var u, c, w, a, g, m;
112
+ if (!o || !s || !r.current.has(s)) return;
113
+ const e = r.current.get(s);
114
+ let t;
115
+ e.toolType === "Text" ? t = {
116
+ ...e.options,
117
+ text: {
118
+ value: ((u = e.options.text) == null ? void 0 : u.value) || "",
119
+ font: {
120
+ ...(c = e.options.text) == null ? void 0 : c.font,
121
+ color: n,
122
+ size: ((a = (w = e.options.text) == null ? void 0 : w.font) == null ? void 0 : a.size) || 20
123
+ }
124
+ }
125
+ } : t = {
126
+ ...e.options,
127
+ line: {
128
+ ...e.options.line,
129
+ color: n,
130
+ width: ((g = e.options.line) == null ? void 0 : g.width) || 2
131
+ }
132
+ };
133
+ const i = x(s, t);
134
+ p(i), T.current.line = { ...T.current.line, color: n, width: ((m = T.current.line) == null ? void 0 : m.width) || 2 };
135
+ }, [o, s, x]), Q = d((n) => {
136
+ if (!o || !s || !r.current.has(s)) return;
137
+ const e = r.current.get(s);
138
+ if (e.toolType !== "Text") return;
139
+ const t = {
140
+ ...e.options,
141
+ text: {
142
+ ...e.options.text,
143
+ value: n
144
+ }
145
+ }, i = x(s, t);
146
+ p(i);
147
+ }, [o, s, x]);
148
+ M(() => {
149
+ I.current = l == null ? void 0 : l.onToolFinished, C.current = l == null ? void 0 : l.onToolsChange;
150
+ }, [l == null ? void 0 : l.onToolFinished, l == null ? void 0 : l.onToolsChange]), M(() => {
151
+ if (!o) return;
152
+ const n = (e) => {
153
+ const t = e.selectedLineTool;
154
+ if (!t) return;
155
+ const i = t.id, u = {
156
+ id: i,
157
+ toolType: t.toolType,
158
+ points: t.points,
159
+ options: t.options
160
+ };
161
+ r.current.set(i, u), y(new Map(r.current)), p(i), (e.stage === "lineToolFinished" || e.stage === "pathFinished") && (L(null), I.current && I.current(u), F());
162
+ };
163
+ return o.subscribeLineToolsAfterEdit(n), () => {
164
+ };
165
+ }, [o]);
166
+ const f = s ? r.current.get(s) : null, V = ((k = (S = f == null ? void 0 : f.options) == null ? void 0 : S.line) == null ? void 0 : k.width) || 2, X = ((W = (U = f == null ? void 0 : f.options) == null ? void 0 : U.line) == null ? void 0 : W.color) || ((q = (j = (h = f == null ? void 0 : f.options) == null ? void 0 : h.text) == null ? void 0 : j.font) == null ? void 0 : q.color) || "#2962FF";
167
+ return {
168
+ activeToolType: A,
169
+ selectedToolId: s,
170
+ selectedTool: f,
171
+ currentWidth: V,
172
+ currentColor: X,
173
+ tools: B,
174
+ activateTool: G,
175
+ addTextTool: H,
176
+ removeAllTools: J,
177
+ removeSelectedTool: K,
178
+ updateLineWidth: N,
179
+ updateColor: P,
180
+ updateText: Q,
181
+ setSelectedToolId: p,
182
+ exportTools: D,
183
+ loadTools: R
184
+ };
185
+ }
186
+ export {
187
+ _ as useLineTools
188
+ };
189
+ //# sourceMappingURL=useLineTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLineTools.js","sources":["../../../src/react/hooks/useLineTools.ts"],"sourcesContent":["import { useState, useRef, useCallback, useEffect } from 'react';\nimport type { IChartApi } from 'lightweight-charts';\nimport type { LineToolType, LineTool, LineToolOptions } from '../types';\nimport { getToolIdFromResult } from '../../utils/getToolId';\n\nexport interface UseLineToolsOptions {\n onToolFinished?: (tool: LineTool) => void;\n onToolsChange?: (tools: LineTool[]) => void;\n initialTools?: LineTool[];\n}\n\nexport function useLineTools(chart: IChartApi | null, options?: UseLineToolsOptions) {\n const [activeToolType, setActiveToolType] = useState<LineToolType | null>(null);\n const [selectedToolId, setSelectedToolId] = useState<string | null>(null);\n const [tools, setTools] = useState<Map<string, LineTool>>(new Map());\n\n const toolsRef = useRef<Map<string, LineTool>>(new Map());\n const lastOptionsRef = useRef<LineToolOptions>({\n line: { width: 2, color: '#2962FF' }\n });\n const onToolFinishedRef = useRef(options?.onToolFinished);\n const onToolsChangeRef = useRef(options?.onToolsChange);\n const initialToolsLoadedRef = useRef(false);\n\n // 도구 변경 알림 함수\n const notifyToolsChange = useCallback(() => {\n if (onToolsChangeRef.current) {\n const toolsArray = Array.from(toolsRef.current.values());\n onToolsChangeRef.current(toolsArray);\n }\n }, []);\n\n // --- 공통 리빌드 헬퍼 ---\n\n /** 모든 도구를 제거 후 재생성하며, targetToolId의 옵션만 updatedOptions로 교체 */\n const rebuildToolsWithUpdate = useCallback((targetToolId: string, updatedOptions: LineToolOptions): string | null => {\n if (!chart) return null;\n\n const allTools = Array.from(toolsRef.current.values());\n (chart as any).removeAllLineTools();\n toolsRef.current.clear();\n\n let newTargetId: string | null = null;\n allTools.forEach(t => {\n const opts = t.id === targetToolId ? updatedOptions : t.options;\n const result = (chart as any).addLineTool(t.toolType, t.points, opts);\n const newId = getToolIdFromResult(result);\n if (newId) {\n toolsRef.current.set(newId, {\n id: newId,\n toolType: t.toolType,\n points: t.points,\n options: opts\n });\n if (t.id === targetToolId) {\n newTargetId = newId;\n }\n }\n });\n\n setTools(new Map(toolsRef.current));\n return newTargetId;\n }, [chart]);\n\n /** excludeId를 제외한 도구들만 재생성 */\n const rebuildToolsExcluding = useCallback((excludeId: string): string | null => {\n if (!chart) return null;\n\n const allTools = Array.from(toolsRef.current.values());\n const remainingTools = allTools.filter(t => t.id !== excludeId);\n\n (chart as any).removeAllLineTools();\n toolsRef.current.clear();\n\n remainingTools.forEach(t => {\n const result = (chart as any).addLineTool(t.toolType, t.points, t.options);\n const newId = getToolIdFromResult(result);\n if (newId) {\n toolsRef.current.set(newId, {\n id: newId,\n toolType: t.toolType,\n points: t.points,\n options: t.options\n });\n }\n });\n\n setTools(new Map(toolsRef.current));\n return toolsRef.current.size > 0 ? Array.from(toolsRef.current.keys())[0] : null;\n }, [chart]);\n\n // 모든 도구를 배열로 내보내기\n const exportTools = useCallback((): LineTool[] => {\n return Array.from(toolsRef.current.values());\n }, []);\n\n // 저장된 도구 불러오기\n const loadTools = useCallback((savedTools: LineTool[]) => {\n if (!chart || !savedTools || savedTools.length === 0) return;\n\n // 기존 도구 제거\n (chart as any).removeAllLineTools();\n toolsRef.current.clear();\n\n // 저장된 도구 복원\n savedTools.forEach(t => {\n const result = (chart as any).addLineTool(t.toolType, t.points, t.options);\n const newId = getToolIdFromResult(result);\n if (newId) {\n toolsRef.current.set(newId, {\n id: newId,\n toolType: t.toolType,\n points: t.points,\n options: t.options\n });\n }\n });\n\n setTools(new Map(toolsRef.current));\n setSelectedToolId(null);\n }, [chart]);\n\n // 초기 도구 로드 (차트 준비 후)\n useEffect(() => {\n if (!chart || initialToolsLoadedRef.current) return;\n if (options?.initialTools && options.initialTools.length > 0) {\n initialToolsLoadedRef.current = true;\n // 차트가 완전히 준비될 때까지 약간 대기\n setTimeout(() => {\n loadTools(options.initialTools!);\n }, 100);\n }\n }, [chart, options?.initialTools, loadTools]);\n\n // Line Tool 활성화\n const activateTool = useCallback((toolType: LineToolType) => {\n if (!chart) return;\n\n if (activeToolType === toolType) {\n setActiveToolType(null);\n return;\n }\n\n setActiveToolType(toolType);\n\n if (toolType === 'Text') {\n // 텍스트는 모달 입력 필요\n return;\n }\n\n (chart as any).addLineTool(toolType, [], {\n line: {\n width: lastOptionsRef.current.line?.width || 2,\n color: lastOptionsRef.current.line?.color || '#2962FF'\n }\n });\n }, [chart, activeToolType]);\n\n // 텍스트 도구 추가\n const addTextTool = useCallback((text: string) => {\n if (!chart || !text) return;\n\n (chart as any).addLineTool('Text', [], {\n text: {\n value: text,\n font: {\n color: lastOptionsRef.current.line?.color || '#2962FF',\n size: (lastOptionsRef.current.line?.width || 2) * 10\n }\n }\n });\n }, [chart]);\n\n // 모든 도구 제거\n const removeAllTools = useCallback(() => {\n if (!chart) return;\n (chart as any).removeAllLineTools();\n toolsRef.current.clear();\n setTools(new Map());\n setSelectedToolId(null);\n setActiveToolType(null);\n notifyToolsChange();\n }, [chart, notifyToolsChange]);\n\n // 선택된 도구 삭제\n const removeSelectedTool = useCallback(() => {\n if (!chart || !selectedToolId) return;\n const firstRemainingId = rebuildToolsExcluding(selectedToolId);\n setSelectedToolId(firstRemainingId);\n notifyToolsChange();\n }, [chart, selectedToolId, rebuildToolsExcluding, notifyToolsChange]);\n\n // 선 두께 변경\n const updateLineWidth = useCallback((newWidth: number) => {\n if (!chart || !selectedToolId || !toolsRef.current.has(selectedToolId)) return;\n\n const tool = toolsRef.current.get(selectedToolId)!;\n let updatedOptions: LineToolOptions;\n\n if (tool.toolType === 'Text') {\n updatedOptions = {\n ...tool.options,\n text: {\n value: tool.options.text?.value || '',\n font: {\n ...tool.options.text?.font,\n color: tool.options.text?.font?.color || '#2962FF',\n size: newWidth * 10,\n }\n }\n };\n } else {\n updatedOptions = {\n ...tool.options,\n line: {\n ...tool.options.line,\n width: newWidth,\n color: tool.options.line?.color || '#2962FF'\n }\n };\n }\n\n const newId = rebuildToolsWithUpdate(selectedToolId, updatedOptions);\n setSelectedToolId(newId);\n lastOptionsRef.current.line = { ...lastOptionsRef.current.line, width: newWidth, color: lastOptionsRef.current.line?.color || '#2962FF' };\n }, [chart, selectedToolId, rebuildToolsWithUpdate]);\n\n // 색상 변경\n const updateColor = useCallback((color: string) => {\n if (!chart || !selectedToolId || !toolsRef.current.has(selectedToolId)) return;\n\n const tool = toolsRef.current.get(selectedToolId)!;\n let updatedOptions: LineToolOptions;\n\n if (tool.toolType === 'Text') {\n updatedOptions = {\n ...tool.options,\n text: {\n value: tool.options.text?.value || '',\n font: {\n ...tool.options.text?.font,\n color: color,\n size: tool.options.text?.font?.size || 20\n }\n }\n };\n } else {\n updatedOptions = {\n ...tool.options,\n line: {\n ...tool.options.line,\n color: color,\n width: tool.options.line?.width || 2\n }\n };\n }\n\n const newId = rebuildToolsWithUpdate(selectedToolId, updatedOptions);\n setSelectedToolId(newId);\n lastOptionsRef.current.line = { ...lastOptionsRef.current.line, color, width: lastOptionsRef.current.line?.width || 2 };\n }, [chart, selectedToolId, rebuildToolsWithUpdate]);\n\n // 텍스트 수정\n const updateText = useCallback((newText: string) => {\n if (!chart || !selectedToolId || !toolsRef.current.has(selectedToolId)) return;\n\n const tool = toolsRef.current.get(selectedToolId)!;\n if (tool.toolType !== 'Text') return;\n\n const updatedOptions: LineToolOptions = {\n ...tool.options,\n text: {\n ...tool.options.text,\n value: newText,\n }\n };\n\n const newId = rebuildToolsWithUpdate(selectedToolId, updatedOptions);\n setSelectedToolId(newId);\n }, [chart, selectedToolId, rebuildToolsWithUpdate]);\n\n // Update callback refs\n useEffect(() => {\n onToolFinishedRef.current = options?.onToolFinished;\n onToolsChangeRef.current = options?.onToolsChange;\n }, [options?.onToolFinished, options?.onToolsChange]);\n\n // LineTools 이벤트 구독\n useEffect(() => {\n if (!chart) return;\n\n const handleLineToolsAfterEdit = (params: any) => {\n const tool = params.selectedLineTool;\n if (!tool) return;\n\n const toolId = tool.id;\n\n const lineTool: LineTool = {\n id: toolId,\n toolType: tool.toolType,\n points: tool.points,\n options: tool.options\n };\n\n toolsRef.current.set(toolId, lineTool);\n\n setTools(new Map(toolsRef.current));\n setSelectedToolId(toolId);\n\n if (params.stage === 'lineToolFinished' || params.stage === 'pathFinished') {\n setActiveToolType(null);\n // Call onToolFinished callback\n if (onToolFinishedRef.current) {\n onToolFinishedRef.current(lineTool);\n }\n // Notify tools change\n notifyToolsChange();\n }\n };\n\n (chart as any).subscribeLineToolsAfterEdit(handleLineToolsAfterEdit);\n\n return () => {\n // cleanup\n };\n }, [chart]);\n\n const selectedTool = selectedToolId ? toolsRef.current.get(selectedToolId) : null;\n const currentWidth = selectedTool?.options?.line?.width || 2;\n const currentColor = selectedTool?.options?.line?.color ||\n selectedTool?.options?.text?.font?.color || '#2962FF';\n\n return {\n activeToolType,\n selectedToolId,\n selectedTool,\n currentWidth,\n currentColor,\n tools,\n activateTool,\n addTextTool,\n removeAllTools,\n removeSelectedTool,\n updateLineWidth,\n updateColor,\n updateText,\n setSelectedToolId,\n exportTools,\n loadTools,\n };\n}\n"],"names":["useLineTools","chart","options","activeToolType","setActiveToolType","useState","selectedToolId","setSelectedToolId","tools","setTools","toolsRef","useRef","lastOptionsRef","onToolFinishedRef","onToolsChangeRef","initialToolsLoadedRef","notifyToolsChange","useCallback","toolsArray","rebuildToolsWithUpdate","targetToolId","updatedOptions","allTools","newTargetId","t","opts","result","newId","getToolIdFromResult","rebuildToolsExcluding","excludeId","remainingTools","exportTools","loadTools","savedTools","useEffect","activateTool","toolType","_a","_b","addTextTool","text","removeAllTools","removeSelectedTool","firstRemainingId","updateLineWidth","newWidth","tool","_d","_c","_e","_f","updateColor","color","updateText","newText","handleLineToolsAfterEdit","params","toolId","lineTool","selectedTool","currentWidth","currentColor","_g"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { IChartApi, ISeriesApi } from 'lightweight-charts';
2
+ import { CandleData } from '../../types';
3
+ /**
4
+ * useShiftSnap Hook
5
+ * Shift 키를 누르면 차트의 crosshair가 가장 가까운 high/low 가격에 스냅됩니다.
6
+ * Shift Snap 시각적 피드백을 위한 horizontal line을 표시합니다.
7
+ */
8
+ export declare function useShiftSnap(chart: IChartApi | null, candleSeries: ISeriesApi<'Candlestick'> | null, candles: CandleData[]): {
9
+ shiftPressed: boolean;
10
+ snapPrice: number | null;
11
+ };
12
+ //# sourceMappingURL=useShiftSnap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShiftSnap.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useShiftSnap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,GAAG,IAAI,EACvB,YAAY,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,IAAI,EAC9C,OAAO,EAAE,UAAU,EAAE;;;EAmHtB"}
@@ -0,0 +1,54 @@
1
+ import { useState as p, useRef as v, useEffect as y, useCallback as P } from "react";
2
+ function k(f, t, h) {
3
+ const [o, m] = p(!1), [w, b] = p(null), r = v(null), n = v(null);
4
+ y(() => {
5
+ const u = (e) => {
6
+ e.key === "Shift" && !o && m(!0);
7
+ }, i = (e) => {
8
+ e.key === "Shift" && (m(!1), b(null));
9
+ };
10
+ return window.addEventListener("keydown", u), window.addEventListener("keyup", i), () => {
11
+ window.removeEventListener("keydown", u), window.removeEventListener("keyup", i);
12
+ };
13
+ }, [o]);
14
+ const d = P((u, i) => {
15
+ if (h.length === 0) return null;
16
+ const e = h.find((l) => {
17
+ const s = typeof l.time == "number" ? l.time : new Date(l.time).getTime() / 1e3;
18
+ return Math.abs(s - u) < 1;
19
+ });
20
+ if (!e) return null;
21
+ const a = Math.abs(e.high - i), c = Math.abs(e.low - i);
22
+ return a < c ? e.high : e.low;
23
+ }, [h]);
24
+ return y(() => {
25
+ if (!f || !t || !o) {
26
+ r.current && (r.current(), r.current = null), n.current && t && (t.removePriceLine(n.current), n.current = null);
27
+ return;
28
+ }
29
+ const u = (e) => {
30
+ var L;
31
+ if (!e.time) return;
32
+ const a = typeof e.time == "number" ? e.time : new Date(e.time).getTime() / 1e3, c = (L = e.seriesData) == null ? void 0 : L.get(t);
33
+ if (!c) return;
34
+ const l = (c.close + c.open) / 2, s = d(a, l);
35
+ s !== null && s !== w && (b(s), n.current && t.removePriceLine(n.current), n.current = t.createPriceLine({
36
+ price: s,
37
+ color: "#2962FF",
38
+ lineWidth: 1,
39
+ lineStyle: 2,
40
+ // Dashed
41
+ lineVisible: !0,
42
+ axisLabelVisible: !0,
43
+ title: "Snap"
44
+ }));
45
+ }, i = f.subscribeCrosshairMove(u);
46
+ return r.current = i, () => {
47
+ r.current && (r.current(), r.current = null), n.current && t && (t.removePriceLine(n.current), n.current = null);
48
+ };
49
+ }, [f, t, o, w, d]), { shiftPressed: o, snapPrice: w };
50
+ }
51
+ export {
52
+ k as useShiftSnap
53
+ };
54
+ //# sourceMappingURL=useShiftSnap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShiftSnap.js","sources":["../../../src/react/hooks/useShiftSnap.ts"],"sourcesContent":["import { useEffect, useState, useRef, useCallback } from 'react';\nimport type { IChartApi, ISeriesApi } from 'lightweight-charts';\nimport type { CandleData } from '../../types';\n\n/**\n * useShiftSnap Hook\n * Shift 키를 누르면 차트의 crosshair가 가장 가까운 high/low 가격에 스냅됩니다.\n * Shift Snap 시각적 피드백을 위한 horizontal line을 표시합니다.\n */\nexport function useShiftSnap(\n chart: IChartApi | null,\n candleSeries: ISeriesApi<'Candlestick'> | null,\n candles: CandleData[]\n) {\n const [shiftPressed, setShiftPressed] = useState(false);\n const [snapPrice, setSnapPrice] = useState<number | null>(null);\n const unsubscribeRef = useRef<(() => void) | null>(null);\n const snapLineRef = useRef<any>(null);\n\n // Shift 키 핸들러\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Shift' && !shiftPressed) {\n setShiftPressed(true);\n }\n };\n\n const handleKeyUp = (e: KeyboardEvent) => {\n if (e.key === 'Shift') {\n setShiftPressed(false);\n setSnapPrice(null);\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n window.addEventListener('keyup', handleKeyUp);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n window.removeEventListener('keyup', handleKeyUp);\n };\n }, [shiftPressed]);\n\n // 가장 가까운 high/low 찾기\n const findNearestHighLow = useCallback((time: number, price: number): number | null => {\n if (candles.length === 0) return null;\n\n // 해당 시간의 캔들 찾기\n const candle = candles.find(c => {\n const candleTime = typeof c.time === 'number' ? c.time : new Date(c.time).getTime() / 1000;\n return Math.abs(candleTime - time) < 1; // Allow 1 second tolerance\n });\n\n if (!candle) return null;\n\n // high와 low 중 더 가까운 것 선택\n const distToHigh = Math.abs(candle.high - price);\n const distToLow = Math.abs(candle.low - price);\n\n return distToHigh < distToLow ? candle.high : candle.low;\n }, [candles]);\n\n // Crosshair move 구독 및 snap line 표시\n useEffect(() => {\n if (!chart || !candleSeries || !shiftPressed) {\n // Shift가 해제되면 구독 해제 및 snap line 제거\n if (unsubscribeRef.current) {\n unsubscribeRef.current();\n unsubscribeRef.current = null;\n }\n if (snapLineRef.current && candleSeries) {\n candleSeries.removePriceLine(snapLineRef.current);\n snapLineRef.current = null;\n }\n return;\n }\n\n // Shift가 눌리면 구독 시작\n const handleCrosshairMove = (param: any) => {\n if (!param.time) return;\n\n const time = typeof param.time === 'number' ? param.time : new Date(param.time).getTime() / 1000;\n\n // 현재 가격 가져오기\n const seriesData = param.seriesData?.get(candleSeries);\n if (!seriesData) return;\n\n const currentPrice = (seriesData.close + seriesData.open) / 2;\n const snappedPrice = findNearestHighLow(time, currentPrice);\n\n if (snappedPrice !== null && snappedPrice !== snapPrice) {\n setSnapPrice(snappedPrice);\n\n // 기존 snap line 제거\n if (snapLineRef.current) {\n candleSeries.removePriceLine(snapLineRef.current);\n }\n\n // 새로운 snap line 추가 (시각적 피드백)\n snapLineRef.current = candleSeries.createPriceLine({\n price: snappedPrice,\n color: '#2962FF',\n lineWidth: 1 as any,\n lineStyle: 2 as any, // Dashed\n lineVisible: true,\n axisLabelVisible: true,\n title: 'Snap',\n });\n }\n };\n\n const unsub = chart.subscribeCrosshairMove(handleCrosshairMove);\n unsubscribeRef.current = unsub as any;\n\n return () => {\n if (unsubscribeRef.current) {\n unsubscribeRef.current();\n unsubscribeRef.current = null;\n }\n if (snapLineRef.current && candleSeries) {\n candleSeries.removePriceLine(snapLineRef.current);\n snapLineRef.current = null;\n }\n };\n }, [chart, candleSeries, shiftPressed, snapPrice, findNearestHighLow]);\n\n return { shiftPressed, snapPrice };\n}\n"],"names":["useShiftSnap","chart","candleSeries","candles","shiftPressed","setShiftPressed","useState","snapPrice","setSnapPrice","unsubscribeRef","useRef","snapLineRef","useEffect","handleKeyDown","handleKeyUp","findNearestHighLow","useCallback","time","price","candle","c","candleTime","distToHigh","distToLow","handleCrosshairMove","param","seriesData","_a","currentPrice","snappedPrice","unsub"],"mappings":";AASO,SAASA,EACdC,GACAC,GACAC,GACA;AACA,QAAM,CAACC,GAAcC,CAAe,IAAIC,EAAS,EAAK,GAChD,CAACC,GAAWC,CAAY,IAAIF,EAAwB,IAAI,GACxDG,IAAiBC,EAA4B,IAAI,GACjDC,IAAcD,EAAY,IAAI;AAGpC,EAAAE,EAAU,MAAM;AACd,UAAMC,IAAgB,CAAC,MAAqB;AAC1C,MAAI,EAAE,QAAQ,WAAW,CAACT,KACxBC,EAAgB,EAAI;AAAA,IAExB,GAEMS,IAAc,CAAC,MAAqB;AACxC,MAAI,EAAE,QAAQ,YACZT,EAAgB,EAAK,GACrBG,EAAa,IAAI;AAAA,IAErB;AAEA,kBAAO,iBAAiB,WAAWK,CAAa,GAChD,OAAO,iBAAiB,SAASC,CAAW,GAErC,MAAM;AACX,aAAO,oBAAoB,WAAWD,CAAa,GACnD,OAAO,oBAAoB,SAASC,CAAW;AAAA,IACjD;AAAA,EACF,GAAG,CAACV,CAAY,CAAC;AAGjB,QAAMW,IAAqBC,EAAY,CAACC,GAAcC,MAAiC;AACrF,QAAIf,EAAQ,WAAW,EAAG,QAAO;AAGjC,UAAMgB,IAAShB,EAAQ,KAAK,CAAAiB,MAAK;AAC/B,YAAMC,IAAa,OAAOD,EAAE,QAAS,WAAWA,EAAE,OAAO,IAAI,KAAKA,EAAE,IAAI,EAAE,YAAY;AACtF,aAAO,KAAK,IAAIC,IAAaJ,CAAI,IAAI;AAAA,IACvC,CAAC;AAED,QAAI,CAACE,EAAQ,QAAO;AAGpB,UAAMG,IAAa,KAAK,IAAIH,EAAO,OAAOD,CAAK,GACzCK,IAAY,KAAK,IAAIJ,EAAO,MAAMD,CAAK;AAE7C,WAAOI,IAAaC,IAAYJ,EAAO,OAAOA,EAAO;AAAA,EACvD,GAAG,CAAChB,CAAO,CAAC;AAGZ,SAAAS,EAAU,MAAM;AACd,QAAI,CAACX,KAAS,CAACC,KAAgB,CAACE,GAAc;AAE5C,MAAIK,EAAe,YACjBA,EAAe,QAAA,GACfA,EAAe,UAAU,OAEvBE,EAAY,WAAWT,MACzBA,EAAa,gBAAgBS,EAAY,OAAO,GAChDA,EAAY,UAAU;AAExB;AAAA,IACF;AAGA,UAAMa,IAAsB,CAACC,MAAe;;AAC1C,UAAI,CAACA,EAAM,KAAM;AAEjB,YAAMR,IAAO,OAAOQ,EAAM,QAAS,WAAWA,EAAM,OAAO,IAAI,KAAKA,EAAM,IAAI,EAAE,YAAY,KAGtFC,KAAaC,IAAAF,EAAM,eAAN,gBAAAE,EAAkB,IAAIzB;AACzC,UAAI,CAACwB,EAAY;AAEjB,YAAME,KAAgBF,EAAW,QAAQA,EAAW,QAAQ,GACtDG,IAAed,EAAmBE,GAAMW,CAAY;AAE1D,MAAIC,MAAiB,QAAQA,MAAiBtB,MAC5CC,EAAaqB,CAAY,GAGrBlB,EAAY,WACdT,EAAa,gBAAgBS,EAAY,OAAO,GAIlDA,EAAY,UAAUT,EAAa,gBAAgB;AAAA,QACjD,OAAO2B;AAAA,QACP,OAAO;AAAA,QACP,WAAW;AAAA,QACX,WAAW;AAAA;AAAA,QACX,aAAa;AAAA,QACb,kBAAkB;AAAA,QAClB,OAAO;AAAA,MAAA,CACR;AAAA,IAEL,GAEMC,IAAQ7B,EAAM,uBAAuBuB,CAAmB;AAC9D,WAAAf,EAAe,UAAUqB,GAElB,MAAM;AACX,MAAIrB,EAAe,YACjBA,EAAe,QAAA,GACfA,EAAe,UAAU,OAEvBE,EAAY,WAAWT,MACzBA,EAAa,gBAAgBS,EAAY,OAAO,GAChDA,EAAY,UAAU;AAAA,IAE1B;AAAA,EACF,GAAG,CAACV,GAAOC,GAAcE,GAAcG,GAAWQ,CAAkB,CAAC,GAE9D,EAAE,cAAAX,GAAc,WAAAG,EAAA;AACzB;"}
@@ -0,0 +1,14 @@
1
+ export { FullFeaturedChart } from './FullFeaturedChart';
2
+ export type { FullFeaturedChartProps } from './types';
3
+ export { useChart } from './hooks/useChart';
4
+ export { useIndicators } from './hooks/useIndicators';
5
+ export { useLineTools } from './hooks/useLineTools';
6
+ export { useShiftSnap } from './hooks/useShiftSnap';
7
+ export type { UseChartOptions, UseChartReturn } from './hooks/useChart';
8
+ export type { UseLineToolsOptions } from './hooks/useLineTools';
9
+ export { loadLightweightCharts } from './loadLightweightCharts';
10
+ export { getLocaleStrings } from './locale';
11
+ export type { Locale, LocaleStrings } from './locale';
12
+ export type { CandleData, TimeFrame, ChartOptions } from '../types';
13
+ export type { IndicatorType, LineToolType, LineTool, IndicatorConfigs, TimeFrame as ChartTimeFrame, MarketSession, TimeframeAvailability, PriceLine, } from './types';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AACA,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxE,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAGhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGtD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACpE,YAAY,EACV,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,SAAS,IAAI,cAAc,EAC3B,aAAa,EACb,qBAAqB,EACrB,SAAS,GACV,MAAM,SAAS,CAAC"}
@@ -0,0 +1,18 @@
1
+ /* empty css */
2
+ import { FullFeaturedChart as e } from "./FullFeaturedChart.js";
3
+ import { useChart as a } from "./hooks/useChart.js";
4
+ import { useIndicators as m } from "./hooks/useIndicators.js";
5
+ import { useLineTools as i } from "./hooks/useLineTools.js";
6
+ import { useShiftSnap as h } from "./hooks/useShiftSnap.js";
7
+ import { loadLightweightCharts as l } from "./loadLightweightCharts.js";
8
+ import { getLocaleStrings as n } from "./locale.js";
9
+ export {
10
+ e as FullFeaturedChart,
11
+ n as getLocaleStrings,
12
+ l as loadLightweightCharts,
13
+ a as useChart,
14
+ m as useIndicators,
15
+ i as useLineTools,
16
+ h as useShiftSnap
17
+ };
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Auto-loads the LightweightCharts standalone script if not already present.
3
+ *
4
+ * Resolution order:
5
+ * 1. window.LightweightCharts already exists → resolve immediately
6
+ * 2. Try script paths in order:
7
+ * a. /lightweight-charts.standalone.production.js
8
+ * b. /lib/lightweight-charts.standalone.production.js
9
+ * 3. Cache the promise so concurrent callers share the same load
10
+ * 4. Reset cache on failure so retry is possible
11
+ */
12
+ declare global {
13
+ interface Window {
14
+ LightweightCharts?: any;
15
+ }
16
+ }
17
+ export declare function loadLightweightCharts(): Promise<any>;
18
+ //# sourceMappingURL=loadLightweightCharts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadLightweightCharts.d.ts","sourceRoot":"","sources":["../../src/react/loadLightweightCharts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,iBAAiB,CAAC,EAAE,GAAG,CAAC;KACzB;CACF;AAuBD,wBAAgB,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,CAkCpD"}
@@ -0,0 +1,32 @@
1
+ let o = null;
2
+ const r = [
3
+ "/lightweight-charts.standalone.production.js",
4
+ "/lib/lightweight-charts.standalone.production.js"
5
+ ];
6
+ function a(e) {
7
+ return new Promise((n, i) => {
8
+ const t = document.createElement("script");
9
+ t.src = e, t.async = !0, t.onload = () => n(), t.onerror = () => {
10
+ t.remove(), i(new Error(`Failed to load script: ${e}`));
11
+ }, document.head.appendChild(t);
12
+ });
13
+ }
14
+ function h() {
15
+ return typeof window < "u" && window.LightweightCharts ? Promise.resolve(window.LightweightCharts) : o || (o = (async () => {
16
+ for (const e of r)
17
+ try {
18
+ if (await a(e), window.LightweightCharts)
19
+ return window.LightweightCharts;
20
+ } catch {
21
+ }
22
+ throw new Error(
23
+ "[loadLightweightCharts] Could not load LightweightCharts from any known path. Please include the standalone script in your HTML or place it at one of: " + r.join(", ")
24
+ );
25
+ })(), o.catch(() => {
26
+ o = null;
27
+ }), o);
28
+ }
29
+ export {
30
+ h as loadLightweightCharts
31
+ };
32
+ //# sourceMappingURL=loadLightweightCharts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadLightweightCharts.js","sources":["../../src/react/loadLightweightCharts.ts"],"sourcesContent":["/**\n * Auto-loads the LightweightCharts standalone script if not already present.\n *\n * Resolution order:\n * 1. window.LightweightCharts already exists → resolve immediately\n * 2. Try script paths in order:\n * a. /lightweight-charts.standalone.production.js\n * b. /lib/lightweight-charts.standalone.production.js\n * 3. Cache the promise so concurrent callers share the same load\n * 4. Reset cache on failure so retry is possible\n */\n\ndeclare global {\n interface Window {\n LightweightCharts?: any;\n }\n}\n\nlet loadPromise: Promise<any> | null = null;\n\nconst SCRIPT_PATHS = [\n '/lightweight-charts.standalone.production.js',\n '/lib/lightweight-charts.standalone.production.js',\n];\n\nfunction loadScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => {\n script.remove();\n reject(new Error(`Failed to load script: ${src}`));\n };\n document.head.appendChild(script);\n });\n}\n\nexport function loadLightweightCharts(): Promise<any> {\n // Already loaded\n if (typeof window !== 'undefined' && window.LightweightCharts) {\n return Promise.resolve(window.LightweightCharts);\n }\n\n // Return cached promise if loading in progress\n if (loadPromise) return loadPromise;\n\n loadPromise = (async () => {\n // Try each path in order\n for (const path of SCRIPT_PATHS) {\n try {\n await loadScript(path);\n if (window.LightweightCharts) {\n return window.LightweightCharts;\n }\n } catch {\n // try next path\n }\n }\n throw new Error(\n '[loadLightweightCharts] Could not load LightweightCharts from any known path. ' +\n 'Please include the standalone script in your HTML or place it at one of: ' +\n SCRIPT_PATHS.join(', ')\n );\n })();\n\n // Reset cache on failure so retry is possible\n loadPromise.catch(() => {\n loadPromise = null;\n });\n\n return loadPromise;\n}\n"],"names":["loadPromise","SCRIPT_PATHS","loadScript","src","resolve","reject","script","loadLightweightCharts","path"],"mappings":"AAkBA,IAAIA,IAAmC;AAEvC,MAAMC,IAAe;AAAA,EACnB;AAAA,EACA;AACF;AAEA,SAASC,EAAWC,GAA4B;AAC9C,SAAO,IAAI,QAAQ,CAACC,GAASC,MAAW;AACtC,UAAMC,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,EAAO,MAAMH,GACbG,EAAO,QAAQ,IACfA,EAAO,SAAS,MAAMF,EAAA,GACtBE,EAAO,UAAU,MAAM;AACrB,MAAAA,EAAO,OAAA,GACPD,EAAO,IAAI,MAAM,0BAA0BF,CAAG,EAAE,CAAC;AAAA,IACnD,GACA,SAAS,KAAK,YAAYG,CAAM;AAAA,EAClC,CAAC;AACH;AAEO,SAASC,IAAsC;AAEpD,SAAI,OAAO,SAAW,OAAe,OAAO,oBACnC,QAAQ,QAAQ,OAAO,iBAAiB,IAI7CP,MAEJA,KAAe,YAAY;AAEzB,eAAWQ,KAAQP;AACjB,UAAI;AAEF,YADA,MAAMC,EAAWM,CAAI,GACjB,OAAO;AACT,iBAAO,OAAO;AAAA,MAElB,QAAQ;AAAA,MAER;AAEF,UAAM,IAAI;AAAA,MACR,4JAEAP,EAAa,KAAK,IAAI;AAAA,IAAA;AAAA,EAE1B,GAAA,GAGAD,EAAY,MAAM,MAAM;AACtB,IAAAA,IAAc;AAAA,EAChB,CAAC,GAEMA;AACT;"}
@@ -0,0 +1,79 @@
1
+ export type Locale = 'en' | 'ko';
2
+ export interface LocaleStrings {
3
+ tf_1m: string;
4
+ tf_5m: string;
5
+ tf_15m: string;
6
+ tf_30m: string;
7
+ tf_1h: string;
8
+ tf_1d: string;
9
+ tf_1w: string;
10
+ tf_1M: string;
11
+ tf_unavailable: string;
12
+ tool_TrendLine: string;
13
+ tool_HorizontalLine: string;
14
+ tool_VerticalLine: string;
15
+ tool_Rectangle: string;
16
+ tool_FibRetracement: string;
17
+ tool_Text: string;
18
+ tool_drawing: string;
19
+ btn_indicators: string;
20
+ btn_draw: string;
21
+ btn_clearAll: string;
22
+ cat_overlay: string;
23
+ cat_oscillator: string;
24
+ ind_sma: string;
25
+ ind_ema: string;
26
+ ind_bbands: string;
27
+ ind_rsi: string;
28
+ ind_macd: string;
29
+ ind_stochastic: string;
30
+ ind_atr: string;
31
+ ind_vwap: string;
32
+ ind_williamsR: string;
33
+ ind_sma_desc: string;
34
+ ind_ema_desc: string;
35
+ ind_bbands_desc: string;
36
+ ind_rsi_desc: string;
37
+ ind_macd_desc: string;
38
+ ind_stochastic_desc: string;
39
+ ind_atr_desc: string;
40
+ ind_vwap_desc: string;
41
+ ind_williamsR_desc: string;
42
+ selectIndicator: string;
43
+ enableIndicator: string;
44
+ color: string;
45
+ period: string;
46
+ periodN: (n: number) => string;
47
+ addPeriod: string;
48
+ thickness: string;
49
+ stdDev: string;
50
+ oversold: string;
51
+ overbought: string;
52
+ upper: string;
53
+ middle: string;
54
+ lower: string;
55
+ fast: string;
56
+ slow: string;
57
+ signal: string;
58
+ bullish: string;
59
+ bearish: string;
60
+ colorPaletteTitle: string;
61
+ kPeriod: string;
62
+ dPeriod: string;
63
+ smooth: string;
64
+ kLine: string;
65
+ dLine: string;
66
+ src_close: string;
67
+ src_open: string;
68
+ src_high: string;
69
+ src_low: string;
70
+ loading: string;
71
+ noData: string;
72
+ textEdit: string;
73
+ textAdd: string;
74
+ textPlaceholder: string;
75
+ cancel: string;
76
+ confirm: string;
77
+ }
78
+ export declare function getLocaleStrings(locale?: Locale): LocaleStrings;
79
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/react/locale.ts"],"names":[],"mappings":"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"}