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.
- package/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/__tests__/FullFeaturedChart.test.d.ts +2 -0
- package/dist/__tests__/FullFeaturedChart.test.d.ts.map +1 -0
- package/dist/__tests__/indicators-accuracy.test.d.ts +2 -0
- package/dist/__tests__/indicators-accuracy.test.d.ts.map +1 -0
- package/dist/__tests__/indicators.test.d.ts +2 -0
- package/dist/__tests__/indicators.test.d.ts.map +1 -0
- package/dist/__tests__/setup.d.ts +1 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/validateCandle.test.d.ts +2 -0
- package/dist/__tests__/validateCandle.test.d.ts.map +1 -0
- package/dist/chart/index.d.ts +2 -0
- package/dist/chart/index.js +5 -0
- package/dist/chart/index.js.map +1 -0
- package/dist/components/TradingChart.d.ts +24 -0
- package/dist/components/TradingChart.d.ts.map +1 -0
- package/dist/components/TradingChart.js +100 -0
- package/dist/components/TradingChart.js.map +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/dipping-charts.css +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/indicators/atr.d.ts +15 -0
- package/dist/indicators/atr.d.ts.map +1 -0
- package/dist/indicators/atr.js +30 -0
- package/dist/indicators/atr.js.map +1 -0
- package/dist/indicators/bollingerBands.d.ts +11 -0
- package/dist/indicators/bollingerBands.d.ts.map +1 -0
- package/dist/indicators/bollingerBands.js +39 -0
- package/dist/indicators/bollingerBands.js.map +1 -0
- package/dist/indicators/currencyStrength.d.ts +43 -0
- package/dist/indicators/currencyStrength.d.ts.map +1 -0
- package/dist/indicators/currencyStrength.js +53 -0
- package/dist/indicators/currencyStrength.js.map +1 -0
- package/dist/indicators/ema.d.ts +11 -0
- package/dist/indicators/ema.d.ts.map +1 -0
- package/dist/indicators/ema.js +24 -0
- package/dist/indicators/ema.js.map +1 -0
- package/dist/indicators/index.d.ts +19 -0
- package/dist/indicators/index.d.ts.map +1 -0
- package/dist/indicators/index.js +23 -0
- package/dist/indicators/index.js.map +1 -0
- package/dist/indicators/macd.d.ts +11 -0
- package/dist/indicators/macd.d.ts.map +1 -0
- package/dist/indicators/macd.js +52 -0
- package/dist/indicators/macd.js.map +1 -0
- package/dist/indicators/rsi.d.ts +11 -0
- package/dist/indicators/rsi.d.ts.map +1 -0
- package/dist/indicators/rsi.js +29 -0
- package/dist/indicators/rsi.js.map +1 -0
- package/dist/indicators/sma.d.ts +13 -0
- package/dist/indicators/sma.d.ts.map +1 -0
- package/dist/indicators/sma.js +22 -0
- package/dist/indicators/sma.js.map +1 -0
- package/dist/indicators/stochastic.d.ts +15 -0
- package/dist/indicators/stochastic.d.ts.map +1 -0
- package/dist/indicators/stochastic.js +34 -0
- package/dist/indicators/stochastic.js.map +1 -0
- package/dist/indicators/types.d.ts +102 -0
- package/dist/indicators/types.d.ts.map +1 -0
- package/dist/indicators/vwap.d.ts +14 -0
- package/dist/indicators/vwap.d.ts.map +1 -0
- package/dist/indicators/vwap.js +17 -0
- package/dist/indicators/vwap.js.map +1 -0
- package/dist/indicators/williamsR.d.ts +17 -0
- package/dist/indicators/williamsR.d.ts.map +1 -0
- package/dist/indicators/williamsR.js +19 -0
- package/dist/indicators/williamsR.js.map +1 -0
- package/dist/react/FullFeaturedChart.d.ts +3 -0
- package/dist/react/FullFeaturedChart.d.ts.map +1 -0
- package/dist/react/FullFeaturedChart.js +640 -0
- package/dist/react/FullFeaturedChart.js.map +1 -0
- package/dist/react/components/IndicatorSettings.d.ts +20 -0
- package/dist/react/components/IndicatorSettings.d.ts.map +1 -0
- package/dist/react/components/IndicatorSettings.js +748 -0
- package/dist/react/components/IndicatorSettings.js.map +1 -0
- package/dist/react/hooks/useChart.d.ts +15 -0
- package/dist/react/hooks/useChart.d.ts.map +1 -0
- package/dist/react/hooks/useChart.js +155 -0
- package/dist/react/hooks/useChart.js.map +1 -0
- package/dist/react/hooks/useIndicators.d.ts +10 -0
- package/dist/react/hooks/useIndicators.d.ts.map +1 -0
- package/dist/react/hooks/useIndicators.js +264 -0
- package/dist/react/hooks/useIndicators.js.map +1 -0
- package/dist/react/hooks/useLineTools.d.ts +26 -0
- package/dist/react/hooks/useLineTools.d.ts.map +1 -0
- package/dist/react/hooks/useLineTools.js +189 -0
- package/dist/react/hooks/useLineTools.js.map +1 -0
- package/dist/react/hooks/useShiftSnap.d.ts +12 -0
- package/dist/react/hooks/useShiftSnap.d.ts.map +1 -0
- package/dist/react/hooks/useShiftSnap.js +54 -0
- package/dist/react/hooks/useShiftSnap.js.map +1 -0
- package/dist/react/index.d.ts +14 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +18 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/loadLightweightCharts.d.ts +18 -0
- package/dist/react/loadLightweightCharts.d.ts.map +1 -0
- package/dist/react/loadLightweightCharts.js +32 -0
- package/dist/react/loadLightweightCharts.js.map +1 -0
- package/dist/react/locale.d.ts +79 -0
- package/dist/react/locale.d.ts.map +1 -0
- package/dist/react/locale.js +158 -0
- package/dist/react/locale.js.map +1 -0
- package/dist/react/types.d.ts +130 -0
- package/dist/react/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +24 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/getToolId.d.ts +9 -0
- package/dist/utils/getToolId.d.ts.map +1 -0
- package/dist/utils/getToolId.js +12 -0
- package/dist/utils/getToolId.js.map +1 -0
- package/dist/utils/mockData.d.ts +10 -0
- package/dist/utils/mockData.d.ts.map +1 -0
- package/dist/utils/mockData.js +61 -0
- package/dist/utils/mockData.js.map +1 -0
- package/dist/utils/snapCrosshair.d.ts +25 -0
- package/dist/utils/snapCrosshair.d.ts.map +1 -0
- package/dist/utils/validateCandle.d.ts +30 -0
- package/dist/utils/validateCandle.d.ts.map +1 -0
- package/dist/utils/validateCandle.js +21 -0
- package/dist/utils/validateCandle.js.map +1 -0
- package/examples/css/base.css +209 -0
- package/examples/css/chart.css +282 -0
- package/examples/css/indicators.css +255 -0
- package/examples/index.html +163 -0
- package/examples/js/chart.js +370 -0
- package/examples/js/indicators.js +27 -0
- package/examples/js/main.js +6 -0
- package/examples/js/ui.js +1641 -0
- package/lib/lightweight-charts.standalone.production.js +7 -0
- package/package.json +106 -0
- 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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"}
|