@tradecanvas/chart 1.1.0 → 1.2.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 -21
- package/README.md +79 -9
- package/dist/Chart.d.ts +28 -0
- package/dist/Chart.d.ts.map +1 -1
- package/dist/DataManager.d.ts.map +1 -1
- package/dist/{DragDropImporter-CLtRQjKD.js → DragDropImporter-BcTzFeRP.js} +312 -223
- package/dist/DragDropImporter-BcTzFeRP.js.map +1 -0
- package/dist/DragDropImporter-DZBrretS.cjs +2 -0
- package/dist/DragDropImporter-DZBrretS.cjs.map +1 -0
- package/dist/charts/IndicatorPriceRange.d.ts +7 -3
- package/dist/charts/IndicatorPriceRange.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -19
- package/dist/index.js.map +1 -1
- package/dist/layout/LayoutManager.d.ts +3 -0
- package/dist/layout/LayoutManager.d.ts.map +1 -1
- package/dist/layout/priceAxisWidth.d.ts +22 -0
- package/dist/layout/priceAxisWidth.d.ts.map +1 -0
- package/dist/widget/ChartWidget.d.ts +24 -1
- package/dist/widget/ChartWidget.d.ts.map +1 -1
- package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
- package/dist/widget/WidgetHotkeySheet.d.ts +3 -1
- package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
- package/dist/widget/WidgetLoadingOverlay.d.ts +41 -0
- package/dist/widget/WidgetLoadingOverlay.d.ts.map +1 -0
- package/dist/widget/WidgetObjectTree.d.ts.map +1 -1
- package/dist/widget/WidgetSettings.d.ts +3 -1
- package/dist/widget/WidgetSettings.d.ts.map +1 -1
- package/dist/widget/WidgetToolbar.d.ts +4 -1
- package/dist/widget/WidgetToolbar.d.ts.map +1 -1
- package/dist/widget/WidgetWatchlist.d.ts +4 -1
- package/dist/widget/WidgetWatchlist.d.ts.map +1 -1
- package/dist/widget/i18n.d.ts +70 -0
- package/dist/widget/i18n.d.ts.map +1 -0
- package/dist/widget/icons.d.ts.map +1 -1
- package/dist/widget/index.cjs +2458 -2380
- package/dist/widget/index.cjs.map +1 -1
- package/dist/widget/index.js +635 -237
- package/dist/widget/index.js.map +1 -1
- package/dist/widget/types.d.ts +10 -0
- package/dist/widget/types.d.ts.map +1 -1
- package/dist/widget/widgetConfig.d.ts.map +1 -1
- package/package.json +6 -3
- package/dist/DragDropImporter-CLtRQjKD.js.map +0 -1
- package/dist/DragDropImporter-pPS0fl5H.cjs +0 -2
- package/dist/DragDropImporter-pPS0fl5H.cjs.map +0 -1
package/dist/widget/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/io/resampleOHLCV.ts","../../src/widget/widgetConfig.ts","../../src/widget/WidgetStyles.ts","../../src/widget/icons.ts","../../src/widget/WidgetDropdown.ts","../../src/widget/WidgetToolbar.ts","../../src/widget/WidgetDrawingSidebar.ts","../../src/widget/WidgetSettings.ts","../../src/widget/WidgetStatusBar.ts","../../src/widget/WidgetCommandPalette.ts","../../src/widget/WidgetSymbolSearch.ts","../../src/widget/WidgetHotkeySheet.ts","../../src/widget/WidgetReplayBar.ts","../../src/widget/WidgetWatchlist.ts","../../src/widget/WidgetAlertsPanel.ts","../../src/widget/WidgetObjectTree.ts","../../src/widget/WidgetIndicatorSettings.ts","../../src/widget/DrawingTemplateStore.ts","../../src/widget/WidgetDrawingStyle.ts","../../src/widget/DrawingFavoritesStore.ts","../../src/widget/WidgetBracketBar.ts","../../src/widget/AlertNotifier.ts","../../src/widget/ladderRows.ts","../../src/widget/WidgetDepthLadder.ts","../../src/widget/WidgetDataWindow.ts","../../src/widget/widgetShareState.ts","../../src/widget/ChartWidget.ts"],"sourcesContent":["import type { DataSeries, OHLCBar, TimeFrame } from '@tradecanvas/commons';\nimport { timeframeToMs, timeframeBucketStart } from '@tradecanvas/commons';\n\nexport interface ResampleOptions {\n /** 0 = Sunday, 1 = Monday (default) — anchor for weekly buckets. */\n weekStartsOn?: 0 | 1;\n}\n\n/**\n * Aggregate a finer OHLCV series into a coarser timeframe.\n *\n * Bars are grouped by calendar-aware bucket (see `timeframeBucketStart`):\n * open = first bar's open, high/low = extremes, close = last bar's close,\n * volume = sum. Input bars are assumed sorted ascending by `time` and are\n * never mutated.\n *\n * Upsampling (target finer than source) cannot synthesize data — pass a target\n * coarser than the source. Use `inferTimeframeMs` to detect the source spacing.\n */\nexport function resampleOHLCV(\n bars: DataSeries,\n target: TimeFrame,\n opts: ResampleOptions = {},\n): DataSeries {\n if (bars.length === 0) return [];\n const weekStartsOn = opts.weekStartsOn ?? 1;\n\n const out: OHLCBar[] = [];\n let current: OHLCBar | null = null;\n let currentKey = Number.NaN;\n\n for (const bar of bars) {\n const key = timeframeBucketStart(bar.time, target, weekStartsOn);\n if (current === null || key !== currentKey) {\n if (current !== null) out.push(current);\n current = {\n time: key,\n open: bar.open,\n high: bar.high,\n low: bar.low,\n close: bar.close,\n volume: bar.volume,\n };\n currentKey = key;\n } else {\n current = {\n time: current.time,\n open: current.open,\n high: Math.max(current.high, bar.high),\n low: Math.min(current.low, bar.low),\n close: bar.close,\n volume: current.volume + bar.volume,\n };\n }\n }\n if (current !== null) out.push(current);\n return out;\n}\n\n/**\n * Estimate the source bar spacing in milliseconds from the median gap between\n * consecutive bars. Robust to occasional gaps (weekends, halts). Returns 0 for\n * series with fewer than two bars.\n */\nexport function inferTimeframeMs(bars: DataSeries): number {\n if (bars.length < 2) return 0;\n const gaps: number[] = [];\n for (let i = 1; i < bars.length; i++) {\n const gap = bars[i].time - bars[i - 1].time;\n if (gap > 0) gaps.push(gap);\n }\n if (gaps.length === 0) return 0;\n gaps.sort((a, b) => a - b);\n return gaps[Math.floor(gaps.length / 2)];\n}\n\n/**\n * Whether `target` is coarser than (or equal to) the source spacing, i.e. a\n * valid downsample. A non-positive `sourceMs` (unknown) is treated as valid.\n */\nexport function canResample(sourceMs: number, target: TimeFrame): boolean {\n if (sourceMs <= 0) return true;\n return timeframeToMs(target) >= sourceMs;\n}\n","import type { ChartType, DrawingToolType, TimeFrame } from '@tradecanvas/commons';\nimport type { IndicatorDef, DrawingToolGroupDef, ChartSettingsState } from './types.js';\n\nexport const TIMEFRAMES: { label: string; value: TimeFrame }[] = [\n { label: '1m', value: '1m' },\n { label: '5m', value: '5m' },\n { label: '15m', value: '15m' },\n { label: '1H', value: '1h' },\n { label: '4H', value: '4h' },\n { label: '1D', value: '1d' },\n];\n\nexport const CHART_TYPES: { label: string; value: ChartType }[] = [\n { label: 'Candlestick', value: 'candlestick' },\n { label: 'Line', value: 'line' },\n { label: 'Area', value: 'area' },\n { label: 'Bar', value: 'bar' },\n { label: 'Heikin-Ashi', value: 'heikinAshi' },\n { label: 'Hollow Candle', value: 'hollowCandle' },\n { label: 'Baseline', value: 'baseline' },\n { label: 'Volume Candles', value: 'volumeCandles' },\n { label: 'Equivolume', value: 'equivolume' },\n { label: 'HLC Area', value: 'hlcArea' },\n { label: 'Step Line', value: 'stepLine' },\n { label: 'Line + Markers', value: 'lineWithMarkers' },\n];\n\nexport const DRAWING_TOOL_GROUPS: DrawingToolGroupDef[] = [\n {\n label: 'Lines',\n tools: [\n { label: 'Trend Line', value: 'trendLine' as DrawingToolType },\n { label: 'Ray', value: 'ray' as DrawingToolType },\n { label: 'Extended Line', value: 'extendedLine' as DrawingToolType },\n ],\n },\n {\n label: 'Horizontal/Vertical',\n tools: [\n { label: 'Horizontal Line', value: 'horizontalLine' as DrawingToolType },\n { label: 'Vertical Line', value: 'verticalLine' as DrawingToolType },\n ],\n },\n {\n label: 'Channels',\n tools: [\n { label: 'Parallel Channel', value: 'parallelChannel' as DrawingToolType },\n { label: 'Regression Channel', value: 'regressionChannel' as DrawingToolType },\n ],\n },\n {\n label: 'Fibonacci',\n tools: [\n { label: 'Fib Retracement', value: 'fibRetracement' as DrawingToolType },\n { label: 'Fib Extension', value: 'fibExtension' as DrawingToolType },\n ],\n },\n {\n label: 'Shapes',\n tools: [\n { label: 'Rectangle', value: 'rectangle' as DrawingToolType },\n { label: 'Ellipse', value: 'ellipse' as DrawingToolType },\n { label: 'Triangle', value: 'triangle' as DrawingToolType },\n ],\n },\n {\n label: 'Gann & Advanced',\n tools: [\n { label: 'Pitchfork', value: 'pitchfork' as DrawingToolType },\n { label: 'Gann Fan', value: 'gannFan' as DrawingToolType },\n { label: 'Gann Box', value: 'gannBox' as DrawingToolType },\n { label: 'Elliott Wave', value: 'elliottWave' as DrawingToolType },\n ],\n },\n {\n label: 'Measure',\n tools: [\n { label: 'Price Range', value: 'priceRange' as DrawingToolType },\n { label: 'Date Range', value: 'dateRange' as DrawingToolType },\n { label: 'Measure', value: 'measure' as DrawingToolType },\n ],\n },\n {\n label: 'Annotation',\n tools: [\n { label: 'Text', value: 'text' as DrawingToolType },\n { label: 'Arrow', value: 'arrow' as DrawingToolType },\n ],\n },\n];\n\nexport const INDICATORS: IndicatorDef[] = [\n { id: 'sma', name: 'SMA', type: 'overlay' },\n { id: 'ema', name: 'EMA', type: 'overlay' },\n { id: 'hma', name: 'Hull MA', type: 'overlay' },\n { id: 'mtfma', name: 'MTF Moving Average', type: 'overlay' },\n { id: 'bb', name: 'Bollinger Bands', type: 'overlay' },\n { id: 'vwap', name: 'VWAP', type: 'overlay' },\n { id: 'avwap', name: 'Anchored VWAP', type: 'overlay' },\n { id: 'svwap', name: 'Session VWAP', type: 'overlay' },\n { id: 'ichimoku', name: 'Ichimoku Cloud', type: 'overlay' },\n { id: 'psar', name: 'Parabolic SAR', type: 'overlay' },\n { id: 'supertrend', name: 'Supertrend', type: 'overlay' },\n { id: 'keltner', name: 'Keltner Channel', type: 'overlay' },\n { id: 'donchian', name: 'Donchian Channel', type: 'overlay' },\n { id: 'pivots', name: 'Pivot Points', type: 'overlay' },\n { id: 'zigzag', name: 'ZigZag', type: 'overlay' },\n { id: 'lrc', name: 'Linear Regression Channel', type: 'overlay' },\n { id: 'chandelier', name: 'Chandelier Exit', type: 'overlay' },\n { id: 'alligator', name: 'Alligator', type: 'overlay' },\n { id: 'rsi', name: 'RSI', type: 'panel' },\n { id: 'macd', name: 'MACD', type: 'panel' },\n { id: 'stochastic', name: 'Stochastic', type: 'panel' },\n { id: 'atr', name: 'ATR', type: 'panel' },\n { id: 'adx', name: 'ADX', type: 'panel' },\n { id: 'obv', name: 'OBV', type: 'panel' },\n { id: 'williamsR', name: 'Williams %R', type: 'panel' },\n { id: 'cci', name: 'CCI', type: 'panel' },\n { id: 'mfi', name: 'MFI', type: 'panel' },\n { id: 'roc', name: 'ROC', type: 'panel' },\n { id: 'tsi', name: 'TSI', type: 'panel' },\n { id: 'cmf', name: 'CMF', type: 'panel' },\n { id: 'aroon', name: 'Aroon', type: 'panel' },\n { id: 'stddev', name: 'Std Deviation', type: 'panel' },\n { id: 'vroc', name: 'Volume ROC', type: 'panel' },\n { id: 'ad', name: 'Acc/Dist', type: 'panel' },\n { id: 'ao', name: 'Awesome Oscillator', type: 'panel' },\n { id: 'chaikinOsc', name: 'Chaikin Oscillator', type: 'panel' },\n { id: 'voldelta', name: 'Volume Delta', type: 'panel' },\n { id: 'vortex', name: 'Vortex Indicator', type: 'panel' },\n { id: 'chop', name: 'Choppiness Index', type: 'panel' },\n { id: 'uo', name: 'Ultimate Oscillator', type: 'panel' },\n { id: 'fi', name: 'Force Index', type: 'panel' },\n { id: 'crsi', name: 'Connors RSI', type: 'panel' },\n { id: 'coppock', name: 'Coppock Curve', type: 'panel' },\n { id: 'kst', name: 'Know Sure Thing', type: 'panel' },\n { id: 'elderray', name: 'Elder Ray', type: 'panel' },\n { id: 'stc', name: 'Schaff Trend Cycle', type: 'panel' },\n { id: 'kvo', name: 'Klinger Oscillator', type: 'panel' },\n { id: 'fisher', name: 'Fisher Transform', type: 'panel' },\n { id: 'dpo', name: 'Detrended Price Osc', type: 'panel' },\n { id: 'bop', name: 'Balance of Power', type: 'panel' },\n { id: 'massindex', name: 'Mass Index', type: 'panel' },\n { id: 'cmo', name: 'Chande Momentum', type: 'panel' },\n { id: 'trix', name: 'TRIX', type: 'panel' },\n { id: 'emv', name: 'Ease of Movement', type: 'panel' },\n { id: 'pvt', name: 'Price Volume Trend', type: 'panel' },\n { id: 'wad', name: 'Williams A/D', type: 'panel' },\n { id: 'chaikinvol', name: 'Chaikin Volatility', type: 'panel' },\n { id: 'rvi', name: 'Relative Vigor Index', type: 'panel' },\n { id: 'stochrsi', name: 'Stochastic RSI', type: 'panel' },\n { id: 'ppo', name: 'Percentage Price Oscillator', type: 'panel' },\n { id: 'ac', name: 'Accelerator Oscillator', type: 'panel' },\n { id: 'rmi', name: 'Relative Momentum Index', type: 'panel' },\n { id: 'disparity', name: 'Disparity Index', type: 'panel' },\n { id: 'qstick', name: 'Qstick', type: 'panel' },\n { id: 'pgo', name: 'Pretty Good Oscillator', type: 'panel' },\n { id: 'volumeProfile', name: 'Volume Profile', type: 'panel' },\n];\n\nexport const POPULAR_INDICATORS = [\n 'sma', 'ema', 'bb', 'rsi', 'macd', 'stochastic',\n 'vwap', 'atr', 'obv', 'ichimoku',\n];\n\nexport const DEFAULT_SYMBOLS = [\n 'BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT',\n];\n\nexport const DEFAULT_SETTINGS: ChartSettingsState = {\n candleUpColor: '#26A69A',\n candleDownColor: '#EF5350',\n candleUpWick: '#26A69A',\n candleDownWick: '#EF5350',\n backgroundColor: '#131722',\n gridColor: '#1E222D',\n gridVisible: true,\n volumeVisible: true,\n volumeProfileVisible: false,\n marketProfileVisible: false,\n marketProfileSplit: false,\n marketProfileLetters: false,\n marketProfileBuckets: 48,\n marketProfileOpacity: 0.32,\n depthHeatmapVisible: false,\n depthHeatmapOpacity: 0.7,\n sessionShadingVisible: false,\n pivotMarkersVisible: false,\n pivotStrength: 5,\n pivotStructureLabels: false,\n periodLevelsVisible: false,\n periodLevelsPeriod: 'day',\n legendVisible: true,\n barCountdown: true,\n logScale: false,\n scaleMode: 'regular',\n autoScale: true,\n crosshairMode: 'magnet',\n numberLocale: 'en-US',\n timezone: 'local',\n};\n","import widgetCss from './WidgetStyles.css?raw';\r\n\r\nlet refCount = 0;\r\nconst STYLE_ID = 'tcw-styles';\r\n\r\n/**\r\n * Inject the widget stylesheet into `document.head`. Reference-counted so\r\n * multiple `ChartWidget` instances share the same `<style>` tag and the last\r\n * to detach removes it. CSS lives in a sibling `.css` file and is inlined at\r\n * build time via Vite's `?raw` query — consumers see a plain string at runtime.\r\n */\r\nexport function injectWidgetStyles(): void {\r\n refCount++;\r\n if (refCount > 1) return;\r\n if (document.getElementById(STYLE_ID)) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = STYLE_ID;\r\n style.textContent = widgetCss;\r\n document.head.appendChild(style);\r\n}\r\n\r\nexport function removeWidgetStyles(): void {\r\n refCount--;\r\n if (refCount > 0) return;\r\n\r\n const style = document.getElementById(STYLE_ID);\r\n if (style) {\r\n style.remove();\r\n }\r\n}\r\n","const ICON_PATHS: Record<string, string> = {\n cursor: '<path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\"/><path d=\"M13 13l6 6\"/>',\n trendingUp: '<polyline points=\"22 7 13.5 15.5 8.5 10.5 2 17\"/><polyline points=\"16 7 22 7 22 13\"/>',\n minus: '<path d=\"M5 12h14\"/>',\n penLine: '<path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\"/>',\n hash: '<line x1=\"4\" y1=\"9\" x2=\"20\" y2=\"9\"/><line x1=\"4\" y1=\"15\" x2=\"20\" y2=\"15\"/><line x1=\"10\" y1=\"3\" x2=\"8\" y2=\"21\"/><line x1=\"16\" y1=\"3\" x2=\"14\" y2=\"21\"/>',\n square: '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/>',\n gitBranch: '<line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\"/><circle cx=\"18\" cy=\"6\" r=\"3\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><path d=\"M18 9a9 9 0 0 1-9 9\"/>',\n ruler: '<path d=\"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z\"/><path d=\"m14.5 12.5 2-2\"/><path d=\"m11.5 9.5 2-2\"/><path d=\"m8.5 6.5 2-2\"/><path d=\"m17.5 15.5 2-2\"/>',\n type: '<polyline points=\"4 7 4 4 20 4 20 7\"/><line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\"/><line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\"/>',\n magnet: '<path d=\"m6 15-4-4 6.75-6.77a7.79 7.79 0 0 1 11 11L13 22l-4-4 6.39-6.36a2.14 2.14 0 0 0-3-3L6 15\"/><path d=\"m5 8 4 4\"/><path d=\"m12 15 4 4\"/>',\n undo: '<path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/>',\n redo: '<path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/>',\n trash: '<path d=\"M3 6h18\"/><path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"/><path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/>',\n camera: '<path d=\"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z\"/><circle cx=\"12\" cy=\"13\" r=\"3\"/>',\n settings: '<path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n moon: '<path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2\"/><path d=\"M12 20v2\"/><path d=\"m4.93 4.93 1.41 1.41\"/><path d=\"m17.66 17.66 1.41 1.41\"/><path d=\"M2 12h2\"/><path d=\"M20 12h2\"/><path d=\"m6.34 17.66-1.41 1.41\"/><path d=\"m19.07 4.93-1.41 1.41\"/>',\n chevronDown: '<path d=\"m6 9 6 6 6-6\"/>',\n chevronUp: '<path d=\"m18 15-6-6-6 6\"/>',\n barChart: '<line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"10\"/><line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"4\"/><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"16\"/>',\n x: '<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>',\n play: '<polygon points=\"6 3 20 12 6 21 6 3\"/>',\n pause: '<rect width=\"4\" height=\"16\" x=\"6\" y=\"4\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"4\"/>',\n stop: '<rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" rx=\"1\"/>',\n receipt: '<path d=\"M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z\"/><path d=\"M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8\"/><path d=\"M12 17.5v-11\"/>',\n bell: '<path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\"/><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\"/>',\n plus: '<path d=\"M5 12h14\"/><path d=\"M12 5v14\"/>',\n layers: '<path d=\"m12 2 9 5-9 5-9-5 9-5Z\"/><path d=\"m3 12 9 5 9-5\"/><path d=\"m3 17 9 5 9-5\"/>',\n eye: '<path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n eyeOff: '<path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c6.5 0 10 7 10 7a13.2 13.2 0 0 1-1.67 2.68\"/><path d=\"M6.6 6.6A13.06 13.06 0 0 0 2 11s3.5 7 10 7a9.1 9.1 0 0 0 5.4-1.6\"/><path d=\"m2 2 20 20\"/>',\n lock: '<rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/>',\n unlock: '<rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 9.9-1\"/>',\n palette: '<circle cx=\"13.5\" cy=\"6.5\" r=\".5\" fill=\"currentColor\"/><circle cx=\"17.5\" cy=\"10.5\" r=\".5\" fill=\"currentColor\"/><circle cx=\"8.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"/><circle cx=\"6.5\" cy=\"12.5\" r=\".5\" fill=\"currentColor\"/><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2Z\"/>',\n trendingDown: '<polyline points=\"22 17 13.5 8.5 8.5 13.5 2 7\"/><polyline points=\"16 17 22 17 22 11\"/>',\n check: '<polyline points=\"20 6 9 17 4 12\"/>',\n ladder: '<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><line x1=\"3\" y1=\"8\" x2=\"21\" y2=\"8\"/><line x1=\"3\" y1=\"13\" x2=\"21\" y2=\"13\"/><line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"/>',\n};\n\nexport function createIcon(name: string, size = 14): string {\n const paths = ICON_PATHS[name];\n if (!paths) return '';\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${paths}</svg>`;\n}\n","export class WidgetDropdown {\n private trigger: HTMLElement;\n private panel: HTMLDivElement;\n private _isOpen = false;\n private onOutsideClick: (e: MouseEvent) => void;\n private onEscapeKey: (e: KeyboardEvent) => void;\n private onTriggerClick: () => void;\n\n constructor(trigger: HTMLElement, config: { width?: string; align?: 'left' | 'right' } = {}) {\n this.trigger = trigger;\n\n this.panel = document.createElement('div');\n this.panel.className = 'tcw-dropdown';\n this.panel.style.width = config.width ?? '200px';\n if (config.align === 'right') {\n this.panel.style.right = '0';\n } else {\n this.panel.style.left = '0';\n }\n this.panel.style.display = 'none';\n\n // Position relative to trigger\n trigger.style.position = 'relative';\n trigger.appendChild(this.panel);\n\n this.onTriggerClick = () => {\n if (this._isOpen) {\n this.close();\n } else {\n this.open();\n }\n };\n\n this.onOutsideClick = (e: MouseEvent) => {\n if (!this.trigger.contains(e.target as Node)) {\n this.close();\n }\n };\n\n this.onEscapeKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n this.close();\n }\n };\n\n trigger.addEventListener('click', this.onTriggerClick);\n }\n\n setContent(html: string): void {\n this.panel.innerHTML = html;\n }\n\n open(): void {\n if (this._isOpen) return;\n this._isOpen = true;\n this.panel.style.display = '';\n document.addEventListener('mousedown', this.onOutsideClick);\n document.addEventListener('keydown', this.onEscapeKey);\n }\n\n close(): void {\n if (!this._isOpen) return;\n this._isOpen = false;\n this.panel.style.display = 'none';\n document.removeEventListener('mousedown', this.onOutsideClick);\n document.removeEventListener('keydown', this.onEscapeKey);\n }\n\n isOpen(): boolean {\n return this._isOpen;\n }\n\n destroy(): void {\n this.trigger.removeEventListener('click', this.onTriggerClick);\n document.removeEventListener('mousedown', this.onOutsideClick);\n document.removeEventListener('keydown', this.onEscapeKey);\n this.panel.remove();\n }\n}\n","import type { ChartType } from '@tradecanvas/commons';\nimport type { ToolbarConfig, ToolbarCallbacks, WidgetState, ActiveIndicator } from './types.js';\nimport { createIcon } from './icons.js';\nimport { WidgetDropdown } from './WidgetDropdown.js';\n\nexport class WidgetToolbar {\n private config: ToolbarConfig;\n private callbacks: ToolbarCallbacks;\n private el: HTMLDivElement;\n private chartTypeDropdown: WidgetDropdown | null = null;\n private indicatorDropdown: WidgetDropdown | null = null;\n private tfButtons: HTMLButtonElement[] = [];\n private chipsContainer: HTMLDivElement | null = null;\n private themeBtn: HTMLButtonElement | null = null;\n\n constructor(host: HTMLElement, config: ToolbarConfig, callbacks: ToolbarCallbacks) {\n this.config = config;\n this.callbacks = callbacks;\n this.el = document.createElement('div');\n this.el.className = 'tcw-toolbar';\n this.build();\n host.appendChild(this.el);\n }\n\n private build(): void {\n const { config, callbacks, el } = this;\n\n // Symbol button\n const symbolBtn = document.createElement('button');\n symbolBtn.className = 'tcw-toolbar-symbol';\n symbolBtn.dataset.role = 'symbol';\n symbolBtn.addEventListener('click', callbacks.onSymbolClick);\n el.appendChild(symbolBtn);\n el.appendChild(this.sep());\n\n // Timeframes\n const tfGroup = document.createElement('div');\n tfGroup.className = 'tcw-toolbar-group';\n for (const tf of config.timeframes) {\n const btn = document.createElement('button');\n btn.className = 'tcw-btn';\n btn.textContent = tf.label;\n btn.dataset.tf = tf.value;\n btn.addEventListener('click', () => callbacks.onTimeframe(tf.value));\n tfGroup.appendChild(btn);\n this.tfButtons.push(btn);\n }\n el.appendChild(tfGroup);\n el.appendChild(this.sep());\n\n // Chart type dropdown\n const ctWrap = document.createElement('div');\n ctWrap.style.position = 'relative';\n ctWrap.style.display = 'inline-flex';\n\n const ctTrigger = document.createElement('button');\n ctTrigger.className = 'tcw-dropdown-trigger';\n ctTrigger.dataset.role = 'charttype';\n ctWrap.appendChild(ctTrigger);\n el.appendChild(ctWrap);\n\n this.chartTypeDropdown = new WidgetDropdown(ctWrap, { width: '160px' });\n this.buildChartTypeMenu();\n\n el.appendChild(this.sep());\n\n // Indicators dropdown\n const indWrap = document.createElement('div');\n indWrap.style.position = 'relative';\n indWrap.style.display = 'inline-flex';\n\n const indTrigger = document.createElement('button');\n indTrigger.className = 'tcw-dropdown-trigger';\n indTrigger.dataset.role = 'indicators';\n indWrap.appendChild(indTrigger);\n el.appendChild(indWrap);\n\n this.indicatorDropdown = new WidgetDropdown(indWrap, { width: '280px' });\n this.buildIndicatorMenu();\n\n // Indicator chips\n this.chipsContainer = document.createElement('div');\n this.chipsContainer.className = 'tcw-indicator-chips';\n el.appendChild(this.chipsContainer);\n\n // Spacer\n el.appendChild(this.spacer());\n\n // Right side buttons\n if (callbacks.onToggleReplay) {\n const replayBtn = this.iconBtn('play', 'Bar replay', callbacks.onToggleReplay);\n replayBtn.dataset.role = 'replay';\n el.appendChild(replayBtn);\n }\n\n if (callbacks.onBracket) {\n const onBracket = callbacks.onBracket;\n const longBtn = this.iconBtn('trendingUp', 'Long bracket', () => onBracket('buy'));\n longBtn.dataset.role = 'long';\n longBtn.classList.add('tcw-btn-long');\n el.appendChild(longBtn);\n const shortBtn = this.iconBtn('trendingDown', 'Short bracket', () => onBracket('sell'));\n shortBtn.dataset.role = 'short';\n shortBtn.classList.add('tcw-btn-short');\n el.appendChild(shortBtn);\n }\n\n if (callbacks.onToggleLadder) {\n const ladderBtn = this.iconBtn('ladder', 'Depth ladder', callbacks.onToggleLadder);\n ladderBtn.dataset.role = 'ladder';\n el.appendChild(ladderBtn);\n }\n\n if (callbacks.onToggleObjects) {\n const objectsBtn = this.iconBtn('layers', 'Objects', callbacks.onToggleObjects);\n objectsBtn.dataset.role = 'objects';\n el.appendChild(objectsBtn);\n }\n\n if (callbacks.onToggleAlerts) {\n const alertsBtn = this.iconBtn('bell', 'Price alerts', callbacks.onToggleAlerts);\n alertsBtn.dataset.role = 'alerts';\n el.appendChild(alertsBtn);\n }\n\n const screenshotBtn = this.iconBtn('camera', 'Screenshot', callbacks.onScreenshot);\n el.appendChild(screenshotBtn);\n\n const settingsBtn = this.iconBtn('settings', 'Chart Settings', callbacks.onSettings);\n el.appendChild(settingsBtn);\n\n this.themeBtn = this.iconBtn('moon', 'Toggle theme', callbacks.onToggleTheme);\n this.themeBtn.dataset.role = 'theme';\n el.appendChild(this.themeBtn);\n }\n\n private buildChartTypeMenu(): void {\n if (!this.chartTypeDropdown) return;\n const items = this.config.chartTypes.map(ct =>\n `<button class=\"tcw-dropdown-item\" data-ct=\"${ct.value}\">${ct.label}</button>`\n ).join('');\n this.chartTypeDropdown.setContent(items);\n\n // Attach events to items after content set\n const panel = this.chartTypeDropdown['panel'] as HTMLDivElement;\n panel.querySelectorAll('.tcw-dropdown-item').forEach((btn) => {\n btn.addEventListener('click', (e) => {\n const value = (e.currentTarget as HTMLElement).dataset.ct as ChartType;\n this.callbacks.onChartType(value);\n this.chartTypeDropdown?.close();\n });\n });\n }\n\n private buildIndicatorMenu(): void {\n if (!this.indicatorDropdown) return;\n const { indicators, popularIndicatorIds } = this.config;\n\n const popular = indicators.filter(d => popularIndicatorIds.includes(d.id));\n const other = indicators.filter(d => !popularIndicatorIds.includes(d.id));\n\n let html = '<div class=\"tcw-dropdown-label\">Popular</div>';\n for (const ind of popular) {\n html += `<button class=\"tcw-dropdown-item\" data-ind=\"${ind.id}\"><span>${ind.name}</span><span class=\"tcw-tag\">${ind.type}</span></button>`;\n }\n html += '<div class=\"tcw-dropdown-divider\"></div>';\n html += '<div class=\"tcw-dropdown-label\">All</div>';\n for (const ind of other) {\n html += `<button class=\"tcw-dropdown-item\" data-ind=\"${ind.id}\"><span>${ind.name}</span><span class=\"tcw-tag\">${ind.type}</span></button>`;\n }\n\n this.indicatorDropdown.setContent(html);\n\n const panel = this.indicatorDropdown['panel'] as HTMLDivElement;\n panel.querySelectorAll('.tcw-dropdown-item[data-ind]').forEach((btn) => {\n btn.addEventListener('click', (e) => {\n const id = (e.currentTarget as HTMLElement).dataset.ind!;\n this.callbacks.onAddIndicator(id);\n });\n });\n }\n\n update(state: WidgetState): void {\n // Symbol\n const symbolBtn = this.el.querySelector('[data-role=\"symbol\"]') as HTMLButtonElement | null;\n if (symbolBtn) symbolBtn.textContent = state.symbol;\n\n // Timeframe buttons\n for (const btn of this.tfButtons) {\n btn.classList.toggle('tcw-active', btn.dataset.tf === state.timeframe);\n }\n\n // Chart type trigger label\n const ctTrigger = this.el.querySelector('[data-role=\"charttype\"]') as HTMLElement | null;\n if (ctTrigger) {\n const label = this.config.chartTypes.find(t => t.value === state.chartType)?.label ?? 'Candles';\n ctTrigger.innerHTML = `${createIcon('barChart', 14)} ${label} ${createIcon('chevronDown', 12)}`;\n }\n\n // Indicator trigger + badge\n const indTrigger = this.el.querySelector('[data-role=\"indicators\"]') as HTMLElement | null;\n if (indTrigger) {\n const count = state.activeIndicators.size;\n let inner = `${createIcon('trendingUp', 14)} Indicators`;\n if (count > 0) {\n inner += ` <span class=\"tcw-badge-count\">${count}</span>`;\n }\n indTrigger.innerHTML = inner;\n }\n\n // Chips\n if (this.chipsContainer) {\n const activeList = this.getActiveIndicatorList(state);\n this.chipsContainer.innerHTML = '';\n for (const ind of activeList) {\n const chip = document.createElement('div');\n chip.className = 'tcw-indicator-chip';\n\n const label = document.createElement('span');\n label.textContent = ind.label;\n chip.appendChild(label);\n\n const removeBtn = document.createElement('button');\n removeBtn.className = 'tcw-chip-remove';\n removeBtn.innerHTML = createIcon('x', 10);\n removeBtn.addEventListener('click', () => this.callbacks.onRemoveIndicator(ind.instanceId));\n chip.appendChild(removeBtn);\n\n this.chipsContainer.appendChild(chip);\n }\n }\n\n // Theme toggle icon\n if (this.themeBtn) {\n this.themeBtn.innerHTML = state.isDark ? createIcon('moon', 14) : createIcon('sun', 14);\n }\n }\n\n private getActiveIndicatorList(state: WidgetState): ActiveIndicator[] {\n const result: ActiveIndicator[] = [];\n for (const [id, instanceId] of state.activeIndicators.entries()) {\n result.push({ instanceId, id, label: id.toUpperCase() });\n }\n return result;\n }\n\n private sep(): HTMLSpanElement {\n const s = document.createElement('span');\n s.className = 'tcw-toolbar-sep';\n return s;\n }\n\n private spacer(): HTMLSpanElement {\n const s = document.createElement('span');\n s.className = 'tcw-toolbar-spacer';\n return s;\n }\n\n private iconBtn(icon: string, title: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.className = 'tcw-btn-icon';\n btn.title = title;\n btn.innerHTML = createIcon(icon, 14);\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n destroy(): void {\n this.chartTypeDropdown?.destroy();\n this.indicatorDropdown?.destroy();\n this.el.remove();\n }\n}\n","import type { SidebarConfig, SidebarCallbacks, WidgetState } from './types.js';\nimport { createIcon } from './icons.js';\n\nconst GROUP_ICONS = [\n 'trendingUp', 'minus', 'penLine', 'hash', 'square', 'gitBranch', 'ruler', 'type',\n];\n\n/** Icon for a drawing tool in the favorites strip — falls back to a pen. */\nconst TOOL_ICONS: Record<string, string> = {\n trendLine: 'trendingUp', ray: 'trendingUp', extendedLine: 'trendingUp',\n horizontalLine: 'minus', verticalLine: 'penLine',\n rectangle: 'square', ellipse: 'square', triangle: 'square', arrow: 'trendingUp',\n parallelChannel: 'gitBranch', regressionChannel: 'gitBranch', pitchfork: 'gitBranch',\n fibRetracement: 'hash', fibExtension: 'hash', fibTimeZones: 'hash',\n gannBox: 'hash', gannFan: 'gitBranch', elliottWave: 'trendingUp',\n priceRange: 'ruler', dateRange: 'ruler', measure: 'ruler',\n textAnnotation: 'type', anchoredVWAP: 'trendingUp', volumeProfileRange: 'barChart',\n};\n\nfunction toolIcon(tool: string): string {\n return TOOL_ICONS[tool] ?? 'penLine';\n}\n\n/** Human label for a tool id, sourced from the configured groups. */\nfunction toolLabel(groups: SidebarConfig['drawingToolGroups'], tool: string): string {\n for (const g of groups) {\n const t = g.tools.find((x) => x.value === tool);\n if (t) return t.label;\n }\n return tool;\n}\n\nexport class WidgetDrawingSidebar {\n private config: SidebarConfig;\n private callbacks: SidebarCallbacks;\n private el: HTMLDivElement;\n private groupWraps: HTMLDivElement[] = [];\n private groupButtons: HTMLButtonElement[] = [];\n private cursorBtn: HTMLButtonElement | null = null;\n private magnetBtn: HTMLButtonElement | null = null;\n private flyoutEl: HTMLDivElement | null = null;\n private favoritesEl: HTMLDivElement | null = null;\n private favoritesDivider: HTMLDivElement | null = null;\n private favorites: string[] = [];\n\n constructor(host: HTMLElement, config: SidebarConfig, callbacks: SidebarCallbacks) {\n this.config = config;\n this.callbacks = callbacks;\n this.el = document.createElement('div');\n this.el.className = 'tcw-sidebar';\n this.build();\n host.appendChild(this.el);\n }\n\n private build(): void {\n const { config, callbacks, el } = this;\n\n // Cursor button\n this.cursorBtn = document.createElement('button');\n this.cursorBtn.className = 'tcw-sidebar-btn';\n this.cursorBtn.title = 'Cursor';\n this.cursorBtn.innerHTML = createIcon('cursor', 14);\n this.cursorBtn.addEventListener('click', callbacks.onCancelDrawing);\n el.appendChild(this.cursorBtn);\n\n el.appendChild(this.divider());\n\n // Favorites strip (pinned tools) — only when favorites are enabled.\n if (callbacks.onToggleFavorite) {\n this.favorites = [...(config.favorites ?? [])];\n this.favoritesEl = document.createElement('div');\n this.favoritesEl.className = 'tcw-sidebar-favorites';\n el.appendChild(this.favoritesEl);\n this.favoritesDivider = this.divider();\n el.appendChild(this.favoritesDivider);\n this.renderFavorites();\n }\n\n // Tool groups\n config.drawingToolGroups.forEach((group, idx) => {\n const wrap = document.createElement('div');\n wrap.className = 'tcw-tool-group-wrap';\n\n const btn = document.createElement('button');\n btn.className = 'tcw-sidebar-btn';\n btn.title = group.label;\n btn.innerHTML = createIcon(GROUP_ICONS[idx] ?? 'square', 14);\n\n if (group.tools.length > 1) {\n const dot = document.createElement('span');\n dot.className = 'tcw-multi-dot';\n btn.appendChild(dot);\n }\n\n btn.addEventListener('click', () => callbacks.onDrawingTool(group.tools[0].value));\n wrap.appendChild(btn);\n\n // Flyout events via JS (not CSS hover)\n wrap.addEventListener('mouseenter', () => this.showFlyout(idx));\n wrap.addEventListener('mouseleave', () => this.hideFlyout());\n\n el.appendChild(wrap);\n this.groupWraps.push(wrap);\n this.groupButtons.push(btn);\n });\n\n // Spacer\n const spacer = document.createElement('div');\n spacer.className = 'tcw-sidebar-spacer';\n el.appendChild(spacer);\n\n el.appendChild(this.divider());\n\n // Bottom tools\n if (callbacks.onToggleStyle) {\n const styleBtn = document.createElement('button');\n styleBtn.className = 'tcw-sidebar-btn';\n styleBtn.title = 'Drawing style & templates';\n styleBtn.dataset.role = 'style';\n styleBtn.innerHTML = createIcon('palette', 14);\n styleBtn.addEventListener('click', callbacks.onToggleStyle);\n el.appendChild(styleBtn);\n }\n\n this.magnetBtn = document.createElement('button');\n this.magnetBtn.className = 'tcw-sidebar-btn';\n this.magnetBtn.title = 'Magnet';\n this.magnetBtn.innerHTML = createIcon('magnet', 14);\n this.magnetBtn.addEventListener('click', callbacks.onToggleMagnet);\n el.appendChild(this.magnetBtn);\n\n const undoBtn = document.createElement('button');\n undoBtn.className = 'tcw-sidebar-btn';\n undoBtn.title = 'Undo';\n undoBtn.innerHTML = createIcon('undo', 14);\n undoBtn.addEventListener('click', callbacks.onUndo);\n el.appendChild(undoBtn);\n\n const redoBtn = document.createElement('button');\n redoBtn.className = 'tcw-sidebar-btn';\n redoBtn.title = 'Redo';\n redoBtn.innerHTML = createIcon('redo', 14);\n redoBtn.addEventListener('click', callbacks.onRedo);\n el.appendChild(redoBtn);\n\n const clearBtn = document.createElement('button');\n clearBtn.className = 'tcw-sidebar-btn tcw-danger';\n clearBtn.title = 'Clear all';\n clearBtn.innerHTML = createIcon('trash', 14);\n clearBtn.addEventListener('click', callbacks.onClearDrawings);\n el.appendChild(clearBtn);\n }\n\n /** Update the pinned-tools strip. */\n setFavorites(favorites: string[]): void {\n this.favorites = [...favorites];\n this.renderFavorites();\n }\n\n private renderFavorites(): void {\n if (!this.favoritesEl) return;\n this.favoritesEl.replaceChildren();\n const visible = this.favorites.length > 0;\n this.favoritesEl.style.display = visible ? '' : 'none';\n if (this.favoritesDivider) this.favoritesDivider.style.display = visible ? '' : 'none';\n\n for (const tool of this.favorites) {\n const btn = document.createElement('button');\n btn.className = 'tcw-sidebar-btn';\n btn.title = `${toolLabel(this.config.drawingToolGroups, tool)} (right-click to unpin)`;\n btn.dataset.toolValue = tool;\n btn.innerHTML = createIcon(toolIcon(tool), 14);\n btn.addEventListener('click', () => this.callbacks.onDrawingTool(tool as never));\n btn.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n this.callbacks.onToggleFavorite?.(tool as never);\n });\n this.favoritesEl.appendChild(btn);\n }\n }\n\n private showFlyout(idx: number): void {\n const group = this.config.drawingToolGroups[idx];\n if (!group || group.tools.length <= 1) return;\n\n this.hideFlyout();\n\n const flyout = document.createElement('div');\n flyout.className = 'tcw-flyout';\n\n const header = document.createElement('div');\n header.className = 'tcw-flyout-header';\n header.textContent = group.label;\n flyout.appendChild(header);\n\n for (const tool of group.tools) {\n const item = document.createElement('button');\n item.className = 'tcw-flyout-item';\n item.textContent = tool.label;\n item.dataset.toolValue = tool.value;\n item.addEventListener('click', () => {\n this.callbacks.onDrawingTool(tool.value);\n this.hideFlyout();\n });\n if (this.callbacks.onToggleFavorite) {\n if (this.favorites.includes(tool.value)) item.classList.add('tcw-flyout-faved');\n item.title = 'Right-click to pin/unpin';\n item.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n this.callbacks.onToggleFavorite?.(tool.value);\n });\n }\n flyout.appendChild(item);\n }\n\n this.flyoutEl = flyout;\n this.groupWraps[idx].appendChild(flyout);\n }\n\n private hideFlyout(): void {\n if (this.flyoutEl) {\n this.flyoutEl.remove();\n this.flyoutEl = null;\n }\n }\n\n update(state: WidgetState): void {\n // Cursor active\n if (this.cursorBtn) {\n this.cursorBtn.classList.toggle('tcw-active', state.activeTool === null);\n }\n\n // Group buttons\n const { drawingToolGroups } = this.config;\n for (let i = 0; i < drawingToolGroups.length; i++) {\n const isActive = drawingToolGroups[i].tools.some(t => t.value === state.activeTool);\n this.groupButtons[i].classList.toggle('tcw-active', isActive);\n }\n\n // Flyout items\n if (this.flyoutEl) {\n this.flyoutEl.querySelectorAll('.tcw-flyout-item').forEach((item) => {\n const el = item as HTMLElement;\n el.classList.toggle('tcw-active', el.dataset.toolValue === state.activeTool);\n });\n }\n\n // Magnet\n if (this.magnetBtn) {\n this.magnetBtn.classList.toggle('tcw-active', state.magnetEnabled);\n this.magnetBtn.title = state.magnetEnabled ? 'Magnet ON' : 'Magnet OFF';\n }\n }\n\n private divider(): HTMLDivElement {\n const d = document.createElement('div');\n d.className = 'tcw-sidebar-divider';\n return d;\n }\n\n destroy(): void {\n this.hideFlyout();\n this.el.remove();\n }\n}\n","import type { ChartSettingsState, SettingsCallbacks } from './types.js';\nimport { createIcon } from './icons.js';\n\ntype Tab = 'style' | 'display' | 'scale';\nconst TABS: Tab[] = ['style', 'display', 'scale'];\n\nexport class WidgetSettings {\n private callbacks: SettingsCallbacks;\n private backdrop: HTMLDivElement | null = null;\n private modal: HTMLDivElement | null = null;\n private currentTab: Tab = 'style';\n private currentSettings: ChartSettingsState | null = null;\n private bodyEl: HTMLDivElement | null = null;\n private tabButtons: HTMLButtonElement[] = [];\n\n constructor(callbacks: SettingsCallbacks) {\n this.callbacks = callbacks;\n }\n\n open(currentSettings: ChartSettingsState): void {\n this.currentSettings = { ...currentSettings };\n this.currentTab = 'style';\n this.buildModal();\n }\n\n close(): void {\n this.backdrop?.remove();\n this.modal?.remove();\n this.backdrop = null;\n this.modal = null;\n this.bodyEl = null;\n this.tabButtons = [];\n }\n\n private buildModal(): void {\n // Backdrop\n this.backdrop = document.createElement('div');\n this.backdrop.className = 'tcw-modal-backdrop';\n this.backdrop.addEventListener('click', () => {\n this.callbacks.onClose();\n this.close();\n });\n document.body.appendChild(this.backdrop);\n\n // Modal\n this.modal = document.createElement('div');\n this.modal.className = 'tcw-modal';\n\n // Header\n const header = document.createElement('div');\n header.className = 'tcw-modal-header';\n const h3 = document.createElement('h3');\n h3.textContent = 'Chart Settings';\n header.appendChild(h3);\n const closeBtn = document.createElement('button');\n closeBtn.className = 'tcw-modal-close';\n closeBtn.innerHTML = createIcon('x', 16);\n closeBtn.addEventListener('click', () => {\n this.callbacks.onClose();\n this.close();\n });\n header.appendChild(closeBtn);\n this.modal.appendChild(header);\n\n // Tabs\n const tabsEl = document.createElement('div');\n tabsEl.className = 'tcw-modal-tabs';\n this.tabButtons = [];\n for (const tab of TABS) {\n const btn = document.createElement('button');\n btn.className = 'tcw-modal-tab';\n btn.textContent = tab;\n btn.dataset.tab = tab;\n if (tab === this.currentTab) btn.classList.add('tcw-active');\n btn.addEventListener('click', () => {\n this.currentTab = tab;\n this.tabButtons.forEach(b => b.classList.toggle('tcw-active', b.dataset.tab === tab));\n this.renderTabContent();\n });\n tabsEl.appendChild(btn);\n this.tabButtons.push(btn);\n }\n this.modal.appendChild(tabsEl);\n\n // Body\n this.bodyEl = document.createElement('div');\n this.bodyEl.className = 'tcw-modal-body';\n this.modal.appendChild(this.bodyEl);\n this.renderTabContent();\n\n // Footer\n const footer = document.createElement('div');\n footer.className = 'tcw-modal-footer';\n const resetBtn = document.createElement('button');\n resetBtn.className = 'tcw-reset-link';\n resetBtn.textContent = 'Reset to defaults';\n resetBtn.addEventListener('click', () => this.callbacks.onReset());\n footer.appendChild(resetBtn);\n const doneBtn = document.createElement('button');\n doneBtn.className = 'tcw-done-btn';\n doneBtn.textContent = 'Done';\n doneBtn.addEventListener('click', () => {\n this.callbacks.onClose();\n this.close();\n });\n footer.appendChild(doneBtn);\n this.modal.appendChild(footer);\n\n document.body.appendChild(this.modal);\n\n // Escape key\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n document.removeEventListener('keydown', onKeyDown);\n this.callbacks.onClose();\n this.close();\n }\n };\n document.addEventListener('keydown', onKeyDown);\n }\n\n private renderTabContent(): void {\n if (!this.bodyEl || !this.currentSettings) return;\n this.bodyEl.innerHTML = '';\n\n switch (this.currentTab) {\n case 'style':\n this.renderStyleTab();\n break;\n case 'display':\n this.renderDisplayTab();\n break;\n case 'scale':\n this.renderScaleTab();\n break;\n }\n }\n\n private renderStyleTab(): void {\n if (!this.bodyEl || !this.currentSettings) return;\n const s = this.currentSettings;\n\n // Candle Colors\n const candleSection = this.section('Candle Colors');\n candleSection.appendChild(this.colorRow('Up Body', s.candleUpColor, (v) => this.patch({ candleUpColor: v })));\n candleSection.appendChild(this.colorRow('Down Body', s.candleDownColor, (v) => this.patch({ candleDownColor: v })));\n candleSection.appendChild(this.colorRow('Up Wick', s.candleUpWick, (v) => this.patch({ candleUpWick: v })));\n candleSection.appendChild(this.colorRow('Down Wick', s.candleDownWick, (v) => this.patch({ candleDownWick: v })));\n this.bodyEl.appendChild(candleSection);\n\n // Background\n const bgSection = this.section('Background');\n bgSection.appendChild(this.colorRow('Background', s.backgroundColor, (v) => this.patch({ backgroundColor: v })));\n bgSection.appendChild(this.colorRow('Grid', s.gridColor, (v) => this.patch({ gridColor: v })));\n this.bodyEl.appendChild(bgSection);\n }\n\n private renderDisplayTab(): void {\n if (!this.bodyEl || !this.currentSettings) return;\n const s = this.currentSettings;\n\n const section = this.section();\n section.appendChild(this.toggleRow('Grid Lines', s.gridVisible, (v) => this.patch({ gridVisible: v })));\n section.appendChild(this.toggleRow('Volume', s.volumeVisible, (v) => this.patch({ volumeVisible: v })));\n section.appendChild(this.toggleRow('Volume Profile', s.volumeProfileVisible, (v) => this.patch({ volumeProfileVisible: v })));\n section.appendChild(this.toggleRow('Market Profile (TPO)', s.marketProfileVisible, (v) => this.patch({ marketProfileVisible: v })));\n section.appendChild(this.toggleRow('MP split by session', s.marketProfileSplit, (v) => this.patch({ marketProfileSplit: v })));\n section.appendChild(this.toggleRow('MP letters (TPO)', s.marketProfileLetters, (v) => this.patch({ marketProfileLetters: v })));\n section.appendChild(this.rangeRow('MP buckets', s.marketProfileBuckets, 8, 200, 1, (v) => this.patch({ marketProfileBuckets: v })));\n section.appendChild(this.rangeRow('MP opacity', s.marketProfileOpacity, 0.05, 1, 0.05, (v) => this.patch({ marketProfileOpacity: v }), (v) => `${Math.round(v * 100)}%`));\n section.appendChild(this.toggleRow('Liquidity heatmap', s.depthHeatmapVisible, (v) => this.patch({ depthHeatmapVisible: v })));\n section.appendChild(this.rangeRow('Heatmap opacity', s.depthHeatmapOpacity, 0.1, 1, 0.05, (v) => this.patch({ depthHeatmapOpacity: v }), (v) => `${Math.round(v * 100)}%`));\n section.appendChild(this.toggleRow('Swing markers', s.pivotMarkersVisible, (v) => this.patch({ pivotMarkersVisible: v })));\n section.appendChild(this.rangeRow('Swing strength', s.pivotStrength, 2, 20, 1, (v) => this.patch({ pivotStrength: v })));\n section.appendChild(this.toggleRow('Swing structure (HH/HL)', s.pivotStructureLabels, (v) => this.patch({ pivotStructureLabels: v })));\n section.appendChild(this.toggleRow('Session shading (RTH)', s.sessionShadingVisible, (v) => this.patch({ sessionShadingVisible: v })));\n section.appendChild(this.toggleRow('Prior-period levels', s.periodLevelsVisible, (v) => this.patch({ periodLevelsVisible: v })));\n section.appendChild(this.selectRow('Period levels basis', s.periodLevelsPeriod, [\n { value: 'day', label: 'Prior Day (PDH/PDL)' },\n { value: 'week', label: 'Prior Week (PWH/PWL)' },\n ], (v) => this.patch({ periodLevelsPeriod: v as ChartSettingsState['periodLevelsPeriod'] })));\n section.appendChild(this.toggleRow('OHLC Legend', s.legendVisible, (v) => this.patch({ legendVisible: v })));\n section.appendChild(this.toggleRow('Bar Countdown', s.barCountdown, (v) => this.patch({ barCountdown: v })));\n\n // Crosshair mode\n section.appendChild(this.selectRow('Crosshair Mode', s.crosshairMode, [\n { label: 'Magnet', value: 'magnet' },\n { label: 'Normal', value: 'normal' },\n { label: 'Hidden', value: 'hidden' },\n ], (v) => this.patch({ crosshairMode: v as ChartSettingsState['crosshairMode'] })));\n\n // Number locale\n section.appendChild(this.selectRow('Timezone', s.timezone, [\n { value: 'local', label: 'Local' },\n { value: '0', label: 'UTC / London' },\n { value: '-300', label: 'New York (UTC-5)' },\n { value: '-360', label: 'Chicago (UTC-6)' },\n { value: '60', label: 'Frankfurt (UTC+1)' },\n { value: '480', label: 'Singapore/HK (UTC+8)' },\n { value: '540', label: 'Tokyo (UTC+9)' },\n { value: '330', label: 'Mumbai (UTC+5:30)' },\n ], (v) => this.patch({ timezone: v })));\n section.appendChild(this.selectRow('Number Locale', s.numberLocale, [\n { label: 'en-US (65,234.00)', value: 'en-US' },\n { label: 'de-DE (65.234,00)', value: 'de-DE' },\n { label: 'fr-FR (65 234,00)', value: 'fr-FR' },\n { label: 'vi-VN (65.234,00)', value: 'vi-VN' },\n { label: 'en-IN (65,234.00)', value: 'en-IN' },\n { label: 'ja-JP (65,234.00)', value: 'ja-JP' },\n ], (v) => this.patch({ numberLocale: v })));\n\n this.bodyEl.appendChild(section);\n }\n\n private renderScaleTab(): void {\n if (!this.bodyEl || !this.currentSettings) return;\n const s = this.currentSettings;\n\n const section = this.section();\n section.appendChild(this.toggleRow('Auto Scale', s.autoScale, (v) => this.patch({ autoScale: v })));\n section.appendChild(this.selectRow('Price Scale', s.scaleMode, [\n { value: 'regular', label: 'Regular' },\n { value: 'logarithmic', label: 'Logarithmic' },\n { value: 'percentage', label: 'Percentage' },\n { value: 'indexedTo100', label: 'Indexed to 100' },\n ], (v) => this.patch({ scaleMode: v as ChartSettingsState['scaleMode'] })));\n this.bodyEl.appendChild(section);\n }\n\n private patch(partial: Partial<ChartSettingsState>): void {\n if (this.currentSettings) {\n Object.assign(this.currentSettings, partial);\n }\n this.callbacks.onChange(partial);\n }\n\n private section(title?: string): HTMLDivElement {\n const div = document.createElement('div');\n div.className = 'tcw-settings-section';\n if (title) {\n const t = document.createElement('div');\n t.className = 'tcw-settings-section-title';\n t.textContent = title;\n div.appendChild(t);\n }\n return div;\n }\n\n private colorRow(label: string, value: string, onChange: (v: string) => void): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n\n const lbl = document.createElement('span');\n lbl.className = 'tcw-settings-label';\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const wrap = document.createElement('div');\n wrap.className = 'tcw-color-picker-wrap';\n\n const input = document.createElement('input');\n input.type = 'color';\n input.value = value;\n\n const hex = document.createElement('span');\n hex.className = 'tcw-color-hex';\n hex.textContent = value;\n\n input.addEventListener('input', () => {\n hex.textContent = input.value;\n onChange(input.value);\n });\n\n wrap.appendChild(input);\n wrap.appendChild(hex);\n row.appendChild(wrap);\n return row;\n }\n\n private toggleRow(label: string, value: boolean, onChange: (v: boolean) => void): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n\n const lbl = document.createElement('span');\n lbl.className = 'tcw-settings-label';\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const toggle = document.createElement('button');\n toggle.className = `tcw-toggle${value ? ' tcw-on' : ''}`;\n toggle.addEventListener('click', () => {\n const newVal = !toggle.classList.contains('tcw-on');\n toggle.classList.toggle('tcw-on', newVal);\n onChange(newVal);\n });\n row.appendChild(toggle);\n return row;\n }\n\n private selectRow(\n label: string,\n value: string,\n options: { label: string; value: string }[],\n onChange: (v: string) => void,\n ): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n\n const lbl = document.createElement('span');\n lbl.className = 'tcw-settings-label';\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const select = document.createElement('select');\n select.className = 'tcw-settings-select';\n for (const opt of options) {\n const o = document.createElement('option');\n o.value = opt.value;\n o.textContent = opt.label;\n if (opt.value === value) o.selected = true;\n select.appendChild(o);\n }\n select.addEventListener('change', () => onChange(select.value));\n row.appendChild(select);\n return row;\n }\n\n private rangeRow(\n label: string,\n value: number,\n min: number,\n max: number,\n step: number,\n onChange: (v: number) => void,\n format: (v: number) => string = (v) => String(v),\n ): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n\n const lbl = document.createElement('span');\n lbl.className = 'tcw-settings-label';\n lbl.textContent = label;\n row.appendChild(lbl);\n\n const wrap = document.createElement('div');\n wrap.className = 'tcw-settings-range';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = String(min);\n input.max = String(max);\n input.step = String(step);\n input.value = String(value);\n\n const out = document.createElement('span');\n out.className = 'tcw-settings-range-val';\n out.textContent = format(value);\n\n input.addEventListener('input', () => {\n const v = Number(input.value);\n out.textContent = format(v);\n onChange(v);\n });\n\n wrap.appendChild(input);\n wrap.appendChild(out);\n row.appendChild(wrap);\n return row;\n }\n\n destroy(): void {\n this.close();\n }\n}\n","export class WidgetStatusBar {\n private el: HTMLDivElement;\n private dotEl: HTMLSpanElement;\n private messageEl: HTMLSpanElement;\n private infoEl: HTMLSpanElement;\n\n constructor(host: HTMLElement) {\n this.el = document.createElement('div');\n this.el.className = 'tcw-statusbar';\n\n const indicator = document.createElement('div');\n indicator.className = 'tcw-status-indicator';\n\n this.dotEl = document.createElement('span');\n this.dotEl.className = 'tcw-status-dot';\n indicator.appendChild(this.dotEl);\n\n this.messageEl = document.createElement('span');\n indicator.appendChild(this.messageEl);\n\n this.el.appendChild(indicator);\n\n this.infoEl = document.createElement('span');\n this.el.appendChild(this.infoEl);\n\n host.appendChild(this.el);\n }\n\n update(state: { connectionState: string; message: string; symbol: string; timeframe: string }): void {\n this.dotEl.className = 'tcw-status-dot';\n if (state.connectionState === 'connected') {\n this.dotEl.classList.add('tcw-connected');\n } else if (state.connectionState === 'error') {\n this.dotEl.classList.add('tcw-error');\n }\n\n this.messageEl.textContent = state.message;\n this.infoEl.textContent = `${state.symbol} ${state.timeframe}`;\n }\n\n destroy(): void {\n this.el.remove();\n }\n}\n","import type { ChartType, DrawingToolType, TimeFrame } from '@tradecanvas/commons';\n\nexport interface CommandItem {\n id: string;\n label: string;\n category: 'indicator' | 'chartType' | 'drawing' | 'timeframe' | 'action';\n shortcut?: string;\n active?: boolean;\n}\n\nexport interface CommandPaletteCallbacks {\n onIndicator: (id: string) => void;\n onChartType: (type: ChartType) => void;\n onDrawingTool: (tool: DrawingToolType) => void;\n onTimeframe: (tf: TimeFrame) => void;\n onAction: (id: string) => void;\n onClose: () => void;\n}\n\nexport class WidgetCommandPalette {\n private backdrop: HTMLDivElement | null = null;\n private modal: HTMLDivElement | null = null;\n private input: HTMLInputElement | null = null;\n private list: HTMLDivElement | null = null;\n private items: CommandItem[] = [];\n private filtered: CommandItem[] = [];\n private selectedIndex = 0;\n private callbacks: CommandPaletteCallbacks;\n private boundKeydown: (e: KeyboardEvent) => void;\n\n constructor(callbacks: CommandPaletteCallbacks) {\n this.callbacks = callbacks;\n this.boundKeydown = this.handleKeydown.bind(this);\n }\n\n open(items: CommandItem[]): void {\n if (this.backdrop) return;\n this.items = items;\n this.filtered = items;\n this.selectedIndex = 0;\n\n this.backdrop = document.createElement('div');\n this.backdrop.className = 'tcw-modal-backdrop';\n this.backdrop.addEventListener('click', () => this.close());\n\n this.modal = document.createElement('div');\n this.modal.className = 'tcw-cmd-palette';\n\n const header = document.createElement('div');\n header.className = 'tcw-cmd-header';\n\n const searchIcon = document.createElement('span');\n searchIcon.className = 'tcw-cmd-icon';\n searchIcon.textContent = '⌕';\n header.appendChild(searchIcon);\n\n this.input = document.createElement('input');\n this.input.className = 'tcw-cmd-input';\n this.input.type = 'text';\n this.input.placeholder = 'Search indicators, chart types, tools...';\n this.input.addEventListener('input', () => this.filter());\n header.appendChild(this.input);\n\n const hint = document.createElement('span');\n hint.className = 'tcw-cmd-hint';\n hint.textContent = 'ESC';\n header.appendChild(hint);\n\n this.modal.appendChild(header);\n\n this.list = document.createElement('div');\n this.list.className = 'tcw-cmd-list';\n this.modal.appendChild(this.list);\n\n const footer = document.createElement('div');\n footer.className = 'tcw-cmd-footer';\n footer.innerHTML = '<span>↑↓ Navigate</span><span>⏎ Select</span><span>Esc Close</span>';\n this.modal.appendChild(footer);\n\n document.body.appendChild(this.backdrop);\n document.body.appendChild(this.modal);\n\n this.renderList();\n this.input.focus();\n document.addEventListener('keydown', this.boundKeydown);\n }\n\n close(): void {\n document.removeEventListener('keydown', this.boundKeydown);\n this.backdrop?.remove();\n this.modal?.remove();\n this.backdrop = null;\n this.modal = null;\n this.input = null;\n this.list = null;\n this.callbacks.onClose();\n }\n\n isOpen(): boolean {\n return this.backdrop !== null;\n }\n\n private filter(): void {\n const query = this.input?.value.toLowerCase().trim() ?? '';\n if (!query) {\n this.filtered = this.items;\n } else {\n this.filtered = this.items.filter(item =>\n item.label.toLowerCase().includes(query) ||\n item.category.toLowerCase().includes(query) ||\n item.id.toLowerCase().includes(query),\n );\n }\n this.selectedIndex = 0;\n this.renderList();\n }\n\n private renderList(): void {\n if (!this.list) return;\n this.list.innerHTML = '';\n\n if (this.filtered.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'tcw-cmd-empty';\n empty.textContent = 'No results found';\n this.list.appendChild(empty);\n return;\n }\n\n let currentCategory = '';\n for (let i = 0; i < this.filtered.length; i++) {\n const item = this.filtered[i];\n\n if (item.category !== currentCategory) {\n currentCategory = item.category;\n const label = document.createElement('div');\n label.className = 'tcw-cmd-category';\n label.textContent = this.categoryLabel(currentCategory);\n this.list.appendChild(label);\n }\n\n const row = document.createElement('button');\n row.className = 'tcw-cmd-item';\n if (i === this.selectedIndex) row.classList.add('tcw-selected');\n if (item.active) row.classList.add('tcw-active');\n row.dataset.index = String(i);\n\n const nameSpan = document.createElement('span');\n nameSpan.className = 'tcw-cmd-item-label';\n nameSpan.textContent = item.label;\n row.appendChild(nameSpan);\n\n if (item.active) {\n const check = document.createElement('span');\n check.className = 'tcw-cmd-check';\n check.textContent = '✓';\n row.appendChild(check);\n }\n\n if (item.shortcut) {\n const kbd = document.createElement('kbd');\n kbd.className = 'tcw-cmd-kbd';\n kbd.textContent = item.shortcut;\n row.appendChild(kbd);\n }\n\n row.addEventListener('click', () => this.select(i));\n row.addEventListener('mouseenter', () => {\n this.selectedIndex = i;\n this.updateSelection();\n });\n\n this.list.appendChild(row);\n }\n }\n\n private updateSelection(): void {\n if (!this.list) return;\n const items = this.list.querySelectorAll('.tcw-cmd-item');\n items.forEach((el, i) => {\n el.classList.toggle('tcw-selected', i === this.selectedIndex);\n });\n items[this.selectedIndex]?.scrollIntoView({ block: 'nearest' });\n }\n\n private select(index: number): void {\n const item = this.filtered[index];\n if (!item) return;\n\n switch (item.category) {\n case 'indicator':\n this.callbacks.onIndicator(item.id);\n break;\n case 'chartType':\n this.callbacks.onChartType(item.id as ChartType);\n break;\n case 'drawing':\n this.callbacks.onDrawingTool(item.id as DrawingToolType);\n break;\n case 'timeframe':\n this.callbacks.onTimeframe(item.id as TimeFrame);\n break;\n case 'action':\n this.callbacks.onAction(item.id);\n break;\n }\n this.close();\n }\n\n private handleKeydown(e: KeyboardEvent): void {\n switch (e.key) {\n case 'Escape':\n e.preventDefault();\n this.close();\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (this.filtered.length > 0) {\n this.selectedIndex = (this.selectedIndex + 1) % this.filtered.length;\n this.updateSelection();\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (this.filtered.length > 0) {\n this.selectedIndex = (this.selectedIndex - 1 + this.filtered.length) % this.filtered.length;\n this.updateSelection();\n }\n break;\n case 'Enter':\n e.preventDefault();\n this.select(this.selectedIndex);\n break;\n }\n }\n\n private categoryLabel(cat: string): string {\n switch (cat) {\n case 'indicator': return 'Indicators';\n case 'chartType': return 'Chart Types';\n case 'drawing': return 'Drawing Tools';\n case 'timeframe': return 'Timeframes';\n case 'action': return 'Actions';\n default: return cat;\n }\n }\n\n destroy(): void {\n this.close();\n }\n}\n","/**\n * Lightweight fuzzy symbol picker. Reuses the command-palette CSS for visual\n * consistency. Scoring is a cheap subsequence match — good enough for symbol\n * lists in the low thousands without pulling in a fuzzy-search dependency.\n */\nexport interface SymbolSearchCallbacks {\n onPick: (symbol: string) => void;\n onClose: () => void;\n}\n\ninterface ScoredSymbol {\n symbol: string;\n score: number;\n}\n\nexport class WidgetSymbolSearch {\n private backdrop: HTMLDivElement | null = null;\n private modal: HTMLDivElement | null = null;\n private input: HTMLInputElement | null = null;\n private list: HTMLDivElement | null = null;\n private symbols: string[] = [];\n private current: string = '';\n private filtered: ScoredSymbol[] = [];\n private selectedIndex = 0;\n private callbacks: SymbolSearchCallbacks;\n private boundKeydown: (e: KeyboardEvent) => void;\n /** One-shot pick override — when set, this open() routes picks here instead. */\n private pickOverride: ((symbol: string) => void) | null = null;\n\n constructor(callbacks: SymbolSearchCallbacks) {\n this.callbacks = callbacks;\n this.boundKeydown = this.handleKeydown.bind(this);\n }\n\n open(symbols: string[], current: string, onPick?: (symbol: string) => void): void {\n if (this.backdrop) return;\n this.pickOverride = onPick ?? null;\n this.symbols = symbols;\n this.current = current;\n this.filtered = symbols.map(s => ({ symbol: s, score: 0 }));\n this.selectedIndex = Math.max(0, symbols.indexOf(current));\n\n this.backdrop = document.createElement('div');\n this.backdrop.className = 'tcw-modal-backdrop';\n this.backdrop.addEventListener('click', () => this.close());\n\n this.modal = document.createElement('div');\n this.modal.className = 'tcw-cmd-palette';\n\n const header = document.createElement('div');\n header.className = 'tcw-cmd-header';\n\n const icon = document.createElement('span');\n icon.className = 'tcw-cmd-icon';\n icon.innerHTML = svgSearch();\n header.appendChild(icon);\n\n this.input = document.createElement('input');\n this.input.className = 'tcw-cmd-input';\n this.input.type = 'text';\n this.input.placeholder = 'Search symbol… (e.g. BTC, ETH, AAPL)';\n this.input.autocomplete = 'off';\n this.input.spellcheck = false;\n this.input.addEventListener('input', () => this.filter());\n header.appendChild(this.input);\n\n const hint = document.createElement('span');\n hint.className = 'tcw-cmd-hint';\n hint.textContent = 'ESC';\n header.appendChild(hint);\n\n this.modal.appendChild(header);\n\n this.list = document.createElement('div');\n this.list.className = 'tcw-cmd-list';\n this.modal.appendChild(this.list);\n\n const footer = document.createElement('div');\n footer.className = 'tcw-cmd-footer';\n footer.innerHTML = '<span>↑↓ Navigate</span><span>⏎ Open</span><span>Esc Close</span>';\n this.modal.appendChild(footer);\n\n document.body.appendChild(this.backdrop);\n document.body.appendChild(this.modal);\n\n this.renderList();\n this.input.focus();\n document.addEventListener('keydown', this.boundKeydown);\n }\n\n close(): void {\n document.removeEventListener('keydown', this.boundKeydown);\n this.backdrop?.remove();\n this.modal?.remove();\n this.backdrop = null;\n this.modal = null;\n this.input = null;\n this.list = null;\n this.pickOverride = null;\n this.callbacks.onClose();\n }\n\n isOpen(): boolean {\n return this.backdrop !== null;\n }\n\n destroy(): void {\n this.close();\n }\n\n private filter(): void {\n const q = (this.input?.value ?? '').toUpperCase().trim();\n if (!q) {\n this.filtered = this.symbols.map(s => ({ symbol: s, score: 0 }));\n } else {\n this.filtered = this.symbols\n .map(s => ({ symbol: s, score: scoreMatch(s.toUpperCase(), q) }))\n .filter(r => r.score > 0)\n .sort((a, b) => b.score - a.score);\n }\n this.selectedIndex = 0;\n this.renderList();\n }\n\n private renderList(): void {\n if (!this.list) return;\n this.list.innerHTML = '';\n\n if (this.filtered.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'tcw-cmd-empty';\n empty.textContent = 'No symbols match';\n this.list.appendChild(empty);\n return;\n }\n\n const query = (this.input?.value ?? '').toUpperCase().trim();\n for (let i = 0; i < this.filtered.length; i++) {\n const { symbol } = this.filtered[i];\n const row = document.createElement('button');\n row.className = 'tcw-cmd-item';\n if (i === this.selectedIndex) row.classList.add('tcw-selected');\n if (symbol === this.current) row.classList.add('tcw-active');\n\n const label = document.createElement('span');\n label.className = 'tcw-cmd-item-label';\n label.innerHTML = highlight(symbol, query);\n row.appendChild(label);\n\n if (symbol === this.current) {\n const check = document.createElement('span');\n check.className = 'tcw-cmd-check';\n check.textContent = '✓';\n row.appendChild(check);\n }\n\n row.addEventListener('click', () => this.pick(i));\n row.addEventListener('mouseenter', () => {\n this.selectedIndex = i;\n this.updateSelection();\n });\n\n this.list.appendChild(row);\n }\n }\n\n private updateSelection(): void {\n if (!this.list) return;\n const items = this.list.querySelectorAll('.tcw-cmd-item');\n items.forEach((el, i) => el.classList.toggle('tcw-selected', i === this.selectedIndex));\n items[this.selectedIndex]?.scrollIntoView({ block: 'nearest' });\n }\n\n private pick(index: number): void {\n const entry = this.filtered[index];\n if (!entry) return;\n const override = this.pickOverride;\n if (override) override(entry.symbol);\n else this.callbacks.onPick(entry.symbol);\n this.close();\n }\n\n private handleKeydown(e: KeyboardEvent): void {\n switch (e.key) {\n case 'Escape':\n e.preventDefault();\n this.close();\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (this.filtered.length > 0) {\n this.selectedIndex = (this.selectedIndex + 1) % this.filtered.length;\n this.updateSelection();\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (this.filtered.length > 0) {\n this.selectedIndex = (this.selectedIndex - 1 + this.filtered.length) % this.filtered.length;\n this.updateSelection();\n }\n break;\n case 'Enter':\n e.preventDefault();\n this.pick(this.selectedIndex);\n break;\n }\n }\n}\n\n/**\n * Cheap fuzzy score:\n * exact match → 1000\n * starts-with → 500 + tighter-prefix bonus\n * subsequence match → 100 − gap penalty\n * no match → 0\n */\nfunction scoreMatch(symbol: string, query: string): number {\n if (symbol === query) return 1000;\n if (symbol.startsWith(query)) return 500 + (50 - Math.min(50, symbol.length - query.length));\n if (symbol.includes(query)) return 200 + (50 - Math.min(50, symbol.length - query.length));\n\n let qi = 0;\n let lastIdx = -1;\n let gapPenalty = 0;\n for (let i = 0; i < symbol.length && qi < query.length; i++) {\n if (symbol[i] === query[qi]) {\n if (lastIdx >= 0) gapPenalty += i - lastIdx - 1;\n lastIdx = i;\n qi++;\n }\n }\n if (qi < query.length) return 0;\n return 100 - Math.min(99, gapPenalty);\n}\n\nfunction highlight(symbol: string, query: string): string {\n if (!query) return escapeHtml(symbol);\n const upper = symbol.toUpperCase();\n let out = '';\n let qi = 0;\n for (let i = 0; i < symbol.length; i++) {\n if (qi < query.length && upper[i] === query[qi]) {\n out += `<mark style=\"background:transparent;color:var(--tcw-accent);font-weight:700\">${escapeHtml(symbol[i])}</mark>`;\n qi++;\n } else {\n out += escapeHtml(symbol[i]);\n }\n }\n return out;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, ch => ({\n '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''',\n } as Record<string, string>)[ch]);\n}\n\nfunction svgSearch(): string {\n return '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"/><path d=\"m21 21-4.3-4.3\"/></svg>';\n}\n","/**\n * Keyboard-shortcut reference sheet. Bound to `?` (and `Shift+/`). Surfaces\n * shortcuts so users discover the widget's hidden interaction model — a\n * premium-feel detail TradingView, Linear, Figma, etc. all ship.\n */\nexport interface HotkeySheetCallbacks {\n onClose: () => void;\n}\n\ninterface HotkeyEntry {\n keys: string[];\n label: string;\n}\n\ninterface HotkeyGroup {\n title: string;\n entries: HotkeyEntry[];\n}\n\nconst isMac =\n typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\nconst mod = isMac ? '⌘' : 'Ctrl';\n\nconst GROUPS: HotkeyGroup[] = [\n {\n title: 'Search & navigation',\n entries: [\n { keys: [mod, 'K'], label: 'Command palette' },\n { keys: [mod, 'P'], label: 'Symbol search' },\n { keys: ['?'], label: 'Show this sheet' },\n ],\n },\n {\n title: 'Chart manipulation',\n entries: [\n { keys: ['Shift', 'Drag'], label: 'Measure tool (bars × price Δ)' },\n { keys: ['Drag', 'Price axis'], label: 'Compress / expand vertical scale' },\n { keys: ['Drag', 'Time axis'], label: 'Zoom time axis' },\n { keys: ['Double-click', 'Price axis'], label: 'Re-enable auto-scale' },\n { keys: ['Double-click', 'Time axis'], label: 'Fit content' },\n { keys: ['Scroll'], label: 'Zoom around cursor' },\n ],\n },\n {\n title: 'Touch (mobile / tablet)',\n entries: [\n { keys: ['1 finger', 'Drag'], label: 'Pan / move crosshair' },\n { keys: ['2 fingers', 'Pinch'], label: 'Zoom around midpoint' },\n { keys: ['Long-press'], label: 'Pin OHLC tooltip at bar' },\n { keys: ['Drag', 'Axis strip'], label: 'Scale price / time axis' },\n ],\n },\n {\n title: 'Keyboard',\n entries: [\n { keys: ['←', '→'], label: 'Pan one bar' },\n { keys: ['+', '−'], label: 'Zoom in / out' },\n { keys: ['Home'], label: 'Scroll to start' },\n { keys: ['End'], label: 'Scroll to end (live edge)' },\n { keys: ['F'], label: 'Fit content' },\n ],\n },\n {\n title: 'Drawing',\n entries: [\n { keys: [mod, 'Z'], label: 'Undo' },\n { keys: [mod, 'Shift', 'Z'], label: 'Redo' },\n { keys: ['Esc'], label: 'Cancel active drawing' },\n ],\n },\n];\n\nexport class WidgetHotkeySheet {\n private backdrop: HTMLDivElement | null = null;\n private modal: HTMLDivElement | null = null;\n private callbacks: HotkeySheetCallbacks;\n private boundKeydown: (e: KeyboardEvent) => void;\n\n constructor(callbacks: HotkeySheetCallbacks) {\n this.callbacks = callbacks;\n this.boundKeydown = (e) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.close();\n }\n };\n }\n\n open(): void {\n if (this.backdrop) return;\n\n this.backdrop = document.createElement('div');\n this.backdrop.className = 'tcw-modal-backdrop';\n this.backdrop.addEventListener('click', () => this.close());\n\n this.modal = document.createElement('div');\n this.modal.className = 'tcw-modal tcw-hotkey-sheet';\n this.modal.style.width = '640px';\n\n const header = document.createElement('div');\n header.className = 'tcw-modal-header';\n header.innerHTML = '<h3>Keyboard shortcuts</h3>';\n const closeBtn = document.createElement('button');\n closeBtn.className = 'tcw-modal-close';\n closeBtn.setAttribute('aria-label', 'Close');\n closeBtn.innerHTML = '×';\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(closeBtn);\n this.modal.appendChild(header);\n\n const body = document.createElement('div');\n body.className = 'tcw-modal-body';\n\n const grid = document.createElement('div');\n grid.className = 'tcw-hotkey-grid';\n\n for (const group of GROUPS) {\n const section = document.createElement('section');\n section.className = 'tcw-hotkey-section';\n const title = document.createElement('div');\n title.className = 'tcw-settings-section-title';\n title.textContent = group.title;\n section.appendChild(title);\n\n for (const entry of group.entries) {\n const row = document.createElement('div');\n row.className = 'tcw-hotkey-row';\n\n const keys = document.createElement('div');\n keys.className = 'tcw-hotkey-keys';\n for (let i = 0; i < entry.keys.length; i++) {\n if (i > 0) {\n const plus = document.createElement('span');\n plus.className = 'tcw-hotkey-sep';\n plus.textContent = '+';\n keys.appendChild(plus);\n }\n const kbd = document.createElement('kbd');\n kbd.className = 'tcw-cmd-kbd';\n kbd.textContent = entry.keys[i];\n keys.appendChild(kbd);\n }\n row.appendChild(keys);\n\n const label = document.createElement('span');\n label.className = 'tcw-hotkey-label';\n label.textContent = entry.label;\n row.appendChild(label);\n\n section.appendChild(row);\n }\n\n grid.appendChild(section);\n }\n\n body.appendChild(grid);\n this.modal.appendChild(body);\n\n const footer = document.createElement('div');\n footer.className = 'tcw-modal-footer';\n footer.innerHTML = '<span style=\"font-size:11px;color:var(--tcw-text-muted)\">Press ? anytime to show this sheet</span>';\n const ok = document.createElement('button');\n ok.className = 'tcw-done-btn';\n ok.textContent = 'Got it';\n ok.addEventListener('click', () => this.close());\n footer.appendChild(ok);\n this.modal.appendChild(footer);\n\n document.body.appendChild(this.backdrop);\n document.body.appendChild(this.modal);\n\n document.addEventListener('keydown', this.boundKeydown);\n }\n\n close(): void {\n document.removeEventListener('keydown', this.boundKeydown);\n this.backdrop?.remove();\n this.modal?.remove();\n this.backdrop = null;\n this.modal = null;\n this.callbacks.onClose();\n }\n\n isOpen(): boolean {\n return this.backdrop !== null;\n }\n\n destroy(): void {\n this.close();\n }\n}\n","/**\r\n * Replay scrubber bar — surfaces the chart's existing replay engine as a\r\n * visible bottom-of-chart control. Mounts under the chart container, owns\r\n * its own lifecycle, and reports user intent up via callbacks (no chart\r\n * coupling — the host calls chart.replayStart() / replayPause() / etc.).\r\n */\r\nexport interface ReplayBarCallbacks {\r\n onPlay: () => void;\r\n onPause: () => void;\r\n onStop: () => void;\r\n onStepBack: () => void;\r\n onStepForward: () => void;\r\n onSeek: (index: number) => void;\r\n onSpeedChange: (barsPerSecond: number) => void;\r\n onClose: () => void;\r\n}\r\n\r\nexport type ReplayBarState = 'playing' | 'paused' | 'stopped';\r\n\r\nconst SPEEDS = [0.5, 1, 2, 5, 10, 20, 50, 100];\r\n\r\nexport class WidgetReplayBar {\r\n private root: HTMLDivElement | null = null;\r\n private scrubber: HTMLInputElement | null = null;\r\n private progressLabel: HTMLSpanElement | null = null;\r\n private playBtn: HTMLButtonElement | null = null;\r\n private state: ReplayBarState = 'stopped';\r\n private total = 0;\r\n private speed = 5;\r\n private callbacks: ReplayBarCallbacks;\r\n\r\n constructor(callbacks: ReplayBarCallbacks) {\r\n this.callbacks = callbacks;\r\n }\r\n\r\n mount(host: HTMLElement, opts: { total: number; speed?: number }): void {\r\n if (this.root) return;\r\n this.total = Math.max(0, opts.total);\r\n this.speed = opts.speed ?? 5;\r\n this.state = 'paused';\r\n\r\n this.root = document.createElement('div');\r\n this.root.className = 'tcw-replay-bar';\r\n this.root.innerHTML = this.markup();\r\n\r\n host.appendChild(this.root);\r\n this.wireEvents();\r\n this.syncUi();\r\n }\r\n\r\n unmount(): void {\r\n this.root?.remove();\r\n this.root = null;\r\n this.scrubber = null;\r\n this.progressLabel = null;\r\n this.playBtn = null;\r\n this.state = 'stopped';\r\n }\r\n\r\n isMounted(): boolean {\r\n return this.root !== null;\r\n }\r\n\r\n setState(state: ReplayBarState): void {\r\n this.state = state;\r\n this.syncUi();\r\n }\r\n\r\n setProgress(current: number, total: number): void {\r\n this.total = total;\r\n if (this.scrubber) {\r\n this.scrubber.max = String(Math.max(0, total - 1));\r\n this.scrubber.value = String(current);\r\n }\r\n if (this.progressLabel) {\r\n this.progressLabel.textContent = `${current + 1} / ${total}`;\r\n }\r\n }\r\n\r\n destroy(): void {\r\n this.unmount();\r\n }\r\n\r\n private markup(): string {\r\n const speeds = SPEEDS.map(s => `<option value=\"${s}\"${s === this.speed ? ' selected' : ''}>${s}× bars/s</option>`).join('');\r\n return `\r\n <button class=\"tcw-replay-btn\" data-act=\"close\" title=\"Exit replay\" aria-label=\"Exit replay\">${svgX()}</button>\r\n <button class=\"tcw-replay-btn\" data-act=\"stepBack\" title=\"Step back\" aria-label=\"Step back\">${svgStepBack()}</button>\r\n <button class=\"tcw-replay-btn tcw-replay-play\" data-act=\"play\" title=\"Play / pause\" aria-label=\"Play / pause\">${svgPlay()}</button>\r\n <button class=\"tcw-replay-btn\" data-act=\"stepForward\" title=\"Step forward\" aria-label=\"Step forward\">${svgStepForward()}</button>\r\n <input type=\"range\" class=\"tcw-replay-scrubber\" data-act=\"seek\" min=\"0\" max=\"${Math.max(0, this.total - 1)}\" value=\"0\" step=\"1\" />\r\n <span class=\"tcw-replay-progress\" data-tcw=\"progress\">1 / ${this.total}</span>\r\n <select class=\"tcw-replay-speed\" data-act=\"speed\">${speeds}</select>\r\n `;\r\n }\r\n\r\n private wireEvents(): void {\r\n if (!this.root) return;\r\n this.scrubber = this.root.querySelector('input[data-act=\"seek\"]');\r\n this.progressLabel = this.root.querySelector('[data-tcw=\"progress\"]');\r\n this.playBtn = this.root.querySelector('button[data-act=\"play\"]');\r\n\r\n this.root.querySelector('[data-act=\"close\"]')?.addEventListener('click', () => this.callbacks.onClose());\r\n this.root.querySelector('[data-act=\"stepBack\"]')?.addEventListener('click', () => this.callbacks.onStepBack());\r\n this.root.querySelector('[data-act=\"stepForward\"]')?.addEventListener('click', () => this.callbacks.onStepForward());\r\n this.playBtn?.addEventListener('click', () => {\r\n if (this.state === 'playing') {\r\n this.callbacks.onPause();\r\n } else {\r\n this.callbacks.onPlay();\r\n }\r\n });\r\n this.scrubber?.addEventListener('input', () => {\r\n const idx = Number(this.scrubber!.value);\r\n this.callbacks.onSeek(idx);\r\n });\r\n (this.root.querySelector('[data-act=\"speed\"]') as HTMLSelectElement | null)?.addEventListener('change', (e) => {\r\n const v = Number((e.target as HTMLSelectElement).value);\r\n this.speed = v;\r\n this.callbacks.onSpeedChange(v);\r\n });\r\n }\r\n\r\n private syncUi(): void {\r\n if (!this.playBtn) return;\r\n this.playBtn.innerHTML = this.state === 'playing' ? svgPause() : svgPlay();\r\n this.playBtn.title = this.state === 'playing' ? 'Pause' : 'Play';\r\n }\r\n}\r\n\r\nfunction svgPlay(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7L8 5z\"/></svg>';\r\n}\r\nfunction svgPause(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/></svg>';\r\n}\r\nfunction svgStepBack(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 6h2v12H6zM20 6L9 12l11 6V6z\"/></svg>';\r\n}\r\nfunction svgStepForward(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M4 6l11 6L4 18V6zM16 6h2v12h-2z\"/></svg>';\r\n}\r\nfunction svgX(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6L6 18M6 6l12 12\"/></svg>';\r\n}\r\n","/**\n * Watchlist sidebar — vertical list of symbols, each with last price, %\n * change, and a mini sparkline. Clicking switches the chart's symbol.\n *\n * The widget tracks the *active* symbol's price/spark automatically from the\n * live stream. For non-active symbols, the host can push data via\n * `setEntry(symbol, …)` so the row reflects whatever the app already has.\n */\nexport interface WatchlistEntry {\n symbol: string;\n lastPrice?: number;\n /** Reference price for % calc (usually session open or 24h-ago close). */\n refPrice?: number;\n /** Recent close samples for the sparkline — last point is the live price. */\n sparkline?: number[];\n}\n\nexport interface WatchlistCallbacks {\n onSelect: (symbol: string) => void;\n}\n\nexport class WidgetWatchlist {\n private el: HTMLDivElement;\n private listEl: HTMLDivElement;\n private rowMap = new Map<string, {\n row: HTMLDivElement;\n priceEl: HTMLSpanElement;\n changeEl: HTMLSpanElement;\n sparkCanvas: HTMLCanvasElement;\n }>();\n private entries = new Map<string, WatchlistEntry>();\n private active: string | null = null;\n private callbacks: WatchlistCallbacks;\n\n constructor(host: HTMLElement, symbols: string[], callbacks: WatchlistCallbacks) {\n this.callbacks = callbacks;\n\n this.el = document.createElement('div');\n this.el.className = 'tcw-watchlist';\n\n const header = document.createElement('div');\n header.className = 'tcw-watchlist-header';\n header.textContent = 'Watchlist';\n this.el.appendChild(header);\n\n this.listEl = document.createElement('div');\n this.listEl.className = 'tcw-watchlist-list';\n this.el.appendChild(this.listEl);\n\n for (const symbol of symbols) {\n this.entries.set(symbol, { symbol });\n this.appendRow(symbol);\n }\n\n host.appendChild(this.el);\n }\n\n /** Replace the symbol set. Rows are diff'd so DOM churn is minimal. */\n setSymbols(symbols: string[]): void {\n const next = new Set(symbols);\n for (const sym of this.rowMap.keys()) {\n if (!next.has(sym)) this.removeRow(sym);\n }\n for (const sym of symbols) {\n if (!this.rowMap.has(sym)) {\n this.entries.set(sym, this.entries.get(sym) ?? { symbol: sym });\n this.appendRow(sym);\n }\n }\n }\n\n setActive(symbol: string): void {\n if (this.active === symbol) return;\n if (this.active && this.rowMap.has(this.active)) {\n this.rowMap.get(this.active)!.row.classList.remove('tcw-watchlist-active');\n }\n this.active = symbol;\n const cur = this.rowMap.get(symbol);\n if (cur) cur.row.classList.add('tcw-watchlist-active');\n }\n\n /** Push a price tick into a row. The widget calls this automatically for\n * the active symbol. Apps can call it for the rest. */\n setEntry(symbol: string, patch: Partial<WatchlistEntry>): void {\n const prev = this.entries.get(symbol) ?? { symbol };\n const next = { ...prev, ...patch };\n this.entries.set(symbol, next);\n this.renderRow(symbol);\n }\n\n destroy(): void {\n this.el.remove();\n this.rowMap.clear();\n this.entries.clear();\n }\n\n private appendRow(symbol: string): void {\n const row = document.createElement('div');\n row.className = 'tcw-watchlist-row';\n row.tabIndex = 0;\n\n const label = document.createElement('div');\n label.className = 'tcw-watchlist-symbol';\n label.textContent = formatSymbol(symbol);\n\n const spark = document.createElement('canvas');\n spark.className = 'tcw-watchlist-spark';\n spark.width = 64;\n spark.height = 22;\n\n const right = document.createElement('div');\n right.className = 'tcw-watchlist-stats';\n const priceEl = document.createElement('span');\n priceEl.className = 'tcw-watchlist-price';\n priceEl.textContent = '—';\n const changeEl = document.createElement('span');\n changeEl.className = 'tcw-watchlist-change';\n changeEl.textContent = '';\n right.appendChild(priceEl);\n right.appendChild(changeEl);\n\n row.appendChild(label);\n row.appendChild(spark);\n row.appendChild(right);\n\n row.addEventListener('click', () => this.callbacks.onSelect(symbol));\n row.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.callbacks.onSelect(symbol);\n }\n });\n\n this.listEl.appendChild(row);\n this.rowMap.set(symbol, { row, priceEl, changeEl, sparkCanvas: spark });\n if (symbol === this.active) row.classList.add('tcw-watchlist-active');\n }\n\n private removeRow(symbol: string): void {\n const ref = this.rowMap.get(symbol);\n if (!ref) return;\n ref.row.remove();\n this.rowMap.delete(symbol);\n }\n\n private renderRow(symbol: string): void {\n const ref = this.rowMap.get(symbol);\n const entry = this.entries.get(symbol);\n if (!ref || !entry) return;\n\n if (entry.lastPrice !== undefined) {\n ref.priceEl.textContent = formatPrice(entry.lastPrice);\n }\n\n if (entry.lastPrice !== undefined && entry.refPrice !== undefined && entry.refPrice !== 0) {\n const diff = entry.lastPrice - entry.refPrice;\n const pct = (diff / entry.refPrice) * 100;\n const sign = diff >= 0 ? '+' : '';\n ref.changeEl.textContent = `${sign}${pct.toFixed(2)}%`;\n ref.changeEl.className = `tcw-watchlist-change ${diff >= 0 ? 'tcw-up' : 'tcw-down'}`;\n } else {\n ref.changeEl.textContent = '';\n }\n\n if (entry.sparkline && entry.sparkline.length >= 2) {\n drawSparkline(ref.sparkCanvas, entry.sparkline, entry.refPrice ?? entry.sparkline[0]);\n }\n }\n}\n\nfunction formatSymbol(symbol: string): string {\n // Add a / separator for typical crypto pair suffixes; leaves stock tickers\n // (AAPL, NVDA) alone.\n for (const quote of ['USDT', 'USD', 'BTC', 'ETH', 'EUR']) {\n if (symbol.length > quote.length && symbol.endsWith(quote)) {\n return symbol.slice(0, -quote.length) + '/' + quote;\n }\n }\n return symbol;\n}\n\nfunction formatPrice(v: number): string {\n if (v === 0) return '0';\n const abs = Math.abs(v);\n if (abs >= 1000) return v.toFixed(2);\n if (abs >= 1) return v.toFixed(4);\n return v.toPrecision(4);\n}\n\nfunction drawSparkline(canvas: HTMLCanvasElement, samples: number[], ref: number): void {\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n const dpr = window.devicePixelRatio || 1;\n if (canvas.width !== canvas.clientWidth * dpr) {\n canvas.width = (canvas.clientWidth || 64) * dpr;\n canvas.height = (canvas.clientHeight || 22) * dpr;\n }\n const w = canvas.width;\n const h = canvas.height;\n\n let lo = Infinity, hi = -Infinity;\n for (const v of samples) {\n if (v < lo) lo = v;\n if (v > hi) hi = v;\n }\n const span = Math.max(hi - lo, 1e-9);\n const last = samples[samples.length - 1];\n const up = last >= ref;\n const color = up ? '#26a17b' : '#f23645';\n\n ctx.clearRect(0, 0, w, h);\n ctx.lineWidth = 1.4 * dpr;\n ctx.strokeStyle = color;\n ctx.beginPath();\n const step = w / (samples.length - 1);\n for (let i = 0; i < samples.length; i++) {\n const x = i * step;\n const y = h - ((samples[i] - lo) / span) * (h - 4) - 2;\n if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);\n }\n ctx.stroke();\n}\n","import type { AlertCondition } from '@tradecanvas/core';\nimport { createIcon } from './icons.js';\n\nexport interface AlertListItem {\n id: string;\n price: number;\n condition: string;\n message?: string;\n triggered: boolean;\n channel?: string;\n label?: string;\n}\n\nexport interface AlertSource {\n /** `'price'` or `<instanceId>:<key>`. */\n channel: string;\n label: string;\n}\n\nexport interface AlertsPanelCallbacks {\n onAdd: (price: number, condition: AlertCondition, message: string | undefined, channel: string, label: string) => void;\n onRemove: (id: string) => void;\n onClear: () => void;\n /** Latest value for a source channel, used to prefill the add form. */\n getChannelValue: (channel: string) => number | null;\n formatPrice: (price: number) => string;\n}\n\nconst CONDITION_OPTIONS: { value: AlertCondition; label: string }[] = [\n { value: 'crossing', label: 'Crossing' },\n { value: 'crossingUp', label: 'Crossing up' },\n { value: 'crossingDown', label: 'Crossing down' },\n { value: 'greaterThan', label: 'Greater than' },\n { value: 'lessThan', label: 'Less than' },\n];\n\nconst CONDITION_LABEL = new Map(CONDITION_OPTIONS.map((o) => [o.value, o.label]));\n\nfunction roundForInput(v: number): number {\n return Math.round(v * 1e6) / 1e6;\n}\n\nfunction formatPlain(v: number): string {\n const abs = Math.abs(v);\n return abs >= 1000 ? v.toFixed(2) : abs >= 1 ? v.toFixed(2) : v.toPrecision(4);\n}\n\n/**\n * Floating price-alerts panel. Lists current alerts (with condition, price,\n * message, and a delete control) and an inline form to add a new one prefilled\n * with the current price. Toggled from the toolbar bell button; the host wires\n * add/remove back to the chart's `AlertManager`.\n */\nexport class WidgetAlertsPanel {\n private el: HTMLDivElement;\n private listEl: HTMLDivElement;\n private priceInput: HTMLInputElement;\n private conditionSelect: HTMLSelectElement;\n private sourceSelect: HTMLSelectElement;\n private messageInput: HTMLInputElement;\n private emptyEl: HTMLDivElement;\n private callbacks: AlertsPanelCallbacks;\n private open = false;\n private alerts: AlertListItem[] = [];\n private sources: AlertSource[] = [{ channel: 'price', label: 'Price' }];\n\n constructor(host: HTMLElement, callbacks: AlertsPanelCallbacks) {\n this.callbacks = callbacks;\n\n this.el = document.createElement('div');\n this.el.className = 'tcw-alerts-panel';\n this.el.hidden = true;\n\n // Header\n const header = document.createElement('div');\n header.className = 'tcw-alerts-header';\n const title = document.createElement('span');\n title.textContent = 'Price Alerts';\n const closeBtn = document.createElement('button');\n closeBtn.className = 'tcw-alerts-close';\n closeBtn.type = 'button';\n closeBtn.setAttribute('aria-label', 'Close alerts');\n closeBtn.innerHTML = createIcon('x', 14);\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(title);\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n // Add form\n const form = document.createElement('form');\n form.className = 'tcw-alerts-form';\n\n this.sourceSelect = document.createElement('select');\n this.sourceSelect.className = 'tcw-alerts-source';\n this.sourceSelect.addEventListener('change', () => this.prefillPrice());\n\n this.priceInput = document.createElement('input');\n this.priceInput.type = 'number';\n this.priceInput.step = 'any';\n this.priceInput.placeholder = 'Value';\n this.priceInput.className = 'tcw-alerts-price';\n this.priceInput.required = true;\n\n this.conditionSelect = document.createElement('select');\n this.conditionSelect.className = 'tcw-alerts-condition';\n for (const opt of CONDITION_OPTIONS) {\n const o = document.createElement('option');\n o.value = opt.value;\n o.textContent = opt.label;\n this.conditionSelect.appendChild(o);\n }\n\n this.messageInput = document.createElement('input');\n this.messageInput.type = 'text';\n this.messageInput.placeholder = 'Note (optional)';\n this.messageInput.className = 'tcw-alerts-message';\n\n const addBtn = document.createElement('button');\n addBtn.type = 'submit';\n addBtn.className = 'tcw-alerts-add';\n addBtn.innerHTML = `${createIcon('plus', 14)}<span>Add alert</span>`;\n\n form.appendChild(this.sourceSelect);\n form.appendChild(this.priceInput);\n form.appendChild(this.conditionSelect);\n form.appendChild(this.messageInput);\n form.appendChild(addBtn);\n form.addEventListener('submit', (e) => {\n e.preventDefault();\n this.submitForm();\n });\n this.el.appendChild(form);\n\n // List\n this.listEl = document.createElement('div');\n this.listEl.className = 'tcw-alerts-list';\n this.el.appendChild(this.listEl);\n\n this.emptyEl = document.createElement('div');\n this.emptyEl.className = 'tcw-alerts-empty';\n this.emptyEl.textContent = 'No alerts yet. Add one above, or right-click the chart.';\n this.listEl.appendChild(this.emptyEl);\n\n this.renderSources();\n host.appendChild(this.el);\n }\n\n /** Replace the alert-source options (price + indicator lines). */\n setSources(sources: AlertSource[]): void {\n this.sources = sources.length > 0 ? sources : [{ channel: 'price', label: 'Price' }];\n this.renderSources();\n }\n\n private renderSources(): void {\n const current = this.sourceSelect.value || 'price';\n this.sourceSelect.replaceChildren();\n for (const src of this.sources) {\n const o = document.createElement('option');\n o.value = src.channel;\n o.textContent = src.label;\n this.sourceSelect.appendChild(o);\n }\n // Keep the prior selection if it still exists, else default to price.\n this.sourceSelect.value = this.sources.some((s) => s.channel === current) ? current : 'price';\n }\n\n isOpen(): boolean {\n return this.open;\n }\n\n toggle(): void {\n this.open ? this.close() : this.openPanel();\n }\n\n openPanel(): void {\n this.open = true;\n this.el.hidden = false;\n if (this.priceInput.value === '') this.prefillPrice();\n }\n\n /** Fill the value input with the selected source's current value. */\n private prefillPrice(): void {\n const v = this.callbacks.getChannelValue(this.sourceSelect.value || 'price');\n this.priceInput.value = v !== null ? String(roundForInput(v)) : '';\n }\n\n close(): void {\n this.open = false;\n this.el.hidden = true;\n }\n\n /** Replace the displayed alert list. */\n setAlerts(alerts: AlertListItem[]): void {\n this.alerts = alerts;\n this.renderList();\n }\n\n destroy(): void {\n this.el.remove();\n }\n\n private submitForm(): void {\n const price = Number(this.priceInput.value);\n if (!Number.isFinite(price)) return;\n const condition = this.conditionSelect.value as AlertCondition;\n const message = this.messageInput.value.trim() || undefined;\n const channel = this.sourceSelect.value || 'price';\n const label = this.sources.find((s) => s.channel === channel)?.label ?? 'Price';\n this.callbacks.onAdd(price, condition, message, channel, label);\n this.messageInput.value = '';\n this.prefillPrice();\n }\n\n private renderList(): void {\n // Clear rows but keep the empty placeholder reference.\n this.listEl.replaceChildren();\n\n if (this.alerts.length === 0) {\n this.listEl.appendChild(this.emptyEl);\n return;\n }\n\n // Show most recent first.\n for (const alert of [...this.alerts].reverse()) {\n const row = document.createElement('div');\n row.className = 'tcw-alerts-row' + (alert.triggered ? ' tcw-alerts-triggered' : '');\n\n const info = document.createElement('div');\n info.className = 'tcw-alerts-info';\n const main = document.createElement('div');\n main.className = 'tcw-alerts-row-main';\n const label = CONDITION_LABEL.get(alert.condition as AlertCondition) ?? alert.condition;\n const isIndicator = alert.channel && alert.channel !== 'price';\n const valueStr = isIndicator ? formatPlain(alert.price) : this.callbacks.formatPrice(alert.price);\n const prefix = isIndicator && alert.label ? `${alert.label} ` : '';\n main.textContent = `${prefix}${label} ${valueStr}`;\n info.appendChild(main);\n if (alert.message) {\n const note = document.createElement('div');\n note.className = 'tcw-alerts-row-note';\n note.textContent = alert.message;\n info.appendChild(note);\n }\n if (alert.triggered) {\n const badge = document.createElement('span');\n badge.className = 'tcw-alerts-badge';\n badge.textContent = 'triggered';\n main.appendChild(badge);\n }\n\n const del = document.createElement('button');\n del.type = 'button';\n del.className = 'tcw-alerts-del';\n del.setAttribute('aria-label', 'Delete alert');\n del.innerHTML = createIcon('trash', 14);\n del.addEventListener('click', () => this.callbacks.onRemove(alert.id));\n\n row.appendChild(info);\n row.appendChild(del);\n this.listEl.appendChild(row);\n }\n }\n}\n","import { createIcon } from './icons.js';\n\nexport interface ObjectTreeIndicator {\n instanceId: string;\n name: string;\n visible: boolean;\n}\n\nexport interface ObjectTreeDrawing {\n id: string;\n label: string;\n visible: boolean;\n locked: boolean;\n}\n\nexport interface ObjectTreeCompare {\n id: string;\n label: string;\n color: string;\n}\n\nexport interface ObjectTreeCallbacks {\n onRemoveIndicator: (instanceId: string) => void;\n onConfigureIndicator?: (instanceId: string) => void;\n onToggleIndicatorVisible?: (instanceId: string, visible: boolean) => void;\n onRemoveDrawing: (id: string) => void;\n onToggleDrawingVisible: (id: string, visible: boolean) => void;\n onToggleDrawingLocked: (id: string, locked: boolean) => void;\n /** When provided, a Compare section with an \"add\" button is shown. */\n onAddCompare?: () => void;\n onRemoveCompare?: (id: string) => void;\n}\n\n/**\n * Object-tree panel — TradingView's layers manager. Lists every active\n * indicator and drawing on the chart with per-item controls: indicators can be\n * removed; drawings can be shown/hidden, locked/unlocked, and removed. Toggled\n * from the toolbar layers button; the host wires actions back to the chart.\n */\nexport class WidgetObjectTree {\n private el: HTMLDivElement;\n private indicatorsEl: HTMLDivElement;\n private drawingsEl: HTMLDivElement;\n private compareEl: HTMLDivElement | null = null;\n private callbacks: ObjectTreeCallbacks;\n private open = false;\n\n constructor(host: HTMLElement, callbacks: ObjectTreeCallbacks) {\n this.callbacks = callbacks;\n\n this.el = document.createElement('div');\n this.el.className = 'tcw-tree-panel';\n this.el.hidden = true;\n\n const header = document.createElement('div');\n header.className = 'tcw-tree-header';\n const title = document.createElement('span');\n title.textContent = 'Objects';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'tcw-tree-close';\n closeBtn.setAttribute('aria-label', 'Close objects');\n closeBtn.innerHTML = createIcon('x', 14);\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(title);\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n this.indicatorsEl = this.makeSection('Indicators');\n this.drawingsEl = this.makeSection('Drawings');\n if (this.callbacks.onAddCompare) {\n this.compareEl = this.makeSection('Compare', () => this.callbacks.onAddCompare?.());\n }\n\n host.appendChild(this.el);\n }\n\n isOpen(): boolean {\n return this.open;\n }\n\n toggle(): void {\n this.open ? this.close() : this.openPanel();\n }\n\n openPanel(): void {\n this.open = true;\n this.el.hidden = false;\n }\n\n close(): void {\n this.open = false;\n this.el.hidden = true;\n }\n\n destroy(): void {\n this.el.remove();\n }\n\n /** Replace all lists. Cheap full re-render — counts are small. */\n setObjects(\n indicators: ObjectTreeIndicator[],\n drawings: ObjectTreeDrawing[],\n compares: ObjectTreeCompare[] = [],\n ): void {\n this.renderIndicators(indicators);\n this.renderDrawings(drawings);\n this.renderCompares(compares);\n }\n\n private makeSection(title: string, onAdd?: () => void): HTMLDivElement {\n const wrap = document.createElement('div');\n wrap.className = 'tcw-tree-section';\n const head = document.createElement('div');\n head.className = 'tcw-tree-section-head';\n const label = document.createElement('span');\n label.textContent = title;\n head.appendChild(label);\n if (onAdd) {\n const addBtn = document.createElement('button');\n addBtn.type = 'button';\n addBtn.className = 'tcw-tree-add';\n addBtn.setAttribute('aria-label', `Add ${title.toLowerCase()}`);\n addBtn.title = `Add ${title.toLowerCase()}`;\n addBtn.innerHTML = createIcon('plus', 13);\n addBtn.addEventListener('click', onAdd);\n head.appendChild(addBtn);\n }\n const list = document.createElement('div');\n list.className = 'tcw-tree-list';\n wrap.appendChild(head);\n wrap.appendChild(list);\n this.el.appendChild(wrap);\n return list;\n }\n\n private renderIndicators(indicators: ObjectTreeIndicator[]): void {\n this.indicatorsEl.replaceChildren();\n if (indicators.length === 0) {\n this.indicatorsEl.appendChild(this.emptyRow('No indicators'));\n return;\n }\n for (const ind of indicators) {\n const row = this.row(ind.name);\n if (!ind.visible) row.classList.add('tcw-tree-hidden');\n const actions = document.createElement('div');\n actions.className = 'tcw-tree-actions';\n if (this.callbacks.onToggleIndicatorVisible) {\n actions.appendChild(this.iconButton(\n ind.visible ? 'eye' : 'eyeOff',\n ind.visible ? 'Hide' : 'Show',\n '',\n () => this.callbacks.onToggleIndicatorVisible?.(ind.instanceId, !ind.visible),\n ));\n }\n if (this.callbacks.onConfigureIndicator) {\n actions.appendChild(this.iconButton('settings', 'Indicator settings', '', () =>\n this.callbacks.onConfigureIndicator?.(ind.instanceId),\n ));\n }\n actions.appendChild(this.iconButton('trash', 'Remove indicator', 'tcw-tree-del', () =>\n this.callbacks.onRemoveIndicator(ind.instanceId),\n ));\n row.appendChild(actions);\n this.indicatorsEl.appendChild(row);\n }\n }\n\n private renderDrawings(drawings: ObjectTreeDrawing[]): void {\n this.drawingsEl.replaceChildren();\n if (drawings.length === 0) {\n this.drawingsEl.appendChild(this.emptyRow('No drawings'));\n return;\n }\n for (const d of drawings) {\n const row = this.row(d.label);\n if (!d.visible) row.classList.add('tcw-tree-hidden');\n\n const actions = document.createElement('div');\n actions.className = 'tcw-tree-actions';\n actions.appendChild(this.iconButton(\n d.visible ? 'eye' : 'eyeOff',\n d.visible ? 'Hide' : 'Show',\n '',\n () => this.callbacks.onToggleDrawingVisible(d.id, !d.visible),\n ));\n actions.appendChild(this.iconButton(\n d.locked ? 'lock' : 'unlock',\n d.locked ? 'Unlock' : 'Lock',\n d.locked ? 'tcw-tree-on' : '',\n () => this.callbacks.onToggleDrawingLocked(d.id, !d.locked),\n ));\n actions.appendChild(this.iconButton('trash', 'Remove drawing', 'tcw-tree-del', () =>\n this.callbacks.onRemoveDrawing(d.id),\n ));\n row.appendChild(actions);\n this.drawingsEl.appendChild(row);\n }\n }\n\n private renderCompares(compares: ObjectTreeCompare[]): void {\n if (!this.compareEl) return;\n this.compareEl.replaceChildren();\n if (compares.length === 0) {\n this.compareEl.appendChild(this.emptyRow('No comparisons'));\n return;\n }\n for (const c of compares) {\n const row = this.row(c.label);\n const dot = document.createElement('span');\n dot.className = 'tcw-tree-dot';\n dot.style.background = c.color;\n row.insertBefore(dot, row.firstChild);\n if (this.callbacks.onRemoveCompare) {\n row.appendChild(this.iconButton('trash', 'Remove comparison', 'tcw-tree-del', () =>\n this.callbacks.onRemoveCompare?.(c.id),\n ));\n }\n this.compareEl.appendChild(row);\n }\n }\n\n private row(label: string): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-tree-row';\n const name = document.createElement('span');\n name.className = 'tcw-tree-name';\n name.textContent = label;\n name.title = label;\n row.appendChild(name);\n return row;\n }\n\n private emptyRow(text: string): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-tree-empty';\n el.textContent = text;\n return el;\n }\n\n private iconButton(icon: string, label: string, extraClass: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = `tcw-tree-btn ${extraClass}`.trim();\n btn.setAttribute('aria-label', label);\n btn.title = label;\n btn.innerHTML = createIcon(icon, 14);\n btn.addEventListener('click', onClick);\n return btn;\n }\n}\n\nconst DRAWING_TYPE_LABELS: Record<string, string> = {\n trendLine: 'Trend Line',\n ray: 'Ray',\n extendedLine: 'Extended Line',\n horizontalLine: 'Horizontal Line',\n verticalLine: 'Vertical Line',\n rectangle: 'Rectangle',\n ellipse: 'Ellipse',\n triangle: 'Triangle',\n arrow: 'Arrow',\n parallelChannel: 'Parallel Channel',\n regressionChannel: 'Regression Channel',\n pitchfork: 'Pitchfork',\n fibRetracement: 'Fib Retracement',\n fibExtension: 'Fib Extension',\n fibTimeZones: 'Fib Time Zones',\n gannBox: 'Gann Box',\n gannFan: 'Gann Fan',\n elliottWave: 'Elliott Wave',\n priceRange: 'Price Range',\n dateRange: 'Date Range',\n measure: 'Measure',\n textAnnotation: 'Text',\n anchoredVWAP: 'Anchored VWAP',\n volumeProfileRange: 'Volume Profile',\n};\n\n/** Human-readable label for a drawing type, falling back to the raw key. */\nexport function drawingTypeLabel(type: string): string {\n return DRAWING_TYPE_LABELS[type] ?? type;\n}\n","import { createIcon } from './icons.js';\n\nexport type IndicatorParamValue = number | string | boolean;\n\nexport interface IndicatorSettingsTarget {\n instanceId: string;\n name: string;\n /** Default config — defines the editable keys and their types. */\n defaults: Record<string, unknown>;\n /** Current values, overlaid on defaults. */\n params: Record<string, unknown>;\n}\n\nexport interface IndicatorSettingsCallbacks {\n onApply: (instanceId: string, params: Record<string, IndicatorParamValue>) => void;\n onClose: () => void;\n}\n\nconst HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\nfunction titleCase(key: string): string {\n // camelCase / snake_case → \"Title Case\"\n return key\n .replace(/_/g, ' ')\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/^./, (c) => c.toUpperCase());\n}\n\n/**\n * Per-indicator parameter editor. Introspects the indicator's default config to\n * decide each control (number → stepper, boolean → toggle, hex string → color,\n * other string → text) and applies edits live via `onApply`.\n */\nexport class WidgetIndicatorSettings {\n private backdrop: HTMLDivElement;\n private modal: HTMLDivElement;\n private bodyEl: HTMLDivElement;\n private titleEl: HTMLHeadingElement;\n private callbacks: IndicatorSettingsCallbacks;\n private target: IndicatorSettingsTarget | null = null;\n private draft: Record<string, IndicatorParamValue> = {};\n\n constructor(host: HTMLElement, callbacks: IndicatorSettingsCallbacks) {\n this.callbacks = callbacks;\n\n this.backdrop = document.createElement('div');\n this.backdrop.className = 'tcw-modal-backdrop';\n this.backdrop.hidden = true;\n this.backdrop.addEventListener('click', (e) => {\n if (e.target === this.backdrop) this.close();\n });\n\n this.modal = document.createElement('div');\n this.modal.className = 'tcw-modal tcw-modal-narrow';\n\n const header = document.createElement('div');\n header.className = 'tcw-modal-header';\n this.titleEl = document.createElement('h3');\n this.titleEl.textContent = 'Indicator';\n const closeBtn = document.createElement('button');\n closeBtn.className = 'tcw-modal-close';\n closeBtn.setAttribute('aria-label', 'Close');\n closeBtn.innerHTML = createIcon('x', 16);\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(this.titleEl);\n header.appendChild(closeBtn);\n\n this.bodyEl = document.createElement('div');\n this.bodyEl.className = 'tcw-modal-body';\n\n const footer = document.createElement('div');\n footer.className = 'tcw-modal-footer';\n const resetBtn = document.createElement('button');\n resetBtn.className = 'tcw-reset-link';\n resetBtn.textContent = 'Reset to defaults';\n resetBtn.addEventListener('click', () => this.resetDefaults());\n const doneBtn = document.createElement('button');\n doneBtn.className = 'tcw-done-btn';\n doneBtn.textContent = 'Done';\n doneBtn.addEventListener('click', () => this.close());\n footer.appendChild(resetBtn);\n footer.appendChild(doneBtn);\n\n this.modal.appendChild(header);\n this.modal.appendChild(this.bodyEl);\n this.modal.appendChild(footer);\n this.backdrop.appendChild(this.modal);\n host.appendChild(this.backdrop);\n }\n\n open(target: IndicatorSettingsTarget): void {\n this.target = target;\n this.titleEl.textContent = `${target.name} settings`;\n this.draft = {};\n this.renderFields();\n this.backdrop.hidden = false;\n }\n\n close(): void {\n this.backdrop.hidden = true;\n this.target = null;\n this.callbacks.onClose();\n }\n\n isOpen(): boolean {\n return !this.backdrop.hidden;\n }\n\n destroy(): void {\n this.backdrop.remove();\n }\n\n private currentValue(key: string): IndicatorParamValue {\n if (key in this.draft) return this.draft[key];\n const cur = this.target?.params[key];\n const def = this.target?.defaults[key];\n const val = cur ?? def;\n return val as IndicatorParamValue;\n }\n\n private setValue(key: string, value: IndicatorParamValue): void {\n if (!this.target) return;\n this.draft[key] = value;\n this.callbacks.onApply(this.target.instanceId, { ...this.draft });\n }\n\n private resetDefaults(): void {\n if (!this.target) return;\n const reset: Record<string, IndicatorParamValue> = {};\n for (const [key, def] of Object.entries(this.target.defaults)) {\n reset[key] = def as IndicatorParamValue;\n }\n this.draft = reset;\n this.callbacks.onApply(this.target.instanceId, { ...reset });\n this.renderFields();\n }\n\n private renderFields(): void {\n this.bodyEl.replaceChildren();\n if (!this.target) return;\n\n const section = document.createElement('div');\n section.className = 'tcw-settings-section';\n\n const keys = Object.keys(this.target.defaults);\n if (keys.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'tcw-settings-label';\n empty.textContent = 'This indicator has no adjustable parameters.';\n section.appendChild(empty);\n }\n\n for (const key of keys) {\n section.appendChild(this.fieldRow(key));\n }\n this.bodyEl.appendChild(section);\n }\n\n private fieldRow(key: string): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n const label = document.createElement('span');\n label.className = 'tcw-settings-label';\n label.textContent = titleCase(key);\n row.appendChild(label);\n\n const value = this.currentValue(key);\n const defType = typeof (this.target?.defaults[key] ?? value);\n\n if (defType === 'boolean') {\n row.appendChild(this.toggleControl(key, Boolean(value)));\n } else if (defType === 'number') {\n row.appendChild(this.numberControl(key, Number(value)));\n } else if (typeof value === 'string' && HEX_RE.test(value)) {\n row.appendChild(this.colorControl(key, value));\n } else {\n row.appendChild(this.textControl(key, String(value ?? '')));\n }\n return row;\n }\n\n private toggleControl(key: string, value: boolean): HTMLButtonElement {\n const toggle = document.createElement('button');\n toggle.className = `tcw-toggle${value ? ' tcw-on' : ''}`;\n toggle.type = 'button';\n toggle.addEventListener('click', () => {\n const next = !toggle.classList.contains('tcw-on');\n toggle.classList.toggle('tcw-on', next);\n this.setValue(key, next);\n });\n return toggle;\n }\n\n private numberControl(key: string, value: number): HTMLInputElement {\n const input = document.createElement('input');\n input.type = 'number';\n input.className = 'tcw-indi-input';\n input.value = String(value);\n // Integer-looking defaults step by 1; fractional defaults step by 0.1.\n input.step = Number.isInteger(value) ? '1' : '0.1';\n input.addEventListener('change', () => {\n const n = Number(input.value);\n if (Number.isFinite(n)) this.setValue(key, n);\n });\n return input;\n }\n\n private colorControl(key: string, value: string): HTMLInputElement {\n const input = document.createElement('input');\n input.type = 'color';\n input.className = 'tcw-indi-color';\n input.value = value.length === 4 ? expandHex(value) : value;\n input.addEventListener('input', () => this.setValue(key, input.value));\n return input;\n }\n\n private textControl(key: string, value: string): HTMLInputElement {\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'tcw-indi-input';\n input.value = value;\n input.addEventListener('change', () => this.setValue(key, input.value));\n return input;\n }\n}\n\nfunction expandHex(short: string): string {\n // #abc → #aabbcc\n const r = short[1], g = short[2], b = short[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n}\n","import type { DrawingStyle } from '@tradecanvas/commons';\n\nexport interface DrawingStyleTemplate {\n name: string;\n style: Partial<DrawingStyle>;\n}\n\n/** Minimal storage surface — satisfied by `localStorage` and easy to mock. */\nexport interface KeyValueStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nfunction defaultStorage(): KeyValueStorage | null {\n try {\n return typeof localStorage !== 'undefined' ? localStorage : null;\n } catch {\n return null;\n }\n}\n\nconst STYLE_KEYS: (keyof DrawingStyle)[] = [\n 'color', 'lineWidth', 'lineStyle', 'fillColor', 'fillOpacity', 'fontSize',\n];\n\n/** Keep only known style keys — guards against junk persisted by older builds. */\nfunction sanitizeStyle(raw: unknown): Partial<DrawingStyle> {\n if (!raw || typeof raw !== 'object') return {};\n const out: Partial<DrawingStyle> = {};\n const obj = raw as Record<string, unknown>;\n for (const key of STYLE_KEYS) {\n if (obj[key] !== undefined) (out as Record<string, unknown>)[key] = obj[key];\n }\n return out;\n}\n\n/**\n * Named drawing-style presets, persisted to a key-value store. Templates are\n * upserted by name (case-sensitive) and ordered most-recently-saved last.\n */\nexport class DrawingTemplateStore {\n private templates: DrawingStyleTemplate[] = [];\n\n constructor(\n private storageKey = 'tcw:draw-templates',\n private storage: KeyValueStorage | null = defaultStorage(),\n ) {\n this.load();\n }\n\n list(): DrawingStyleTemplate[] {\n return this.templates.map((t) => ({ name: t.name, style: { ...t.style } }));\n }\n\n get(name: string): DrawingStyleTemplate | null {\n const t = this.templates.find((x) => x.name === name);\n return t ? { name: t.name, style: { ...t.style } } : null;\n }\n\n /** Insert or replace a template by name. */\n save(name: string, style: Partial<DrawingStyle>): void {\n const trimmed = name.trim();\n if (!trimmed) return;\n const clean = sanitizeStyle(style);\n this.templates = this.templates.filter((t) => t.name !== trimmed);\n this.templates.push({ name: trimmed, style: clean });\n this.persist();\n }\n\n remove(name: string): void {\n const next = this.templates.filter((t) => t.name !== name);\n if (next.length === this.templates.length) return;\n this.templates = next;\n this.persist();\n }\n\n clear(): void {\n this.templates = [];\n this.persist();\n }\n\n private load(): void {\n if (!this.storage) return;\n try {\n const raw = this.storage.getItem(this.storageKey);\n if (!raw) return;\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return;\n this.templates = parsed\n .filter((t) => t && typeof t.name === 'string')\n .map((t) => ({ name: t.name, style: sanitizeStyle(t.style) }));\n } catch {\n // Corrupt or unavailable storage — start empty.\n }\n }\n\n private persist(): void {\n if (!this.storage) return;\n try {\n this.storage.setItem(this.storageKey, JSON.stringify(this.templates));\n } catch {\n // Storage full or blocked — keep the in-memory copy.\n }\n }\n}\n","import type { DrawingStyle } from '@tradecanvas/commons';\nimport { createIcon } from './icons.js';\nimport { DrawingTemplateStore } from './DrawingTemplateStore.js';\n\nexport interface DrawingStyleCallbacks {\n /** Apply a style change to the active (next) drawing and the selected one. */\n onStyleChange: (style: Partial<DrawingStyle>) => void;\n /** Current active drawing style, for seeding controls and saving templates. */\n getStyle: () => DrawingStyle;\n}\n\nconst SWATCHES = ['#2962ff', '#089981', '#f23645', '#ff9800', '#ab47bc', '#26c6da', '#ffffff', '#787b86'];\nconst WIDTHS = [1, 2, 3, 4];\nconst LINE_STYLES: DrawingStyle['lineStyle'][] = ['solid', 'dashed', 'dotted'];\n\n/**\n * Drawing style popover — pick colour, line width, and line style for the next\n * drawing (and the selected one), plus save/apply named style templates\n * persisted via `DrawingTemplateStore`.\n */\nexport class WidgetDrawingStyle {\n private el: HTMLDivElement;\n private templatesEl: HTMLDivElement;\n private nameInput: HTMLInputElement;\n private callbacks: DrawingStyleCallbacks;\n private store: DrawingTemplateStore;\n private open = false;\n\n constructor(host: HTMLElement, callbacks: DrawingStyleCallbacks, store: DrawingTemplateStore) {\n this.callbacks = callbacks;\n this.store = store;\n\n this.el = document.createElement('div');\n this.el.className = 'tcw-style-panel';\n this.el.hidden = true;\n\n const header = document.createElement('div');\n header.className = 'tcw-style-header';\n const title = document.createElement('span');\n title.textContent = 'Drawing Style';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'tcw-style-close';\n closeBtn.setAttribute('aria-label', 'Close');\n closeBtn.innerHTML = createIcon('x', 14);\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(title);\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n this.el.appendChild(this.colorRow());\n this.el.appendChild(this.widthRow());\n this.el.appendChild(this.lineStyleRow());\n\n // Templates\n const tmplHead = document.createElement('div');\n tmplHead.className = 'tcw-style-subhead';\n tmplHead.textContent = 'Templates';\n this.el.appendChild(tmplHead);\n\n const saveRow = document.createElement('div');\n saveRow.className = 'tcw-style-save';\n this.nameInput = document.createElement('input');\n this.nameInput.type = 'text';\n this.nameInput.placeholder = 'Template name';\n this.nameInput.className = 'tcw-style-name';\n const saveBtn = document.createElement('button');\n saveBtn.type = 'button';\n saveBtn.className = 'tcw-style-savebtn';\n saveBtn.innerHTML = `${createIcon('plus', 13)}<span>Save</span>`;\n saveBtn.addEventListener('click', () => this.saveTemplate());\n saveRow.appendChild(this.nameInput);\n saveRow.appendChild(saveBtn);\n this.el.appendChild(saveRow);\n\n this.templatesEl = document.createElement('div');\n this.templatesEl.className = 'tcw-style-templates';\n this.el.appendChild(this.templatesEl);\n\n host.appendChild(this.el);\n this.renderTemplates();\n }\n\n isOpen(): boolean {\n return this.open;\n }\n\n toggle(): void {\n this.open ? this.close() : this.openPanel();\n }\n\n openPanel(): void {\n this.open = true;\n this.el.hidden = false;\n this.syncActiveControls();\n this.renderTemplates();\n }\n\n close(): void {\n this.open = false;\n this.el.hidden = true;\n }\n\n destroy(): void {\n this.el.remove();\n }\n\n private colorRow(): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-style-row tcw-style-colors';\n for (const c of SWATCHES) {\n const sw = document.createElement('button');\n sw.type = 'button';\n sw.className = 'tcw-style-swatch';\n sw.style.background = c;\n sw.dataset.color = c;\n sw.setAttribute('aria-label', c);\n sw.addEventListener('click', () => this.applyStyle({ color: c }));\n row.appendChild(sw);\n }\n const picker = document.createElement('input');\n picker.type = 'color';\n picker.className = 'tcw-style-picker';\n picker.addEventListener('input', () => this.applyStyle({ color: picker.value }));\n row.appendChild(picker);\n return row;\n }\n\n private widthRow(): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-style-row tcw-style-widths';\n for (const w of WIDTHS) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'tcw-style-width';\n btn.dataset.width = String(w);\n const bar = document.createElement('span');\n bar.style.height = `${w}px`;\n btn.appendChild(bar);\n btn.addEventListener('click', () => this.applyStyle({ lineWidth: w }));\n row.appendChild(btn);\n }\n return row;\n }\n\n private lineStyleRow(): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-style-row tcw-style-dashes';\n for (const ls of LINE_STYLES) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'tcw-style-dash';\n btn.dataset.linestyle = ls;\n btn.textContent = ls === 'solid' ? '──' : ls === 'dashed' ? '╌╌' : '┄┄';\n btn.title = ls;\n btn.addEventListener('click', () => this.applyStyle({ lineStyle: ls }));\n row.appendChild(btn);\n }\n return row;\n }\n\n private applyStyle(patch: Partial<DrawingStyle>): void {\n this.callbacks.onStyleChange(patch);\n this.syncActiveControls();\n }\n\n /** Mark the controls matching the current active style. */\n private syncActiveControls(): void {\n const style = this.callbacks.getStyle();\n this.el.querySelectorAll<HTMLElement>('.tcw-style-swatch').forEach((sw) => {\n sw.classList.toggle('tcw-on', sw.dataset.color?.toLowerCase() === style.color?.toLowerCase());\n });\n this.el.querySelectorAll<HTMLElement>('.tcw-style-width').forEach((b) => {\n b.classList.toggle('tcw-on', Number(b.dataset.width) === style.lineWidth);\n });\n this.el.querySelectorAll<HTMLElement>('.tcw-style-dash').forEach((b) => {\n b.classList.toggle('tcw-on', b.dataset.linestyle === style.lineStyle);\n });\n }\n\n private saveTemplate(): void {\n const name = this.nameInput.value.trim();\n if (!name) return;\n this.store.save(name, this.callbacks.getStyle());\n this.nameInput.value = '';\n this.renderTemplates();\n }\n\n private renderTemplates(): void {\n this.templatesEl.replaceChildren();\n const templates = this.store.list();\n if (templates.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'tcw-style-empty';\n empty.textContent = 'No saved templates';\n this.templatesEl.appendChild(empty);\n return;\n }\n for (const t of templates) {\n const row = document.createElement('div');\n row.className = 'tcw-style-template';\n\n const apply = document.createElement('button');\n apply.type = 'button';\n apply.className = 'tcw-style-apply';\n const dot = document.createElement('span');\n dot.className = 'tcw-style-tdot';\n dot.style.background = (t.style.color as string) ?? 'var(--tcw-text-muted)';\n const label = document.createElement('span');\n label.textContent = t.name;\n apply.appendChild(dot);\n apply.appendChild(label);\n apply.addEventListener('click', () => {\n this.callbacks.onStyleChange({ ...t.style });\n this.syncActiveControls();\n });\n\n const del = document.createElement('button');\n del.type = 'button';\n del.className = 'tcw-style-tdel';\n del.setAttribute('aria-label', 'Delete template');\n del.innerHTML = createIcon('trash', 13);\n del.addEventListener('click', () => {\n this.store.remove(t.name);\n this.renderTemplates();\n });\n\n row.appendChild(apply);\n row.appendChild(del);\n this.templatesEl.appendChild(row);\n }\n }\n}\n","import type { KeyValueStorage } from './DrawingTemplateStore.js';\n\nfunction defaultStorage(): KeyValueStorage | null {\n try {\n return typeof localStorage !== 'undefined' ? localStorage : null;\n } catch {\n return null;\n }\n}\n\n/**\n * An ordered, de-duplicated set of pinned drawing-tool ids, persisted to a\n * key-value store. Order is insertion order (most-recently-pinned last).\n */\nexport class DrawingFavoritesStore {\n private favorites: string[] = [];\n\n constructor(\n private storageKey = 'tcw:draw-favorites',\n private storage: KeyValueStorage | null = defaultStorage(),\n ) {\n this.load();\n }\n\n list(): string[] {\n return [...this.favorites];\n }\n\n has(tool: string): boolean {\n return this.favorites.includes(tool);\n }\n\n add(tool: string): void {\n if (!tool || this.favorites.includes(tool)) return;\n this.favorites = [...this.favorites, tool];\n this.persist();\n }\n\n remove(tool: string): void {\n if (!this.favorites.includes(tool)) return;\n this.favorites = this.favorites.filter((t) => t !== tool);\n this.persist();\n }\n\n /** Toggle a tool's pinned state. Returns the new state (true = pinned). */\n toggle(tool: string): boolean {\n if (this.has(tool)) {\n this.remove(tool);\n return false;\n }\n this.add(tool);\n return true;\n }\n\n /** Seed the favorites only when none are stored yet (first run). */\n seedDefaults(tools: string[]): void {\n if (this.favorites.length > 0) return;\n this.favorites = [...new Set(tools.filter(Boolean))];\n this.persist();\n }\n\n private load(): void {\n if (!this.storage) return;\n try {\n const raw = this.storage.getItem(this.storageKey);\n if (!raw) return;\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) {\n this.favorites = [...new Set(parsed.filter((t) => typeof t === 'string'))];\n }\n } catch {\n // Corrupt or unavailable — start empty.\n }\n }\n\n private persist(): void {\n if (!this.storage) return;\n try {\n this.storage.setItem(this.storageKey, JSON.stringify(this.favorites));\n } catch {\n // Storage full or blocked — keep the in-memory copy.\n }\n }\n}\n","import { createIcon } from './icons.js';\n\nexport interface BracketBarCallbacks {\n onConfirm: () => void;\n onCancel: () => void;\n}\n\n/**\n * Floating confirm/cancel bar shown while a bracket order is being placed.\n * The live entry / SL / TP numbers are drawn on the chart canvas; this bar\n * just carries the commit and discard actions (also bound to Enter / Esc).\n */\nexport class WidgetBracketBar {\n private el: HTMLDivElement;\n private labelEl: HTMLSpanElement;\n private callbacks: BracketBarCallbacks;\n private visible = false;\n\n constructor(host: HTMLElement, callbacks: BracketBarCallbacks) {\n this.callbacks = callbacks;\n\n this.el = document.createElement('div');\n this.el.className = 'tcw-bracket-bar';\n this.el.hidden = true;\n\n this.labelEl = document.createElement('span');\n this.labelEl.className = 'tcw-bracket-label';\n this.el.appendChild(this.labelEl);\n\n const hint = document.createElement('span');\n hint.className = 'tcw-bracket-hint';\n hint.textContent = 'drag lines to adjust';\n this.el.appendChild(hint);\n\n const cancel = document.createElement('button');\n cancel.type = 'button';\n cancel.className = 'tcw-bracket-cancel';\n cancel.innerHTML = `${createIcon('x', 14)}<span>Cancel</span>`;\n cancel.addEventListener('click', () => this.callbacks.onCancel());\n\n const confirm = document.createElement('button');\n confirm.type = 'button';\n confirm.className = 'tcw-bracket-confirm';\n confirm.innerHTML = `${createIcon('check', 14)}<span>Place</span>`;\n confirm.addEventListener('click', () => this.callbacks.onConfirm());\n\n this.el.appendChild(cancel);\n this.el.appendChild(confirm);\n host.appendChild(this.el);\n }\n\n show(side: 'buy' | 'sell'): void {\n this.visible = true;\n this.labelEl.textContent = side === 'buy' ? 'Long bracket' : 'Short bracket';\n this.labelEl.dataset.side = side;\n this.el.hidden = false;\n }\n\n hide(): void {\n this.visible = false;\n this.el.hidden = true;\n }\n\n isVisible(): boolean {\n return this.visible;\n }\n\n destroy(): void {\n this.el.remove();\n }\n}\n","export interface AlertNotifyOptions {\n /** Play a sound on trigger. `true` = built-in beep, string = audio URL. Default `false`. */\n sound?: boolean | string;\n /** Show a desktop notification (requests permission on first use). Default `false`. */\n desktop?: boolean;\n /** Title for desktop notifications. Default `'Price alert'`. */\n title?: string;\n}\n\n/** True when the Notification API is present and not denied. */\nexport function canRequestNotifications(): boolean {\n return typeof Notification !== 'undefined' && Notification.permission !== 'denied';\n}\n\n/**\n * Plays a sound and/or raises a desktop notification when a price alert fires.\n * Browser-API heavy by nature — every entry point is guarded so it degrades to\n * a no-op in SSR, unsupported browsers, or when permission is denied.\n */\nexport class AlertNotifier {\n private options: AlertNotifyOptions;\n private audioCtx: AudioContext | null = null;\n private audioEl: HTMLAudioElement | null = null;\n private permissionAsked = false;\n\n constructor(options: AlertNotifyOptions = {}) {\n this.options = options;\n if (typeof options.sound === 'string') {\n try {\n this.audioEl = new Audio(options.sound);\n this.audioEl.preload = 'auto';\n } catch {\n this.audioEl = null;\n }\n }\n // Request notification permission up front so the first alert isn't silent.\n if (options.desktop) this.ensurePermission();\n }\n\n setOptions(options: AlertNotifyOptions): void {\n this.options = { ...this.options, ...options };\n }\n\n /** Fire the configured notifications for a triggered alert. */\n notify(message: string): void {\n if (this.options.sound) this.playSound();\n if (this.options.desktop) this.showDesktop(message);\n }\n\n private playSound(): void {\n if (this.audioEl) {\n this.audioEl.currentTime = 0;\n void this.audioEl.play().catch(() => {});\n return;\n }\n this.beep();\n }\n\n /** A short two-tone beep via Web Audio — no asset required. */\n private beep(): void {\n try {\n const Ctx = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!Ctx) return;\n if (!this.audioCtx) this.audioCtx = new Ctx();\n const ctx = this.audioCtx;\n const now = ctx.currentTime;\n const gain = ctx.createGain();\n gain.gain.setValueAtTime(0.0001, now);\n gain.gain.exponentialRampToValueAtTime(0.2, now + 0.01);\n gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.35);\n gain.connect(ctx.destination);\n const osc = ctx.createOscillator();\n osc.type = 'sine';\n osc.frequency.setValueAtTime(880, now);\n osc.frequency.setValueAtTime(1320, now + 0.16);\n osc.connect(gain);\n osc.start(now);\n osc.stop(now + 0.36);\n } catch {\n // Audio unavailable or blocked by autoplay policy — silent.\n }\n }\n\n private ensurePermission(): void {\n if (this.permissionAsked) return;\n this.permissionAsked = true;\n if (typeof Notification === 'undefined') return;\n if (Notification.permission === 'default') {\n void Notification.requestPermission().catch(() => {});\n }\n }\n\n private showDesktop(message: string): void {\n if (typeof Notification === 'undefined') return;\n if (Notification.permission !== 'granted') {\n this.ensurePermission();\n return;\n }\n try {\n new Notification(this.options.title ?? 'Price alert', { body: message });\n } catch {\n // Some browsers throw if not invoked from a user gesture — ignore.\n }\n }\n\n destroy(): void {\n try {\n void this.audioCtx?.close();\n } catch {\n // ignore\n }\n this.audioCtx = null;\n this.audioEl = null;\n }\n}\n","import type { DepthData } from '@tradecanvas/commons';\n\nexport interface LadderRow {\n price: number;\n bidVolume: number;\n askVolume: number;\n}\n\nexport interface LadderModel {\n /** Rows ordered high → low price (asks on top, bids below). */\n rows: LadderRow[];\n /** Largest single-side volume across the shown rows (for bar scaling). */\n maxVolume: number;\n /** Midpoint between best bid and best ask, or null if a side is empty. */\n mid: number | null;\n}\n\n/**\n * Build a depth-of-market ladder from an order book: the best `maxLevels` asks\n * (lowest prices) and best `maxLevels` bids (highest prices), merged into rows\n * ordered high→low. A price present on both sides is merged into one row.\n */\nexport function buildLadderRows(data: DepthData, maxLevels = 12): LadderModel {\n const asks = [...data.asks].sort((a, b) => a.price - b.price).slice(0, maxLevels);\n const bids = [...data.bids].sort((a, b) => b.price - a.price).slice(0, maxLevels);\n\n const bestAsk = asks.length > 0 ? asks[0].price : null;\n const bestBid = bids.length > 0 ? bids[0].price : null;\n const mid = bestAsk !== null && bestBid !== null ? (bestAsk + bestBid) / 2 : null;\n\n const byPrice = new Map<number, LadderRow>();\n const rowAt = (price: number): LadderRow => {\n let row = byPrice.get(price);\n if (!row) {\n row = { price, bidVolume: 0, askVolume: 0 };\n byPrice.set(price, row);\n }\n return row;\n };\n for (const a of asks) rowAt(a.price).askVolume += a.volume;\n for (const b of bids) rowAt(b.price).bidVolume += b.volume;\n\n const rows = [...byPrice.values()].sort((a, b) => b.price - a.price);\n let maxVolume = 0;\n for (const r of rows) maxVolume = Math.max(maxVolume, r.bidVolume, r.askVolume);\n\n return { rows, maxVolume, mid };\n}\n","import type { DepthData } from '@tradecanvas/commons';\nimport { createIcon } from './icons.js';\nimport { buildLadderRows, type LadderModel } from './ladderRows.js';\n\nexport interface DepthLadderCallbacks {\n /** Buy at `price` (clicked an ask cell) or sell at `price` (clicked a bid cell). */\n onTrade: (side: 'buy' | 'sell', price: number) => void;\n formatPrice: (price: number) => string;\n}\n\n/**\n * Depth-of-market ladder (DOM). Renders the order book as price rows with bid\n * and ask size columns; clicking an ask cell buys at that price, a bid cell\n * sells. Fed by `setData(depth)`; the bar widths scale to the largest visible\n * size.\n */\nexport class WidgetDepthLadder {\n private el: HTMLDivElement;\n private bodyEl: HTMLDivElement;\n private callbacks: DepthLadderCallbacks;\n private open = false;\n private levels: number;\n\n constructor(host: HTMLElement, callbacks: DepthLadderCallbacks, levels = 12) {\n this.callbacks = callbacks;\n this.levels = levels;\n\n this.el = document.createElement('div');\n this.el.className = 'tcw-ladder';\n this.el.hidden = true;\n\n const header = document.createElement('div');\n header.className = 'tcw-ladder-header';\n const title = document.createElement('span');\n title.textContent = 'Depth Ladder';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'tcw-ladder-close';\n closeBtn.setAttribute('aria-label', 'Close');\n closeBtn.innerHTML = createIcon('x', 14);\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(title);\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n const cols = document.createElement('div');\n cols.className = 'tcw-ladder-cols';\n cols.innerHTML = '<span>Bid</span><span>Price</span><span>Ask</span>';\n this.el.appendChild(cols);\n\n this.bodyEl = document.createElement('div');\n this.bodyEl.className = 'tcw-ladder-body';\n this.el.appendChild(this.bodyEl);\n\n host.appendChild(this.el);\n }\n\n isOpen(): boolean {\n return this.open;\n }\n\n toggle(): void {\n this.open ? this.close() : this.openPanel();\n }\n\n openPanel(): void {\n this.open = true;\n this.el.hidden = false;\n }\n\n close(): void {\n this.open = false;\n this.el.hidden = true;\n }\n\n setData(depth: DepthData | null): void {\n if (!depth) {\n this.renderEmpty();\n return;\n }\n this.render(buildLadderRows(depth, this.levels));\n }\n\n destroy(): void {\n this.el.remove();\n }\n\n private renderEmpty(): void {\n this.bodyEl.replaceChildren();\n const empty = document.createElement('div');\n empty.className = 'tcw-ladder-empty';\n empty.textContent = 'No order-book data';\n this.bodyEl.appendChild(empty);\n }\n\n private render(model: LadderModel): void {\n this.bodyEl.replaceChildren();\n if (model.rows.length === 0) {\n this.renderEmpty();\n return;\n }\n const inv = model.maxVolume > 0 ? 1 / model.maxVolume : 0;\n\n for (const row of model.rows) {\n const isAsk = row.askVolume > 0;\n const tr = document.createElement('div');\n tr.className = 'tcw-ladder-row';\n\n // Bid cell (click → sell at price)\n const bid = document.createElement('button');\n bid.type = 'button';\n bid.className = 'tcw-ladder-cell tcw-ladder-bid';\n if (row.bidVolume > 0) {\n bid.textContent = formatSize(row.bidVolume);\n bid.style.setProperty('--w', `${(row.bidVolume * inv * 100).toFixed(1)}%`);\n bid.title = `Sell @ ${this.callbacks.formatPrice(row.price)}`;\n bid.addEventListener('click', () => this.callbacks.onTrade('sell', row.price));\n } else {\n bid.disabled = true;\n }\n\n const price = document.createElement('div');\n price.className = `tcw-ladder-price ${isAsk ? 'tcw-ask' : 'tcw-bid'}`;\n price.textContent = this.callbacks.formatPrice(row.price);\n\n // Ask cell (click → buy at price)\n const ask = document.createElement('button');\n ask.type = 'button';\n ask.className = 'tcw-ladder-cell tcw-ladder-ask';\n if (row.askVolume > 0) {\n ask.textContent = formatSize(row.askVolume);\n ask.style.setProperty('--w', `${(row.askVolume * inv * 100).toFixed(1)}%`);\n ask.title = `Buy @ ${this.callbacks.formatPrice(row.price)}`;\n ask.addEventListener('click', () => this.callbacks.onTrade('buy', row.price));\n } else {\n ask.disabled = true;\n }\n\n tr.appendChild(bid);\n tr.appendChild(price);\n tr.appendChild(ask);\n this.bodyEl.appendChild(tr);\n }\n }\n}\n\nfunction formatSize(v: number): string {\n if (v >= 1000) return (v / 1000).toFixed(1) + 'k';\n if (v >= 1) return v.toFixed(2).replace(/\\.00$/, '');\n return v.toPrecision(2);\n}\n","import { createIcon } from './icons.js';\n\nexport interface DataWindowIndicator {\n name: string;\n values: { key: string; value: number }[];\n}\n\nexport interface DataWindowModel {\n ohlc: { open: number; high: number; low: number; close: number; volume: number } | null;\n change: number;\n changePct: number;\n indicators: DataWindowIndicator[];\n}\n\nexport interface DataWindowCallbacks {\n formatPrice: (price: number) => string;\n}\n\n/**\n * Data Window — a floating readout of the exact O/H/L/C/V, change, and every\n * active indicator value at the hovered bar. Updated from `crosshairMove`.\n */\nexport class WidgetDataWindow {\n private el: HTMLDivElement;\n private bodyEl: HTMLDivElement;\n private callbacks: DataWindowCallbacks;\n private open = false;\n\n constructor(host: HTMLElement, callbacks: DataWindowCallbacks) {\n this.callbacks = callbacks;\n\n this.el = document.createElement('div');\n this.el.className = 'tcw-datawin';\n this.el.hidden = true;\n\n const header = document.createElement('div');\n header.className = 'tcw-datawin-header';\n const title = document.createElement('span');\n title.textContent = 'Data Window';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.className = 'tcw-datawin-close';\n closeBtn.setAttribute('aria-label', 'Close');\n closeBtn.innerHTML = createIcon('x', 14);\n closeBtn.addEventListener('click', () => this.close());\n header.appendChild(title);\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n this.bodyEl = document.createElement('div');\n this.bodyEl.className = 'tcw-datawin-body';\n this.el.appendChild(this.bodyEl);\n\n host.appendChild(this.el);\n }\n\n isOpen(): boolean {\n return this.open;\n }\n\n toggle(): void {\n this.open ? this.close() : this.openPanel();\n }\n\n openPanel(): void {\n this.open = true;\n this.el.hidden = false;\n }\n\n close(): void {\n this.open = false;\n this.el.hidden = true;\n }\n\n destroy(): void {\n this.el.remove();\n }\n\n render(model: DataWindowModel): void {\n if (!this.open) return;\n this.bodyEl.replaceChildren();\n\n if (!model.ohlc) {\n const empty = document.createElement('div');\n empty.className = 'tcw-datawin-empty';\n empty.textContent = 'Hover the chart';\n this.bodyEl.appendChild(empty);\n return;\n }\n\n const fp = this.callbacks.formatPrice;\n const o = model.ohlc;\n this.bodyEl.appendChild(this.row('Open', fp(o.open)));\n this.bodyEl.appendChild(this.row('High', fp(o.high)));\n this.bodyEl.appendChild(this.row('Low', fp(o.low)));\n this.bodyEl.appendChild(this.row('Close', fp(o.close)));\n const tone = model.change > 0 ? 'up' : model.change < 0 ? 'down' : '';\n const sign = model.change > 0 ? '+' : '';\n this.bodyEl.appendChild(this.row('Change', `${sign}${fp(model.change)} (${sign}${model.changePct.toFixed(2)}%)`, tone));\n this.bodyEl.appendChild(this.row('Volume', formatVolume(o.volume)));\n\n for (const ind of model.indicators) {\n const head = document.createElement('div');\n head.className = 'tcw-datawin-sub';\n head.textContent = ind.name;\n this.bodyEl.appendChild(head);\n for (const v of ind.values) {\n this.bodyEl.appendChild(this.row(v.key, formatNumber(v.value)));\n }\n }\n }\n\n private row(label: string, value: string, tone = ''): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-datawin-row';\n const l = document.createElement('span');\n l.className = 'tcw-datawin-label';\n l.textContent = label;\n const v = document.createElement('span');\n v.className = `tcw-datawin-value${tone ? ` tcw-${tone}` : ''}`;\n v.textContent = value;\n row.appendChild(l);\n row.appendChild(v);\n return row;\n }\n}\n\nfunction formatNumber(v: number): string {\n if (!Number.isFinite(v)) return '—';\n const abs = Math.abs(v);\n if (abs >= 1000) return v.toFixed(2);\n if (abs >= 1) return v.toFixed(4);\n return v.toPrecision(4);\n}\n\nfunction formatVolume(v: number): string {\n if (v >= 1_000_000_000) return (v / 1_000_000_000).toFixed(2) + 'B';\n if (v >= 1_000_000) return (v / 1_000_000).toFixed(2) + 'M';\n if (v >= 1_000) return (v / 1_000).toFixed(2) + 'K';\n return v.toFixed(0);\n}\n","import type { ChartType, TimeFrame, DrawingState, PriceScaleMode } from '@tradecanvas/commons';\n\nexport interface ShareableIndicator {\n id: string;\n params: Record<string, number | string | boolean>;\n}\n\nexport interface ShareableWidgetState {\n v: 1;\n symbol: string;\n timeframe: TimeFrame;\n chartType: ChartType;\n scaleMode: PriceScaleMode;\n indicators: ShareableIndicator[];\n drawings: DrawingState[];\n}\n\ninterface NodeBufferCtor {\n from(input: string, encoding: string): { toString(encoding: string): string };\n}\nconst nodeBuffer = (globalThis as { Buffer?: NodeBufferCtor }).Buffer;\n\nfunction utf8ToBase64(str: string): string {\n if (nodeBuffer) return nodeBuffer.from(str, 'utf8').toString('base64');\n const bytes = new TextEncoder().encode(str);\n let bin = '';\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin);\n}\n\nfunction base64ToUtf8(b64: string): string {\n if (nodeBuffer) return nodeBuffer.from(b64, 'base64').toString('utf8');\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return new TextDecoder().decode(bytes);\n}\n\nfunction toBase64Url(b64: string): string {\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction fromBase64Url(s: string): string {\n const b64 = s.replace(/-/g, '+').replace(/_/g, '/');\n const pad = b64.length % 4 === 0 ? '' : '='.repeat(4 - (b64.length % 4));\n return b64 + pad;\n}\n\n/** Encode a shareable widget state to a compact, URL-safe string. */\nexport function encodeWidgetState(state: ShareableWidgetState): string {\n return toBase64Url(utf8ToBase64(JSON.stringify(state)));\n}\n\n/**\n * Decode a shareable-state string. Returns null for anything malformed or of an\n * unknown version — callers should treat null as \"ignore and keep current view\".\n */\nexport function decodeWidgetState(encoded: string): ShareableWidgetState | null {\n if (!encoded) return null;\n try {\n const json = base64ToUtf8(fromBase64Url(encoded));\n const obj = JSON.parse(json);\n if (!obj || obj.v !== 1 || typeof obj.symbol !== 'string') return null;\n return {\n v: 1,\n symbol: obj.symbol,\n timeframe: obj.timeframe,\n chartType: obj.chartType,\n scaleMode: obj.scaleMode ?? 'regular',\n indicators: Array.isArray(obj.indicators) ? obj.indicators : [],\n drawings: Array.isArray(obj.drawings) ? obj.drawings : [],\n };\n } catch {\n return null;\n }\n}\n\nconst HASH_KEY = 'tcw';\n\n/** Read a `#tcw=<encoded>` fragment from a URL hash, or null. */\nexport function readShareHash(hash: string): string | null {\n const clean = hash.startsWith('#') ? hash.slice(1) : hash;\n for (const part of clean.split('&')) {\n const eq = part.indexOf('=');\n if (eq > 0 && part.slice(0, eq) === HASH_KEY) return decodeURIComponent(part.slice(eq + 1));\n }\n return null;\n}\n\n/** Build a shareable URL by replacing the `tcw` hash param on `base`. */\nexport function buildShareUrl(base: string, encoded: string): string {\n const [withoutHash] = base.split('#');\n return `${withoutHash}#${HASH_KEY}=${encoded}`;\n}\n","import type { ChartType, DrawingToolType, Theme, TimeFrame } from '@tradecanvas/commons';\r\nimport { Chart } from '../Chart.js';\r\nimport { DARK_THEME, LIGHT_THEME } from '@tradecanvas/commons';\r\nimport type { ChartWidgetOptions, WidgetState, ChartSettingsState } from './types.js';\r\nimport { TIMEFRAMES, CHART_TYPES, INDICATORS, POPULAR_INDICATORS, DRAWING_TOOL_GROUPS, DEFAULT_SYMBOLS, DEFAULT_SETTINGS } from './widgetConfig.js';\r\nimport { injectWidgetStyles, removeWidgetStyles } from './WidgetStyles.js';\r\nimport { WidgetToolbar } from './WidgetToolbar.js';\r\nimport { WidgetDrawingSidebar } from './WidgetDrawingSidebar.js';\r\nimport { WidgetSettings } from './WidgetSettings.js';\r\nimport { WidgetStatusBar } from './WidgetStatusBar.js';\r\nimport { WidgetCommandPalette } from './WidgetCommandPalette.js';\r\nimport { WidgetSymbolSearch } from './WidgetSymbolSearch.js';\r\nimport { WidgetHotkeySheet } from './WidgetHotkeySheet.js';\r\nimport { WidgetReplayBar } from './WidgetReplayBar.js';\r\nimport { WidgetWatchlist, type WatchlistEntry } from './WidgetWatchlist.js';\r\nimport { WidgetAlertsPanel } from './WidgetAlertsPanel.js';\r\nimport { WidgetObjectTree, drawingTypeLabel } from './WidgetObjectTree.js';\r\nimport { WidgetIndicatorSettings } from './WidgetIndicatorSettings.js';\r\nimport { WidgetDrawingStyle } from './WidgetDrawingStyle.js';\r\nimport { DrawingTemplateStore } from './DrawingTemplateStore.js';\r\nimport { DrawingFavoritesStore } from './DrawingFavoritesStore.js';\r\nimport { WidgetBracketBar } from './WidgetBracketBar.js';\r\nimport { AlertNotifier } from './AlertNotifier.js';\r\nimport { WidgetDepthLadder } from './WidgetDepthLadder.js';\r\nimport { WidgetDataWindow, type DataWindowModel } from './WidgetDataWindow.js';\r\nimport type { DepthData } from '@tradecanvas/commons';\r\nimport { encodeWidgetState, decodeWidgetState, readShareHash, buildShareUrl } from './widgetShareState.js';\r\nimport { DragDropImporter, resampleOHLCV, inferTimeframeMs } from '../io/index.js';\r\nimport type { DataSeries } from '@tradecanvas/commons';\r\nimport { timeframeToMs } from '@tradecanvas/commons';\r\nimport type { CommandItem } from './WidgetCommandPalette.js';\r\n\r\n/** Distinct line colors for comparison overlays, cycled by add order. */\r\nconst COMPARE_COLORS = ['#f7931a', '#627eea', '#26a17b', '#e84142', '#8247e5', '#f3ba2f'];\r\n\r\nexport class ChartWidget {\r\n private chart: Chart;\r\n private state: WidgetState;\r\n private toolbar: WidgetToolbar | null = null;\r\n private sidebar: WidgetDrawingSidebar | null = null;\r\n private settings: WidgetSettings | null = null;\r\n private statusBar: WidgetStatusBar | null = null;\r\n private commandPalette: WidgetCommandPalette | null = null;\r\n private symbolSearch: WidgetSymbolSearch | null = null;\r\n private hotkeySheet: WidgetHotkeySheet | null = null;\r\n private replayBar: WidgetReplayBar | null = null;\r\n private dragDrop: DragDropImporter | null = null;\r\n private alertsPanel: WidgetAlertsPanel | null = null;\r\n private objectTree: WidgetObjectTree | null = null;\r\n private indicatorSettings: WidgetIndicatorSettings | null = null;\r\n private drawingStyle: WidgetDrawingStyle | null = null;\r\n private bracketBar: WidgetBracketBar | null = null;\r\n private alertNotifier: AlertNotifier | null = null;\r\n private depthLadder: WidgetDepthLadder | null = null;\r\n private dataWindow: WidgetDataWindow | null = null;\r\n private lastHoverIndex: number | null = null;\r\n private favoritesStore = new DrawingFavoritesStore();\r\n private watchlist: WidgetWatchlist | null = null;\r\n private watchlistSparkBuffer = new Map<string, number[]>();\r\n private sessionRefPrice: number | null = null;\r\n private watchlistInterval: ReturnType<typeof setInterval> | null = null;\r\n private replayOriginalData: DataSeries | null = null;\r\n private replayPollInterval: ReturnType<typeof setInterval> | null = null;\r\n private replaySpeed = 5;\r\n private layoutKeyPrefix: string | null = null;\r\n private layoutDebounceMs = 1500;\r\n private activeLayoutKey: string | null = null;\r\n private root: HTMLDivElement;\r\n private chartContainer: HTMLDivElement;\r\n private destroyed = false;\r\n private options: ChartWidgetOptions;\r\n private symbols: string[];\r\n private settingsState: ChartSettingsState;\r\n private adapter: import('@tradecanvas/commons').DataAdapter | null = null;\r\n private boundGlobalKeydown: ((e: KeyboardEvent) => void) | null = null;\r\n // Finest-resolution series the widget has seen. When no live adapter is\r\n // attached, switching to a coarser timeframe resamples from this base\r\n // instead of refetching. See `setData` / `applyTimeframeData`.\r\n private baseSeries: DataSeries | null = null;\r\n private baseTimeframeMs = 0;\r\n private compares: { id: string; symbol: string; color: string }[] = [];\r\n\r\n constructor(container: HTMLElement, options: ChartWidgetOptions = {}) {\r\n this.options = options;\r\n this.symbols = options.symbols ?? DEFAULT_SYMBOLS;\r\n this.settingsState = { ...DEFAULT_SETTINGS };\r\n\r\n // Resolve layout persistence config. Treated as opt-in — defaults to\r\n // `false` so existing apps don't suddenly start writing to localStorage.\r\n if (options.persistLayouts) {\r\n const cfg = options.persistLayouts === true ? {} : options.persistLayouts;\r\n this.layoutKeyPrefix = cfg.keyPrefix ?? 'tcw:layout:';\r\n this.layoutDebounceMs = cfg.debounceMs ?? 1500;\r\n }\r\n\r\n // Resolve theme\r\n const isDark = this.resolveIsDark(options.theme);\r\n const resolvedTheme = this.resolveTheme(options.theme);\r\n\r\n // Initialize state\r\n this.state = {\r\n symbol: options.symbol ?? this.symbols[0] ?? 'BTCUSDT',\r\n timeframe: options.timeframe ?? '5m',\r\n chartType: options.chartOptions?.chartType ?? 'candlestick',\r\n isDark,\r\n activeIndicators: new Map(),\r\n activeTool: null,\r\n magnetEnabled: true,\r\n connectionState: 'connecting',\r\n connectionMessage: 'Connecting...',\r\n };\r\n\r\n\r\n // 1. Inject styles\r\n injectWidgetStyles();\r\n\r\n // 2. Create DOM skeleton\r\n this.root = document.createElement('div');\r\n this.root.className = 'tcw-root';\r\n this.root.dataset.tcwTheme = isDark ? 'dark' : 'light';\r\n container.appendChild(this.root);\r\n\r\n // 3. Create toolbar\r\n if (options.toolbar !== false) {\r\n this.toolbar = new WidgetToolbar(\r\n this.root,\r\n {\r\n symbols: this.symbols,\r\n timeframes: options.timeframes\r\n ? TIMEFRAMES.filter(tf => (options.timeframes as TimeFrame[]).includes(tf.value))\r\n : TIMEFRAMES,\r\n chartTypes: options.chartTypes\r\n ? CHART_TYPES.filter(ct => (options.chartTypes as ChartType[]).includes(ct.value))\r\n : CHART_TYPES,\r\n indicators: INDICATORS,\r\n popularIndicatorIds: POPULAR_INDICATORS,\r\n },\r\n {\r\n onSymbolClick: () => this.handleSymbolClick(),\r\n onTimeframe: (tf) => this.handleTimeframe(tf),\r\n onChartType: (type) => this.handleChartType(type),\r\n onAddIndicator: (id) => this.handleAddIndicator(id),\r\n onRemoveIndicator: (iid) => this.handleRemoveIndicator(iid),\r\n onScreenshot: () => this.chart.screenshot(),\r\n onSettings: () => this.openSettings(),\r\n onToggleTheme: () => this.handleToggleTheme(),\r\n onToggleReplay: () => this.toggleReplay(),\r\n onToggleAlerts: options.alerts !== false ? () => this.toggleAlerts() : undefined,\r\n onToggleObjects: options.objectTree !== false ? () => this.toggleObjects() : undefined,\r\n onBracket: options.trading !== false ? (side) => this.startBracket(side) : undefined,\r\n onToggleLadder: options.trading !== false && options.depthLadder ? () => this.depthLadder?.toggle() : undefined,\r\n },\r\n );\r\n }\r\n\r\n // 4. Create body\r\n const body = document.createElement('div');\r\n body.className = 'tcw-body';\r\n\r\n if (options.drawingTools !== false) {\r\n if (options.drawingFavorites) this.favoritesStore.seedDefaults(options.drawingFavorites);\r\n this.sidebar = new WidgetDrawingSidebar(\r\n body,\r\n { drawingToolGroups: DRAWING_TOOL_GROUPS, favorites: this.favoritesStore.list() as DrawingToolType[] },\r\n {\r\n onDrawingTool: (tool) => this.handleDrawingTool(tool),\r\n onCancelDrawing: () => this.handleCancelDrawing(),\r\n onToggleMagnet: () => this.handleToggleMagnet(),\r\n onToggleFavorite: (tool) => this.handleToggleFavorite(tool),\r\n onUndo: () => this.chart.undo(),\r\n onRedo: () => this.chart.redo(),\r\n onClearDrawings: () => {\r\n this.chart.clearDrawings();\r\n this.state = { ...this.state, activeTool: null };\r\n this.updateUI();\r\n },\r\n onToggleStyle: () => this.drawingStyle?.toggle(),\r\n },\r\n );\r\n }\r\n\r\n this.chartContainer = document.createElement('div');\r\n this.chartContainer.className = 'tcw-chart-container';\r\n body.appendChild(this.chartContainer);\r\n\r\n // Watchlist sidebar (right side). Appended AFTER the chart container so\r\n // it sits to the right of the canvas in the flexbox row.\r\n if (options.watchlist) {\r\n this.watchlist = new WidgetWatchlist(body, this.symbols, {\r\n onSelect: (sym) => { void this.setSymbol(sym); },\r\n });\r\n this.watchlist.setActive(this.state.symbol);\r\n }\r\n\r\n this.root.appendChild(body);\r\n\r\n // 5. Create chart\r\n this.chart = new Chart(this.chartContainer, {\r\n chartType: this.state.chartType,\r\n theme: resolvedTheme,\r\n autoScale: true,\r\n crosshair: { mode: 'magnet' },\r\n features: {\r\n drawings: true,\r\n drawingMagnet: true,\r\n drawingUndoRedo: true,\r\n indicators: true,\r\n trading: options.trading !== false,\r\n tradingContextMenu: options.trading !== false,\r\n volume: true,\r\n legend: true,\r\n crosshair: true,\r\n keyboard: true,\r\n screenshot: true,\r\n alerts: true,\r\n barCountdown: true,\r\n logScale: true,\r\n watermark: true,\r\n },\r\n ...options.chartOptions,\r\n });\r\n\r\n // Drag-and-drop CSV / JSON onto the chart container — instant data load.\r\n // Opt-out via `dragDropImport: false`. The adapter (live stream) keeps\r\n // running but the next bar update will append to whatever we just\r\n // loaded — that's the expected behavior when overlaying historical data.\r\n if (options.dragDropImport !== false) {\r\n this.dragDrop = new DragDropImporter(this.chartContainer, {\r\n onData: (data, result, file) => {\r\n this.setData(data);\r\n this.toast(`Loaded ${result.data.length} bars from ${file.name}` + (result.skipped > 0 ? ` (${result.skipped} skipped)` : ''));\r\n },\r\n onError: (err, file) => {\r\n this.toast(`${file.name}: ${err.message}`, 'error');\r\n },\r\n });\r\n this.dragDrop.attach();\r\n }\r\n\r\n // 6. Create status bar\r\n if (options.statusBar !== false) {\r\n this.statusBar = new WidgetStatusBar(this.root);\r\n }\r\n\r\n // 7. Create settings (lazy, not appended until opened)\r\n if (options.settings !== false) {\r\n this.settings = new WidgetSettings({\r\n onChange: (patch) => this.applySettings(patch),\r\n onReset: () => this.resetSettings(),\r\n onClose: () => {},\r\n });\r\n }\r\n\r\n // 8a. Symbol search\r\n this.symbolSearch = new WidgetSymbolSearch({\r\n onPick: (sym) => { void this.setSymbol(sym); },\r\n onClose: () => {},\r\n });\r\n this.hotkeySheet = new WidgetHotkeySheet({ onClose: () => {} });\r\n\r\n // Replay: click a revealed bar to jump the replay cursor there.\r\n this.chart.on('barClick', (e) => {\r\n if (!this.replayBar?.isMounted()) return;\r\n const idx = (e.payload as { barIndex?: number }).barIndex;\r\n if (typeof idx !== 'number') return;\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(idx);\r\n this.replayBar.setState('paused');\r\n });\r\n\r\n // Data Window — precise OHLCV + indicator values at the hovered bar.\r\n this.dataWindow = new WidgetDataWindow(this.root, { formatPrice: (p) => this.formatAlertPrice(p) });\r\n this.chart.on('crosshairMove', (e) => {\r\n const p = e.payload as { barIndex?: number };\r\n this.lastHoverIndex = typeof p.barIndex === 'number' ? p.barIndex : null;\r\n if (this.dataWindow?.isOpen()) this.dataWindow.render(this.buildDataWindowModel());\r\n });\r\n\r\n // Drawing style + templates popover (paired with the sidebar palette button)\r\n if (options.drawingTools !== false) {\r\n this.drawingStyle = new WidgetDrawingStyle(\r\n this.root,\r\n {\r\n onStyleChange: (style) => {\r\n this.chart.setDrawingStyle(style);\r\n this.chart.setSelectedDrawingStyle(style);\r\n },\r\n getStyle: () => this.chart.getDrawingStyle(),\r\n },\r\n new DrawingTemplateStore(),\r\n );\r\n }\r\n\r\n // Bracket-order placement: floating confirm/cancel bar + event wiring.\r\n if (options.trading !== false) {\r\n this.bracketBar = new WidgetBracketBar(this.root, {\r\n onConfirm: () => this.chart.confirmBracket(),\r\n onCancel: () => {\r\n this.chart.cancelBracket();\r\n this.bracketBar?.hide();\r\n },\r\n });\r\n this.chart.on('bracketPlace', (e) => {\r\n const b = e.payload;\r\n this.bracketBar?.hide();\r\n this.toast(`${b.side === 'buy' ? 'Long' : 'Short'} bracket placed · ${b.riskReward.toFixed(2)}R`);\r\n });\r\n\r\n // Depth-of-market ladder (opt-in; fed via widget.setDepth)\r\n if (options.depthLadder) {\r\n this.depthLadder = new WidgetDepthLadder(this.root, {\r\n onTrade: (side, price) => {\r\n this.chart.placeOrderIntent({ side, type: 'limit', price });\r\n this.toast(`${side === 'buy' ? 'Buy' : 'Sell'} limit @ ${this.formatAlertPrice(price)}`);\r\n },\r\n formatPrice: (p) => this.formatAlertPrice(p),\r\n });\r\n }\r\n // Esc-cancel originates in the chart; reflect it in the bar.\r\n this.chart.on('dataUpdate', (e) => {\r\n const p = e.payload as { bracket?: string };\r\n if (p && p.bracket === 'cancelled') this.bracketBar?.hide();\r\n });\r\n }\r\n\r\n // 8a-bis. Price alerts panel (floating popover, toggled from the bell button)\r\n if (options.alerts !== false) {\r\n this.alertsPanel = new WidgetAlertsPanel(this.root, {\r\n onAdd: (price, condition, message, channel, label) => {\r\n this.chart.addAlert(price, condition, message, channel, label);\r\n },\r\n onRemove: (id) => this.chart.removeAlert(id),\r\n onClear: () => this.chart.clearAlerts(),\r\n getChannelValue: (channel) => this.getAlertChannelValue(channel),\r\n formatPrice: (p) => this.formatAlertPrice(p),\r\n });\r\n\r\n // Keep the panel list and toasts in sync with the chart's AlertManager.\r\n this.chart.on('alertAdd', () => this.refreshAlerts());\r\n this.chart.on('alertRemove', () => this.refreshAlerts());\r\n this.chart.on('alertUpdate', () => this.refreshAlerts());\r\n if (options.alertNotifications) {\r\n this.alertNotifier = new AlertNotifier(options.alertNotifications);\r\n }\r\n this.chart.on('alertTriggered', (e) => {\r\n const p = e.payload;\r\n const text = `Price ${this.formatAlertPrice(p.price)}${p.message ? ` — ${p.message}` : ''}`;\r\n this.toast(`🔔 Alert: ${text}`, 'info');\r\n this.alertNotifier?.notify(text);\r\n this.refreshAlerts();\r\n });\r\n }\r\n\r\n // 8a-ter. Object tree (indicators + drawings manager)\r\n if (options.objectTree !== false) {\r\n this.indicatorSettings = new WidgetIndicatorSettings(this.root, {\r\n onApply: (instanceId, params) => this.chart.updateIndicator(instanceId, params),\r\n onClose: () => {},\r\n });\r\n this.objectTree = new WidgetObjectTree(this.root, {\r\n onRemoveIndicator: (iid) => this.handleRemoveIndicator(iid),\r\n onConfigureIndicator: (iid) => this.openIndicatorSettings(iid),\r\n onToggleIndicatorVisible: (iid, visible) => {\r\n this.chart.setIndicatorVisible(iid, visible);\r\n this.refreshObjects();\r\n },\r\n onRemoveDrawing: (id) => {\r\n this.chart.removeDrawing(id);\r\n this.refreshObjects();\r\n },\r\n onToggleDrawingVisible: (id, visible) => {\r\n this.chart.setDrawingVisible(id, visible);\r\n this.refreshObjects();\r\n },\r\n onToggleDrawingLocked: (id, locked) => {\r\n this.chart.setDrawingLocked(id, locked);\r\n this.refreshObjects();\r\n },\r\n onAddCompare: () => this.handleAddCompare(),\r\n onRemoveCompare: (id) => this.handleRemoveCompare(id),\r\n });\r\n const refresh = () => { if (this.objectTree?.isOpen()) this.refreshObjects(); };\r\n this.chart.on('drawingCreate', refresh);\r\n this.chart.on('drawingRemove', refresh);\r\n this.chart.on('indicatorAdd', refresh);\r\n this.chart.on('indicatorRemove', refresh);\r\n }\r\n\r\n // 8b. Command palette\r\n this.commandPalette = new WidgetCommandPalette({\r\n onIndicator: (id) => this.handleAddIndicator(id),\r\n onChartType: (type) => this.handleChartType(type),\r\n onDrawingTool: (tool) => this.handleDrawingTool(tool),\r\n onTimeframe: (tf) => this.handleTimeframe(tf),\r\n onAction: (id) => this.handleAction(id),\r\n onClose: () => {},\r\n });\r\n\r\n this.boundGlobalKeydown = (e: KeyboardEvent) => {\r\n if ((e.ctrlKey || e.metaKey) && e.key === 'k') {\r\n e.preventDefault();\r\n this.toggleCommandPalette();\r\n } else if ((e.ctrlKey || e.metaKey) && (e.key === 'p' || e.key === 'P')) {\r\n // Ctrl/Cmd+P → symbol search (matches Bloomberg / many trading UIs)\r\n e.preventDefault();\r\n this.symbolSearch?.open(this.symbols, this.state.symbol);\r\n } else if (e.key === '?' && !e.ctrlKey && !e.metaKey && !e.altKey) {\r\n // Only fire when the user isn't typing into an input.\r\n const active = document.activeElement as HTMLElement | null;\r\n if (active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' || active.isContentEditable)) return;\r\n e.preventDefault();\r\n this.hotkeySheet?.open();\r\n }\r\n };\r\n document.addEventListener('keydown', this.boundGlobalKeydown);\r\n\r\n // 9. Connect stream\r\n if (options.adapter) {\r\n this.adapter = options.adapter;\r\n this.connectStream();\r\n }\r\n\r\n // Watchlist live-update loop. 1s cadence keeps DOM churn low while still\r\n // feeling responsive; for sub-second visual response, apps can call\r\n // `setWatchlistEntry` directly from their own WebSocket.\r\n if (this.watchlist) {\r\n this.watchlistInterval = setInterval(() => this.tickWatchlist(), 1000);\r\n }\r\n\r\n // Initial UI update\r\n this.updateUI();\r\n\r\n // 9. Fire onReady\r\n options.onReady?.(this.chart);\r\n\r\n // Deep-link restore: apply a `#tcw=` view from the URL when enabled.\r\n if (options.shareUrl && typeof location !== 'undefined') {\r\n const encoded = readShareHash(location.hash);\r\n if (encoded) void this.importState(encoded);\r\n }\r\n }\r\n\r\n // --- Public API ---\r\n\r\n /** Replace the searchable symbol catalog. Does not change the active symbol. */\r\n setSymbols(symbols: string[]): void {\r\n this.symbols = symbols;\r\n this.watchlist?.setSymbols(symbols);\r\n }\r\n\r\n async setSymbol(symbol: string): Promise<void> {\r\n // Flush the outgoing symbol's layout BEFORE switching state, so the\r\n // saved snapshot reflects what the user actually saw under that ticker.\r\n this.flushActiveLayout();\r\n this.state = { ...this.state, symbol };\r\n this.sessionRefPrice = null;\r\n this.options.onSymbolChange?.(symbol);\r\n this.updateUI();\r\n this.watchlist?.setActive(symbol);\r\n if (this.adapter) {\r\n await this.connectStream();\r\n }\r\n }\r\n\r\n /**\r\n * Push an entry into the watchlist (e.g., from your own WebSocket).\r\n * Call with the symbols you care about; the active symbol is updated\r\n * automatically from the chart's live data.\r\n */\r\n setWatchlistEntry(symbol: string, entry: Partial<WatchlistEntry>): void {\r\n this.watchlist?.setEntry(symbol, entry);\r\n }\r\n\r\n private tickWatchlist(): void {\r\n if (!this.watchlist) return;\r\n const data = this.chart.getData();\r\n if (data.length === 0) return;\r\n const last = data[data.length - 1];\r\n // Reference price: first bar of the loaded slice — that's the closest\r\n // approximation of \"session open\" without timezone bookkeeping. Apps\r\n // that need true session-open can override via `setWatchlistEntry`.\r\n if (this.sessionRefPrice === null) {\r\n this.sessionRefPrice = data[0].open;\r\n }\r\n\r\n const buf = this.watchlistSparkBuffer.get(this.state.symbol) ?? [];\r\n buf.push(last.close);\r\n if (buf.length > 40) buf.shift();\r\n this.watchlistSparkBuffer.set(this.state.symbol, buf);\r\n\r\n this.watchlist.setEntry(this.state.symbol, {\r\n lastPrice: last.close,\r\n refPrice: this.sessionRefPrice,\r\n sparkline: buf.slice(),\r\n });\r\n }\r\n\r\n async setTimeframe(tf: TimeFrame): Promise<void> {\r\n this.state = { ...this.state, timeframe: tf };\r\n this.options.onTimeframeChange?.(tf);\r\n this.updateUI();\r\n if (this.adapter) {\r\n await this.connectStream();\r\n return;\r\n }\r\n if (this.options.resampleTimeframes !== false) {\r\n this.applyTimeframeData();\r\n }\r\n }\r\n\r\n setTheme(theme: import('@tradecanvas/commons').ThemeName | Theme): void {\r\n const isDark = this.resolveIsDark(theme);\r\n const resolved = this.resolveTheme(theme);\r\n this.state = { ...this.state, isDark };\r\n this.root.dataset.tcwTheme = isDark ? 'dark' : 'light';\r\n this.chart.setTheme(resolved);\r\n this.updateUI();\r\n }\r\n\r\n getChart(): Chart {\r\n return this.chart;\r\n }\r\n\r\n destroy(): void {\r\n if (this.destroyed) return;\r\n this.destroyed = true;\r\n\r\n if (this.boundGlobalKeydown) {\r\n document.removeEventListener('keydown', this.boundGlobalKeydown);\r\n }\r\n this.flushActiveLayout();\r\n this.commandPalette?.destroy();\r\n this.symbolSearch?.destroy();\r\n this.hotkeySheet?.destroy();\r\n if (this.replayPollInterval) clearInterval(this.replayPollInterval);\r\n this.replayBar?.destroy();\r\n this.dragDrop?.detach();\r\n this.alertsPanel?.destroy();\r\n this.objectTree?.destroy();\r\n this.indicatorSettings?.destroy();\r\n this.drawingStyle?.destroy();\r\n this.bracketBar?.destroy();\r\n this.alertNotifier?.destroy();\r\n this.depthLadder?.destroy();\r\n this.dataWindow?.destroy();\r\n if (this.watchlistInterval) clearInterval(this.watchlistInterval);\r\n this.watchlist?.destroy();\r\n this.toolbar?.destroy();\r\n this.sidebar?.destroy();\r\n this.settings?.destroy();\r\n this.statusBar?.destroy();\r\n this.chart.destroy();\r\n this.root.remove();\r\n removeWidgetStyles();\r\n }\r\n\r\n // --- Internal handlers ---\r\n\r\n private handleSymbolClick(): void {\r\n // Opens the fuzzy search modal. The cycle-through behaviour the toolbar\r\n // used to do is gone — a real search scales past 3-4 symbols and matches\r\n // user expectations from TradingView, Bloomberg, etc.\r\n this.symbolSearch?.open(this.symbols, this.state.symbol);\r\n }\r\n\r\n private handleTimeframe(tf: TimeFrame): void {\r\n this.state = { ...this.state, timeframe: tf };\r\n this.options.onTimeframeChange?.(tf);\r\n this.updateUI();\r\n if (this.adapter) {\r\n // Live adapter owns the data — refetch at the native resolution.\r\n this.connectStream();\r\n return;\r\n }\r\n if (this.options.resampleTimeframes === false) return;\r\n // Static data: aggregate the base series locally. Lazily adopt whatever is\r\n // currently on the chart as the base if the host fed it via getChart().\r\n if (!this.baseSeries) {\r\n const current = this.chart.getData();\r\n if (current.length > 0) {\r\n this.baseSeries = current;\r\n this.baseTimeframeMs = inferTimeframeMs(current);\r\n }\r\n }\r\n this.applyTimeframeData();\r\n }\r\n\r\n /**\r\n * Load the widget's base series. Prefer this over `getChart().setData()` so\r\n * client-side timeframe resampling has a finest-resolution source to\r\n * aggregate from. The data is rendered at the current timeframe (resampled\r\n * when that timeframe is coarser than the data's native spacing).\r\n */\r\n setData(data: DataSeries): void {\r\n this.baseSeries = data;\r\n this.baseTimeframeMs = inferTimeframeMs(data);\r\n this.applyTimeframeData();\r\n }\r\n\r\n /** Render the base series at the active timeframe, resampling when coarser. */\r\n private applyTimeframeData(): void {\r\n if (!this.baseSeries) return;\r\n const targetMs = timeframeToMs(this.state.timeframe);\r\n if (this.baseTimeframeMs > 0 && targetMs > this.baseTimeframeMs) {\r\n const weekStartsOn = this.options.weekStartsOn ?? 1;\r\n this.chart.setData(resampleOHLCV(this.baseSeries, this.state.timeframe, { weekStartsOn }));\r\n } else {\r\n this.chart.setData(this.baseSeries);\r\n }\r\n }\r\n\r\n private toggleAlerts(): void {\r\n if (!this.alertsPanel) return;\r\n this.alertsPanel.toggle();\r\n if (this.alertsPanel.isOpen()) this.refreshAlerts();\r\n }\r\n\r\n private handleToggleFavorite(tool: DrawingToolType): void {\r\n const pinned = this.favoritesStore.toggle(tool);\r\n this.sidebar?.setFavorites(this.favoritesStore.list());\r\n this.toast(pinned ? 'Pinned to favorites' : 'Unpinned');\r\n }\r\n\r\n /** Encode the current view (symbol, timeframe, chart type, scale, indicators, drawings). */\r\n exportState(): string {\r\n const indicators = this.chart.getActiveIndicators().map((i) => ({\r\n id: i.id,\r\n params: i.params as Record<string, number | string | boolean>,\r\n }));\r\n return encodeWidgetState({\r\n v: 1,\r\n symbol: this.state.symbol,\r\n timeframe: this.state.timeframe,\r\n chartType: this.state.chartType,\r\n scaleMode: this.chart.getScaleMode(),\r\n indicators,\r\n drawings: this.chart.getDrawings(),\r\n });\r\n }\r\n\r\n /** Restore a view from an `exportState()` string. Returns false if malformed. */\r\n async importState(encoded: string): Promise<boolean> {\r\n const s = decodeWidgetState(encoded);\r\n if (!s) return false;\r\n\r\n // Symbol/timeframe first so any stream/layout restore happens before we\r\n // overlay the shared view on top.\r\n if (s.symbol && s.symbol !== this.state.symbol) await this.setSymbol(s.symbol);\r\n if (s.timeframe && s.timeframe !== this.state.timeframe) await this.setTimeframe(s.timeframe);\r\n\r\n if (s.chartType) this.handleChartType(s.chartType);\r\n this.chart.setScaleMode(s.scaleMode);\r\n\r\n for (const [, instanceId] of this.state.activeIndicators) this.chart.removeIndicator(instanceId);\r\n const map = new Map<string, string>();\r\n for (const ind of s.indicators) {\r\n const iid = this.chart.addIndicator(ind.id, ind.params);\r\n if (iid) map.set(ind.id, iid);\r\n }\r\n this.state = { ...this.state, activeIndicators: map };\r\n this.chart.setDrawings(s.drawings);\r\n this.updateUI();\r\n return true;\r\n }\r\n\r\n /** Copy the chart image to the clipboard, with a toast on success/failure. */\r\n async copyChartImage(): Promise<void> {\r\n const ok = await this.chart.copyScreenshot();\r\n this.toast(ok ? 'Chart image copied' : 'Copy failed — image clipboard unavailable', ok ? 'info' : 'error');\r\n }\r\n\r\n /** Copy a shareable deep-link (current view encoded in the URL hash) to the clipboard. */\r\n async copyShareLink(): Promise<void> {\r\n const base = typeof location !== 'undefined' ? location.href : '';\r\n const url = buildShareUrl(base, this.exportState());\r\n try {\r\n await navigator.clipboard.writeText(url);\r\n this.toast('Share link copied');\r\n } catch {\r\n this.toast('Copy failed — clipboard unavailable', 'error');\r\n }\r\n }\r\n\r\n /** Feed order-book depth to the chart overlay, depth ladder, and heatmap. */\r\n setDepth(depth: DepthData | null): void {\r\n this.chart.setDepthData(depth);\r\n this.depthLadder?.setData(depth);\r\n if (depth) this.chart.pushDepthSnapshot(depth);\r\n }\r\n\r\n /** Begin a draggable bracket order at the latest price and show the action bar. */\r\n startBracket(side: 'buy' | 'sell'): void {\r\n if (this.chart.startBracket(side)) {\r\n this.bracketBar?.show(side);\r\n }\r\n }\r\n\r\n private buildDataWindowModel(): DataWindowModel {\r\n const data = this.chart.getData();\r\n const idx = this.lastHoverIndex;\r\n if (idx === null || idx < 0 || idx >= data.length) {\r\n return { ohlc: null, change: 0, changePct: 0, indicators: [] };\r\n }\r\n const bar = data[idx];\r\n const prevClose = idx > 0 ? data[idx - 1].close : bar.open;\r\n const change = bar.close - prevClose;\r\n const changePct = prevClose !== 0 ? (change / prevClose) * 100 : 0;\r\n\r\n const indicators = this.chart.getActiveIndicators().map((ind) => {\r\n const series = this.chart.getIndicatorOutput(ind.instanceId)?.series;\r\n const point = series?.[idx] ?? null;\r\n const values = point\r\n ? Object.entries(point)\r\n .filter(([, v]) => typeof v === 'number' && Number.isFinite(v))\r\n .map(([key, v]) => ({ key, value: v as number }))\r\n : [];\r\n return { name: ind.descriptor.name, values };\r\n }).filter((i) => i.values.length > 0);\r\n\r\n return {\r\n ohlc: { open: bar.open, high: bar.high, low: bar.low, close: bar.close, volume: bar.volume },\r\n change,\r\n changePct,\r\n indicators,\r\n };\r\n }\r\n\r\n private toggleDataWindow(): void {\r\n if (!this.dataWindow) return;\r\n this.dataWindow.toggle();\r\n if (this.dataWindow.isOpen()) this.dataWindow.render(this.buildDataWindowModel());\r\n }\r\n\r\n private toggleObjects(): void {\r\n if (!this.objectTree) return;\r\n this.objectTree.toggle();\r\n if (this.objectTree.isOpen()) this.refreshObjects();\r\n }\r\n\r\n private openIndicatorSettings(instanceId: string): void {\r\n if (!this.indicatorSettings) return;\r\n const ind = this.chart.getActiveIndicators().find((i) => i.instanceId === instanceId);\r\n if (!ind) return;\r\n this.indicatorSettings.open({\r\n instanceId,\r\n name: ind.descriptor.name,\r\n defaults: ind.descriptor.defaultConfig,\r\n params: ind.params,\r\n });\r\n }\r\n\r\n private refreshObjects(): void {\r\n if (!this.objectTree) return;\r\n const indicators = this.chart.getActiveIndicators().map((i) => ({\r\n instanceId: i.instanceId,\r\n name: i.descriptor.name,\r\n visible: i.visible,\r\n }));\r\n const drawings = this.chart.getDrawings().map((d) => ({\r\n id: d.id,\r\n label: drawingTypeLabel(d.type),\r\n visible: d.visible,\r\n locked: d.locked,\r\n }));\r\n const compares = this.compares.map((c) => ({ id: c.id, label: c.symbol, color: c.color }));\r\n this.objectTree.setObjects(indicators, drawings, compares);\r\n }\r\n\r\n private async handleAddCompare(): Promise<void> {\r\n if (!this.adapter) {\r\n this.toast('Comparison needs a live data adapter', 'error');\r\n return;\r\n }\r\n const taken = new Set([this.state.symbol, ...this.compares.map((c) => c.symbol)]);\r\n const options = this.symbols.filter((s) => !taken.has(s));\r\n this.symbolSearch?.open(options.length ? options : this.symbols, this.state.symbol, (symbol) => {\r\n void this.addCompareSymbol(symbol);\r\n });\r\n }\r\n\r\n /** Overlay another symbol's normalized series. Fetches history via the adapter. */\r\n async addCompareSymbol(symbol: string): Promise<void> {\r\n if (!this.adapter || this.compares.some((c) => c.symbol === symbol)) return;\r\n const color = COMPARE_COLORS[this.compares.length % COMPARE_COLORS.length];\r\n const id = `cmp_${symbol}`;\r\n try {\r\n const bars = await this.adapter.fetchHistory(symbol, this.state.timeframe, this.options.historyLimit ?? 500);\r\n // Percent mode normalizes mixed-price symbols (e.g. BTC vs a $2 alt) onto\r\n // a shared % axis — the right default for comparison.\r\n if (this.compares.length === 0) this.chart.setCompareMode('percent');\r\n this.chart.addCompareSymbol(id, symbol, bars, color);\r\n this.compares = [...this.compares, { id, symbol, color }];\r\n this.refreshObjects();\r\n this.toast(`Comparing ${symbol}`);\r\n } catch (err: unknown) {\r\n this.toast(`${symbol}: ${err instanceof Error ? err.message : 'failed to load'}`, 'error');\r\n }\r\n }\r\n\r\n private handleRemoveCompare(id: string): void {\r\n this.chart.removeCompareSymbol(id);\r\n this.compares = this.compares.filter((c) => c.id !== id);\r\n this.refreshObjects();\r\n }\r\n\r\n /** Refetch every comparison overlay at the current symbol/timeframe. */\r\n private async refetchCompares(): Promise<void> {\r\n if (!this.adapter || this.compares.length === 0) return;\r\n // A comparison against the now-active symbol is redundant — drop it.\r\n const stale = this.compares.filter((c) => c.symbol === this.state.symbol);\r\n for (const c of stale) this.handleRemoveCompare(c.id);\r\n\r\n for (const c of this.compares) {\r\n try {\r\n const bars = await this.adapter.fetchHistory(c.symbol, this.state.timeframe, this.options.historyLimit ?? 500);\r\n this.chart.updateCompareData(c.id, bars);\r\n } catch { /* leave the stale overlay in place if the refetch fails */ }\r\n }\r\n }\r\n\r\n private refreshAlerts(): void {\r\n if (!this.alertsPanel) return;\r\n this.alertsPanel.setSources(this.buildAlertSources());\r\n this.alertsPanel.setAlerts(\r\n this.chart.getAlerts().map((a) => ({\r\n id: a.id,\r\n price: a.price,\r\n condition: a.condition,\r\n message: a.message,\r\n triggered: a.triggered,\r\n channel: a.channel,\r\n label: a.label,\r\n })),\r\n );\r\n }\r\n\r\n /** Price + every active indicator line, as selectable alert sources. */\r\n private buildAlertSources(): { channel: string; label: string }[] {\r\n const sources = [{ channel: 'price', label: 'Price' }];\r\n for (const ind of this.chart.getActiveIndicators()) {\r\n // Use the latest point — multi-output indicators (MACD, Stochastic) only\r\n // have all their lines populated once warmed up; the first point may not.\r\n const series = this.chart.getIndicatorOutput(ind.instanceId)?.series;\r\n const point = series && series.length > 0 ? series[series.length - 1] : null;\r\n const keys = point ? Object.keys(point).filter((k) => typeof point[k] === 'number') : [];\r\n for (const key of keys) {\r\n const label = keys.length > 1 ? `${ind.descriptor.name} ${key}` : ind.descriptor.name;\r\n sources.push({ channel: `${ind.instanceId}:${key}`, label });\r\n }\r\n }\r\n return sources;\r\n }\r\n\r\n /** Latest value for an alert source channel (price or indicator line). */\r\n private getAlertChannelValue(channel: string): number | null {\r\n const data = this.chart.getData();\r\n if (channel === 'price') return data.length > 0 ? data[data.length - 1].close : null;\r\n const sep = channel.indexOf(':');\r\n if (sep < 0 || data.length === 0) return null;\r\n const instanceId = channel.slice(0, sep);\r\n const key = channel.slice(sep + 1);\r\n const v = this.chart.getIndicatorOutput(instanceId)?.series?.[data.length - 1]?.[key];\r\n return typeof v === 'number' && Number.isFinite(v) ? v : null;\r\n }\r\n\r\n private formatAlertPrice(price: number): string {\r\n // No fixed precision config on the widget — pick digits from magnitude so\r\n // BTC (64,200.5) and a sub-dollar alt (0.04821) both read sensibly.\r\n const abs = Math.abs(price);\r\n const digits = abs >= 1000 ? 2 : abs >= 1 ? 4 : 6;\r\n const locale = this.settingsState.numberLocale || undefined;\r\n return price.toLocaleString(locale, { minimumFractionDigits: 2, maximumFractionDigits: digits });\r\n }\r\n\r\n private handleChartType(type: ChartType): void {\r\n this.state = { ...this.state, chartType: type };\r\n this.chart.setChartType(type);\r\n this.updateUI();\r\n }\r\n\r\n private handleAddIndicator(indId: string): void {\r\n if (this.state.activeIndicators.has(indId)) {\r\n // Toggle off\r\n const instanceId = this.state.activeIndicators.get(indId)!;\r\n this.chart.removeIndicator(instanceId);\r\n const next = new Map(this.state.activeIndicators);\r\n next.delete(indId);\r\n this.state = { ...this.state, activeIndicators: next };\r\n } else {\r\n const instanceId = this.chart.addIndicator(indId);\r\n if (instanceId) {\r\n const next = new Map(this.state.activeIndicators);\r\n next.set(indId, instanceId);\r\n this.state = { ...this.state, activeIndicators: next };\r\n }\r\n }\r\n this.updateUI();\r\n }\r\n\r\n private handleRemoveIndicator(instanceId: string): void {\r\n this.chart.removeIndicator(instanceId);\r\n const next = new Map(this.state.activeIndicators);\r\n for (const [id, iid] of next.entries()) {\r\n if (iid === instanceId) {\r\n next.delete(id);\r\n break;\r\n }\r\n }\r\n this.state = { ...this.state, activeIndicators: next };\r\n this.updateUI();\r\n }\r\n\r\n private toggleCommandPalette(): void {\r\n if (this.commandPalette?.isOpen()) {\r\n this.commandPalette.close();\r\n return;\r\n }\r\n this.commandPalette?.open(this.buildCommandItems());\r\n }\r\n\r\n private buildCommandItems(): CommandItem[] {\r\n const items: CommandItem[] = [];\r\n\r\n for (const ind of INDICATORS) {\r\n items.push({\r\n id: ind.id,\r\n label: ind.name,\r\n category: 'indicator',\r\n active: this.state.activeIndicators.has(ind.id),\r\n });\r\n }\r\n\r\n for (const ct of CHART_TYPES) {\r\n items.push({\r\n id: ct.value,\r\n label: ct.label,\r\n category: 'chartType',\r\n active: this.state.chartType === ct.value,\r\n });\r\n }\r\n\r\n for (const group of DRAWING_TOOL_GROUPS) {\r\n for (const tool of group.tools) {\r\n items.push({\r\n id: tool.value,\r\n label: tool.label,\r\n category: 'drawing',\r\n active: this.state.activeTool === tool.value,\r\n });\r\n }\r\n }\r\n\r\n for (const tf of TIMEFRAMES) {\r\n items.push({\r\n id: tf.value,\r\n label: tf.label,\r\n category: 'timeframe',\r\n active: this.state.timeframe === tf.value,\r\n });\r\n }\r\n\r\n items.push(\r\n { id: 'screenshot', label: 'Screenshot', category: 'action', shortcut: '' },\r\n { id: 'copyImage', label: 'Copy Chart Image', category: 'action' },\r\n { id: 'toggleTheme', label: 'Toggle Theme', category: 'action' },\r\n { id: 'settings', label: 'Settings', category: 'action' },\r\n { id: 'shareView', label: 'Share View (copy link)', category: 'action' },\r\n { id: 'autoFib', label: 'Auto Fibonacci (visible swing)', category: 'action' },\r\n { id: 'dataWindow', label: 'Toggle Data Window', category: 'action' },\r\n { id: 'clearDrawings', label: 'Clear All Drawings', category: 'action' },\r\n );\r\n\r\n return items;\r\n }\r\n\r\n private handleAction(id: string): void {\r\n switch (id) {\r\n case 'screenshot':\r\n this.chart.screenshot();\r\n break;\r\n case 'toggleTheme':\r\n this.handleToggleTheme();\r\n break;\r\n case 'settings':\r\n this.openSettings();\r\n break;\r\n case 'copyImage':\r\n void this.copyChartImage();\r\n break;\r\n case 'shareView':\r\n void this.copyShareLink();\r\n break;\r\n case 'autoFib': {\r\n const id = this.chart.autoFib();\r\n this.toast(id ? 'Auto Fibonacci added' : 'No clear swing in view');\r\n break;\r\n }\r\n case 'dataWindow':\r\n this.toggleDataWindow();\r\n break;\r\n case 'clearDrawings':\r\n this.chart.clearDrawings();\r\n this.state = { ...this.state, activeTool: null };\r\n this.updateUI();\r\n break;\r\n }\r\n }\r\n\r\n private handleDrawingTool(tool: DrawingToolType): void {\r\n this.state = { ...this.state, activeTool: tool };\r\n this.chart.setDrawingTool(tool);\r\n this.updateUI();\r\n }\r\n\r\n private handleCancelDrawing(): void {\r\n this.state = { ...this.state, activeTool: null };\r\n this.chart.setDrawingTool(null);\r\n this.updateUI();\r\n }\r\n\r\n private handleToggleMagnet(): void {\r\n const magnetEnabled = !this.state.magnetEnabled;\r\n this.state = { ...this.state, magnetEnabled };\r\n this.chart.setDrawingMagnet(magnetEnabled);\r\n this.updateUI();\r\n }\r\n\r\n private handleToggleTheme(): void {\r\n const isDark = !this.state.isDark;\r\n this.state = { ...this.state, isDark };\r\n this.root.dataset.tcwTheme = isDark ? 'dark' : 'light';\r\n this.chart.setTheme(isDark ? DARK_THEME : LIGHT_THEME);\r\n this.chart.setWatermark(this.state.symbol.replace('USDT', ' / USDT'), {\r\n fontSize: 48,\r\n color: isDark ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.03)',\r\n });\r\n this.updateUI();\r\n }\r\n\r\n private openSettings(): void {\r\n this.settings?.open(this.settingsState);\r\n }\r\n\r\n // --- Toast ---\r\n\r\n /**\r\n * Show a transient toast inside the widget. Auto-dismisses after 3.5s.\r\n * Used by the drag-drop importer for success / failure feedback, but\r\n * exposed so apps can post their own (e.g. \"alert triggered at 64,200\").\r\n */\r\n toast(message: string, kind: 'info' | 'error' = 'info'): void {\r\n const el = document.createElement('div');\r\n el.className = `tcw-toast ${kind === 'error' ? 'tcw-toast-error' : ''}`;\r\n el.textContent = message;\r\n this.root.appendChild(el);\r\n // Trigger CSS transition on next frame\r\n requestAnimationFrame(() => el.classList.add('tcw-toast-in'));\r\n setTimeout(() => {\r\n el.classList.remove('tcw-toast-in');\r\n el.addEventListener('transitionend', () => el.remove(), { once: true });\r\n // Hard timeout in case transitionend doesn't fire (display:none, etc.)\r\n setTimeout(() => el.remove(), 400);\r\n }, 3500);\r\n }\r\n\r\n // --- Layout persistence ---\r\n\r\n /**\r\n * Wipe the layout saved for `symbol` (or the active symbol if omitted).\r\n * Useful as an \"Reset layout\" command in user-facing menus.\r\n */\r\n clearSavedLayout(symbol?: string): void {\r\n if (!this.layoutKeyPrefix) return;\r\n const target = symbol ?? this.state.symbol;\r\n try {\r\n localStorage.removeItem(this.layoutKeyPrefix + target);\r\n } catch { /* localStorage may be unavailable (private mode, SSR, etc.) */ }\r\n }\r\n\r\n private applySymbolLayout(symbol: string): void {\r\n if (!this.layoutKeyPrefix) return;\r\n const key = this.layoutKeyPrefix + symbol;\r\n this.activeLayoutKey = key;\r\n\r\n try {\r\n // Best-effort load. If parsing or any restore step throws, we silently\r\n // fall back to a fresh layout — a corrupted layout shouldn't break the\r\n // chart.\r\n const ok = this.chart.loadStateFromStorage(key);\r\n if (ok) this.rebuildActiveIndicatorsMapFromChart();\r\n } catch { /* swallow — layout will be rebuilt from user actions */ }\r\n\r\n // Wire chart-level auto-save so any further drawing/indicator change\r\n // flushes itself into this symbol's slot.\r\n this.chart.setAutoSave(key, this.layoutDebounceMs);\r\n }\r\n\r\n private flushActiveLayout(): void {\r\n if (!this.activeLayoutKey) return;\r\n try { this.chart.saveState(this.activeLayoutKey); } catch { /* same */ }\r\n this.chart.disableAutoSave();\r\n this.activeLayoutKey = null;\r\n }\r\n\r\n /**\r\n * After loading a layout, the chart restores indicator instances but our\r\n * `state.activeIndicators` map (used to render the chip strip) is stale.\r\n * Rebuild it from the live `getActiveIndicators` list.\r\n */\r\n private rebuildActiveIndicatorsMapFromChart(): void {\r\n const next = new Map<string, string>();\r\n for (const a of this.chart.getActiveIndicators()) {\r\n next.set(a.id, a.instanceId);\r\n }\r\n this.state = { ...this.state, activeIndicators: next };\r\n this.updateUI();\r\n }\r\n\r\n // --- Replay ---\r\n\r\n private toggleReplay(): void {\r\n if (this.replayBar?.isMounted()) {\r\n this.exitReplay();\r\n } else {\r\n this.enterReplay();\r\n }\r\n }\r\n\r\n private enterReplay(): void {\r\n const data = this.chart.getData();\r\n if (data.length < 2) return;\r\n\r\n // Snapshot full series so we can restore it on exit. The chart's\r\n // dataManager gets mutated to slices during replay.\r\n this.replayOriginalData = data.slice();\r\n\r\n // Mount the scrubber bar inside the chart container so it floats above the\r\n // canvas. It owns its own absolute positioning via the .tcw-replay-bar CSS.\r\n this.replayBar = new WidgetReplayBar({\r\n onPlay: () => {\r\n if (this.chart.getReplayState() === 'paused') {\r\n this.chart.replayResume();\r\n } else {\r\n this.chart.replayStart({ speed: this.replaySpeed, interval: 200 });\r\n }\r\n this.replayBar?.setState('playing');\r\n },\r\n onPause: () => {\r\n this.chart.replayPause();\r\n this.replayBar?.setState('paused');\r\n },\r\n onStop: () => {\r\n this.chart.replayStop();\r\n this.replayBar?.setState('paused');\r\n },\r\n onStepBack: () => {\r\n const p = this.chart.getReplayProgress();\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(Math.max(0, p.current - 1));\r\n this.replayBar?.setState('paused');\r\n },\r\n onStepForward: () => {\r\n const p = this.chart.getReplayProgress();\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(Math.min(p.total - 1, p.current + 1));\r\n this.replayBar?.setState('paused');\r\n },\r\n onSeek: (idx) => {\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(idx);\r\n this.replayBar?.setState('paused');\r\n },\r\n onSpeedChange: (s) => {\r\n this.replaySpeed = s;\r\n this.chart.setReplaySpeed(s);\r\n },\r\n onClose: () => this.exitReplay(),\r\n });\r\n this.replayBar.mount(this.chartContainer, { total: data.length, speed: this.replaySpeed });\r\n\r\n // Boot replay paused at bar 1 so the user sees a starting state. Then\r\n // start polling progress for the scrubber — cheap, runs at 200ms.\r\n this.chart.replayStart({ speed: this.replaySpeed, interval: 200, startIndex: 1 });\r\n this.chart.replayPause();\r\n this.replayBar.setState('paused');\r\n\r\n this.replayPollInterval = setInterval(() => {\r\n if (!this.replayBar?.isMounted()) return;\r\n const p = this.chart.getReplayProgress();\r\n this.replayBar.setProgress(p.current, p.total);\r\n const state = this.chart.getReplayState();\r\n if (state === 'stopped') {\r\n this.replayBar.setState('paused');\r\n } else {\r\n this.replayBar.setState(state);\r\n }\r\n }, 150);\r\n }\r\n\r\n private exitReplay(): void {\r\n if (this.replayPollInterval) {\r\n clearInterval(this.replayPollInterval);\r\n this.replayPollInterval = null;\r\n }\r\n this.chart.replayStop();\r\n this.replayBar?.unmount();\r\n this.replayBar = null;\r\n if (this.replayOriginalData) {\r\n this.chart.setData(this.replayOriginalData);\r\n this.replayOriginalData = null;\r\n }\r\n }\r\n\r\n private applySettings(patch: Partial<ChartSettingsState>): void {\r\n this.settingsState = { ...this.settingsState, ...patch };\r\n\r\n if (patch.gridVisible !== undefined) this.chart.setGridVisible(patch.gridVisible);\r\n if (patch.volumeVisible !== undefined) this.chart.setVolumeVisible(patch.volumeVisible);\r\n if (patch.volumeProfileVisible !== undefined) this.chart.setVolumeProfileVisible(patch.volumeProfileVisible);\r\n if (patch.marketProfileVisible !== undefined) this.chart.setMarketProfileVisible(patch.marketProfileVisible);\r\n if (patch.marketProfileSplit !== undefined) this.chart.setMarketProfileConfig({ splitBySession: patch.marketProfileSplit });\r\n if (patch.marketProfileLetters !== undefined) this.chart.setMarketProfileConfig({ letters: patch.marketProfileLetters });\r\n if (patch.marketProfileBuckets !== undefined) this.chart.setMarketProfileConfig({ buckets: patch.marketProfileBuckets });\r\n if (patch.marketProfileOpacity !== undefined) this.chart.setMarketProfileConfig({ opacity: patch.marketProfileOpacity });\r\n if (patch.depthHeatmapVisible !== undefined) this.chart.setDepthHeatmapVisible(patch.depthHeatmapVisible);\r\n if (patch.depthHeatmapOpacity !== undefined) this.chart.setDepthHeatmapConfig({ opacity: patch.depthHeatmapOpacity });\r\n if (patch.sessionShadingVisible !== undefined) this.chart.setSessionShadingVisible(patch.sessionShadingVisible);\r\n if (patch.pivotMarkersVisible !== undefined) this.chart.setPivotMarkersVisible(patch.pivotMarkersVisible);\r\n if (patch.pivotStrength !== undefined) this.chart.setPivotMarkersConfig({ left: patch.pivotStrength, right: patch.pivotStrength });\r\n if (patch.pivotStructureLabels !== undefined) this.chart.setPivotMarkersConfig({ structureLabels: patch.pivotStructureLabels });\r\n if (patch.periodLevelsVisible !== undefined) this.chart.setPeriodLevelsVisible(patch.periodLevelsVisible);\r\n if (patch.periodLevelsPeriod !== undefined) this.chart.setPeriodLevelsPeriod(patch.periodLevelsPeriod);\r\n if (patch.crosshairMode !== undefined) this.chart.setCrosshairMode(patch.crosshairMode);\r\n if (patch.autoScale !== undefined) this.chart.setAutoScale(patch.autoScale);\r\n if (patch.scaleMode !== undefined) {\r\n this.chart.setScaleMode(patch.scaleMode);\r\n // Keep the legacy logScale flag mirrored so persisted layouts stay valid.\r\n this.settingsState = { ...this.settingsState, logScale: patch.scaleMode === 'logarithmic' };\r\n } else if (patch.logScale !== undefined) {\r\n this.chart.setLogScale(patch.logScale);\r\n this.settingsState = { ...this.settingsState, scaleMode: patch.logScale ? 'logarithmic' : 'regular' };\r\n }\r\n if (patch.numberLocale !== undefined) this.chart.setNumberLocale(patch.numberLocale);\r\n if (patch.timezone !== undefined) {\r\n this.chart.setTimezoneOffset(patch.timezone === 'local' ? null : Number(patch.timezone));\r\n }\r\n\r\n // Apply theme colors\r\n const currentTheme = this.chart.getTheme();\r\n const themeUpdate = { ...currentTheme } as Record<string, unknown>;\r\n let themeChanged = false;\r\n\r\n if (patch.candleUpColor !== undefined) { themeUpdate.candleUp = patch.candleUpColor; themeChanged = true; }\r\n if (patch.candleDownColor !== undefined) { themeUpdate.candleDown = patch.candleDownColor; themeChanged = true; }\r\n if (patch.candleUpWick !== undefined) { themeUpdate.candleUpWick = patch.candleUpWick; themeChanged = true; }\r\n if (patch.candleDownWick !== undefined) { themeUpdate.candleDownWick = patch.candleDownWick; themeChanged = true; }\r\n if (patch.backgroundColor !== undefined) { themeUpdate.background = patch.backgroundColor; themeChanged = true; }\r\n if (patch.gridColor !== undefined) { themeUpdate.grid = patch.gridColor; themeChanged = true; }\r\n\r\n if (themeChanged) {\r\n this.chart.setTheme(themeUpdate as unknown as Theme);\r\n }\r\n }\r\n\r\n private resetSettings(): void {\r\n this.settingsState = { ...DEFAULT_SETTINGS };\r\n this.applySettings(this.settingsState);\r\n }\r\n\r\n private async connectStream(): Promise<void> {\r\n if (!this.adapter) return;\r\n\r\n this.state = {\r\n ...this.state,\r\n connectionState: 'connecting',\r\n connectionMessage: 'Connecting...',\r\n };\r\n this.updateUI();\r\n\r\n try {\r\n this.chart.disconnectStream();\r\n await this.chart.connect({\r\n adapter: this.adapter,\r\n symbol: this.state.symbol,\r\n timeframe: this.state.timeframe,\r\n historyLimit: this.options.historyLimit ?? 500,\r\n });\r\n\r\n this.chart.setWatermark(this.state.symbol.replace('USDT', ' / USDT'), {\r\n fontSize: 48,\r\n color: this.state.isDark ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.03)',\r\n });\r\n\r\n // Re-apply per-symbol layout (indicators, drawings, chart type) after\r\n // the new history is in. Doing this *after* connect ensures indicators\r\n // recalculate against the loaded data, not the previous symbol's data.\r\n this.applySymbolLayout(this.state.symbol);\r\n\r\n this.state = {\r\n ...this.state,\r\n connectionState: 'connected',\r\n connectionMessage: 'Live',\r\n };\r\n\r\n // Re-pull comparison overlays at the (possibly new) timeframe so they\r\n // stay aligned with the main series. Drop the active symbol if it ended\r\n // up in the compare set after a symbol switch.\r\n void this.refetchCompares();\r\n } catch (err: unknown) {\r\n this.state = {\r\n ...this.state,\r\n connectionState: 'error',\r\n connectionMessage: err instanceof Error ? err.message : 'Connection failed',\r\n };\r\n }\r\n\r\n this.updateUI();\r\n }\r\n\r\n private updateUI(): void {\r\n this.toolbar?.update(this.state);\r\n this.sidebar?.update(this.state);\r\n this.statusBar?.update({\r\n connectionState: this.state.connectionState,\r\n message: this.state.connectionMessage,\r\n symbol: this.state.symbol,\r\n timeframe: this.state.timeframe,\r\n });\r\n }\r\n\r\n private resolveIsDark(theme?: import('@tradecanvas/commons').ThemeName | Theme): boolean {\r\n if (theme === undefined || theme === 'dark') return true;\r\n if (theme === 'light') return false;\r\n // If it's a Theme object, check background color\r\n if (typeof theme === 'object' && theme.background) {\r\n return this.isColorDark(theme.background);\r\n }\r\n return true;\r\n }\r\n\r\n private resolveTheme(theme?: import('@tradecanvas/commons').ThemeName | Theme): Theme {\r\n if (theme === undefined || theme === 'dark') return DARK_THEME;\r\n if (theme === 'light') return LIGHT_THEME;\r\n if (typeof theme === 'object') return theme as Theme;\r\n return DARK_THEME;\r\n }\r\n\r\n private isColorDark(color: string): boolean {\r\n // Simple heuristic: if it starts with # and R+G+B < 384 (half of 768)\r\n if (color.startsWith('#') && color.length >= 7) {\r\n const r = parseInt(color.slice(1, 3), 16);\r\n const g = parseInt(color.slice(3, 5), 16);\r\n const b = parseInt(color.slice(5, 7), 16);\r\n return (r + g + b) < 384;\r\n }\r\n return true;\r\n }\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/io/resampleOHLCV.ts","../../src/widget/widgetConfig.ts","../../src/widget/WidgetStyles.ts","../../src/widget/icons.ts","../../src/widget/WidgetDropdown.ts","../../src/widget/WidgetToolbar.ts","../../src/widget/WidgetDrawingSidebar.ts","../../src/widget/WidgetSettings.ts","../../src/widget/WidgetStatusBar.ts","../../src/widget/WidgetCommandPalette.ts","../../src/widget/WidgetSymbolSearch.ts","../../src/widget/WidgetHotkeySheet.ts","../../src/widget/WidgetReplayBar.ts","../../src/widget/WidgetWatchlist.ts","../../src/widget/WidgetAlertsPanel.ts","../../src/widget/WidgetObjectTree.ts","../../src/widget/WidgetIndicatorSettings.ts","../../src/widget/DrawingTemplateStore.ts","../../src/widget/WidgetDrawingStyle.ts","../../src/widget/DrawingFavoritesStore.ts","../../src/widget/WidgetBracketBar.ts","../../src/widget/AlertNotifier.ts","../../src/widget/ladderRows.ts","../../src/widget/WidgetDepthLadder.ts","../../src/widget/WidgetDataWindow.ts","../../src/widget/widgetShareState.ts","../../src/widget/i18n.ts","../../src/widget/WidgetLoadingOverlay.ts","../../src/widget/ChartWidget.ts"],"sourcesContent":["import type { DataSeries, OHLCBar, TimeFrame } from '@tradecanvas/commons';\r\nimport { timeframeToMs, timeframeBucketStart } from '@tradecanvas/commons';\r\n\r\nexport interface ResampleOptions {\r\n /** 0 = Sunday, 1 = Monday (default) — anchor for weekly buckets. */\r\n weekStartsOn?: 0 | 1;\r\n}\r\n\r\n/**\r\n * Aggregate a finer OHLCV series into a coarser timeframe.\r\n *\r\n * Bars are grouped by calendar-aware bucket (see `timeframeBucketStart`):\r\n * open = first bar's open, high/low = extremes, close = last bar's close,\r\n * volume = sum. Input bars are assumed sorted ascending by `time` and are\r\n * never mutated.\r\n *\r\n * Upsampling (target finer than source) cannot synthesize data — pass a target\r\n * coarser than the source. Use `inferTimeframeMs` to detect the source spacing.\r\n */\r\nexport function resampleOHLCV(\r\n bars: DataSeries,\r\n target: TimeFrame,\r\n opts: ResampleOptions = {},\r\n): DataSeries {\r\n if (bars.length === 0) return [];\r\n const weekStartsOn = opts.weekStartsOn ?? 1;\r\n\r\n const out: OHLCBar[] = [];\r\n let current: OHLCBar | null = null;\r\n let currentKey = Number.NaN;\r\n\r\n for (const bar of bars) {\r\n const key = timeframeBucketStart(bar.time, target, weekStartsOn);\r\n if (current === null || key !== currentKey) {\r\n if (current !== null) out.push(current);\r\n current = {\r\n time: key,\r\n open: bar.open,\r\n high: bar.high,\r\n low: bar.low,\r\n close: bar.close,\r\n volume: bar.volume,\r\n };\r\n currentKey = key;\r\n } else {\r\n current = {\r\n time: current.time,\r\n open: current.open,\r\n high: Math.max(current.high, bar.high),\r\n low: Math.min(current.low, bar.low),\r\n close: bar.close,\r\n volume: current.volume + bar.volume,\r\n };\r\n }\r\n }\r\n if (current !== null) out.push(current);\r\n return out;\r\n}\r\n\r\n/**\r\n * Estimate the source bar spacing in milliseconds from the median gap between\r\n * consecutive bars. Robust to occasional gaps (weekends, halts). Returns 0 for\r\n * series with fewer than two bars.\r\n */\r\nexport function inferTimeframeMs(bars: DataSeries): number {\r\n if (bars.length < 2) return 0;\r\n const gaps: number[] = [];\r\n for (let i = 1; i < bars.length; i++) {\r\n const gap = bars[i].time - bars[i - 1].time;\r\n if (gap > 0) gaps.push(gap);\r\n }\r\n if (gaps.length === 0) return 0;\r\n gaps.sort((a, b) => a - b);\r\n return gaps[Math.floor(gaps.length / 2)];\r\n}\r\n\r\n/**\r\n * Whether `target` is coarser than (or equal to) the source spacing, i.e. a\r\n * valid downsample. A non-positive `sourceMs` (unknown) is treated as valid.\r\n */\r\nexport function canResample(sourceMs: number, target: TimeFrame): boolean {\r\n if (sourceMs <= 0) return true;\r\n return timeframeToMs(target) >= sourceMs;\r\n}\r\n","import type { ChartType, DrawingToolType, TimeFrame } from '@tradecanvas/commons';\r\nimport type { IndicatorDef, DrawingToolGroupDef, ChartSettingsState } from './types.js';\r\n\r\nexport const TIMEFRAMES: { label: string; value: TimeFrame }[] = [\r\n { label: '1m', value: '1m' },\r\n { label: '5m', value: '5m' },\r\n { label: '15m', value: '15m' },\r\n { label: '1H', value: '1h' },\r\n { label: '4H', value: '4h' },\r\n { label: '1D', value: '1d' },\r\n];\r\n\r\nexport const CHART_TYPES: { label: string; value: ChartType }[] = [\r\n { label: 'Candlestick', value: 'candlestick' },\r\n { label: 'Line', value: 'line' },\r\n { label: 'Area', value: 'area' },\r\n { label: 'Bar', value: 'bar' },\r\n { label: 'Heikin-Ashi', value: 'heikinAshi' },\r\n { label: 'Hollow Candle', value: 'hollowCandle' },\r\n { label: 'Baseline', value: 'baseline' },\r\n { label: 'Volume Candles', value: 'volumeCandles' },\r\n { label: 'Equivolume', value: 'equivolume' },\r\n { label: 'HLC Area', value: 'hlcArea' },\r\n { label: 'Step Line', value: 'stepLine' },\r\n { label: 'Line + Markers', value: 'lineWithMarkers' },\r\n];\r\n\r\nexport const DRAWING_TOOL_GROUPS: DrawingToolGroupDef[] = [\r\n {\r\n label: 'Lines',\r\n tools: [\r\n { label: 'Trend Line', value: 'trendLine' as DrawingToolType },\r\n { label: 'Ray', value: 'ray' as DrawingToolType },\r\n { label: 'Extended Line', value: 'extendedLine' as DrawingToolType },\r\n { label: 'Info Line', value: 'infoLine' as DrawingToolType },\r\n { label: 'Trend Angle', value: 'trendAngle' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Horizontal/Vertical',\r\n tools: [\r\n { label: 'Horizontal Line', value: 'horizontalLine' as DrawingToolType },\r\n { label: 'Horizontal Ray', value: 'horizontalRay' as DrawingToolType },\r\n { label: 'Vertical Line', value: 'verticalLine' as DrawingToolType },\r\n { label: 'Cross Line', value: 'crossLine' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Channels',\r\n tools: [\r\n { label: 'Parallel Channel', value: 'parallelChannel' as DrawingToolType },\r\n { label: 'Regression Channel', value: 'regressionChannel' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Fibonacci',\r\n tools: [\r\n { label: 'Fib Retracement', value: 'fibRetracement' as DrawingToolType },\r\n { label: 'Fib Extension', value: 'fibExtension' as DrawingToolType },\r\n { label: 'Fib Channel', value: 'fibChannel' as DrawingToolType },\r\n { label: 'Fib Time Zones', value: 'fibTimeZones' as DrawingToolType },\r\n { label: 'Fib Speed Resistance Fan', value: 'fibSpeedResistanceFan' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Shapes',\r\n tools: [\r\n { label: 'Rectangle', value: 'rectangle' as DrawingToolType },\r\n { label: 'Circle', value: 'circle' as DrawingToolType },\r\n { label: 'Ellipse', value: 'ellipse' as DrawingToolType },\r\n { label: 'Triangle', value: 'triangle' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Gann & Pitchforks',\r\n tools: [\r\n { label: 'Pitchfork', value: 'pitchfork' as DrawingToolType },\r\n { label: 'Schiff Pitchfork', value: 'schiffPitchfork' as DrawingToolType },\r\n { label: 'Modified Schiff Pitchfork', value: 'modifiedSchiffPitchfork' as DrawingToolType },\r\n { label: 'Gann Fan', value: 'gannFan' as DrawingToolType },\r\n { label: 'Gann Box', value: 'gannBox' as DrawingToolType },\r\n { label: 'Cyclic Lines', value: 'cyclicLines' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Patterns',\r\n tools: [\r\n { label: 'XABCD Pattern', value: 'xabcdPattern' as DrawingToolType },\r\n { label: 'ABCD Pattern', value: 'abcdPattern' as DrawingToolType },\r\n { label: 'Head and Shoulders', value: 'headAndShoulders' as DrawingToolType },\r\n { label: 'Elliott Wave', value: 'elliottWave' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Measure',\r\n tools: [\r\n { label: 'Price Range', value: 'priceRange' as DrawingToolType },\r\n { label: 'Date Range', value: 'dateRange' as DrawingToolType },\r\n { label: 'Date and Price Range', value: 'dateAndPriceRange' as DrawingToolType },\r\n { label: 'Measure', value: 'measure' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Annotation',\r\n tools: [\r\n { label: 'Text', value: 'text' as DrawingToolType },\r\n { label: 'Price Label', value: 'priceLabel' as DrawingToolType },\r\n { label: 'Arrow', value: 'arrow' as DrawingToolType },\r\n ],\r\n },\r\n {\r\n label: 'Forecasting',\r\n tools: [\r\n { label: 'Long/Short Position', value: 'riskReward' as DrawingToolType },\r\n { label: 'Anchored VWAP', value: 'anchoredVWAP' as DrawingToolType },\r\n { label: 'Fixed Range Volume Profile', value: 'volumeProfileRange' as DrawingToolType },\r\n ],\r\n },\r\n];\r\n\r\nexport const INDICATORS: IndicatorDef[] = [\r\n { id: 'sma', name: 'SMA', type: 'overlay' },\r\n { id: 'ema', name: 'EMA', type: 'overlay' },\r\n { id: 'tema', name: 'Triple EMA', type: 'overlay' },\r\n { id: 'vwma', name: 'VWMA', type: 'overlay' },\r\n { id: 'wma', name: 'Weighted MA', type: 'overlay' },\r\n { id: 'hma', name: 'Hull MA', type: 'overlay' },\r\n { id: 'mtfma', name: 'MTF Moving Average', type: 'overlay' },\r\n { id: 'bb', name: 'Bollinger Bands', type: 'overlay' },\r\n { id: 'envelope', name: 'Envelope', type: 'overlay' },\r\n { id: 'vwap', name: 'VWAP', type: 'overlay' },\r\n { id: 'avwap', name: 'Anchored VWAP', type: 'overlay' },\r\n { id: 'svwap', name: 'Session VWAP', type: 'overlay' },\r\n { id: 'ichimoku', name: 'Ichimoku Cloud', type: 'overlay' },\r\n { id: 'psar', name: 'Parabolic SAR', type: 'overlay' },\r\n { id: 'supertrend', name: 'Supertrend', type: 'overlay' },\r\n { id: 'keltner', name: 'Keltner Channel', type: 'overlay' },\r\n { id: 'donchian', name: 'Donchian Channel', type: 'overlay' },\r\n { id: 'pivots', name: 'Pivot Points', type: 'overlay' },\r\n { id: 'zigzag', name: 'ZigZag', type: 'overlay' },\r\n { id: 'lrc', name: 'Linear Regression Channel', type: 'overlay' },\r\n { id: 'chandelier', name: 'Chandelier Exit', type: 'overlay' },\r\n { id: 'alligator', name: 'Alligator', type: 'overlay' },\r\n { id: 'rsi', name: 'RSI', type: 'panel' },\r\n { id: 'macd', name: 'MACD', type: 'panel' },\r\n { id: 'stochastic', name: 'Stochastic', type: 'panel' },\r\n { id: 'atr', name: 'ATR', type: 'panel' },\r\n { id: 'adx', name: 'ADX', type: 'panel' },\r\n { id: 'obv', name: 'OBV', type: 'panel' },\r\n { id: 'williamsR', name: 'Williams %R', type: 'panel' },\r\n { id: 'cci', name: 'CCI', type: 'panel' },\r\n { id: 'mfi', name: 'MFI', type: 'panel' },\r\n { id: 'roc', name: 'ROC', type: 'panel' },\r\n { id: 'tsi', name: 'TSI', type: 'panel' },\r\n { id: 'cmf', name: 'CMF', type: 'panel' },\r\n { id: 'aroon', name: 'Aroon', type: 'panel' },\r\n { id: 'stddev', name: 'Std Deviation', type: 'panel' },\r\n { id: 'vroc', name: 'Volume ROC', type: 'panel' },\r\n { id: 'ad', name: 'Acc/Dist', type: 'panel' },\r\n { id: 'ao', name: 'Awesome Oscillator', type: 'panel' },\r\n { id: 'chaikinOsc', name: 'Chaikin Oscillator', type: 'panel' },\r\n { id: 'voldelta', name: 'Volume Delta', type: 'panel' },\r\n { id: 'vortex', name: 'Vortex Indicator', type: 'panel' },\r\n { id: 'chop', name: 'Choppiness Index', type: 'panel' },\r\n { id: 'uo', name: 'Ultimate Oscillator', type: 'panel' },\r\n { id: 'fi', name: 'Force Index', type: 'panel' },\r\n { id: 'crsi', name: 'Connors RSI', type: 'panel' },\r\n { id: 'coppock', name: 'Coppock Curve', type: 'panel' },\r\n { id: 'kst', name: 'Know Sure Thing', type: 'panel' },\r\n { id: 'elderray', name: 'Elder Ray', type: 'panel' },\r\n { id: 'stc', name: 'Schaff Trend Cycle', type: 'panel' },\r\n { id: 'kvo', name: 'Klinger Oscillator', type: 'panel' },\r\n { id: 'fisher', name: 'Fisher Transform', type: 'panel' },\r\n { id: 'dpo', name: 'Detrended Price Osc', type: 'panel' },\r\n { id: 'bop', name: 'Balance of Power', type: 'panel' },\r\n { id: 'massindex', name: 'Mass Index', type: 'panel' },\r\n { id: 'cmo', name: 'Chande Momentum', type: 'panel' },\r\n { id: 'trix', name: 'TRIX', type: 'panel' },\r\n { id: 'emv', name: 'Ease of Movement', type: 'panel' },\r\n { id: 'pvt', name: 'Price Volume Trend', type: 'panel' },\r\n { id: 'wad', name: 'Williams A/D', type: 'panel' },\r\n { id: 'chaikinvol', name: 'Chaikin Volatility', type: 'panel' },\r\n { id: 'rvi', name: 'Relative Vigor Index', type: 'panel' },\r\n { id: 'stochrsi', name: 'Stochastic RSI', type: 'panel' },\r\n { id: 'ppo', name: 'Percentage Price Oscillator', type: 'panel' },\r\n { id: 'ac', name: 'Accelerator Oscillator', type: 'panel' },\r\n { id: 'rmi', name: 'Relative Momentum Index', type: 'panel' },\r\n { id: 'disparity', name: 'Disparity Index', type: 'panel' },\r\n { id: 'qstick', name: 'Qstick', type: 'panel' },\r\n { id: 'pgo', name: 'Pretty Good Oscillator', type: 'panel' },\r\n { id: 'volumeProfile', name: 'Volume Profile', type: 'panel' },\r\n];\r\n\r\nexport const POPULAR_INDICATORS = [\r\n 'sma', 'ema', 'bb', 'rsi', 'macd', 'stochastic',\r\n 'vwap', 'atr', 'obv', 'ichimoku',\r\n];\r\n\r\nexport const DEFAULT_SYMBOLS = [\r\n 'BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT',\r\n];\r\n\r\nexport const DEFAULT_SETTINGS: ChartSettingsState = {\r\n candleUpColor: '#26A69A',\r\n candleDownColor: '#EF5350',\r\n candleUpWick: '#26A69A',\r\n candleDownWick: '#EF5350',\r\n backgroundColor: '#131722',\r\n gridColor: '#1E222D',\r\n gridVisible: true,\r\n volumeVisible: true,\r\n volumeProfileVisible: false,\r\n marketProfileVisible: false,\r\n marketProfileSplit: false,\r\n marketProfileLetters: false,\r\n marketProfileBuckets: 48,\r\n marketProfileOpacity: 0.32,\r\n depthHeatmapVisible: false,\r\n depthHeatmapOpacity: 0.7,\r\n sessionShadingVisible: false,\r\n pivotMarkersVisible: false,\r\n pivotStrength: 5,\r\n pivotStructureLabels: false,\r\n periodLevelsVisible: false,\r\n periodLevelsPeriod: 'day',\r\n legendVisible: true,\r\n barCountdown: true,\r\n logScale: false,\r\n scaleMode: 'regular',\r\n autoScale: true,\r\n crosshairMode: 'magnet',\r\n numberLocale: 'en-US',\r\n timezone: 'local',\r\n};\r\n","import widgetCss from './WidgetStyles.css?raw';\r\n\r\nlet refCount = 0;\r\nconst STYLE_ID = 'tcw-styles';\r\n\r\n/**\r\n * Inject the widget stylesheet into `document.head`. Reference-counted so\r\n * multiple `ChartWidget` instances share the same `<style>` tag and the last\r\n * to detach removes it. CSS lives in a sibling `.css` file and is inlined at\r\n * build time via Vite's `?raw` query — consumers see a plain string at runtime.\r\n */\r\nexport function injectWidgetStyles(): void {\r\n refCount++;\r\n if (refCount > 1) return;\r\n if (document.getElementById(STYLE_ID)) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = STYLE_ID;\r\n style.textContent = widgetCss;\r\n document.head.appendChild(style);\r\n}\r\n\r\nexport function removeWidgetStyles(): void {\r\n refCount--;\r\n if (refCount > 0) return;\r\n\r\n const style = document.getElementById(STYLE_ID);\r\n if (style) {\r\n style.remove();\r\n }\r\n}\r\n","const ICON_PATHS: Record<string, string> = {\r\n cursor: '<path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\"/><path d=\"M13 13l6 6\"/>',\r\n trendingUp: '<polyline points=\"22 7 13.5 15.5 8.5 10.5 2 17\"/><polyline points=\"16 7 22 7 22 13\"/>',\r\n minus: '<path d=\"M5 12h14\"/>',\r\n penLine: '<path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\"/>',\r\n zigzag: '<polyline points=\"2 18 7 8 12 14 17 4 22 12\"/>',\r\n hash: '<line x1=\"4\" y1=\"9\" x2=\"20\" y2=\"9\"/><line x1=\"4\" y1=\"15\" x2=\"20\" y2=\"15\"/><line x1=\"10\" y1=\"3\" x2=\"8\" y2=\"21\"/><line x1=\"16\" y1=\"3\" x2=\"14\" y2=\"21\"/>',\r\n square: '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/>',\r\n gitBranch: '<line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\"/><circle cx=\"18\" cy=\"6\" r=\"3\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><path d=\"M18 9a9 9 0 0 1-9 9\"/>',\r\n ruler: '<path d=\"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z\"/><path d=\"m14.5 12.5 2-2\"/><path d=\"m11.5 9.5 2-2\"/><path d=\"m8.5 6.5 2-2\"/><path d=\"m17.5 15.5 2-2\"/>',\r\n type: '<polyline points=\"4 7 4 4 20 4 20 7\"/><line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\"/><line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\"/>',\r\n magnet: '<path d=\"m6 15-4-4 6.75-6.77a7.79 7.79 0 0 1 11 11L13 22l-4-4 6.39-6.36a2.14 2.14 0 0 0-3-3L6 15\"/><path d=\"m5 8 4 4\"/><path d=\"m12 15 4 4\"/>',\r\n undo: '<path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/>',\r\n redo: '<path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/>',\r\n trash: '<path d=\"M3 6h18\"/><path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"/><path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/>',\r\n camera: '<path d=\"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z\"/><circle cx=\"12\" cy=\"13\" r=\"3\"/>',\r\n settings: '<path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\r\n moon: '<path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\"/>',\r\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2\"/><path d=\"M12 20v2\"/><path d=\"m4.93 4.93 1.41 1.41\"/><path d=\"m17.66 17.66 1.41 1.41\"/><path d=\"M2 12h2\"/><path d=\"M20 12h2\"/><path d=\"m6.34 17.66-1.41 1.41\"/><path d=\"m19.07 4.93-1.41 1.41\"/>',\r\n chevronDown: '<path d=\"m6 9 6 6 6-6\"/>',\r\n chevronUp: '<path d=\"m18 15-6-6-6 6\"/>',\r\n barChart: '<line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"10\"/><line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"4\"/><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"16\"/>',\r\n x: '<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>',\r\n play: '<polygon points=\"6 3 20 12 6 21 6 3\"/>',\r\n pause: '<rect width=\"4\" height=\"16\" x=\"6\" y=\"4\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"4\"/>',\r\n stop: '<rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" rx=\"1\"/>',\r\n receipt: '<path d=\"M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z\"/><path d=\"M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8\"/><path d=\"M12 17.5v-11\"/>',\r\n bell: '<path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\"/><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\"/>',\r\n plus: '<path d=\"M5 12h14\"/><path d=\"M12 5v14\"/>',\r\n layers: '<path d=\"m12 2 9 5-9 5-9-5 9-5Z\"/><path d=\"m3 12 9 5 9-5\"/><path d=\"m3 17 9 5 9-5\"/>',\r\n eye: '<path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\r\n eyeOff: '<path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c6.5 0 10 7 10 7a13.2 13.2 0 0 1-1.67 2.68\"/><path d=\"M6.6 6.6A13.06 13.06 0 0 0 2 11s3.5 7 10 7a9.1 9.1 0 0 0 5.4-1.6\"/><path d=\"m2 2 20 20\"/>',\r\n lock: '<rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/>',\r\n unlock: '<rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 9.9-1\"/>',\r\n palette: '<circle cx=\"13.5\" cy=\"6.5\" r=\".5\" fill=\"currentColor\"/><circle cx=\"17.5\" cy=\"10.5\" r=\".5\" fill=\"currentColor\"/><circle cx=\"8.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"/><circle cx=\"6.5\" cy=\"12.5\" r=\".5\" fill=\"currentColor\"/><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2Z\"/>',\r\n trendingDown: '<polyline points=\"22 17 13.5 8.5 8.5 13.5 2 7\"/><polyline points=\"16 17 22 17 22 11\"/>',\r\n check: '<polyline points=\"20 6 9 17 4 12\"/>',\r\n ladder: '<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><line x1=\"3\" y1=\"8\" x2=\"21\" y2=\"8\"/><line x1=\"3\" y1=\"13\" x2=\"21\" y2=\"13\"/><line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"/>',\r\n};\r\n\r\nexport function createIcon(name: string, size = 14): string {\r\n const paths = ICON_PATHS[name];\r\n if (!paths) return '';\r\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${paths}</svg>`;\r\n}\r\n","export class WidgetDropdown {\r\n private trigger: HTMLElement;\r\n private panel: HTMLDivElement;\r\n private _isOpen = false;\r\n private onOutsideClick: (e: MouseEvent) => void;\r\n private onEscapeKey: (e: KeyboardEvent) => void;\r\n private onTriggerClick: () => void;\r\n\r\n constructor(trigger: HTMLElement, config: { width?: string; align?: 'left' | 'right' } = {}) {\r\n this.trigger = trigger;\r\n\r\n this.panel = document.createElement('div');\r\n this.panel.className = 'tcw-dropdown';\r\n this.panel.style.width = config.width ?? '200px';\r\n if (config.align === 'right') {\r\n this.panel.style.right = '0';\r\n } else {\r\n this.panel.style.left = '0';\r\n }\r\n this.panel.style.display = 'none';\r\n\r\n // Position relative to trigger\r\n trigger.style.position = 'relative';\r\n trigger.appendChild(this.panel);\r\n\r\n this.onTriggerClick = () => {\r\n if (this._isOpen) {\r\n this.close();\r\n } else {\r\n this.open();\r\n }\r\n };\r\n\r\n this.onOutsideClick = (e: MouseEvent) => {\r\n if (!this.trigger.contains(e.target as Node)) {\r\n this.close();\r\n }\r\n };\r\n\r\n this.onEscapeKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n this.close();\r\n }\r\n };\r\n\r\n trigger.addEventListener('click', this.onTriggerClick);\r\n }\r\n\r\n setContent(html: string): void {\r\n this.panel.innerHTML = html;\r\n }\r\n\r\n open(): void {\r\n if (this._isOpen) return;\r\n this._isOpen = true;\r\n this.panel.style.display = '';\r\n document.addEventListener('mousedown', this.onOutsideClick);\r\n document.addEventListener('keydown', this.onEscapeKey);\r\n }\r\n\r\n close(): void {\r\n if (!this._isOpen) return;\r\n this._isOpen = false;\r\n this.panel.style.display = 'none';\r\n document.removeEventListener('mousedown', this.onOutsideClick);\r\n document.removeEventListener('keydown', this.onEscapeKey);\r\n }\r\n\r\n isOpen(): boolean {\r\n return this._isOpen;\r\n }\r\n\r\n destroy(): void {\r\n this.trigger.removeEventListener('click', this.onTriggerClick);\r\n document.removeEventListener('mousedown', this.onOutsideClick);\r\n document.removeEventListener('keydown', this.onEscapeKey);\r\n this.panel.remove();\r\n }\r\n}\r\n","import type { ChartType } from '@tradecanvas/commons';\r\nimport type { ToolbarConfig, ToolbarCallbacks, WidgetState, ActiveIndicator } from './types.js';\r\nimport { createIcon } from './icons.js';\r\nimport { WidgetDropdown } from './WidgetDropdown.js';\r\nimport type { Translator } from './i18n.js';\r\n\r\nexport class WidgetToolbar {\r\n private config: ToolbarConfig;\r\n private callbacks: ToolbarCallbacks;\r\n private t: Translator;\r\n private el: HTMLDivElement;\r\n private chartTypeDropdown: WidgetDropdown | null = null;\r\n private indicatorDropdown: WidgetDropdown | null = null;\r\n private tfButtons: HTMLButtonElement[] = [];\r\n private chipsContainer: HTMLDivElement | null = null;\r\n private themeBtn: HTMLButtonElement | null = null;\r\n\r\n constructor(host: HTMLElement, config: ToolbarConfig, callbacks: ToolbarCallbacks, t: Translator) {\r\n this.config = config;\r\n this.callbacks = callbacks;\r\n this.t = t;\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-toolbar';\r\n this.build();\r\n host.appendChild(this.el);\r\n }\r\n\r\n private build(): void {\r\n const { config, callbacks, el } = this;\r\n\r\n // Symbol button\r\n const symbolBtn = document.createElement('button');\r\n symbolBtn.className = 'tcw-toolbar-symbol';\r\n symbolBtn.dataset.role = 'symbol';\r\n symbolBtn.addEventListener('click', callbacks.onSymbolClick);\r\n el.appendChild(symbolBtn);\r\n el.appendChild(this.sep());\r\n\r\n // Timeframes\r\n const tfGroup = document.createElement('div');\r\n tfGroup.className = 'tcw-toolbar-group';\r\n for (const tf of config.timeframes) {\r\n const btn = document.createElement('button');\r\n btn.className = 'tcw-btn';\r\n btn.textContent = tf.label;\r\n btn.dataset.tf = tf.value;\r\n btn.addEventListener('click', () => callbacks.onTimeframe(tf.value));\r\n tfGroup.appendChild(btn);\r\n this.tfButtons.push(btn);\r\n }\r\n el.appendChild(tfGroup);\r\n el.appendChild(this.sep());\r\n\r\n // Chart type dropdown\r\n const ctWrap = document.createElement('div');\r\n ctWrap.style.position = 'relative';\r\n ctWrap.style.display = 'inline-flex';\r\n\r\n const ctTrigger = document.createElement('button');\r\n ctTrigger.className = 'tcw-dropdown-trigger';\r\n ctTrigger.dataset.role = 'charttype';\r\n ctWrap.appendChild(ctTrigger);\r\n el.appendChild(ctWrap);\r\n\r\n this.chartTypeDropdown = new WidgetDropdown(ctWrap, { width: '160px' });\r\n this.buildChartTypeMenu();\r\n\r\n el.appendChild(this.sep());\r\n\r\n // Indicators dropdown\r\n const indWrap = document.createElement('div');\r\n indWrap.style.position = 'relative';\r\n indWrap.style.display = 'inline-flex';\r\n\r\n const indTrigger = document.createElement('button');\r\n indTrigger.className = 'tcw-dropdown-trigger';\r\n indTrigger.dataset.role = 'indicators';\r\n indWrap.appendChild(indTrigger);\r\n el.appendChild(indWrap);\r\n\r\n this.indicatorDropdown = new WidgetDropdown(indWrap, { width: '280px' });\r\n this.buildIndicatorMenu();\r\n\r\n // Indicator chips\r\n this.chipsContainer = document.createElement('div');\r\n this.chipsContainer.className = 'tcw-indicator-chips';\r\n el.appendChild(this.chipsContainer);\r\n\r\n // Spacer\r\n el.appendChild(this.spacer());\r\n\r\n // Right side buttons\r\n if (callbacks.onToggleReplay) {\r\n const replayBtn = this.iconBtn('play', this.t('toolbar.replay'), callbacks.onToggleReplay);\r\n replayBtn.dataset.role = 'replay';\r\n el.appendChild(replayBtn);\r\n }\r\n\r\n if (callbacks.onBracket) {\r\n const onBracket = callbacks.onBracket;\r\n const longBtn = this.iconBtn('trendingUp', this.t('toolbar.longBracket'), () => onBracket('buy'));\r\n longBtn.dataset.role = 'long';\r\n longBtn.classList.add('tcw-btn-long');\r\n el.appendChild(longBtn);\r\n const shortBtn = this.iconBtn('trendingDown', this.t('toolbar.shortBracket'), () => onBracket('sell'));\r\n shortBtn.dataset.role = 'short';\r\n shortBtn.classList.add('tcw-btn-short');\r\n el.appendChild(shortBtn);\r\n }\r\n\r\n if (callbacks.onToggleLadder) {\r\n const ladderBtn = this.iconBtn('ladder', this.t('toolbar.depthLadder'), callbacks.onToggleLadder);\r\n ladderBtn.dataset.role = 'ladder';\r\n el.appendChild(ladderBtn);\r\n }\r\n\r\n if (callbacks.onToggleObjects) {\r\n const objectsBtn = this.iconBtn('layers', this.t('toolbar.objects'), callbacks.onToggleObjects);\r\n objectsBtn.dataset.role = 'objects';\r\n el.appendChild(objectsBtn);\r\n }\r\n\r\n if (callbacks.onToggleAlerts) {\r\n const alertsBtn = this.iconBtn('bell', this.t('toolbar.priceAlerts'), callbacks.onToggleAlerts);\r\n alertsBtn.dataset.role = 'alerts';\r\n el.appendChild(alertsBtn);\r\n }\r\n\r\n const screenshotBtn = this.iconBtn('camera', this.t('toolbar.screenshot'), callbacks.onScreenshot);\r\n el.appendChild(screenshotBtn);\r\n\r\n const settingsBtn = this.iconBtn('settings', this.t('toolbar.settings'), callbacks.onSettings);\r\n el.appendChild(settingsBtn);\r\n\r\n this.themeBtn = this.iconBtn('moon', this.t('toolbar.toggleTheme'), callbacks.onToggleTheme);\r\n this.themeBtn.dataset.role = 'theme';\r\n el.appendChild(this.themeBtn);\r\n }\r\n\r\n private chartTypeLabel(ct: { value: ChartType; label: string }): string {\r\n const key = `chartType.${ct.value}` as const;\r\n const translated = this.t(key as Parameters<Translator>[0]);\r\n return translated === key ? ct.label : translated;\r\n }\r\n\r\n private buildChartTypeMenu(): void {\r\n if (!this.chartTypeDropdown) return;\r\n const items = this.config.chartTypes.map(ct =>\r\n `<button class=\"tcw-dropdown-item\" data-ct=\"${ct.value}\">${this.chartTypeLabel(ct)}</button>`\r\n ).join('');\r\n this.chartTypeDropdown.setContent(items);\r\n\r\n // Attach events to items after content set\r\n const panel = this.chartTypeDropdown['panel'] as HTMLDivElement;\r\n panel.querySelectorAll('.tcw-dropdown-item').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n const value = (e.currentTarget as HTMLElement).dataset.ct as ChartType;\r\n this.callbacks.onChartType(value);\r\n this.chartTypeDropdown?.close();\r\n });\r\n });\r\n }\r\n\r\n private buildIndicatorMenu(): void {\r\n if (!this.indicatorDropdown) return;\r\n const { indicators, popularIndicatorIds } = this.config;\r\n\r\n const popular = indicators.filter(d => popularIndicatorIds.includes(d.id));\r\n const other = indicators.filter(d => !popularIndicatorIds.includes(d.id));\r\n\r\n const typeLabel = (type: string) => this.t(`indicatorType.${type}` as Parameters<Translator>[0]);\r\n\r\n let html = `<div class=\"tcw-dropdown-label\">${this.t('toolbar.indicators.popular')}</div>`;\r\n for (const ind of popular) {\r\n html += `<button class=\"tcw-dropdown-item\" data-ind=\"${ind.id}\"><span>${ind.name}</span><span class=\"tcw-tag\">${typeLabel(ind.type)}</span></button>`;\r\n }\r\n html += '<div class=\"tcw-dropdown-divider\"></div>';\r\n html += `<div class=\"tcw-dropdown-label\">${this.t('toolbar.indicators.all')}</div>`;\r\n for (const ind of other) {\r\n html += `<button class=\"tcw-dropdown-item\" data-ind=\"${ind.id}\"><span>${ind.name}</span><span class=\"tcw-tag\">${typeLabel(ind.type)}</span></button>`;\r\n }\r\n\r\n this.indicatorDropdown.setContent(html);\r\n\r\n const panel = this.indicatorDropdown['panel'] as HTMLDivElement;\r\n panel.querySelectorAll('.tcw-dropdown-item[data-ind]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n const id = (e.currentTarget as HTMLElement).dataset.ind!;\r\n this.callbacks.onAddIndicator(id);\r\n });\r\n });\r\n }\r\n\r\n update(state: WidgetState): void {\r\n // Symbol\r\n const symbolBtn = this.el.querySelector('[data-role=\"symbol\"]') as HTMLButtonElement | null;\r\n if (symbolBtn) symbolBtn.textContent = state.symbol;\r\n\r\n // Timeframe buttons\r\n for (const btn of this.tfButtons) {\r\n btn.classList.toggle('tcw-active', btn.dataset.tf === state.timeframe);\r\n }\r\n\r\n // Chart type trigger label\r\n const ctTrigger = this.el.querySelector('[data-role=\"charttype\"]') as HTMLElement | null;\r\n if (ctTrigger) {\r\n const ct = this.config.chartTypes.find(ct => ct.value === state.chartType);\r\n const label = ct ? this.chartTypeLabel(ct) : state.chartType;\r\n ctTrigger.innerHTML = `${createIcon('barChart', 14)} ${label} ${createIcon('chevronDown', 12)}`;\r\n }\r\n\r\n // Indicator trigger + badge\r\n const indTrigger = this.el.querySelector('[data-role=\"indicators\"]') as HTMLElement | null;\r\n if (indTrigger) {\r\n const count = state.activeIndicators.size;\r\n let inner = `${createIcon('trendingUp', 14)} ${this.t('toolbar.indicators')}`;\r\n if (count > 0) {\r\n inner += ` <span class=\"tcw-badge-count\">${count}</span>`;\r\n }\r\n indTrigger.innerHTML = inner;\r\n }\r\n\r\n // Chips\r\n if (this.chipsContainer) {\r\n const activeList = this.getActiveIndicatorList(state);\r\n this.chipsContainer.innerHTML = '';\r\n for (const ind of activeList) {\r\n const chip = document.createElement('div');\r\n chip.className = 'tcw-indicator-chip';\r\n\r\n const label = document.createElement('span');\r\n label.textContent = ind.label;\r\n chip.appendChild(label);\r\n\r\n const removeBtn = document.createElement('button');\r\n removeBtn.className = 'tcw-chip-remove';\r\n removeBtn.innerHTML = createIcon('x', 10);\r\n removeBtn.addEventListener('click', () => this.callbacks.onRemoveIndicator(ind.instanceId));\r\n chip.appendChild(removeBtn);\r\n\r\n this.chipsContainer.appendChild(chip);\r\n }\r\n }\r\n\r\n // Theme toggle icon\r\n if (this.themeBtn) {\r\n this.themeBtn.innerHTML = state.isDark ? createIcon('moon', 14) : createIcon('sun', 14);\r\n }\r\n }\r\n\r\n private getActiveIndicatorList(state: WidgetState): ActiveIndicator[] {\r\n const result: ActiveIndicator[] = [];\r\n for (const [id, instanceId] of state.activeIndicators.entries()) {\r\n result.push({ instanceId, id, label: id.toUpperCase() });\r\n }\r\n return result;\r\n }\r\n\r\n private sep(): HTMLSpanElement {\r\n const s = document.createElement('span');\r\n s.className = 'tcw-toolbar-sep';\r\n return s;\r\n }\r\n\r\n private spacer(): HTMLSpanElement {\r\n const s = document.createElement('span');\r\n s.className = 'tcw-toolbar-spacer';\r\n return s;\r\n }\r\n\r\n private iconBtn(icon: string, title: string, onClick: () => void): HTMLButtonElement {\r\n const btn = document.createElement('button');\r\n btn.className = 'tcw-btn-icon';\r\n btn.title = title;\r\n btn.innerHTML = createIcon(icon, 14);\r\n btn.addEventListener('click', onClick);\r\n return btn;\r\n }\r\n\r\n destroy(): void {\r\n this.chartTypeDropdown?.destroy();\r\n this.indicatorDropdown?.destroy();\r\n this.el.remove();\r\n }\r\n}\r\n","import type { SidebarConfig, SidebarCallbacks, WidgetState } from './types.js';\r\nimport { createIcon } from './icons.js';\r\n\r\nconst GROUP_ICONS = [\r\n 'trendingUp', 'minus', 'penLine', 'hash', 'square', 'gitBranch', 'zigzag', 'ruler', 'type', 'ladder',\r\n];\r\n\r\n/** Icon for a drawing tool in the favorites strip — falls back to a pen. */\r\nconst TOOL_ICONS: Record<string, string> = {\r\n trendLine: 'trendingUp', ray: 'trendingUp', extendedLine: 'trendingUp',\r\n infoLine: 'trendingUp', trendAngle: 'trendingUp',\r\n horizontalLine: 'minus', horizontalRay: 'minus', verticalLine: 'penLine', crossLine: 'plus',\r\n rectangle: 'square', circle: 'square', ellipse: 'square', triangle: 'square', arrow: 'trendingUp',\r\n parallelChannel: 'gitBranch', regressionChannel: 'gitBranch',\r\n pitchfork: 'gitBranch', schiffPitchfork: 'gitBranch', modifiedSchiffPitchfork: 'gitBranch',\r\n fibRetracement: 'hash', fibExtension: 'hash', fibTimeZones: 'hash', fibChannel: 'hash', fibSpeedResistanceFan: 'hash',\r\n gannBox: 'hash', gannFan: 'gitBranch', cyclicLines: 'barChart',\r\n elliottWave: 'zigzag', xabcdPattern: 'zigzag', abcdPattern: 'zigzag', headAndShoulders: 'zigzag',\r\n priceRange: 'ruler', dateRange: 'ruler', dateAndPriceRange: 'ruler', measure: 'ruler',\r\n text: 'type', textAnnotation: 'type', priceLabel: 'type',\r\n anchoredVWAP: 'trendingUp', volumeProfileRange: 'barChart',\r\n riskReward: 'square',\r\n};\r\n\r\nfunction toolIcon(tool: string): string {\r\n return TOOL_ICONS[tool] ?? 'penLine';\r\n}\r\n\r\n/** Human label for a tool id, sourced from the configured groups. */\r\nfunction toolLabel(groups: SidebarConfig['drawingToolGroups'], tool: string): string {\r\n for (const g of groups) {\r\n const t = g.tools.find((x) => x.value === tool);\r\n if (t) return t.label;\r\n }\r\n return tool;\r\n}\r\n\r\nexport class WidgetDrawingSidebar {\r\n private config: SidebarConfig;\r\n private callbacks: SidebarCallbacks;\r\n private el: HTMLDivElement;\r\n private groupWraps: HTMLDivElement[] = [];\r\n private groupButtons: HTMLButtonElement[] = [];\r\n private cursorBtn: HTMLButtonElement | null = null;\r\n private magnetBtn: HTMLButtonElement | null = null;\r\n private flyoutEl: HTMLDivElement | null = null;\r\n private favoritesEl: HTMLDivElement | null = null;\r\n private favoritesDivider: HTMLDivElement | null = null;\r\n private favorites: string[] = [];\r\n\r\n constructor(host: HTMLElement, config: SidebarConfig, callbacks: SidebarCallbacks) {\r\n this.config = config;\r\n this.callbacks = callbacks;\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-sidebar';\r\n this.build();\r\n host.appendChild(this.el);\r\n }\r\n\r\n private build(): void {\r\n const { config, callbacks, el } = this;\r\n\r\n // Cursor button\r\n this.cursorBtn = document.createElement('button');\r\n this.cursorBtn.className = 'tcw-sidebar-btn';\r\n this.cursorBtn.title = 'Cursor';\r\n this.cursorBtn.innerHTML = createIcon('cursor', 14);\r\n this.cursorBtn.addEventListener('click', callbacks.onCancelDrawing);\r\n el.appendChild(this.cursorBtn);\r\n\r\n el.appendChild(this.divider());\r\n\r\n // Favorites strip (pinned tools) — only when favorites are enabled.\r\n if (callbacks.onToggleFavorite) {\r\n this.favorites = [...(config.favorites ?? [])];\r\n this.favoritesEl = document.createElement('div');\r\n this.favoritesEl.className = 'tcw-sidebar-favorites';\r\n el.appendChild(this.favoritesEl);\r\n this.favoritesDivider = this.divider();\r\n el.appendChild(this.favoritesDivider);\r\n this.renderFavorites();\r\n }\r\n\r\n // Tool groups\r\n config.drawingToolGroups.forEach((group, idx) => {\r\n const wrap = document.createElement('div');\r\n wrap.className = 'tcw-tool-group-wrap';\r\n\r\n const btn = document.createElement('button');\r\n btn.className = 'tcw-sidebar-btn';\r\n btn.title = group.label;\r\n btn.innerHTML = createIcon(GROUP_ICONS[idx] ?? 'square', 14);\r\n\r\n if (group.tools.length > 1) {\r\n const dot = document.createElement('span');\r\n dot.className = 'tcw-multi-dot';\r\n btn.appendChild(dot);\r\n }\r\n\r\n btn.addEventListener('click', () => callbacks.onDrawingTool(group.tools[0].value));\r\n wrap.appendChild(btn);\r\n\r\n // Flyout events via JS (not CSS hover)\r\n wrap.addEventListener('mouseenter', () => this.showFlyout(idx));\r\n wrap.addEventListener('mouseleave', () => this.hideFlyout());\r\n\r\n el.appendChild(wrap);\r\n this.groupWraps.push(wrap);\r\n this.groupButtons.push(btn);\r\n });\r\n\r\n // Spacer\r\n const spacer = document.createElement('div');\r\n spacer.className = 'tcw-sidebar-spacer';\r\n el.appendChild(spacer);\r\n\r\n el.appendChild(this.divider());\r\n\r\n // Bottom tools\r\n if (callbacks.onToggleStyle) {\r\n const styleBtn = document.createElement('button');\r\n styleBtn.className = 'tcw-sidebar-btn';\r\n styleBtn.title = 'Drawing style & templates';\r\n styleBtn.dataset.role = 'style';\r\n styleBtn.innerHTML = createIcon('palette', 14);\r\n styleBtn.addEventListener('click', callbacks.onToggleStyle);\r\n el.appendChild(styleBtn);\r\n }\r\n\r\n this.magnetBtn = document.createElement('button');\r\n this.magnetBtn.className = 'tcw-sidebar-btn';\r\n this.magnetBtn.title = 'Magnet';\r\n this.magnetBtn.innerHTML = createIcon('magnet', 14);\r\n this.magnetBtn.addEventListener('click', callbacks.onToggleMagnet);\r\n el.appendChild(this.magnetBtn);\r\n\r\n const undoBtn = document.createElement('button');\r\n undoBtn.className = 'tcw-sidebar-btn';\r\n undoBtn.title = 'Undo';\r\n undoBtn.innerHTML = createIcon('undo', 14);\r\n undoBtn.addEventListener('click', callbacks.onUndo);\r\n el.appendChild(undoBtn);\r\n\r\n const redoBtn = document.createElement('button');\r\n redoBtn.className = 'tcw-sidebar-btn';\r\n redoBtn.title = 'Redo';\r\n redoBtn.innerHTML = createIcon('redo', 14);\r\n redoBtn.addEventListener('click', callbacks.onRedo);\r\n el.appendChild(redoBtn);\r\n\r\n const clearBtn = document.createElement('button');\r\n clearBtn.className = 'tcw-sidebar-btn tcw-danger';\r\n clearBtn.title = 'Clear all';\r\n clearBtn.innerHTML = createIcon('trash', 14);\r\n clearBtn.addEventListener('click', callbacks.onClearDrawings);\r\n el.appendChild(clearBtn);\r\n }\r\n\r\n /** Update the pinned-tools strip. */\r\n setFavorites(favorites: string[]): void {\r\n this.favorites = [...favorites];\r\n this.renderFavorites();\r\n }\r\n\r\n private renderFavorites(): void {\r\n if (!this.favoritesEl) return;\r\n this.favoritesEl.replaceChildren();\r\n const visible = this.favorites.length > 0;\r\n this.favoritesEl.style.display = visible ? '' : 'none';\r\n if (this.favoritesDivider) this.favoritesDivider.style.display = visible ? '' : 'none';\r\n\r\n for (const tool of this.favorites) {\r\n const btn = document.createElement('button');\r\n btn.className = 'tcw-sidebar-btn';\r\n btn.title = `${toolLabel(this.config.drawingToolGroups, tool)} (right-click to unpin)`;\r\n btn.dataset.toolValue = tool;\r\n btn.innerHTML = createIcon(toolIcon(tool), 14);\r\n btn.addEventListener('click', () => this.callbacks.onDrawingTool(tool as never));\r\n btn.addEventListener('contextmenu', (e) => {\r\n e.preventDefault();\r\n this.callbacks.onToggleFavorite?.(tool as never);\r\n });\r\n this.favoritesEl.appendChild(btn);\r\n }\r\n }\r\n\r\n private showFlyout(idx: number): void {\r\n const group = this.config.drawingToolGroups[idx];\r\n if (!group || group.tools.length <= 1) return;\r\n\r\n this.hideFlyout();\r\n\r\n const flyout = document.createElement('div');\r\n flyout.className = 'tcw-flyout';\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-flyout-header';\r\n header.textContent = group.label;\r\n flyout.appendChild(header);\r\n\r\n for (const tool of group.tools) {\r\n const item = document.createElement('button');\r\n item.className = 'tcw-flyout-item';\r\n item.textContent = tool.label;\r\n item.dataset.toolValue = tool.value;\r\n item.addEventListener('click', () => {\r\n this.callbacks.onDrawingTool(tool.value);\r\n this.hideFlyout();\r\n });\r\n if (this.callbacks.onToggleFavorite) {\r\n if (this.favorites.includes(tool.value)) item.classList.add('tcw-flyout-faved');\r\n item.title = 'Right-click to pin/unpin';\r\n item.addEventListener('contextmenu', (e) => {\r\n e.preventDefault();\r\n this.callbacks.onToggleFavorite?.(tool.value);\r\n });\r\n }\r\n flyout.appendChild(item);\r\n }\r\n\r\n this.flyoutEl = flyout;\r\n this.groupWraps[idx].appendChild(flyout);\r\n }\r\n\r\n private hideFlyout(): void {\r\n if (this.flyoutEl) {\r\n this.flyoutEl.remove();\r\n this.flyoutEl = null;\r\n }\r\n }\r\n\r\n update(state: WidgetState): void {\r\n // Cursor active\r\n if (this.cursorBtn) {\r\n this.cursorBtn.classList.toggle('tcw-active', state.activeTool === null);\r\n }\r\n\r\n // Group buttons\r\n const { drawingToolGroups } = this.config;\r\n for (let i = 0; i < drawingToolGroups.length; i++) {\r\n const isActive = drawingToolGroups[i].tools.some(t => t.value === state.activeTool);\r\n this.groupButtons[i].classList.toggle('tcw-active', isActive);\r\n }\r\n\r\n // Flyout items\r\n if (this.flyoutEl) {\r\n this.flyoutEl.querySelectorAll('.tcw-flyout-item').forEach((item) => {\r\n const el = item as HTMLElement;\r\n el.classList.toggle('tcw-active', el.dataset.toolValue === state.activeTool);\r\n });\r\n }\r\n\r\n // Magnet\r\n if (this.magnetBtn) {\r\n this.magnetBtn.classList.toggle('tcw-active', state.magnetEnabled);\r\n this.magnetBtn.title = state.magnetEnabled ? 'Magnet ON' : 'Magnet OFF';\r\n }\r\n }\r\n\r\n private divider(): HTMLDivElement {\r\n const d = document.createElement('div');\r\n d.className = 'tcw-sidebar-divider';\r\n return d;\r\n }\r\n\r\n destroy(): void {\r\n this.hideFlyout();\r\n this.el.remove();\r\n }\r\n}\r\n","import type { ChartSettingsState, SettingsCallbacks } from './types.js';\r\nimport { createIcon } from './icons.js';\r\nimport type { Translator } from './i18n.js';\r\n\r\ntype Tab = 'style' | 'display' | 'scale';\r\nconst TABS: Tab[] = ['style', 'display', 'scale'];\r\n\r\nexport class WidgetSettings {\r\n private callbacks: SettingsCallbacks;\r\n private t: Translator;\r\n private backdrop: HTMLDivElement | null = null;\r\n private modal: HTMLDivElement | null = null;\r\n private currentTab: Tab = 'style';\r\n private currentSettings: ChartSettingsState | null = null;\r\n private bodyEl: HTMLDivElement | null = null;\r\n private tabButtons: HTMLButtonElement[] = [];\r\n\r\n constructor(callbacks: SettingsCallbacks, t: Translator) {\r\n this.callbacks = callbacks;\r\n this.t = t;\r\n }\r\n\r\n open(currentSettings: ChartSettingsState): void {\r\n this.currentSettings = { ...currentSettings };\r\n this.currentTab = 'style';\r\n this.buildModal();\r\n }\r\n\r\n close(): void {\r\n this.backdrop?.remove();\r\n this.modal?.remove();\r\n this.backdrop = null;\r\n this.modal = null;\r\n this.bodyEl = null;\r\n this.tabButtons = [];\r\n }\r\n\r\n private buildModal(): void {\r\n // Backdrop\r\n this.backdrop = document.createElement('div');\r\n this.backdrop.className = 'tcw-modal-backdrop';\r\n this.backdrop.addEventListener('click', () => {\r\n this.callbacks.onClose();\r\n this.close();\r\n });\r\n document.body.appendChild(this.backdrop);\r\n\r\n // Modal\r\n this.modal = document.createElement('div');\r\n this.modal.className = 'tcw-modal';\r\n\r\n // Header\r\n const header = document.createElement('div');\r\n header.className = 'tcw-modal-header';\r\n const h3 = document.createElement('h3');\r\n h3.textContent = this.t('settings.title');\r\n header.appendChild(h3);\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'tcw-modal-close';\r\n closeBtn.innerHTML = createIcon('x', 16);\r\n closeBtn.addEventListener('click', () => {\r\n this.callbacks.onClose();\r\n this.close();\r\n });\r\n header.appendChild(closeBtn);\r\n this.modal.appendChild(header);\r\n\r\n // Tabs\r\n const tabsEl = document.createElement('div');\r\n tabsEl.className = 'tcw-modal-tabs';\r\n this.tabButtons = [];\r\n for (const tab of TABS) {\r\n const btn = document.createElement('button');\r\n btn.className = 'tcw-modal-tab';\r\n btn.textContent = this.t(`settings.tab.${tab}` as Parameters<Translator>[0]);\r\n btn.dataset.tab = tab;\r\n if (tab === this.currentTab) btn.classList.add('tcw-active');\r\n btn.addEventListener('click', () => {\r\n this.currentTab = tab;\r\n this.tabButtons.forEach(b => b.classList.toggle('tcw-active', b.dataset.tab === tab));\r\n this.renderTabContent();\r\n });\r\n tabsEl.appendChild(btn);\r\n this.tabButtons.push(btn);\r\n }\r\n this.modal.appendChild(tabsEl);\r\n\r\n // Body\r\n this.bodyEl = document.createElement('div');\r\n this.bodyEl.className = 'tcw-modal-body';\r\n this.modal.appendChild(this.bodyEl);\r\n this.renderTabContent();\r\n\r\n // Footer\r\n const footer = document.createElement('div');\r\n footer.className = 'tcw-modal-footer';\r\n const resetBtn = document.createElement('button');\r\n resetBtn.className = 'tcw-reset-link';\r\n resetBtn.textContent = this.t('settings.resetToDefaults');\r\n resetBtn.addEventListener('click', () => this.callbacks.onReset());\r\n footer.appendChild(resetBtn);\r\n const doneBtn = document.createElement('button');\r\n doneBtn.className = 'tcw-done-btn';\r\n doneBtn.textContent = this.t('settings.done');\r\n doneBtn.addEventListener('click', () => {\r\n this.callbacks.onClose();\r\n this.close();\r\n });\r\n footer.appendChild(doneBtn);\r\n this.modal.appendChild(footer);\r\n\r\n document.body.appendChild(this.modal);\r\n\r\n // Escape key\r\n const onKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n document.removeEventListener('keydown', onKeyDown);\r\n this.callbacks.onClose();\r\n this.close();\r\n }\r\n };\r\n document.addEventListener('keydown', onKeyDown);\r\n }\r\n\r\n private renderTabContent(): void {\r\n if (!this.bodyEl || !this.currentSettings) return;\r\n this.bodyEl.innerHTML = '';\r\n\r\n switch (this.currentTab) {\r\n case 'style':\r\n this.renderStyleTab();\r\n break;\r\n case 'display':\r\n this.renderDisplayTab();\r\n break;\r\n case 'scale':\r\n this.renderScaleTab();\r\n break;\r\n }\r\n }\r\n\r\n private renderStyleTab(): void {\r\n if (!this.bodyEl || !this.currentSettings) return;\r\n const s = this.currentSettings;\r\n\r\n // Candle Colors\r\n const candleSection = this.section(this.t('settings.section.candleColors'));\r\n candleSection.appendChild(this.colorRow('Up Body', s.candleUpColor, (v) => this.patch({ candleUpColor: v })));\r\n candleSection.appendChild(this.colorRow('Down Body', s.candleDownColor, (v) => this.patch({ candleDownColor: v })));\r\n candleSection.appendChild(this.colorRow('Up Wick', s.candleUpWick, (v) => this.patch({ candleUpWick: v })));\r\n candleSection.appendChild(this.colorRow('Down Wick', s.candleDownWick, (v) => this.patch({ candleDownWick: v })));\r\n this.bodyEl.appendChild(candleSection);\r\n\r\n // Background\r\n const bgSection = this.section(this.t('settings.section.background'));\r\n bgSection.appendChild(this.colorRow('Background', s.backgroundColor, (v) => this.patch({ backgroundColor: v })));\r\n bgSection.appendChild(this.colorRow('Grid', s.gridColor, (v) => this.patch({ gridColor: v })));\r\n this.bodyEl.appendChild(bgSection);\r\n }\r\n\r\n private renderDisplayTab(): void {\r\n if (!this.bodyEl || !this.currentSettings) return;\r\n const s = this.currentSettings;\r\n\r\n const section = this.section();\r\n section.appendChild(this.toggleRow('Grid Lines', s.gridVisible, (v) => this.patch({ gridVisible: v })));\r\n section.appendChild(this.toggleRow('Volume', s.volumeVisible, (v) => this.patch({ volumeVisible: v })));\r\n section.appendChild(this.toggleRow('Volume Profile', s.volumeProfileVisible, (v) => this.patch({ volumeProfileVisible: v })));\r\n section.appendChild(this.toggleRow('Market Profile (TPO)', s.marketProfileVisible, (v) => this.patch({ marketProfileVisible: v })));\r\n section.appendChild(this.toggleRow('MP split by session', s.marketProfileSplit, (v) => this.patch({ marketProfileSplit: v })));\r\n section.appendChild(this.toggleRow('MP letters (TPO)', s.marketProfileLetters, (v) => this.patch({ marketProfileLetters: v })));\r\n section.appendChild(this.rangeRow('MP buckets', s.marketProfileBuckets, 8, 200, 1, (v) => this.patch({ marketProfileBuckets: v })));\r\n section.appendChild(this.rangeRow('MP opacity', s.marketProfileOpacity, 0.05, 1, 0.05, (v) => this.patch({ marketProfileOpacity: v }), (v) => `${Math.round(v * 100)}%`));\r\n section.appendChild(this.toggleRow('Liquidity heatmap', s.depthHeatmapVisible, (v) => this.patch({ depthHeatmapVisible: v })));\r\n section.appendChild(this.rangeRow('Heatmap opacity', s.depthHeatmapOpacity, 0.1, 1, 0.05, (v) => this.patch({ depthHeatmapOpacity: v }), (v) => `${Math.round(v * 100)}%`));\r\n section.appendChild(this.toggleRow('Swing markers', s.pivotMarkersVisible, (v) => this.patch({ pivotMarkersVisible: v })));\r\n section.appendChild(this.rangeRow('Swing strength', s.pivotStrength, 2, 20, 1, (v) => this.patch({ pivotStrength: v })));\r\n section.appendChild(this.toggleRow('Swing structure (HH/HL)', s.pivotStructureLabels, (v) => this.patch({ pivotStructureLabels: v })));\r\n section.appendChild(this.toggleRow('Session shading (RTH)', s.sessionShadingVisible, (v) => this.patch({ sessionShadingVisible: v })));\r\n section.appendChild(this.toggleRow('Prior-period levels', s.periodLevelsVisible, (v) => this.patch({ periodLevelsVisible: v })));\r\n section.appendChild(this.selectRow('Period levels basis', s.periodLevelsPeriod, [\r\n { value: 'day', label: 'Prior Day (PDH/PDL)' },\r\n { value: 'week', label: 'Prior Week (PWH/PWL)' },\r\n ], (v) => this.patch({ periodLevelsPeriod: v as ChartSettingsState['periodLevelsPeriod'] })));\r\n section.appendChild(this.toggleRow('OHLC Legend', s.legendVisible, (v) => this.patch({ legendVisible: v })));\r\n section.appendChild(this.toggleRow('Bar Countdown', s.barCountdown, (v) => this.patch({ barCountdown: v })));\r\n\r\n // Crosshair mode\r\n section.appendChild(this.selectRow('Crosshair Mode', s.crosshairMode, [\r\n { label: 'Magnet', value: 'magnet' },\r\n { label: 'Normal', value: 'normal' },\r\n { label: 'Hidden', value: 'hidden' },\r\n ], (v) => this.patch({ crosshairMode: v as ChartSettingsState['crosshairMode'] })));\r\n\r\n // Number locale\r\n section.appendChild(this.selectRow('Timezone', s.timezone, [\r\n { value: 'local', label: 'Local' },\r\n { value: '0', label: 'UTC / London' },\r\n { value: '-300', label: 'New York (UTC-5)' },\r\n { value: '-360', label: 'Chicago (UTC-6)' },\r\n { value: '60', label: 'Frankfurt (UTC+1)' },\r\n { value: '480', label: 'Singapore/HK (UTC+8)' },\r\n { value: '540', label: 'Tokyo (UTC+9)' },\r\n { value: '330', label: 'Mumbai (UTC+5:30)' },\r\n ], (v) => this.patch({ timezone: v })));\r\n section.appendChild(this.selectRow('Number Locale', s.numberLocale, [\r\n { label: 'en-US (65,234.00)', value: 'en-US' },\r\n { label: 'de-DE (65.234,00)', value: 'de-DE' },\r\n { label: 'fr-FR (65 234,00)', value: 'fr-FR' },\r\n { label: 'vi-VN (65.234,00)', value: 'vi-VN' },\r\n { label: 'en-IN (65,234.00)', value: 'en-IN' },\r\n { label: 'ja-JP (65,234.00)', value: 'ja-JP' },\r\n ], (v) => this.patch({ numberLocale: v })));\r\n\r\n this.bodyEl.appendChild(section);\r\n }\r\n\r\n private renderScaleTab(): void {\r\n if (!this.bodyEl || !this.currentSettings) return;\r\n const s = this.currentSettings;\r\n\r\n const section = this.section();\r\n section.appendChild(this.toggleRow('Auto Scale', s.autoScale, (v) => this.patch({ autoScale: v })));\r\n section.appendChild(this.selectRow('Price Scale', s.scaleMode, [\r\n { value: 'regular', label: 'Regular' },\r\n { value: 'logarithmic', label: 'Logarithmic' },\r\n { value: 'percentage', label: 'Percentage' },\r\n { value: 'indexedTo100', label: 'Indexed to 100' },\r\n ], (v) => this.patch({ scaleMode: v as ChartSettingsState['scaleMode'] })));\r\n this.bodyEl.appendChild(section);\r\n }\r\n\r\n private patch(partial: Partial<ChartSettingsState>): void {\r\n if (this.currentSettings) {\r\n Object.assign(this.currentSettings, partial);\r\n }\r\n this.callbacks.onChange(partial);\r\n }\r\n\r\n private section(title?: string): HTMLDivElement {\r\n const div = document.createElement('div');\r\n div.className = 'tcw-settings-section';\r\n if (title) {\r\n const t = document.createElement('div');\r\n t.className = 'tcw-settings-section-title';\r\n t.textContent = title;\r\n div.appendChild(t);\r\n }\r\n return div;\r\n }\r\n\r\n private colorRow(label: string, value: string, onChange: (v: string) => void): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-settings-row';\r\n\r\n const lbl = document.createElement('span');\r\n lbl.className = 'tcw-settings-label';\r\n lbl.textContent = label;\r\n row.appendChild(lbl);\r\n\r\n const wrap = document.createElement('div');\r\n wrap.className = 'tcw-color-picker-wrap';\r\n\r\n const input = document.createElement('input');\r\n input.type = 'color';\r\n input.value = value;\r\n\r\n const hex = document.createElement('span');\r\n hex.className = 'tcw-color-hex';\r\n hex.textContent = value;\r\n\r\n input.addEventListener('input', () => {\r\n hex.textContent = input.value;\r\n onChange(input.value);\r\n });\r\n\r\n wrap.appendChild(input);\r\n wrap.appendChild(hex);\r\n row.appendChild(wrap);\r\n return row;\r\n }\r\n\r\n private toggleRow(label: string, value: boolean, onChange: (v: boolean) => void): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-settings-row';\r\n\r\n const lbl = document.createElement('span');\r\n lbl.className = 'tcw-settings-label';\r\n lbl.textContent = label;\r\n row.appendChild(lbl);\r\n\r\n const toggle = document.createElement('button');\r\n toggle.className = `tcw-toggle${value ? ' tcw-on' : ''}`;\r\n toggle.addEventListener('click', () => {\r\n const newVal = !toggle.classList.contains('tcw-on');\r\n toggle.classList.toggle('tcw-on', newVal);\r\n onChange(newVal);\r\n });\r\n row.appendChild(toggle);\r\n return row;\r\n }\r\n\r\n private selectRow(\r\n label: string,\r\n value: string,\r\n options: { label: string; value: string }[],\r\n onChange: (v: string) => void,\r\n ): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-settings-row';\r\n\r\n const lbl = document.createElement('span');\r\n lbl.className = 'tcw-settings-label';\r\n lbl.textContent = label;\r\n row.appendChild(lbl);\r\n\r\n const select = document.createElement('select');\r\n select.className = 'tcw-settings-select';\r\n for (const opt of options) {\r\n const o = document.createElement('option');\r\n o.value = opt.value;\r\n o.textContent = opt.label;\r\n if (opt.value === value) o.selected = true;\r\n select.appendChild(o);\r\n }\r\n select.addEventListener('change', () => onChange(select.value));\r\n row.appendChild(select);\r\n return row;\r\n }\r\n\r\n private rangeRow(\r\n label: string,\r\n value: number,\r\n min: number,\r\n max: number,\r\n step: number,\r\n onChange: (v: number) => void,\r\n format: (v: number) => string = (v) => String(v),\r\n ): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-settings-row';\r\n\r\n const lbl = document.createElement('span');\r\n lbl.className = 'tcw-settings-label';\r\n lbl.textContent = label;\r\n row.appendChild(lbl);\r\n\r\n const wrap = document.createElement('div');\r\n wrap.className = 'tcw-settings-range';\r\n\r\n const input = document.createElement('input');\r\n input.type = 'range';\r\n input.min = String(min);\r\n input.max = String(max);\r\n input.step = String(step);\r\n input.value = String(value);\r\n\r\n const out = document.createElement('span');\r\n out.className = 'tcw-settings-range-val';\r\n out.textContent = format(value);\r\n\r\n input.addEventListener('input', () => {\r\n const v = Number(input.value);\r\n out.textContent = format(v);\r\n onChange(v);\r\n });\r\n\r\n wrap.appendChild(input);\r\n wrap.appendChild(out);\r\n row.appendChild(wrap);\r\n return row;\r\n }\r\n\r\n destroy(): void {\r\n this.close();\r\n }\r\n}\r\n","export class WidgetStatusBar {\r\n private el: HTMLDivElement;\r\n private dotEl: HTMLSpanElement;\r\n private messageEl: HTMLSpanElement;\r\n private infoEl: HTMLSpanElement;\r\n\r\n constructor(host: HTMLElement) {\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-statusbar';\r\n\r\n const indicator = document.createElement('div');\r\n indicator.className = 'tcw-status-indicator';\r\n\r\n this.dotEl = document.createElement('span');\r\n this.dotEl.className = 'tcw-status-dot';\r\n indicator.appendChild(this.dotEl);\r\n\r\n this.messageEl = document.createElement('span');\r\n indicator.appendChild(this.messageEl);\r\n\r\n this.el.appendChild(indicator);\r\n\r\n this.infoEl = document.createElement('span');\r\n this.el.appendChild(this.infoEl);\r\n\r\n host.appendChild(this.el);\r\n }\r\n\r\n update(state: { connectionState: string; message: string; symbol: string; timeframe: string }): void {\r\n this.dotEl.className = 'tcw-status-dot';\r\n if (state.connectionState === 'connected') {\r\n this.dotEl.classList.add('tcw-connected');\r\n } else if (state.connectionState === 'error') {\r\n this.dotEl.classList.add('tcw-error');\r\n }\r\n\r\n this.messageEl.textContent = state.message;\r\n this.infoEl.textContent = `${state.symbol} ${state.timeframe}`;\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n }\r\n}\r\n","import type { ChartType, DrawingToolType, TimeFrame } from '@tradecanvas/commons';\r\n\r\nexport interface CommandItem {\r\n id: string;\r\n label: string;\r\n category: 'indicator' | 'chartType' | 'drawing' | 'timeframe' | 'action';\r\n shortcut?: string;\r\n active?: boolean;\r\n}\r\n\r\nexport interface CommandPaletteCallbacks {\r\n onIndicator: (id: string) => void;\r\n onChartType: (type: ChartType) => void;\r\n onDrawingTool: (tool: DrawingToolType) => void;\r\n onTimeframe: (tf: TimeFrame) => void;\r\n onAction: (id: string) => void;\r\n onClose: () => void;\r\n}\r\n\r\nexport class WidgetCommandPalette {\r\n private backdrop: HTMLDivElement | null = null;\r\n private modal: HTMLDivElement | null = null;\r\n private input: HTMLInputElement | null = null;\r\n private list: HTMLDivElement | null = null;\r\n private items: CommandItem[] = [];\r\n private filtered: CommandItem[] = [];\r\n private selectedIndex = 0;\r\n private callbacks: CommandPaletteCallbacks;\r\n private boundKeydown: (e: KeyboardEvent) => void;\r\n\r\n constructor(callbacks: CommandPaletteCallbacks) {\r\n this.callbacks = callbacks;\r\n this.boundKeydown = this.handleKeydown.bind(this);\r\n }\r\n\r\n open(items: CommandItem[]): void {\r\n if (this.backdrop) return;\r\n this.items = items;\r\n this.filtered = items;\r\n this.selectedIndex = 0;\r\n\r\n this.backdrop = document.createElement('div');\r\n this.backdrop.className = 'tcw-modal-backdrop';\r\n this.backdrop.addEventListener('click', () => this.close());\r\n\r\n this.modal = document.createElement('div');\r\n this.modal.className = 'tcw-cmd-palette';\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-cmd-header';\r\n\r\n const searchIcon = document.createElement('span');\r\n searchIcon.className = 'tcw-cmd-icon';\r\n searchIcon.textContent = '⌕';\r\n header.appendChild(searchIcon);\r\n\r\n this.input = document.createElement('input');\r\n this.input.className = 'tcw-cmd-input';\r\n this.input.type = 'text';\r\n this.input.placeholder = 'Search indicators, chart types, tools...';\r\n this.input.addEventListener('input', () => this.filter());\r\n header.appendChild(this.input);\r\n\r\n const hint = document.createElement('span');\r\n hint.className = 'tcw-cmd-hint';\r\n hint.textContent = 'ESC';\r\n header.appendChild(hint);\r\n\r\n this.modal.appendChild(header);\r\n\r\n this.list = document.createElement('div');\r\n this.list.className = 'tcw-cmd-list';\r\n this.modal.appendChild(this.list);\r\n\r\n const footer = document.createElement('div');\r\n footer.className = 'tcw-cmd-footer';\r\n footer.innerHTML = '<span>↑↓ Navigate</span><span>⏎ Select</span><span>Esc Close</span>';\r\n this.modal.appendChild(footer);\r\n\r\n document.body.appendChild(this.backdrop);\r\n document.body.appendChild(this.modal);\r\n\r\n this.renderList();\r\n this.input.focus();\r\n document.addEventListener('keydown', this.boundKeydown);\r\n }\r\n\r\n close(): void {\r\n document.removeEventListener('keydown', this.boundKeydown);\r\n this.backdrop?.remove();\r\n this.modal?.remove();\r\n this.backdrop = null;\r\n this.modal = null;\r\n this.input = null;\r\n this.list = null;\r\n this.callbacks.onClose();\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.backdrop !== null;\r\n }\r\n\r\n private filter(): void {\r\n const query = this.input?.value.toLowerCase().trim() ?? '';\r\n if (!query) {\r\n this.filtered = this.items;\r\n } else {\r\n this.filtered = this.items.filter(item =>\r\n item.label.toLowerCase().includes(query) ||\r\n item.category.toLowerCase().includes(query) ||\r\n item.id.toLowerCase().includes(query),\r\n );\r\n }\r\n this.selectedIndex = 0;\r\n this.renderList();\r\n }\r\n\r\n private renderList(): void {\r\n if (!this.list) return;\r\n this.list.innerHTML = '';\r\n\r\n if (this.filtered.length === 0) {\r\n const empty = document.createElement('div');\r\n empty.className = 'tcw-cmd-empty';\r\n empty.textContent = 'No results found';\r\n this.list.appendChild(empty);\r\n return;\r\n }\r\n\r\n let currentCategory = '';\r\n for (let i = 0; i < this.filtered.length; i++) {\r\n const item = this.filtered[i];\r\n\r\n if (item.category !== currentCategory) {\r\n currentCategory = item.category;\r\n const label = document.createElement('div');\r\n label.className = 'tcw-cmd-category';\r\n label.textContent = this.categoryLabel(currentCategory);\r\n this.list.appendChild(label);\r\n }\r\n\r\n const row = document.createElement('button');\r\n row.className = 'tcw-cmd-item';\r\n if (i === this.selectedIndex) row.classList.add('tcw-selected');\r\n if (item.active) row.classList.add('tcw-active');\r\n row.dataset.index = String(i);\r\n\r\n const nameSpan = document.createElement('span');\r\n nameSpan.className = 'tcw-cmd-item-label';\r\n nameSpan.textContent = item.label;\r\n row.appendChild(nameSpan);\r\n\r\n if (item.active) {\r\n const check = document.createElement('span');\r\n check.className = 'tcw-cmd-check';\r\n check.textContent = '✓';\r\n row.appendChild(check);\r\n }\r\n\r\n if (item.shortcut) {\r\n const kbd = document.createElement('kbd');\r\n kbd.className = 'tcw-cmd-kbd';\r\n kbd.textContent = item.shortcut;\r\n row.appendChild(kbd);\r\n }\r\n\r\n row.addEventListener('click', () => this.select(i));\r\n row.addEventListener('mouseenter', () => {\r\n this.selectedIndex = i;\r\n this.updateSelection();\r\n });\r\n\r\n this.list.appendChild(row);\r\n }\r\n }\r\n\r\n private updateSelection(): void {\r\n if (!this.list) return;\r\n const items = this.list.querySelectorAll('.tcw-cmd-item');\r\n items.forEach((el, i) => {\r\n el.classList.toggle('tcw-selected', i === this.selectedIndex);\r\n });\r\n items[this.selectedIndex]?.scrollIntoView({ block: 'nearest' });\r\n }\r\n\r\n private select(index: number): void {\r\n const item = this.filtered[index];\r\n if (!item) return;\r\n\r\n switch (item.category) {\r\n case 'indicator':\r\n this.callbacks.onIndicator(item.id);\r\n break;\r\n case 'chartType':\r\n this.callbacks.onChartType(item.id as ChartType);\r\n break;\r\n case 'drawing':\r\n this.callbacks.onDrawingTool(item.id as DrawingToolType);\r\n break;\r\n case 'timeframe':\r\n this.callbacks.onTimeframe(item.id as TimeFrame);\r\n break;\r\n case 'action':\r\n this.callbacks.onAction(item.id);\r\n break;\r\n }\r\n this.close();\r\n }\r\n\r\n private handleKeydown(e: KeyboardEvent): void {\r\n switch (e.key) {\r\n case 'Escape':\r\n e.preventDefault();\r\n this.close();\r\n break;\r\n case 'ArrowDown':\r\n e.preventDefault();\r\n if (this.filtered.length > 0) {\r\n this.selectedIndex = (this.selectedIndex + 1) % this.filtered.length;\r\n this.updateSelection();\r\n }\r\n break;\r\n case 'ArrowUp':\r\n e.preventDefault();\r\n if (this.filtered.length > 0) {\r\n this.selectedIndex = (this.selectedIndex - 1 + this.filtered.length) % this.filtered.length;\r\n this.updateSelection();\r\n }\r\n break;\r\n case 'Enter':\r\n e.preventDefault();\r\n this.select(this.selectedIndex);\r\n break;\r\n }\r\n }\r\n\r\n private categoryLabel(cat: string): string {\r\n switch (cat) {\r\n case 'indicator': return 'Indicators';\r\n case 'chartType': return 'Chart Types';\r\n case 'drawing': return 'Drawing Tools';\r\n case 'timeframe': return 'Timeframes';\r\n case 'action': return 'Actions';\r\n default: return cat;\r\n }\r\n }\r\n\r\n destroy(): void {\r\n this.close();\r\n }\r\n}\r\n","/**\r\n * Lightweight fuzzy symbol picker. Reuses the command-palette CSS for visual\r\n * consistency. Scoring is a cheap subsequence match — good enough for symbol\r\n * lists in the low thousands without pulling in a fuzzy-search dependency.\r\n */\r\nexport interface SymbolSearchCallbacks {\r\n onPick: (symbol: string) => void;\r\n onClose: () => void;\r\n}\r\n\r\ninterface ScoredSymbol {\r\n symbol: string;\r\n score: number;\r\n}\r\n\r\nexport class WidgetSymbolSearch {\r\n private backdrop: HTMLDivElement | null = null;\r\n private modal: HTMLDivElement | null = null;\r\n private input: HTMLInputElement | null = null;\r\n private list: HTMLDivElement | null = null;\r\n private symbols: string[] = [];\r\n private current: string = '';\r\n private filtered: ScoredSymbol[] = [];\r\n private selectedIndex = 0;\r\n private callbacks: SymbolSearchCallbacks;\r\n private boundKeydown: (e: KeyboardEvent) => void;\r\n /** One-shot pick override — when set, this open() routes picks here instead. */\r\n private pickOverride: ((symbol: string) => void) | null = null;\r\n\r\n constructor(callbacks: SymbolSearchCallbacks) {\r\n this.callbacks = callbacks;\r\n this.boundKeydown = this.handleKeydown.bind(this);\r\n }\r\n\r\n open(symbols: string[], current: string, onPick?: (symbol: string) => void): void {\r\n if (this.backdrop) return;\r\n this.pickOverride = onPick ?? null;\r\n this.symbols = symbols;\r\n this.current = current;\r\n this.filtered = symbols.map(s => ({ symbol: s, score: 0 }));\r\n this.selectedIndex = Math.max(0, symbols.indexOf(current));\r\n\r\n this.backdrop = document.createElement('div');\r\n this.backdrop.className = 'tcw-modal-backdrop';\r\n this.backdrop.addEventListener('click', () => this.close());\r\n\r\n this.modal = document.createElement('div');\r\n this.modal.className = 'tcw-cmd-palette';\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-cmd-header';\r\n\r\n const icon = document.createElement('span');\r\n icon.className = 'tcw-cmd-icon';\r\n icon.innerHTML = svgSearch();\r\n header.appendChild(icon);\r\n\r\n this.input = document.createElement('input');\r\n this.input.className = 'tcw-cmd-input';\r\n this.input.type = 'text';\r\n this.input.placeholder = 'Search symbol… (e.g. BTC, ETH, AAPL)';\r\n this.input.autocomplete = 'off';\r\n this.input.spellcheck = false;\r\n this.input.addEventListener('input', () => this.filter());\r\n header.appendChild(this.input);\r\n\r\n const hint = document.createElement('span');\r\n hint.className = 'tcw-cmd-hint';\r\n hint.textContent = 'ESC';\r\n header.appendChild(hint);\r\n\r\n this.modal.appendChild(header);\r\n\r\n this.list = document.createElement('div');\r\n this.list.className = 'tcw-cmd-list';\r\n this.modal.appendChild(this.list);\r\n\r\n const footer = document.createElement('div');\r\n footer.className = 'tcw-cmd-footer';\r\n footer.innerHTML = '<span>↑↓ Navigate</span><span>⏎ Open</span><span>Esc Close</span>';\r\n this.modal.appendChild(footer);\r\n\r\n document.body.appendChild(this.backdrop);\r\n document.body.appendChild(this.modal);\r\n\r\n this.renderList();\r\n this.input.focus();\r\n document.addEventListener('keydown', this.boundKeydown);\r\n }\r\n\r\n close(): void {\r\n document.removeEventListener('keydown', this.boundKeydown);\r\n this.backdrop?.remove();\r\n this.modal?.remove();\r\n this.backdrop = null;\r\n this.modal = null;\r\n this.input = null;\r\n this.list = null;\r\n this.pickOverride = null;\r\n this.callbacks.onClose();\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.backdrop !== null;\r\n }\r\n\r\n destroy(): void {\r\n this.close();\r\n }\r\n\r\n private filter(): void {\r\n const q = (this.input?.value ?? '').toUpperCase().trim();\r\n if (!q) {\r\n this.filtered = this.symbols.map(s => ({ symbol: s, score: 0 }));\r\n } else {\r\n this.filtered = this.symbols\r\n .map(s => ({ symbol: s, score: scoreMatch(s.toUpperCase(), q) }))\r\n .filter(r => r.score > 0)\r\n .sort((a, b) => b.score - a.score);\r\n }\r\n this.selectedIndex = 0;\r\n this.renderList();\r\n }\r\n\r\n private renderList(): void {\r\n if (!this.list) return;\r\n this.list.innerHTML = '';\r\n\r\n if (this.filtered.length === 0) {\r\n const empty = document.createElement('div');\r\n empty.className = 'tcw-cmd-empty';\r\n empty.textContent = 'No symbols match';\r\n this.list.appendChild(empty);\r\n return;\r\n }\r\n\r\n const query = (this.input?.value ?? '').toUpperCase().trim();\r\n for (let i = 0; i < this.filtered.length; i++) {\r\n const { symbol } = this.filtered[i];\r\n const row = document.createElement('button');\r\n row.className = 'tcw-cmd-item';\r\n if (i === this.selectedIndex) row.classList.add('tcw-selected');\r\n if (symbol === this.current) row.classList.add('tcw-active');\r\n\r\n const label = document.createElement('span');\r\n label.className = 'tcw-cmd-item-label';\r\n label.innerHTML = highlight(symbol, query);\r\n row.appendChild(label);\r\n\r\n if (symbol === this.current) {\r\n const check = document.createElement('span');\r\n check.className = 'tcw-cmd-check';\r\n check.textContent = '✓';\r\n row.appendChild(check);\r\n }\r\n\r\n row.addEventListener('click', () => this.pick(i));\r\n row.addEventListener('mouseenter', () => {\r\n this.selectedIndex = i;\r\n this.updateSelection();\r\n });\r\n\r\n this.list.appendChild(row);\r\n }\r\n }\r\n\r\n private updateSelection(): void {\r\n if (!this.list) return;\r\n const items = this.list.querySelectorAll('.tcw-cmd-item');\r\n items.forEach((el, i) => el.classList.toggle('tcw-selected', i === this.selectedIndex));\r\n items[this.selectedIndex]?.scrollIntoView({ block: 'nearest' });\r\n }\r\n\r\n private pick(index: number): void {\r\n const entry = this.filtered[index];\r\n if (!entry) return;\r\n const override = this.pickOverride;\r\n if (override) override(entry.symbol);\r\n else this.callbacks.onPick(entry.symbol);\r\n this.close();\r\n }\r\n\r\n private handleKeydown(e: KeyboardEvent): void {\r\n switch (e.key) {\r\n case 'Escape':\r\n e.preventDefault();\r\n this.close();\r\n break;\r\n case 'ArrowDown':\r\n e.preventDefault();\r\n if (this.filtered.length > 0) {\r\n this.selectedIndex = (this.selectedIndex + 1) % this.filtered.length;\r\n this.updateSelection();\r\n }\r\n break;\r\n case 'ArrowUp':\r\n e.preventDefault();\r\n if (this.filtered.length > 0) {\r\n this.selectedIndex = (this.selectedIndex - 1 + this.filtered.length) % this.filtered.length;\r\n this.updateSelection();\r\n }\r\n break;\r\n case 'Enter':\r\n e.preventDefault();\r\n this.pick(this.selectedIndex);\r\n break;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Cheap fuzzy score:\r\n * exact match → 1000\r\n * starts-with → 500 + tighter-prefix bonus\r\n * subsequence match → 100 − gap penalty\r\n * no match → 0\r\n */\r\nfunction scoreMatch(symbol: string, query: string): number {\r\n if (symbol === query) return 1000;\r\n if (symbol.startsWith(query)) return 500 + (50 - Math.min(50, symbol.length - query.length));\r\n if (symbol.includes(query)) return 200 + (50 - Math.min(50, symbol.length - query.length));\r\n\r\n let qi = 0;\r\n let lastIdx = -1;\r\n let gapPenalty = 0;\r\n for (let i = 0; i < symbol.length && qi < query.length; i++) {\r\n if (symbol[i] === query[qi]) {\r\n if (lastIdx >= 0) gapPenalty += i - lastIdx - 1;\r\n lastIdx = i;\r\n qi++;\r\n }\r\n }\r\n if (qi < query.length) return 0;\r\n return 100 - Math.min(99, gapPenalty);\r\n}\r\n\r\nfunction highlight(symbol: string, query: string): string {\r\n if (!query) return escapeHtml(symbol);\r\n const upper = symbol.toUpperCase();\r\n let out = '';\r\n let qi = 0;\r\n for (let i = 0; i < symbol.length; i++) {\r\n if (qi < query.length && upper[i] === query[qi]) {\r\n out += `<mark style=\"background:transparent;color:var(--tcw-accent);font-weight:700\">${escapeHtml(symbol[i])}</mark>`;\r\n qi++;\r\n } else {\r\n out += escapeHtml(symbol[i]);\r\n }\r\n }\r\n return out;\r\n}\r\n\r\nfunction escapeHtml(s: string): string {\r\n return s.replace(/[&<>\"']/g, ch => ({\r\n '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''',\r\n } as Record<string, string>)[ch]);\r\n}\r\n\r\nfunction svgSearch(): string {\r\n return '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"/><path d=\"m21 21-4.3-4.3\"/></svg>';\r\n}\r\n","import type { MessageKey, Translator } from './i18n.js';\r\n\r\n/**\r\n * Keyboard-shortcut reference sheet. Bound to `?` (and `Shift+/`). Surfaces\r\n * shortcuts so users discover the widget's hidden interaction model — a\r\n * premium-feel detail TradingView, Linear, Figma, etc. all ship.\r\n */\r\nexport interface HotkeySheetCallbacks {\r\n onClose: () => void;\r\n}\r\n\r\n// Group titles translate via this lookup; individual shortcut labels (and\r\n// the `keys` badges) stay English for now — see README \"Widget i18n\".\r\nconst GROUP_TITLE_KEYS: Record<string, MessageKey> = {\r\n 'Search & navigation': 'hotkeys.group.searchNavigation',\r\n 'Chart manipulation': 'hotkeys.group.chartManipulation',\r\n 'Touch (mobile / tablet)': 'hotkeys.group.touch',\r\n 'Keyboard': 'hotkeys.group.keyboard',\r\n 'Drawing': 'hotkeys.group.drawing',\r\n};\r\n\r\ninterface HotkeyEntry {\r\n keys: string[];\r\n label: string;\r\n}\r\n\r\ninterface HotkeyGroup {\r\n title: string;\r\n entries: HotkeyEntry[];\r\n}\r\n\r\nconst isMac =\r\n typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\r\nconst mod = isMac ? '⌘' : 'Ctrl';\r\n\r\nconst GROUPS: HotkeyGroup[] = [\r\n {\r\n title: 'Search & navigation',\r\n entries: [\r\n { keys: [mod, 'K'], label: 'Command palette' },\r\n { keys: [mod, 'P'], label: 'Symbol search' },\r\n { keys: ['?'], label: 'Show this sheet' },\r\n ],\r\n },\r\n {\r\n title: 'Chart manipulation',\r\n entries: [\r\n { keys: ['Shift', 'Drag'], label: 'Measure tool (bars × price Δ)' },\r\n { keys: ['Drag', 'Price axis'], label: 'Compress / expand vertical scale' },\r\n { keys: ['Drag', 'Time axis'], label: 'Zoom time axis' },\r\n { keys: ['Double-click', 'Price axis'], label: 'Re-enable auto-scale' },\r\n { keys: ['Double-click', 'Time axis'], label: 'Fit content' },\r\n { keys: ['Scroll'], label: 'Zoom around cursor' },\r\n ],\r\n },\r\n {\r\n title: 'Touch (mobile / tablet)',\r\n entries: [\r\n { keys: ['1 finger', 'Drag'], label: 'Pan / move crosshair' },\r\n { keys: ['2 fingers', 'Pinch'], label: 'Zoom around midpoint' },\r\n { keys: ['Long-press'], label: 'Pin OHLC tooltip at bar' },\r\n { keys: ['Drag', 'Axis strip'], label: 'Scale price / time axis' },\r\n ],\r\n },\r\n {\r\n title: 'Keyboard',\r\n entries: [\r\n { keys: ['←', '→'], label: 'Pan one bar' },\r\n { keys: ['+', '−'], label: 'Zoom in / out' },\r\n { keys: ['Home'], label: 'Scroll to start' },\r\n { keys: ['End'], label: 'Scroll to end (live edge)' },\r\n { keys: ['F'], label: 'Fit content' },\r\n ],\r\n },\r\n {\r\n title: 'Drawing',\r\n entries: [\r\n { keys: [mod, 'Z'], label: 'Undo' },\r\n { keys: [mod, 'Shift', 'Z'], label: 'Redo' },\r\n { keys: ['Esc'], label: 'Cancel active drawing' },\r\n ],\r\n },\r\n];\r\n\r\nexport class WidgetHotkeySheet {\r\n private backdrop: HTMLDivElement | null = null;\r\n private modal: HTMLDivElement | null = null;\r\n private callbacks: HotkeySheetCallbacks;\r\n private t: Translator;\r\n private boundKeydown: (e: KeyboardEvent) => void;\r\n\r\n constructor(callbacks: HotkeySheetCallbacks, t: Translator) {\r\n this.callbacks = callbacks;\r\n this.t = t;\r\n this.boundKeydown = (e) => {\r\n if (e.key === 'Escape') {\r\n e.preventDefault();\r\n this.close();\r\n }\r\n };\r\n }\r\n\r\n open(): void {\r\n if (this.backdrop) return;\r\n\r\n this.backdrop = document.createElement('div');\r\n this.backdrop.className = 'tcw-modal-backdrop';\r\n this.backdrop.addEventListener('click', () => this.close());\r\n\r\n this.modal = document.createElement('div');\r\n this.modal.className = 'tcw-modal tcw-hotkey-sheet';\r\n this.modal.style.width = '640px';\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-modal-header';\r\n header.innerHTML = `<h3>${this.t('hotkeys.title')}</h3>`;\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'tcw-modal-close';\r\n closeBtn.setAttribute('aria-label', this.t('hotkeys.close'));\r\n closeBtn.innerHTML = '×';\r\n closeBtn.addEventListener('click', () => this.close());\r\n header.appendChild(closeBtn);\r\n this.modal.appendChild(header);\r\n\r\n const body = document.createElement('div');\r\n body.className = 'tcw-modal-body';\r\n\r\n const grid = document.createElement('div');\r\n grid.className = 'tcw-hotkey-grid';\r\n\r\n for (const group of GROUPS) {\r\n const section = document.createElement('section');\r\n section.className = 'tcw-hotkey-section';\r\n const title = document.createElement('div');\r\n title.className = 'tcw-settings-section-title';\r\n const titleKey = GROUP_TITLE_KEYS[group.title];\r\n title.textContent = titleKey ? this.t(titleKey) : group.title;\r\n section.appendChild(title);\r\n\r\n for (const entry of group.entries) {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-hotkey-row';\r\n\r\n const keys = document.createElement('div');\r\n keys.className = 'tcw-hotkey-keys';\r\n for (let i = 0; i < entry.keys.length; i++) {\r\n if (i > 0) {\r\n const plus = document.createElement('span');\r\n plus.className = 'tcw-hotkey-sep';\r\n plus.textContent = '+';\r\n keys.appendChild(plus);\r\n }\r\n const kbd = document.createElement('kbd');\r\n kbd.className = 'tcw-cmd-kbd';\r\n kbd.textContent = entry.keys[i];\r\n keys.appendChild(kbd);\r\n }\r\n row.appendChild(keys);\r\n\r\n const label = document.createElement('span');\r\n label.className = 'tcw-hotkey-label';\r\n label.textContent = entry.label;\r\n row.appendChild(label);\r\n\r\n section.appendChild(row);\r\n }\r\n\r\n grid.appendChild(section);\r\n }\r\n\r\n body.appendChild(grid);\r\n this.modal.appendChild(body);\r\n\r\n const footer = document.createElement('div');\r\n footer.className = 'tcw-modal-footer';\r\n footer.innerHTML = '<span style=\"font-size:11px;color:var(--tcw-text-muted)\">Press ? anytime to show this sheet</span>';\r\n const ok = document.createElement('button');\r\n ok.className = 'tcw-done-btn';\r\n ok.textContent = this.t('hotkeys.gotIt');\r\n ok.addEventListener('click', () => this.close());\r\n footer.appendChild(ok);\r\n this.modal.appendChild(footer);\r\n\r\n document.body.appendChild(this.backdrop);\r\n document.body.appendChild(this.modal);\r\n\r\n document.addEventListener('keydown', this.boundKeydown);\r\n }\r\n\r\n close(): void {\r\n document.removeEventListener('keydown', this.boundKeydown);\r\n this.backdrop?.remove();\r\n this.modal?.remove();\r\n this.backdrop = null;\r\n this.modal = null;\r\n this.callbacks.onClose();\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.backdrop !== null;\r\n }\r\n\r\n destroy(): void {\r\n this.close();\r\n }\r\n}\r\n","/**\r\n * Replay scrubber bar — surfaces the chart's existing replay engine as a\r\n * visible bottom-of-chart control. Mounts under the chart container, owns\r\n * its own lifecycle, and reports user intent up via callbacks (no chart\r\n * coupling — the host calls chart.replayStart() / replayPause() / etc.).\r\n */\r\nexport interface ReplayBarCallbacks {\r\n onPlay: () => void;\r\n onPause: () => void;\r\n onStop: () => void;\r\n onStepBack: () => void;\r\n onStepForward: () => void;\r\n onSeek: (index: number) => void;\r\n onSpeedChange: (barsPerSecond: number) => void;\r\n onClose: () => void;\r\n}\r\n\r\nexport type ReplayBarState = 'playing' | 'paused' | 'stopped';\r\n\r\nconst SPEEDS = [0.5, 1, 2, 5, 10, 20, 50, 100];\r\n\r\nexport class WidgetReplayBar {\r\n private root: HTMLDivElement | null = null;\r\n private scrubber: HTMLInputElement | null = null;\r\n private progressLabel: HTMLSpanElement | null = null;\r\n private playBtn: HTMLButtonElement | null = null;\r\n private state: ReplayBarState = 'stopped';\r\n private total = 0;\r\n private speed = 5;\r\n private callbacks: ReplayBarCallbacks;\r\n\r\n constructor(callbacks: ReplayBarCallbacks) {\r\n this.callbacks = callbacks;\r\n }\r\n\r\n mount(host: HTMLElement, opts: { total: number; speed?: number }): void {\r\n if (this.root) return;\r\n this.total = Math.max(0, opts.total);\r\n this.speed = opts.speed ?? 5;\r\n this.state = 'paused';\r\n\r\n this.root = document.createElement('div');\r\n this.root.className = 'tcw-replay-bar';\r\n this.root.innerHTML = this.markup();\r\n\r\n host.appendChild(this.root);\r\n this.wireEvents();\r\n this.syncUi();\r\n }\r\n\r\n unmount(): void {\r\n this.root?.remove();\r\n this.root = null;\r\n this.scrubber = null;\r\n this.progressLabel = null;\r\n this.playBtn = null;\r\n this.state = 'stopped';\r\n }\r\n\r\n isMounted(): boolean {\r\n return this.root !== null;\r\n }\r\n\r\n setState(state: ReplayBarState): void {\r\n this.state = state;\r\n this.syncUi();\r\n }\r\n\r\n setProgress(current: number, total: number): void {\r\n this.total = total;\r\n if (this.scrubber) {\r\n this.scrubber.max = String(Math.max(0, total - 1));\r\n this.scrubber.value = String(current);\r\n }\r\n if (this.progressLabel) {\r\n this.progressLabel.textContent = `${current + 1} / ${total}`;\r\n }\r\n }\r\n\r\n destroy(): void {\r\n this.unmount();\r\n }\r\n\r\n private markup(): string {\r\n const speeds = SPEEDS.map(s => `<option value=\"${s}\"${s === this.speed ? ' selected' : ''}>${s}× bars/s</option>`).join('');\r\n return `\r\n <button class=\"tcw-replay-btn\" data-act=\"close\" title=\"Exit replay\" aria-label=\"Exit replay\">${svgX()}</button>\r\n <button class=\"tcw-replay-btn\" data-act=\"stepBack\" title=\"Step back\" aria-label=\"Step back\">${svgStepBack()}</button>\r\n <button class=\"tcw-replay-btn tcw-replay-play\" data-act=\"play\" title=\"Play / pause\" aria-label=\"Play / pause\">${svgPlay()}</button>\r\n <button class=\"tcw-replay-btn\" data-act=\"stepForward\" title=\"Step forward\" aria-label=\"Step forward\">${svgStepForward()}</button>\r\n <input type=\"range\" class=\"tcw-replay-scrubber\" data-act=\"seek\" min=\"0\" max=\"${Math.max(0, this.total - 1)}\" value=\"0\" step=\"1\" />\r\n <span class=\"tcw-replay-progress\" data-tcw=\"progress\">1 / ${this.total}</span>\r\n <select class=\"tcw-replay-speed\" data-act=\"speed\">${speeds}</select>\r\n `;\r\n }\r\n\r\n private wireEvents(): void {\r\n if (!this.root) return;\r\n this.scrubber = this.root.querySelector('input[data-act=\"seek\"]');\r\n this.progressLabel = this.root.querySelector('[data-tcw=\"progress\"]');\r\n this.playBtn = this.root.querySelector('button[data-act=\"play\"]');\r\n\r\n this.root.querySelector('[data-act=\"close\"]')?.addEventListener('click', () => this.callbacks.onClose());\r\n this.root.querySelector('[data-act=\"stepBack\"]')?.addEventListener('click', () => this.callbacks.onStepBack());\r\n this.root.querySelector('[data-act=\"stepForward\"]')?.addEventListener('click', () => this.callbacks.onStepForward());\r\n this.playBtn?.addEventListener('click', () => {\r\n if (this.state === 'playing') {\r\n this.callbacks.onPause();\r\n } else {\r\n this.callbacks.onPlay();\r\n }\r\n });\r\n this.scrubber?.addEventListener('input', () => {\r\n const idx = Number(this.scrubber!.value);\r\n this.callbacks.onSeek(idx);\r\n });\r\n (this.root.querySelector('[data-act=\"speed\"]') as HTMLSelectElement | null)?.addEventListener('change', (e) => {\r\n const v = Number((e.target as HTMLSelectElement).value);\r\n this.speed = v;\r\n this.callbacks.onSpeedChange(v);\r\n });\r\n }\r\n\r\n private syncUi(): void {\r\n if (!this.playBtn) return;\r\n this.playBtn.innerHTML = this.state === 'playing' ? svgPause() : svgPlay();\r\n this.playBtn.title = this.state === 'playing' ? 'Pause' : 'Play';\r\n }\r\n}\r\n\r\nfunction svgPlay(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7L8 5z\"/></svg>';\r\n}\r\nfunction svgPause(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/></svg>';\r\n}\r\nfunction svgStepBack(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 6h2v12H6zM20 6L9 12l11 6V6z\"/></svg>';\r\n}\r\nfunction svgStepForward(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M4 6l11 6L4 18V6zM16 6h2v12h-2z\"/></svg>';\r\n}\r\nfunction svgX(): string {\r\n return '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6L6 18M6 6l12 12\"/></svg>';\r\n}\r\n","/**\r\n * Watchlist sidebar — vertical list of symbols, each with last price, %\r\n * change, and a mini sparkline. Clicking switches the chart's symbol.\r\n *\r\n * The widget tracks the *active* symbol's price/spark automatically from the\r\n * live stream. For non-active symbols, the host can push data via\r\n * `setEntry(symbol, …)` so the row reflects whatever the app already has.\r\n */\r\nexport interface WatchlistEntry {\r\n symbol: string;\r\n lastPrice?: number;\r\n /** Reference price for % calc (usually session open or 24h-ago close). */\r\n refPrice?: number;\r\n /** Recent close samples for the sparkline — last point is the live price. */\r\n sparkline?: number[];\r\n}\r\n\r\nexport interface WatchlistCallbacks {\r\n onSelect: (symbol: string) => void;\r\n}\r\n\r\nexport class WidgetWatchlist {\r\n private el: HTMLDivElement;\r\n private listEl: HTMLDivElement;\r\n private rowMap = new Map<string, {\r\n row: HTMLDivElement;\r\n priceEl: HTMLSpanElement;\r\n changeEl: HTMLSpanElement;\r\n sparkCanvas: HTMLCanvasElement;\r\n }>();\r\n private entries = new Map<string, WatchlistEntry>();\r\n private active: string | null = null;\r\n private callbacks: WatchlistCallbacks;\r\n private locale: string | undefined;\r\n\r\n constructor(host: HTMLElement, symbols: string[], callbacks: WatchlistCallbacks, title = 'Watchlist') {\r\n this.callbacks = callbacks;\r\n\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-watchlist';\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-watchlist-header';\r\n header.textContent = title;\r\n this.el.appendChild(header);\r\n\r\n this.listEl = document.createElement('div');\r\n this.listEl.className = 'tcw-watchlist-list';\r\n this.el.appendChild(this.listEl);\r\n\r\n for (const symbol of symbols) {\r\n this.entries.set(symbol, { symbol });\r\n this.appendRow(symbol);\r\n }\r\n\r\n host.appendChild(this.el);\r\n }\r\n\r\n /** Set the BCP 47 locale used for price/percent formatting. */\r\n setLocale(locale: string | undefined): void {\r\n this.locale = locale;\r\n for (const symbol of this.entries.keys()) this.renderRow(symbol);\r\n }\r\n\r\n /** Replace the symbol set. Rows are diff'd so DOM churn is minimal. */\r\n setSymbols(symbols: string[]): void {\r\n const next = new Set(symbols);\r\n for (const sym of this.rowMap.keys()) {\r\n if (!next.has(sym)) this.removeRow(sym);\r\n }\r\n for (const sym of symbols) {\r\n if (!this.rowMap.has(sym)) {\r\n this.entries.set(sym, this.entries.get(sym) ?? { symbol: sym });\r\n this.appendRow(sym);\r\n }\r\n }\r\n }\r\n\r\n setActive(symbol: string): void {\r\n if (this.active === symbol) return;\r\n if (this.active && this.rowMap.has(this.active)) {\r\n this.rowMap.get(this.active)!.row.classList.remove('tcw-watchlist-active');\r\n }\r\n this.active = symbol;\r\n const cur = this.rowMap.get(symbol);\r\n if (cur) cur.row.classList.add('tcw-watchlist-active');\r\n }\r\n\r\n /** Push a price tick into a row. The widget calls this automatically for\r\n * the active symbol. Apps can call it for the rest. */\r\n setEntry(symbol: string, patch: Partial<WatchlistEntry>): void {\r\n const prev = this.entries.get(symbol) ?? { symbol };\r\n const next = { ...prev, ...patch };\r\n this.entries.set(symbol, next);\r\n this.renderRow(symbol);\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n this.rowMap.clear();\r\n this.entries.clear();\r\n }\r\n\r\n private appendRow(symbol: string): void {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-watchlist-row';\r\n row.tabIndex = 0;\r\n\r\n const label = document.createElement('div');\r\n label.className = 'tcw-watchlist-symbol';\r\n label.textContent = formatSymbol(symbol);\r\n\r\n const spark = document.createElement('canvas');\r\n spark.className = 'tcw-watchlist-spark';\r\n spark.width = 64;\r\n spark.height = 22;\r\n\r\n const right = document.createElement('div');\r\n right.className = 'tcw-watchlist-stats';\r\n const priceEl = document.createElement('span');\r\n priceEl.className = 'tcw-watchlist-price';\r\n priceEl.textContent = '—';\r\n const changeEl = document.createElement('span');\r\n changeEl.className = 'tcw-watchlist-change';\r\n changeEl.textContent = '';\r\n right.appendChild(priceEl);\r\n right.appendChild(changeEl);\r\n\r\n row.appendChild(label);\r\n row.appendChild(spark);\r\n row.appendChild(right);\r\n\r\n row.addEventListener('click', () => this.callbacks.onSelect(symbol));\r\n row.addEventListener('keydown', (e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n this.callbacks.onSelect(symbol);\r\n }\r\n });\r\n\r\n this.listEl.appendChild(row);\r\n this.rowMap.set(symbol, { row, priceEl, changeEl, sparkCanvas: spark });\r\n if (symbol === this.active) row.classList.add('tcw-watchlist-active');\r\n }\r\n\r\n private removeRow(symbol: string): void {\r\n const ref = this.rowMap.get(symbol);\r\n if (!ref) return;\r\n ref.row.remove();\r\n this.rowMap.delete(symbol);\r\n }\r\n\r\n private renderRow(symbol: string): void {\r\n const ref = this.rowMap.get(symbol);\r\n const entry = this.entries.get(symbol);\r\n if (!ref || !entry) return;\r\n\r\n if (entry.lastPrice !== undefined) {\r\n ref.priceEl.textContent = formatPrice(entry.lastPrice, this.locale);\r\n }\r\n\r\n if (entry.lastPrice !== undefined && entry.refPrice !== undefined && entry.refPrice !== 0) {\r\n const diff = entry.lastPrice - entry.refPrice;\r\n const pct = (diff / entry.refPrice) * 100;\r\n const sign = diff >= 0 ? '+' : '-';\r\n const pctText = Math.abs(pct).toLocaleString(this.locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 });\r\n ref.changeEl.textContent = `${sign}${pctText}%`;\r\n ref.changeEl.className = `tcw-watchlist-change ${diff >= 0 ? 'tcw-up' : 'tcw-down'}`;\r\n } else {\r\n ref.changeEl.textContent = '';\r\n }\r\n\r\n if (entry.sparkline && entry.sparkline.length >= 2) {\r\n drawSparkline(ref.sparkCanvas, entry.sparkline, entry.refPrice ?? entry.sparkline[0]);\r\n }\r\n }\r\n}\r\n\r\nfunction formatSymbol(symbol: string): string {\r\n // Add a / separator for typical crypto pair suffixes; leaves stock tickers\r\n // (AAPL, NVDA) alone.\r\n for (const quote of ['USDT', 'USD', 'BTC', 'ETH', 'EUR']) {\r\n if (symbol.length > quote.length && symbol.endsWith(quote)) {\r\n return symbol.slice(0, -quote.length) + '/' + quote;\r\n }\r\n }\r\n return symbol;\r\n}\r\n\r\nfunction formatPrice(v: number, locale: string | undefined): string {\r\n if (v === 0) return '0';\r\n const abs = Math.abs(v);\r\n if (abs >= 1000) return v.toLocaleString(locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 });\r\n if (abs >= 1) return v.toLocaleString(locale, { minimumFractionDigits: 4, maximumFractionDigits: 4 });\r\n // toPrecision(4) has no locale-aware equivalent via toLocaleString (it\r\n // targets significant digits, not decimal places) — reformat its raw\r\n // fixed-notation output through Number.toLocaleString for the separator.\r\n const precise = Number(v.toPrecision(4));\r\n return precise.toLocaleString(locale, { maximumFractionDigits: 10 });\r\n}\r\n\r\nfunction drawSparkline(canvas: HTMLCanvasElement, samples: number[], ref: number): void {\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n const dpr = window.devicePixelRatio || 1;\r\n if (canvas.width !== canvas.clientWidth * dpr) {\r\n canvas.width = (canvas.clientWidth || 64) * dpr;\r\n canvas.height = (canvas.clientHeight || 22) * dpr;\r\n }\r\n const w = canvas.width;\r\n const h = canvas.height;\r\n\r\n let lo = Infinity, hi = -Infinity;\r\n for (const v of samples) {\r\n if (v < lo) lo = v;\r\n if (v > hi) hi = v;\r\n }\r\n const span = Math.max(hi - lo, 1e-9);\r\n const last = samples[samples.length - 1];\r\n const up = last >= ref;\r\n const color = up ? '#26a17b' : '#f23645';\r\n\r\n ctx.clearRect(0, 0, w, h);\r\n ctx.lineWidth = 1.4 * dpr;\r\n ctx.strokeStyle = color;\r\n ctx.beginPath();\r\n const step = w / (samples.length - 1);\r\n for (let i = 0; i < samples.length; i++) {\r\n const x = i * step;\r\n const y = h - ((samples[i] - lo) / span) * (h - 4) - 2;\r\n if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);\r\n }\r\n ctx.stroke();\r\n}\r\n","import type { AlertCondition } from '@tradecanvas/core';\r\nimport { createIcon } from './icons.js';\r\n\r\nexport interface AlertListItem {\r\n id: string;\r\n price: number;\r\n condition: string;\r\n message?: string;\r\n triggered: boolean;\r\n channel?: string;\r\n label?: string;\r\n}\r\n\r\nexport interface AlertSource {\r\n /** `'price'` or `<instanceId>:<key>`. */\r\n channel: string;\r\n label: string;\r\n}\r\n\r\nexport interface AlertsPanelCallbacks {\r\n onAdd: (price: number, condition: AlertCondition, message: string | undefined, channel: string, label: string) => void;\r\n onRemove: (id: string) => void;\r\n onClear: () => void;\r\n /** Latest value for a source channel, used to prefill the add form. */\r\n getChannelValue: (channel: string) => number | null;\r\n formatPrice: (price: number) => string;\r\n}\r\n\r\nconst CONDITION_OPTIONS: { value: AlertCondition; label: string }[] = [\r\n { value: 'crossing', label: 'Crossing' },\r\n { value: 'crossingUp', label: 'Crossing up' },\r\n { value: 'crossingDown', label: 'Crossing down' },\r\n { value: 'greaterThan', label: 'Greater than' },\r\n { value: 'lessThan', label: 'Less than' },\r\n];\r\n\r\nconst CONDITION_LABEL = new Map(CONDITION_OPTIONS.map((o) => [o.value, o.label]));\r\n\r\nfunction roundForInput(v: number): number {\r\n return Math.round(v * 1e6) / 1e6;\r\n}\r\n\r\nfunction formatPlain(v: number): string {\r\n const abs = Math.abs(v);\r\n return abs >= 1000 ? v.toFixed(2) : abs >= 1 ? v.toFixed(2) : v.toPrecision(4);\r\n}\r\n\r\n/**\r\n * Floating price-alerts panel. Lists current alerts (with condition, price,\r\n * message, and a delete control) and an inline form to add a new one prefilled\r\n * with the current price. Toggled from the toolbar bell button; the host wires\r\n * add/remove back to the chart's `AlertManager`.\r\n */\r\nexport class WidgetAlertsPanel {\r\n private el: HTMLDivElement;\r\n private listEl: HTMLDivElement;\r\n private priceInput: HTMLInputElement;\r\n private conditionSelect: HTMLSelectElement;\r\n private sourceSelect: HTMLSelectElement;\r\n private messageInput: HTMLInputElement;\r\n private emptyEl: HTMLDivElement;\r\n private callbacks: AlertsPanelCallbacks;\r\n private open = false;\r\n private alerts: AlertListItem[] = [];\r\n private sources: AlertSource[] = [{ channel: 'price', label: 'Price' }];\r\n\r\n constructor(host: HTMLElement, callbacks: AlertsPanelCallbacks) {\r\n this.callbacks = callbacks;\r\n\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-alerts-panel';\r\n this.el.hidden = true;\r\n\r\n // Header\r\n const header = document.createElement('div');\r\n header.className = 'tcw-alerts-header';\r\n const title = document.createElement('span');\r\n title.textContent = 'Price Alerts';\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'tcw-alerts-close';\r\n closeBtn.type = 'button';\r\n closeBtn.setAttribute('aria-label', 'Close alerts');\r\n closeBtn.innerHTML = createIcon('x', 14);\r\n closeBtn.addEventListener('click', () => this.close());\r\n header.appendChild(title);\r\n header.appendChild(closeBtn);\r\n this.el.appendChild(header);\r\n\r\n // Add form\r\n const form = document.createElement('form');\r\n form.className = 'tcw-alerts-form';\r\n\r\n this.sourceSelect = document.createElement('select');\r\n this.sourceSelect.className = 'tcw-alerts-source';\r\n this.sourceSelect.addEventListener('change', () => this.prefillPrice());\r\n\r\n this.priceInput = document.createElement('input');\r\n this.priceInput.type = 'number';\r\n this.priceInput.step = 'any';\r\n this.priceInput.placeholder = 'Value';\r\n this.priceInput.className = 'tcw-alerts-price';\r\n this.priceInput.required = true;\r\n\r\n this.conditionSelect = document.createElement('select');\r\n this.conditionSelect.className = 'tcw-alerts-condition';\r\n for (const opt of CONDITION_OPTIONS) {\r\n const o = document.createElement('option');\r\n o.value = opt.value;\r\n o.textContent = opt.label;\r\n this.conditionSelect.appendChild(o);\r\n }\r\n\r\n this.messageInput = document.createElement('input');\r\n this.messageInput.type = 'text';\r\n this.messageInput.placeholder = 'Note (optional)';\r\n this.messageInput.className = 'tcw-alerts-message';\r\n\r\n const addBtn = document.createElement('button');\r\n addBtn.type = 'submit';\r\n addBtn.className = 'tcw-alerts-add';\r\n addBtn.innerHTML = `${createIcon('plus', 14)}<span>Add alert</span>`;\r\n\r\n form.appendChild(this.sourceSelect);\r\n form.appendChild(this.priceInput);\r\n form.appendChild(this.conditionSelect);\r\n form.appendChild(this.messageInput);\r\n form.appendChild(addBtn);\r\n form.addEventListener('submit', (e) => {\r\n e.preventDefault();\r\n this.submitForm();\r\n });\r\n this.el.appendChild(form);\r\n\r\n // List\r\n this.listEl = document.createElement('div');\r\n this.listEl.className = 'tcw-alerts-list';\r\n this.el.appendChild(this.listEl);\r\n\r\n this.emptyEl = document.createElement('div');\r\n this.emptyEl.className = 'tcw-alerts-empty';\r\n this.emptyEl.textContent = 'No alerts yet. Add one above, or right-click the chart.';\r\n this.listEl.appendChild(this.emptyEl);\r\n\r\n this.renderSources();\r\n host.appendChild(this.el);\r\n }\r\n\r\n /** Replace the alert-source options (price + indicator lines). */\r\n setSources(sources: AlertSource[]): void {\r\n this.sources = sources.length > 0 ? sources : [{ channel: 'price', label: 'Price' }];\r\n this.renderSources();\r\n }\r\n\r\n private renderSources(): void {\r\n const current = this.sourceSelect.value || 'price';\r\n this.sourceSelect.replaceChildren();\r\n for (const src of this.sources) {\r\n const o = document.createElement('option');\r\n o.value = src.channel;\r\n o.textContent = src.label;\r\n this.sourceSelect.appendChild(o);\r\n }\r\n // Keep the prior selection if it still exists, else default to price.\r\n this.sourceSelect.value = this.sources.some((s) => s.channel === current) ? current : 'price';\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.open;\r\n }\r\n\r\n toggle(): void {\r\n this.open ? this.close() : this.openPanel();\r\n }\r\n\r\n openPanel(): void {\r\n this.open = true;\r\n this.el.hidden = false;\r\n if (this.priceInput.value === '') this.prefillPrice();\r\n }\r\n\r\n /** Fill the value input with the selected source's current value. */\r\n private prefillPrice(): void {\r\n const v = this.callbacks.getChannelValue(this.sourceSelect.value || 'price');\r\n this.priceInput.value = v !== null ? String(roundForInput(v)) : '';\r\n }\r\n\r\n close(): void {\r\n this.open = false;\r\n this.el.hidden = true;\r\n }\r\n\r\n /** Replace the displayed alert list. */\r\n setAlerts(alerts: AlertListItem[]): void {\r\n this.alerts = alerts;\r\n this.renderList();\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n }\r\n\r\n private submitForm(): void {\r\n const price = Number(this.priceInput.value);\r\n if (!Number.isFinite(price)) return;\r\n const condition = this.conditionSelect.value as AlertCondition;\r\n const message = this.messageInput.value.trim() || undefined;\r\n const channel = this.sourceSelect.value || 'price';\r\n const label = this.sources.find((s) => s.channel === channel)?.label ?? 'Price';\r\n this.callbacks.onAdd(price, condition, message, channel, label);\r\n this.messageInput.value = '';\r\n this.prefillPrice();\r\n }\r\n\r\n private renderList(): void {\r\n // Clear rows but keep the empty placeholder reference.\r\n this.listEl.replaceChildren();\r\n\r\n if (this.alerts.length === 0) {\r\n this.listEl.appendChild(this.emptyEl);\r\n return;\r\n }\r\n\r\n // Show most recent first.\r\n for (const alert of [...this.alerts].reverse()) {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-alerts-row' + (alert.triggered ? ' tcw-alerts-triggered' : '');\r\n\r\n const info = document.createElement('div');\r\n info.className = 'tcw-alerts-info';\r\n const main = document.createElement('div');\r\n main.className = 'tcw-alerts-row-main';\r\n const label = CONDITION_LABEL.get(alert.condition as AlertCondition) ?? alert.condition;\r\n const isIndicator = alert.channel && alert.channel !== 'price';\r\n const valueStr = isIndicator ? formatPlain(alert.price) : this.callbacks.formatPrice(alert.price);\r\n const prefix = isIndicator && alert.label ? `${alert.label} ` : '';\r\n main.textContent = `${prefix}${label} ${valueStr}`;\r\n info.appendChild(main);\r\n if (alert.message) {\r\n const note = document.createElement('div');\r\n note.className = 'tcw-alerts-row-note';\r\n note.textContent = alert.message;\r\n info.appendChild(note);\r\n }\r\n if (alert.triggered) {\r\n const badge = document.createElement('span');\r\n badge.className = 'tcw-alerts-badge';\r\n badge.textContent = 'triggered';\r\n main.appendChild(badge);\r\n }\r\n\r\n const del = document.createElement('button');\r\n del.type = 'button';\r\n del.className = 'tcw-alerts-del';\r\n del.setAttribute('aria-label', 'Delete alert');\r\n del.innerHTML = createIcon('trash', 14);\r\n del.addEventListener('click', () => this.callbacks.onRemove(alert.id));\r\n\r\n row.appendChild(info);\r\n row.appendChild(del);\r\n this.listEl.appendChild(row);\r\n }\r\n }\r\n}\r\n","import { createIcon } from './icons.js';\r\n\r\nexport interface ObjectTreeIndicator {\r\n instanceId: string;\r\n name: string;\r\n visible: boolean;\r\n}\r\n\r\nexport interface ObjectTreeDrawing {\r\n id: string;\r\n label: string;\r\n visible: boolean;\r\n locked: boolean;\r\n}\r\n\r\nexport interface ObjectTreeCompare {\r\n id: string;\r\n label: string;\r\n color: string;\r\n}\r\n\r\nexport interface ObjectTreeCallbacks {\r\n onRemoveIndicator: (instanceId: string) => void;\r\n onConfigureIndicator?: (instanceId: string) => void;\r\n onToggleIndicatorVisible?: (instanceId: string, visible: boolean) => void;\r\n onRemoveDrawing: (id: string) => void;\r\n onToggleDrawingVisible: (id: string, visible: boolean) => void;\r\n onToggleDrawingLocked: (id: string, locked: boolean) => void;\r\n /** When provided, a Compare section with an \"add\" button is shown. */\r\n onAddCompare?: () => void;\r\n onRemoveCompare?: (id: string) => void;\r\n}\r\n\r\n/**\r\n * Object-tree panel — TradingView's layers manager. Lists every active\r\n * indicator and drawing on the chart with per-item controls: indicators can be\r\n * removed; drawings can be shown/hidden, locked/unlocked, and removed. Toggled\r\n * from the toolbar layers button; the host wires actions back to the chart.\r\n */\r\nexport class WidgetObjectTree {\r\n private el: HTMLDivElement;\r\n private indicatorsEl: HTMLDivElement;\r\n private drawingsEl: HTMLDivElement;\r\n private compareEl: HTMLDivElement | null = null;\r\n private callbacks: ObjectTreeCallbacks;\r\n private open = false;\r\n\r\n constructor(host: HTMLElement, callbacks: ObjectTreeCallbacks) {\r\n this.callbacks = callbacks;\r\n\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-tree-panel';\r\n this.el.hidden = true;\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-tree-header';\r\n const title = document.createElement('span');\r\n title.textContent = 'Objects';\r\n const closeBtn = document.createElement('button');\r\n closeBtn.type = 'button';\r\n closeBtn.className = 'tcw-tree-close';\r\n closeBtn.setAttribute('aria-label', 'Close objects');\r\n closeBtn.innerHTML = createIcon('x', 14);\r\n closeBtn.addEventListener('click', () => this.close());\r\n header.appendChild(title);\r\n header.appendChild(closeBtn);\r\n this.el.appendChild(header);\r\n\r\n this.indicatorsEl = this.makeSection('Indicators');\r\n this.drawingsEl = this.makeSection('Drawings');\r\n if (this.callbacks.onAddCompare) {\r\n this.compareEl = this.makeSection('Compare', () => this.callbacks.onAddCompare?.());\r\n }\r\n\r\n host.appendChild(this.el);\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.open;\r\n }\r\n\r\n toggle(): void {\r\n this.open ? this.close() : this.openPanel();\r\n }\r\n\r\n openPanel(): void {\r\n this.open = true;\r\n this.el.hidden = false;\r\n }\r\n\r\n close(): void {\r\n this.open = false;\r\n this.el.hidden = true;\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n }\r\n\r\n /** Replace all lists. Cheap full re-render — counts are small. */\r\n setObjects(\r\n indicators: ObjectTreeIndicator[],\r\n drawings: ObjectTreeDrawing[],\r\n compares: ObjectTreeCompare[] = [],\r\n ): void {\r\n this.renderIndicators(indicators);\r\n this.renderDrawings(drawings);\r\n this.renderCompares(compares);\r\n }\r\n\r\n private makeSection(title: string, onAdd?: () => void): HTMLDivElement {\r\n const wrap = document.createElement('div');\r\n wrap.className = 'tcw-tree-section';\r\n const head = document.createElement('div');\r\n head.className = 'tcw-tree-section-head';\r\n const label = document.createElement('span');\r\n label.textContent = title;\r\n head.appendChild(label);\r\n if (onAdd) {\r\n const addBtn = document.createElement('button');\r\n addBtn.type = 'button';\r\n addBtn.className = 'tcw-tree-add';\r\n addBtn.setAttribute('aria-label', `Add ${title.toLowerCase()}`);\r\n addBtn.title = `Add ${title.toLowerCase()}`;\r\n addBtn.innerHTML = createIcon('plus', 13);\r\n addBtn.addEventListener('click', onAdd);\r\n head.appendChild(addBtn);\r\n }\r\n const list = document.createElement('div');\r\n list.className = 'tcw-tree-list';\r\n wrap.appendChild(head);\r\n wrap.appendChild(list);\r\n this.el.appendChild(wrap);\r\n return list;\r\n }\r\n\r\n private renderIndicators(indicators: ObjectTreeIndicator[]): void {\r\n this.indicatorsEl.replaceChildren();\r\n if (indicators.length === 0) {\r\n this.indicatorsEl.appendChild(this.emptyRow('No indicators'));\r\n return;\r\n }\r\n for (const ind of indicators) {\r\n const row = this.row(ind.name);\r\n if (!ind.visible) row.classList.add('tcw-tree-hidden');\r\n const actions = document.createElement('div');\r\n actions.className = 'tcw-tree-actions';\r\n if (this.callbacks.onToggleIndicatorVisible) {\r\n actions.appendChild(this.iconButton(\r\n ind.visible ? 'eye' : 'eyeOff',\r\n ind.visible ? 'Hide' : 'Show',\r\n '',\r\n () => this.callbacks.onToggleIndicatorVisible?.(ind.instanceId, !ind.visible),\r\n ));\r\n }\r\n if (this.callbacks.onConfigureIndicator) {\r\n actions.appendChild(this.iconButton('settings', 'Indicator settings', '', () =>\r\n this.callbacks.onConfigureIndicator?.(ind.instanceId),\r\n ));\r\n }\r\n actions.appendChild(this.iconButton('trash', 'Remove indicator', 'tcw-tree-del', () =>\r\n this.callbacks.onRemoveIndicator(ind.instanceId),\r\n ));\r\n row.appendChild(actions);\r\n this.indicatorsEl.appendChild(row);\r\n }\r\n }\r\n\r\n private renderDrawings(drawings: ObjectTreeDrawing[]): void {\r\n this.drawingsEl.replaceChildren();\r\n if (drawings.length === 0) {\r\n this.drawingsEl.appendChild(this.emptyRow('No drawings'));\r\n return;\r\n }\r\n for (const d of drawings) {\r\n const row = this.row(d.label);\r\n if (!d.visible) row.classList.add('tcw-tree-hidden');\r\n\r\n const actions = document.createElement('div');\r\n actions.className = 'tcw-tree-actions';\r\n actions.appendChild(this.iconButton(\r\n d.visible ? 'eye' : 'eyeOff',\r\n d.visible ? 'Hide' : 'Show',\r\n '',\r\n () => this.callbacks.onToggleDrawingVisible(d.id, !d.visible),\r\n ));\r\n actions.appendChild(this.iconButton(\r\n d.locked ? 'lock' : 'unlock',\r\n d.locked ? 'Unlock' : 'Lock',\r\n d.locked ? 'tcw-tree-on' : '',\r\n () => this.callbacks.onToggleDrawingLocked(d.id, !d.locked),\r\n ));\r\n actions.appendChild(this.iconButton('trash', 'Remove drawing', 'tcw-tree-del', () =>\r\n this.callbacks.onRemoveDrawing(d.id),\r\n ));\r\n row.appendChild(actions);\r\n this.drawingsEl.appendChild(row);\r\n }\r\n }\r\n\r\n private renderCompares(compares: ObjectTreeCompare[]): void {\r\n if (!this.compareEl) return;\r\n this.compareEl.replaceChildren();\r\n if (compares.length === 0) {\r\n this.compareEl.appendChild(this.emptyRow('No comparisons'));\r\n return;\r\n }\r\n for (const c of compares) {\r\n const row = this.row(c.label);\r\n const dot = document.createElement('span');\r\n dot.className = 'tcw-tree-dot';\r\n dot.style.background = c.color;\r\n row.insertBefore(dot, row.firstChild);\r\n if (this.callbacks.onRemoveCompare) {\r\n row.appendChild(this.iconButton('trash', 'Remove comparison', 'tcw-tree-del', () =>\r\n this.callbacks.onRemoveCompare?.(c.id),\r\n ));\r\n }\r\n this.compareEl.appendChild(row);\r\n }\r\n }\r\n\r\n private row(label: string): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-tree-row';\r\n const name = document.createElement('span');\r\n name.className = 'tcw-tree-name';\r\n name.textContent = label;\r\n name.title = label;\r\n row.appendChild(name);\r\n return row;\r\n }\r\n\r\n private emptyRow(text: string): HTMLDivElement {\r\n const el = document.createElement('div');\r\n el.className = 'tcw-tree-empty';\r\n el.textContent = text;\r\n return el;\r\n }\r\n\r\n private iconButton(icon: string, label: string, extraClass: string, onClick: () => void): HTMLButtonElement {\r\n const btn = document.createElement('button');\r\n btn.type = 'button';\r\n btn.className = `tcw-tree-btn ${extraClass}`.trim();\r\n btn.setAttribute('aria-label', label);\r\n btn.title = label;\r\n btn.innerHTML = createIcon(icon, 14);\r\n btn.addEventListener('click', onClick);\r\n return btn;\r\n }\r\n}\r\n\r\nconst DRAWING_TYPE_LABELS: Record<string, string> = {\r\n trendLine: 'Trend Line',\r\n ray: 'Ray',\r\n extendedLine: 'Extended Line',\r\n horizontalLine: 'Horizontal Line',\r\n horizontalRay: 'Horizontal Ray',\r\n crossLine: 'Cross Line',\r\n infoLine: 'Info Line',\r\n trendAngle: 'Trend Angle',\r\n circle: 'Circle',\r\n fibChannel: 'Fib Channel',\r\n fibSpeedResistanceFan: 'Fib Speed Resistance Fan',\r\n schiffPitchfork: 'Schiff Pitchfork',\r\n modifiedSchiffPitchfork: 'Modified Schiff Pitchfork',\r\n xabcdPattern: 'XABCD Pattern',\r\n abcdPattern: 'ABCD Pattern',\r\n headAndShoulders: 'Head and Shoulders',\r\n dateAndPriceRange: 'Date and Price Range',\r\n cyclicLines: 'Cyclic Lines',\r\n priceLabel: 'Price Label',\r\n verticalLine: 'Vertical Line',\r\n rectangle: 'Rectangle',\r\n ellipse: 'Ellipse',\r\n triangle: 'Triangle',\r\n arrow: 'Arrow',\r\n parallelChannel: 'Parallel Channel',\r\n regressionChannel: 'Regression Channel',\r\n pitchfork: 'Pitchfork',\r\n fibRetracement: 'Fib Retracement',\r\n fibExtension: 'Fib Extension',\r\n fibTimeZones: 'Fib Time Zones',\r\n gannBox: 'Gann Box',\r\n gannFan: 'Gann Fan',\r\n elliottWave: 'Elliott Wave',\r\n priceRange: 'Price Range',\r\n dateRange: 'Date Range',\r\n measure: 'Measure',\r\n text: 'Text',\r\n textAnnotation: 'Text',\r\n anchoredVWAP: 'Anchored VWAP',\r\n volumeProfileRange: 'Volume Profile',\r\n riskReward: 'Long/Short Position',\r\n};\r\n\r\n/** Human-readable label for a drawing type, falling back to the raw key. */\r\nexport function drawingTypeLabel(type: string): string {\r\n return DRAWING_TYPE_LABELS[type] ?? type;\r\n}\r\n","import { createIcon } from './icons.js';\r\n\r\nexport type IndicatorParamValue = number | string | boolean;\r\n\r\nexport interface IndicatorSettingsTarget {\r\n instanceId: string;\r\n name: string;\r\n /** Default config — defines the editable keys and their types. */\r\n defaults: Record<string, unknown>;\r\n /** Current values, overlaid on defaults. */\r\n params: Record<string, unknown>;\r\n}\r\n\r\nexport interface IndicatorSettingsCallbacks {\r\n onApply: (instanceId: string, params: Record<string, IndicatorParamValue>) => void;\r\n onClose: () => void;\r\n}\r\n\r\nconst HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\r\n\r\nfunction titleCase(key: string): string {\r\n // camelCase / snake_case → \"Title Case\"\r\n return key\r\n .replace(/_/g, ' ')\r\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\r\n .replace(/^./, (c) => c.toUpperCase());\r\n}\r\n\r\n/**\r\n * Per-indicator parameter editor. Introspects the indicator's default config to\r\n * decide each control (number → stepper, boolean → toggle, hex string → color,\r\n * other string → text) and applies edits live via `onApply`.\r\n */\r\nexport class WidgetIndicatorSettings {\r\n private backdrop: HTMLDivElement;\r\n private modal: HTMLDivElement;\r\n private bodyEl: HTMLDivElement;\r\n private titleEl: HTMLHeadingElement;\r\n private callbacks: IndicatorSettingsCallbacks;\r\n private target: IndicatorSettingsTarget | null = null;\r\n private draft: Record<string, IndicatorParamValue> = {};\r\n\r\n constructor(host: HTMLElement, callbacks: IndicatorSettingsCallbacks) {\r\n this.callbacks = callbacks;\r\n\r\n this.backdrop = document.createElement('div');\r\n this.backdrop.className = 'tcw-modal-backdrop';\r\n this.backdrop.hidden = true;\r\n this.backdrop.addEventListener('click', (e) => {\r\n if (e.target === this.backdrop) this.close();\r\n });\r\n\r\n this.modal = document.createElement('div');\r\n this.modal.className = 'tcw-modal tcw-modal-narrow';\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-modal-header';\r\n this.titleEl = document.createElement('h3');\r\n this.titleEl.textContent = 'Indicator';\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'tcw-modal-close';\r\n closeBtn.setAttribute('aria-label', 'Close');\r\n closeBtn.innerHTML = createIcon('x', 16);\r\n closeBtn.addEventListener('click', () => this.close());\r\n header.appendChild(this.titleEl);\r\n header.appendChild(closeBtn);\r\n\r\n this.bodyEl = document.createElement('div');\r\n this.bodyEl.className = 'tcw-modal-body';\r\n\r\n const footer = document.createElement('div');\r\n footer.className = 'tcw-modal-footer';\r\n const resetBtn = document.createElement('button');\r\n resetBtn.className = 'tcw-reset-link';\r\n resetBtn.textContent = 'Reset to defaults';\r\n resetBtn.addEventListener('click', () => this.resetDefaults());\r\n const doneBtn = document.createElement('button');\r\n doneBtn.className = 'tcw-done-btn';\r\n doneBtn.textContent = 'Done';\r\n doneBtn.addEventListener('click', () => this.close());\r\n footer.appendChild(resetBtn);\r\n footer.appendChild(doneBtn);\r\n\r\n this.modal.appendChild(header);\r\n this.modal.appendChild(this.bodyEl);\r\n this.modal.appendChild(footer);\r\n this.backdrop.appendChild(this.modal);\r\n host.appendChild(this.backdrop);\r\n }\r\n\r\n open(target: IndicatorSettingsTarget): void {\r\n this.target = target;\r\n this.titleEl.textContent = `${target.name} settings`;\r\n this.draft = {};\r\n this.renderFields();\r\n this.backdrop.hidden = false;\r\n }\r\n\r\n close(): void {\r\n this.backdrop.hidden = true;\r\n this.target = null;\r\n this.callbacks.onClose();\r\n }\r\n\r\n isOpen(): boolean {\r\n return !this.backdrop.hidden;\r\n }\r\n\r\n destroy(): void {\r\n this.backdrop.remove();\r\n }\r\n\r\n private currentValue(key: string): IndicatorParamValue {\r\n if (key in this.draft) return this.draft[key];\r\n const cur = this.target?.params[key];\r\n const def = this.target?.defaults[key];\r\n const val = cur ?? def;\r\n return val as IndicatorParamValue;\r\n }\r\n\r\n private setValue(key: string, value: IndicatorParamValue): void {\r\n if (!this.target) return;\r\n this.draft[key] = value;\r\n this.callbacks.onApply(this.target.instanceId, { ...this.draft });\r\n }\r\n\r\n private resetDefaults(): void {\r\n if (!this.target) return;\r\n const reset: Record<string, IndicatorParamValue> = {};\r\n for (const [key, def] of Object.entries(this.target.defaults)) {\r\n reset[key] = def as IndicatorParamValue;\r\n }\r\n this.draft = reset;\r\n this.callbacks.onApply(this.target.instanceId, { ...reset });\r\n this.renderFields();\r\n }\r\n\r\n private renderFields(): void {\r\n this.bodyEl.replaceChildren();\r\n if (!this.target) return;\r\n\r\n const section = document.createElement('div');\r\n section.className = 'tcw-settings-section';\r\n\r\n const keys = Object.keys(this.target.defaults);\r\n if (keys.length === 0) {\r\n const empty = document.createElement('div');\r\n empty.className = 'tcw-settings-label';\r\n empty.textContent = 'This indicator has no adjustable parameters.';\r\n section.appendChild(empty);\r\n }\r\n\r\n for (const key of keys) {\r\n section.appendChild(this.fieldRow(key));\r\n }\r\n this.bodyEl.appendChild(section);\r\n }\r\n\r\n private fieldRow(key: string): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-settings-row';\r\n const label = document.createElement('span');\r\n label.className = 'tcw-settings-label';\r\n label.textContent = titleCase(key);\r\n row.appendChild(label);\r\n\r\n const value = this.currentValue(key);\r\n const defType = typeof (this.target?.defaults[key] ?? value);\r\n\r\n if (defType === 'boolean') {\r\n row.appendChild(this.toggleControl(key, Boolean(value)));\r\n } else if (defType === 'number') {\r\n row.appendChild(this.numberControl(key, Number(value)));\r\n } else if (typeof value === 'string' && HEX_RE.test(value)) {\r\n row.appendChild(this.colorControl(key, value));\r\n } else {\r\n row.appendChild(this.textControl(key, String(value ?? '')));\r\n }\r\n return row;\r\n }\r\n\r\n private toggleControl(key: string, value: boolean): HTMLButtonElement {\r\n const toggle = document.createElement('button');\r\n toggle.className = `tcw-toggle${value ? ' tcw-on' : ''}`;\r\n toggle.type = 'button';\r\n toggle.addEventListener('click', () => {\r\n const next = !toggle.classList.contains('tcw-on');\r\n toggle.classList.toggle('tcw-on', next);\r\n this.setValue(key, next);\r\n });\r\n return toggle;\r\n }\r\n\r\n private numberControl(key: string, value: number): HTMLInputElement {\r\n const input = document.createElement('input');\r\n input.type = 'number';\r\n input.className = 'tcw-indi-input';\r\n input.value = String(value);\r\n // Integer-looking defaults step by 1; fractional defaults step by 0.1.\r\n input.step = Number.isInteger(value) ? '1' : '0.1';\r\n input.addEventListener('change', () => {\r\n const n = Number(input.value);\r\n if (Number.isFinite(n)) this.setValue(key, n);\r\n });\r\n return input;\r\n }\r\n\r\n private colorControl(key: string, value: string): HTMLInputElement {\r\n const input = document.createElement('input');\r\n input.type = 'color';\r\n input.className = 'tcw-indi-color';\r\n input.value = value.length === 4 ? expandHex(value) : value;\r\n input.addEventListener('input', () => this.setValue(key, input.value));\r\n return input;\r\n }\r\n\r\n private textControl(key: string, value: string): HTMLInputElement {\r\n const input = document.createElement('input');\r\n input.type = 'text';\r\n input.className = 'tcw-indi-input';\r\n input.value = value;\r\n input.addEventListener('change', () => this.setValue(key, input.value));\r\n return input;\r\n }\r\n}\r\n\r\nfunction expandHex(short: string): string {\r\n // #abc → #aabbcc\r\n const r = short[1], g = short[2], b = short[3];\r\n return `#${r}${r}${g}${g}${b}${b}`;\r\n}\r\n","import type { DrawingStyle } from '@tradecanvas/commons';\r\n\r\nexport interface DrawingStyleTemplate {\r\n name: string;\r\n style: Partial<DrawingStyle>;\r\n}\r\n\r\n/** Minimal storage surface — satisfied by `localStorage` and easy to mock. */\r\nexport interface KeyValueStorage {\r\n getItem(key: string): string | null;\r\n setItem(key: string, value: string): void;\r\n}\r\n\r\nfunction defaultStorage(): KeyValueStorage | null {\r\n try {\r\n return typeof localStorage !== 'undefined' ? localStorage : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nconst STYLE_KEYS: (keyof DrawingStyle)[] = [\r\n 'color', 'lineWidth', 'lineStyle', 'fillColor', 'fillOpacity', 'fontSize',\r\n];\r\n\r\n/** Keep only known style keys — guards against junk persisted by older builds. */\r\nfunction sanitizeStyle(raw: unknown): Partial<DrawingStyle> {\r\n if (!raw || typeof raw !== 'object') return {};\r\n const out: Partial<DrawingStyle> = {};\r\n const obj = raw as Record<string, unknown>;\r\n for (const key of STYLE_KEYS) {\r\n if (obj[key] !== undefined) (out as Record<string, unknown>)[key] = obj[key];\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Named drawing-style presets, persisted to a key-value store. Templates are\r\n * upserted by name (case-sensitive) and ordered most-recently-saved last.\r\n */\r\nexport class DrawingTemplateStore {\r\n private templates: DrawingStyleTemplate[] = [];\r\n\r\n constructor(\r\n private storageKey = 'tcw:draw-templates',\r\n private storage: KeyValueStorage | null = defaultStorage(),\r\n ) {\r\n this.load();\r\n }\r\n\r\n list(): DrawingStyleTemplate[] {\r\n return this.templates.map((t) => ({ name: t.name, style: { ...t.style } }));\r\n }\r\n\r\n get(name: string): DrawingStyleTemplate | null {\r\n const t = this.templates.find((x) => x.name === name);\r\n return t ? { name: t.name, style: { ...t.style } } : null;\r\n }\r\n\r\n /** Insert or replace a template by name. */\r\n save(name: string, style: Partial<DrawingStyle>): void {\r\n const trimmed = name.trim();\r\n if (!trimmed) return;\r\n const clean = sanitizeStyle(style);\r\n this.templates = this.templates.filter((t) => t.name !== trimmed);\r\n this.templates.push({ name: trimmed, style: clean });\r\n this.persist();\r\n }\r\n\r\n remove(name: string): void {\r\n const next = this.templates.filter((t) => t.name !== name);\r\n if (next.length === this.templates.length) return;\r\n this.templates = next;\r\n this.persist();\r\n }\r\n\r\n clear(): void {\r\n this.templates = [];\r\n this.persist();\r\n }\r\n\r\n private load(): void {\r\n if (!this.storage) return;\r\n try {\r\n const raw = this.storage.getItem(this.storageKey);\r\n if (!raw) return;\r\n const parsed = JSON.parse(raw);\r\n if (!Array.isArray(parsed)) return;\r\n this.templates = parsed\r\n .filter((t) => t && typeof t.name === 'string')\r\n .map((t) => ({ name: t.name, style: sanitizeStyle(t.style) }));\r\n } catch {\r\n // Corrupt or unavailable storage — start empty.\r\n }\r\n }\r\n\r\n private persist(): void {\r\n if (!this.storage) return;\r\n try {\r\n this.storage.setItem(this.storageKey, JSON.stringify(this.templates));\r\n } catch {\r\n // Storage full or blocked — keep the in-memory copy.\r\n }\r\n }\r\n}\r\n","import type { DrawingStyle } from '@tradecanvas/commons';\r\nimport { createIcon } from './icons.js';\r\nimport { DrawingTemplateStore } from './DrawingTemplateStore.js';\r\n\r\nexport interface DrawingStyleCallbacks {\r\n /** Apply a style change to the active (next) drawing and the selected one. */\r\n onStyleChange: (style: Partial<DrawingStyle>) => void;\r\n /** Current active drawing style, for seeding controls and saving templates. */\r\n getStyle: () => DrawingStyle;\r\n}\r\n\r\nconst SWATCHES = ['#2962ff', '#089981', '#f23645', '#ff9800', '#ab47bc', '#26c6da', '#ffffff', '#787b86'];\r\nconst WIDTHS = [1, 2, 3, 4];\r\nconst LINE_STYLES: DrawingStyle['lineStyle'][] = ['solid', 'dashed', 'dotted'];\r\n\r\n/**\r\n * Drawing style popover — pick colour, line width, and line style for the next\r\n * drawing (and the selected one), plus save/apply named style templates\r\n * persisted via `DrawingTemplateStore`.\r\n */\r\nexport class WidgetDrawingStyle {\r\n private el: HTMLDivElement;\r\n private templatesEl: HTMLDivElement;\r\n private nameInput: HTMLInputElement;\r\n private callbacks: DrawingStyleCallbacks;\r\n private store: DrawingTemplateStore;\r\n private open = false;\r\n\r\n constructor(host: HTMLElement, callbacks: DrawingStyleCallbacks, store: DrawingTemplateStore) {\r\n this.callbacks = callbacks;\r\n this.store = store;\r\n\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-style-panel';\r\n this.el.hidden = true;\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-style-header';\r\n const title = document.createElement('span');\r\n title.textContent = 'Drawing Style';\r\n const closeBtn = document.createElement('button');\r\n closeBtn.type = 'button';\r\n closeBtn.className = 'tcw-style-close';\r\n closeBtn.setAttribute('aria-label', 'Close');\r\n closeBtn.innerHTML = createIcon('x', 14);\r\n closeBtn.addEventListener('click', () => this.close());\r\n header.appendChild(title);\r\n header.appendChild(closeBtn);\r\n this.el.appendChild(header);\r\n\r\n this.el.appendChild(this.colorRow());\r\n this.el.appendChild(this.widthRow());\r\n this.el.appendChild(this.lineStyleRow());\r\n\r\n // Templates\r\n const tmplHead = document.createElement('div');\r\n tmplHead.className = 'tcw-style-subhead';\r\n tmplHead.textContent = 'Templates';\r\n this.el.appendChild(tmplHead);\r\n\r\n const saveRow = document.createElement('div');\r\n saveRow.className = 'tcw-style-save';\r\n this.nameInput = document.createElement('input');\r\n this.nameInput.type = 'text';\r\n this.nameInput.placeholder = 'Template name';\r\n this.nameInput.className = 'tcw-style-name';\r\n const saveBtn = document.createElement('button');\r\n saveBtn.type = 'button';\r\n saveBtn.className = 'tcw-style-savebtn';\r\n saveBtn.innerHTML = `${createIcon('plus', 13)}<span>Save</span>`;\r\n saveBtn.addEventListener('click', () => this.saveTemplate());\r\n saveRow.appendChild(this.nameInput);\r\n saveRow.appendChild(saveBtn);\r\n this.el.appendChild(saveRow);\r\n\r\n this.templatesEl = document.createElement('div');\r\n this.templatesEl.className = 'tcw-style-templates';\r\n this.el.appendChild(this.templatesEl);\r\n\r\n host.appendChild(this.el);\r\n this.renderTemplates();\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.open;\r\n }\r\n\r\n toggle(): void {\r\n this.open ? this.close() : this.openPanel();\r\n }\r\n\r\n openPanel(): void {\r\n this.open = true;\r\n this.el.hidden = false;\r\n this.syncActiveControls();\r\n this.renderTemplates();\r\n }\r\n\r\n close(): void {\r\n this.open = false;\r\n this.el.hidden = true;\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n }\r\n\r\n private colorRow(): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-style-row tcw-style-colors';\r\n for (const c of SWATCHES) {\r\n const sw = document.createElement('button');\r\n sw.type = 'button';\r\n sw.className = 'tcw-style-swatch';\r\n sw.style.background = c;\r\n sw.dataset.color = c;\r\n sw.setAttribute('aria-label', c);\r\n sw.addEventListener('click', () => this.applyStyle({ color: c }));\r\n row.appendChild(sw);\r\n }\r\n const picker = document.createElement('input');\r\n picker.type = 'color';\r\n picker.className = 'tcw-style-picker';\r\n picker.addEventListener('input', () => this.applyStyle({ color: picker.value }));\r\n row.appendChild(picker);\r\n return row;\r\n }\r\n\r\n private widthRow(): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-style-row tcw-style-widths';\r\n for (const w of WIDTHS) {\r\n const btn = document.createElement('button');\r\n btn.type = 'button';\r\n btn.className = 'tcw-style-width';\r\n btn.dataset.width = String(w);\r\n const bar = document.createElement('span');\r\n bar.style.height = `${w}px`;\r\n btn.appendChild(bar);\r\n btn.addEventListener('click', () => this.applyStyle({ lineWidth: w }));\r\n row.appendChild(btn);\r\n }\r\n return row;\r\n }\r\n\r\n private lineStyleRow(): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-style-row tcw-style-dashes';\r\n for (const ls of LINE_STYLES) {\r\n const btn = document.createElement('button');\r\n btn.type = 'button';\r\n btn.className = 'tcw-style-dash';\r\n btn.dataset.linestyle = ls;\r\n btn.textContent = ls === 'solid' ? '──' : ls === 'dashed' ? '╌╌' : '┄┄';\r\n btn.title = ls;\r\n btn.addEventListener('click', () => this.applyStyle({ lineStyle: ls }));\r\n row.appendChild(btn);\r\n }\r\n return row;\r\n }\r\n\r\n private applyStyle(patch: Partial<DrawingStyle>): void {\r\n this.callbacks.onStyleChange(patch);\r\n this.syncActiveControls();\r\n }\r\n\r\n /** Mark the controls matching the current active style. */\r\n private syncActiveControls(): void {\r\n const style = this.callbacks.getStyle();\r\n this.el.querySelectorAll<HTMLElement>('.tcw-style-swatch').forEach((sw) => {\r\n sw.classList.toggle('tcw-on', sw.dataset.color?.toLowerCase() === style.color?.toLowerCase());\r\n });\r\n this.el.querySelectorAll<HTMLElement>('.tcw-style-width').forEach((b) => {\r\n b.classList.toggle('tcw-on', Number(b.dataset.width) === style.lineWidth);\r\n });\r\n this.el.querySelectorAll<HTMLElement>('.tcw-style-dash').forEach((b) => {\r\n b.classList.toggle('tcw-on', b.dataset.linestyle === style.lineStyle);\r\n });\r\n }\r\n\r\n private saveTemplate(): void {\r\n const name = this.nameInput.value.trim();\r\n if (!name) return;\r\n this.store.save(name, this.callbacks.getStyle());\r\n this.nameInput.value = '';\r\n this.renderTemplates();\r\n }\r\n\r\n private renderTemplates(): void {\r\n this.templatesEl.replaceChildren();\r\n const templates = this.store.list();\r\n if (templates.length === 0) {\r\n const empty = document.createElement('div');\r\n empty.className = 'tcw-style-empty';\r\n empty.textContent = 'No saved templates';\r\n this.templatesEl.appendChild(empty);\r\n return;\r\n }\r\n for (const t of templates) {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-style-template';\r\n\r\n const apply = document.createElement('button');\r\n apply.type = 'button';\r\n apply.className = 'tcw-style-apply';\r\n const dot = document.createElement('span');\r\n dot.className = 'tcw-style-tdot';\r\n dot.style.background = (t.style.color as string) ?? 'var(--tcw-text-muted)';\r\n const label = document.createElement('span');\r\n label.textContent = t.name;\r\n apply.appendChild(dot);\r\n apply.appendChild(label);\r\n apply.addEventListener('click', () => {\r\n this.callbacks.onStyleChange({ ...t.style });\r\n this.syncActiveControls();\r\n });\r\n\r\n const del = document.createElement('button');\r\n del.type = 'button';\r\n del.className = 'tcw-style-tdel';\r\n del.setAttribute('aria-label', 'Delete template');\r\n del.innerHTML = createIcon('trash', 13);\r\n del.addEventListener('click', () => {\r\n this.store.remove(t.name);\r\n this.renderTemplates();\r\n });\r\n\r\n row.appendChild(apply);\r\n row.appendChild(del);\r\n this.templatesEl.appendChild(row);\r\n }\r\n }\r\n}\r\n","import type { KeyValueStorage } from './DrawingTemplateStore.js';\r\n\r\nfunction defaultStorage(): KeyValueStorage | null {\r\n try {\r\n return typeof localStorage !== 'undefined' ? localStorage : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * An ordered, de-duplicated set of pinned drawing-tool ids, persisted to a\r\n * key-value store. Order is insertion order (most-recently-pinned last).\r\n */\r\nexport class DrawingFavoritesStore {\r\n private favorites: string[] = [];\r\n\r\n constructor(\r\n private storageKey = 'tcw:draw-favorites',\r\n private storage: KeyValueStorage | null = defaultStorage(),\r\n ) {\r\n this.load();\r\n }\r\n\r\n list(): string[] {\r\n return [...this.favorites];\r\n }\r\n\r\n has(tool: string): boolean {\r\n return this.favorites.includes(tool);\r\n }\r\n\r\n add(tool: string): void {\r\n if (!tool || this.favorites.includes(tool)) return;\r\n this.favorites = [...this.favorites, tool];\r\n this.persist();\r\n }\r\n\r\n remove(tool: string): void {\r\n if (!this.favorites.includes(tool)) return;\r\n this.favorites = this.favorites.filter((t) => t !== tool);\r\n this.persist();\r\n }\r\n\r\n /** Toggle a tool's pinned state. Returns the new state (true = pinned). */\r\n toggle(tool: string): boolean {\r\n if (this.has(tool)) {\r\n this.remove(tool);\r\n return false;\r\n }\r\n this.add(tool);\r\n return true;\r\n }\r\n\r\n /** Seed the favorites only when none are stored yet (first run). */\r\n seedDefaults(tools: string[]): void {\r\n if (this.favorites.length > 0) return;\r\n this.favorites = [...new Set(tools.filter(Boolean))];\r\n this.persist();\r\n }\r\n\r\n private load(): void {\r\n if (!this.storage) return;\r\n try {\r\n const raw = this.storage.getItem(this.storageKey);\r\n if (!raw) return;\r\n const parsed = JSON.parse(raw);\r\n if (Array.isArray(parsed)) {\r\n this.favorites = [...new Set(parsed.filter((t) => typeof t === 'string'))];\r\n }\r\n } catch {\r\n // Corrupt or unavailable — start empty.\r\n }\r\n }\r\n\r\n private persist(): void {\r\n if (!this.storage) return;\r\n try {\r\n this.storage.setItem(this.storageKey, JSON.stringify(this.favorites));\r\n } catch {\r\n // Storage full or blocked — keep the in-memory copy.\r\n }\r\n }\r\n}\r\n","import { createIcon } from './icons.js';\r\n\r\nexport interface BracketBarCallbacks {\r\n onConfirm: () => void;\r\n onCancel: () => void;\r\n}\r\n\r\n/**\r\n * Floating confirm/cancel bar shown while a bracket order is being placed.\r\n * The live entry / SL / TP numbers are drawn on the chart canvas; this bar\r\n * just carries the commit and discard actions (also bound to Enter / Esc).\r\n */\r\nexport class WidgetBracketBar {\r\n private el: HTMLDivElement;\r\n private labelEl: HTMLSpanElement;\r\n private callbacks: BracketBarCallbacks;\r\n private visible = false;\r\n\r\n constructor(host: HTMLElement, callbacks: BracketBarCallbacks) {\r\n this.callbacks = callbacks;\r\n\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-bracket-bar';\r\n this.el.hidden = true;\r\n\r\n this.labelEl = document.createElement('span');\r\n this.labelEl.className = 'tcw-bracket-label';\r\n this.el.appendChild(this.labelEl);\r\n\r\n const hint = document.createElement('span');\r\n hint.className = 'tcw-bracket-hint';\r\n hint.textContent = 'drag lines to adjust';\r\n this.el.appendChild(hint);\r\n\r\n const cancel = document.createElement('button');\r\n cancel.type = 'button';\r\n cancel.className = 'tcw-bracket-cancel';\r\n cancel.innerHTML = `${createIcon('x', 14)}<span>Cancel</span>`;\r\n cancel.addEventListener('click', () => this.callbacks.onCancel());\r\n\r\n const confirm = document.createElement('button');\r\n confirm.type = 'button';\r\n confirm.className = 'tcw-bracket-confirm';\r\n confirm.innerHTML = `${createIcon('check', 14)}<span>Place</span>`;\r\n confirm.addEventListener('click', () => this.callbacks.onConfirm());\r\n\r\n this.el.appendChild(cancel);\r\n this.el.appendChild(confirm);\r\n host.appendChild(this.el);\r\n }\r\n\r\n show(side: 'buy' | 'sell'): void {\r\n this.visible = true;\r\n this.labelEl.textContent = side === 'buy' ? 'Long bracket' : 'Short bracket';\r\n this.labelEl.dataset.side = side;\r\n this.el.hidden = false;\r\n }\r\n\r\n hide(): void {\r\n this.visible = false;\r\n this.el.hidden = true;\r\n }\r\n\r\n isVisible(): boolean {\r\n return this.visible;\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n }\r\n}\r\n","export interface AlertNotifyOptions {\r\n /** Play a sound on trigger. `true` = built-in beep, string = audio URL. Default `false`. */\r\n sound?: boolean | string;\r\n /** Show a desktop notification (requests permission on first use). Default `false`. */\r\n desktop?: boolean;\r\n /** Title for desktop notifications. Default `'Price alert'`. */\r\n title?: string;\r\n}\r\n\r\n/** True when the Notification API is present and not denied. */\r\nexport function canRequestNotifications(): boolean {\r\n return typeof Notification !== 'undefined' && Notification.permission !== 'denied';\r\n}\r\n\r\n/**\r\n * Plays a sound and/or raises a desktop notification when a price alert fires.\r\n * Browser-API heavy by nature — every entry point is guarded so it degrades to\r\n * a no-op in SSR, unsupported browsers, or when permission is denied.\r\n */\r\nexport class AlertNotifier {\r\n private options: AlertNotifyOptions;\r\n private audioCtx: AudioContext | null = null;\r\n private audioEl: HTMLAudioElement | null = null;\r\n private permissionAsked = false;\r\n\r\n constructor(options: AlertNotifyOptions = {}) {\r\n this.options = options;\r\n if (typeof options.sound === 'string') {\r\n try {\r\n this.audioEl = new Audio(options.sound);\r\n this.audioEl.preload = 'auto';\r\n } catch {\r\n this.audioEl = null;\r\n }\r\n }\r\n // Request notification permission up front so the first alert isn't silent.\r\n if (options.desktop) this.ensurePermission();\r\n }\r\n\r\n setOptions(options: AlertNotifyOptions): void {\r\n this.options = { ...this.options, ...options };\r\n }\r\n\r\n /** Fire the configured notifications for a triggered alert. */\r\n notify(message: string): void {\r\n if (this.options.sound) this.playSound();\r\n if (this.options.desktop) this.showDesktop(message);\r\n }\r\n\r\n private playSound(): void {\r\n if (this.audioEl) {\r\n this.audioEl.currentTime = 0;\r\n void this.audioEl.play().catch(() => {});\r\n return;\r\n }\r\n this.beep();\r\n }\r\n\r\n /** A short two-tone beep via Web Audio — no asset required. */\r\n private beep(): void {\r\n try {\r\n const Ctx = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\r\n if (!Ctx) return;\r\n if (!this.audioCtx) this.audioCtx = new Ctx();\r\n const ctx = this.audioCtx;\r\n const now = ctx.currentTime;\r\n const gain = ctx.createGain();\r\n gain.gain.setValueAtTime(0.0001, now);\r\n gain.gain.exponentialRampToValueAtTime(0.2, now + 0.01);\r\n gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.35);\r\n gain.connect(ctx.destination);\r\n const osc = ctx.createOscillator();\r\n osc.type = 'sine';\r\n osc.frequency.setValueAtTime(880, now);\r\n osc.frequency.setValueAtTime(1320, now + 0.16);\r\n osc.connect(gain);\r\n osc.start(now);\r\n osc.stop(now + 0.36);\r\n } catch {\r\n // Audio unavailable or blocked by autoplay policy — silent.\r\n }\r\n }\r\n\r\n private ensurePermission(): void {\r\n if (this.permissionAsked) return;\r\n this.permissionAsked = true;\r\n if (typeof Notification === 'undefined') return;\r\n if (Notification.permission === 'default') {\r\n void Notification.requestPermission().catch(() => {});\r\n }\r\n }\r\n\r\n private showDesktop(message: string): void {\r\n if (typeof Notification === 'undefined') return;\r\n if (Notification.permission !== 'granted') {\r\n this.ensurePermission();\r\n return;\r\n }\r\n try {\r\n new Notification(this.options.title ?? 'Price alert', { body: message });\r\n } catch {\r\n // Some browsers throw if not invoked from a user gesture — ignore.\r\n }\r\n }\r\n\r\n destroy(): void {\r\n try {\r\n void this.audioCtx?.close();\r\n } catch {\r\n // ignore\r\n }\r\n this.audioCtx = null;\r\n this.audioEl = null;\r\n }\r\n}\r\n","import type { DepthData } from '@tradecanvas/commons';\r\n\r\nexport interface LadderRow {\r\n price: number;\r\n bidVolume: number;\r\n askVolume: number;\r\n}\r\n\r\nexport interface LadderModel {\r\n /** Rows ordered high → low price (asks on top, bids below). */\r\n rows: LadderRow[];\r\n /** Largest single-side volume across the shown rows (for bar scaling). */\r\n maxVolume: number;\r\n /** Midpoint between best bid and best ask, or null if a side is empty. */\r\n mid: number | null;\r\n}\r\n\r\n/**\r\n * Build a depth-of-market ladder from an order book: the best `maxLevels` asks\r\n * (lowest prices) and best `maxLevels` bids (highest prices), merged into rows\r\n * ordered high→low. A price present on both sides is merged into one row.\r\n */\r\nexport function buildLadderRows(data: DepthData, maxLevels = 12): LadderModel {\r\n const asks = [...data.asks].sort((a, b) => a.price - b.price).slice(0, maxLevels);\r\n const bids = [...data.bids].sort((a, b) => b.price - a.price).slice(0, maxLevels);\r\n\r\n const bestAsk = asks.length > 0 ? asks[0].price : null;\r\n const bestBid = bids.length > 0 ? bids[0].price : null;\r\n const mid = bestAsk !== null && bestBid !== null ? (bestAsk + bestBid) / 2 : null;\r\n\r\n const byPrice = new Map<number, LadderRow>();\r\n const rowAt = (price: number): LadderRow => {\r\n let row = byPrice.get(price);\r\n if (!row) {\r\n row = { price, bidVolume: 0, askVolume: 0 };\r\n byPrice.set(price, row);\r\n }\r\n return row;\r\n };\r\n for (const a of asks) rowAt(a.price).askVolume += a.volume;\r\n for (const b of bids) rowAt(b.price).bidVolume += b.volume;\r\n\r\n const rows = [...byPrice.values()].sort((a, b) => b.price - a.price);\r\n let maxVolume = 0;\r\n for (const r of rows) maxVolume = Math.max(maxVolume, r.bidVolume, r.askVolume);\r\n\r\n return { rows, maxVolume, mid };\r\n}\r\n","import type { DepthData } from '@tradecanvas/commons';\r\nimport { createIcon } from './icons.js';\r\nimport { buildLadderRows, type LadderModel } from './ladderRows.js';\r\n\r\nexport interface DepthLadderCallbacks {\r\n /** Buy at `price` (clicked an ask cell) or sell at `price` (clicked a bid cell). */\r\n onTrade: (side: 'buy' | 'sell', price: number) => void;\r\n formatPrice: (price: number) => string;\r\n}\r\n\r\n/**\r\n * Depth-of-market ladder (DOM). Renders the order book as price rows with bid\r\n * and ask size columns; clicking an ask cell buys at that price, a bid cell\r\n * sells. Fed by `setData(depth)`; the bar widths scale to the largest visible\r\n * size.\r\n */\r\nexport class WidgetDepthLadder {\r\n private el: HTMLDivElement;\r\n private bodyEl: HTMLDivElement;\r\n private callbacks: DepthLadderCallbacks;\r\n private open = false;\r\n private levels: number;\r\n\r\n constructor(host: HTMLElement, callbacks: DepthLadderCallbacks, levels = 12) {\r\n this.callbacks = callbacks;\r\n this.levels = levels;\r\n\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-ladder';\r\n this.el.hidden = true;\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-ladder-header';\r\n const title = document.createElement('span');\r\n title.textContent = 'Depth Ladder';\r\n const closeBtn = document.createElement('button');\r\n closeBtn.type = 'button';\r\n closeBtn.className = 'tcw-ladder-close';\r\n closeBtn.setAttribute('aria-label', 'Close');\r\n closeBtn.innerHTML = createIcon('x', 14);\r\n closeBtn.addEventListener('click', () => this.close());\r\n header.appendChild(title);\r\n header.appendChild(closeBtn);\r\n this.el.appendChild(header);\r\n\r\n const cols = document.createElement('div');\r\n cols.className = 'tcw-ladder-cols';\r\n cols.innerHTML = '<span>Bid</span><span>Price</span><span>Ask</span>';\r\n this.el.appendChild(cols);\r\n\r\n this.bodyEl = document.createElement('div');\r\n this.bodyEl.className = 'tcw-ladder-body';\r\n this.el.appendChild(this.bodyEl);\r\n\r\n host.appendChild(this.el);\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.open;\r\n }\r\n\r\n toggle(): void {\r\n this.open ? this.close() : this.openPanel();\r\n }\r\n\r\n openPanel(): void {\r\n this.open = true;\r\n this.el.hidden = false;\r\n }\r\n\r\n close(): void {\r\n this.open = false;\r\n this.el.hidden = true;\r\n }\r\n\r\n setData(depth: DepthData | null): void {\r\n if (!depth) {\r\n this.renderEmpty();\r\n return;\r\n }\r\n this.render(buildLadderRows(depth, this.levels));\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n }\r\n\r\n private renderEmpty(): void {\r\n this.bodyEl.replaceChildren();\r\n const empty = document.createElement('div');\r\n empty.className = 'tcw-ladder-empty';\r\n empty.textContent = 'No order-book data';\r\n this.bodyEl.appendChild(empty);\r\n }\r\n\r\n private render(model: LadderModel): void {\r\n this.bodyEl.replaceChildren();\r\n if (model.rows.length === 0) {\r\n this.renderEmpty();\r\n return;\r\n }\r\n const inv = model.maxVolume > 0 ? 1 / model.maxVolume : 0;\r\n\r\n for (const row of model.rows) {\r\n const isAsk = row.askVolume > 0;\r\n const tr = document.createElement('div');\r\n tr.className = 'tcw-ladder-row';\r\n\r\n // Bid cell (click → sell at price)\r\n const bid = document.createElement('button');\r\n bid.type = 'button';\r\n bid.className = 'tcw-ladder-cell tcw-ladder-bid';\r\n if (row.bidVolume > 0) {\r\n bid.textContent = formatSize(row.bidVolume);\r\n bid.style.setProperty('--w', `${(row.bidVolume * inv * 100).toFixed(1)}%`);\r\n bid.title = `Sell @ ${this.callbacks.formatPrice(row.price)}`;\r\n bid.addEventListener('click', () => this.callbacks.onTrade('sell', row.price));\r\n } else {\r\n bid.disabled = true;\r\n }\r\n\r\n const price = document.createElement('div');\r\n price.className = `tcw-ladder-price ${isAsk ? 'tcw-ask' : 'tcw-bid'}`;\r\n price.textContent = this.callbacks.formatPrice(row.price);\r\n\r\n // Ask cell (click → buy at price)\r\n const ask = document.createElement('button');\r\n ask.type = 'button';\r\n ask.className = 'tcw-ladder-cell tcw-ladder-ask';\r\n if (row.askVolume > 0) {\r\n ask.textContent = formatSize(row.askVolume);\r\n ask.style.setProperty('--w', `${(row.askVolume * inv * 100).toFixed(1)}%`);\r\n ask.title = `Buy @ ${this.callbacks.formatPrice(row.price)}`;\r\n ask.addEventListener('click', () => this.callbacks.onTrade('buy', row.price));\r\n } else {\r\n ask.disabled = true;\r\n }\r\n\r\n tr.appendChild(bid);\r\n tr.appendChild(price);\r\n tr.appendChild(ask);\r\n this.bodyEl.appendChild(tr);\r\n }\r\n }\r\n}\r\n\r\nfunction formatSize(v: number): string {\r\n if (v >= 1000) return (v / 1000).toFixed(1) + 'k';\r\n if (v >= 1) return v.toFixed(2).replace(/\\.00$/, '');\r\n return v.toPrecision(2);\r\n}\r\n","import { createIcon } from './icons.js';\r\n\r\nexport interface DataWindowIndicator {\r\n name: string;\r\n values: { key: string; value: number }[];\r\n}\r\n\r\nexport interface DataWindowModel {\r\n ohlc: { open: number; high: number; low: number; close: number; volume: number } | null;\r\n change: number;\r\n changePct: number;\r\n indicators: DataWindowIndicator[];\r\n}\r\n\r\nexport interface DataWindowCallbacks {\r\n formatPrice: (price: number) => string;\r\n}\r\n\r\n/**\r\n * Data Window — a floating readout of the exact O/H/L/C/V, change, and every\r\n * active indicator value at the hovered bar. Updated from `crosshairMove`.\r\n */\r\nexport class WidgetDataWindow {\r\n private el: HTMLDivElement;\r\n private bodyEl: HTMLDivElement;\r\n private callbacks: DataWindowCallbacks;\r\n private open = false;\r\n\r\n constructor(host: HTMLElement, callbacks: DataWindowCallbacks) {\r\n this.callbacks = callbacks;\r\n\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-datawin';\r\n this.el.hidden = true;\r\n\r\n const header = document.createElement('div');\r\n header.className = 'tcw-datawin-header';\r\n const title = document.createElement('span');\r\n title.textContent = 'Data Window';\r\n const closeBtn = document.createElement('button');\r\n closeBtn.type = 'button';\r\n closeBtn.className = 'tcw-datawin-close';\r\n closeBtn.setAttribute('aria-label', 'Close');\r\n closeBtn.innerHTML = createIcon('x', 14);\r\n closeBtn.addEventListener('click', () => this.close());\r\n header.appendChild(title);\r\n header.appendChild(closeBtn);\r\n this.el.appendChild(header);\r\n\r\n this.bodyEl = document.createElement('div');\r\n this.bodyEl.className = 'tcw-datawin-body';\r\n this.el.appendChild(this.bodyEl);\r\n\r\n host.appendChild(this.el);\r\n }\r\n\r\n isOpen(): boolean {\r\n return this.open;\r\n }\r\n\r\n toggle(): void {\r\n this.open ? this.close() : this.openPanel();\r\n }\r\n\r\n openPanel(): void {\r\n this.open = true;\r\n this.el.hidden = false;\r\n }\r\n\r\n close(): void {\r\n this.open = false;\r\n this.el.hidden = true;\r\n }\r\n\r\n destroy(): void {\r\n this.el.remove();\r\n }\r\n\r\n render(model: DataWindowModel): void {\r\n if (!this.open) return;\r\n this.bodyEl.replaceChildren();\r\n\r\n if (!model.ohlc) {\r\n const empty = document.createElement('div');\r\n empty.className = 'tcw-datawin-empty';\r\n empty.textContent = 'Hover the chart';\r\n this.bodyEl.appendChild(empty);\r\n return;\r\n }\r\n\r\n const fp = this.callbacks.formatPrice;\r\n const o = model.ohlc;\r\n this.bodyEl.appendChild(this.row('Open', fp(o.open)));\r\n this.bodyEl.appendChild(this.row('High', fp(o.high)));\r\n this.bodyEl.appendChild(this.row('Low', fp(o.low)));\r\n this.bodyEl.appendChild(this.row('Close', fp(o.close)));\r\n const tone = model.change > 0 ? 'up' : model.change < 0 ? 'down' : '';\r\n const sign = model.change > 0 ? '+' : '';\r\n this.bodyEl.appendChild(this.row('Change', `${sign}${fp(model.change)} (${sign}${model.changePct.toFixed(2)}%)`, tone));\r\n this.bodyEl.appendChild(this.row('Volume', formatVolume(o.volume)));\r\n\r\n for (const ind of model.indicators) {\r\n const head = document.createElement('div');\r\n head.className = 'tcw-datawin-sub';\r\n head.textContent = ind.name;\r\n this.bodyEl.appendChild(head);\r\n for (const v of ind.values) {\r\n this.bodyEl.appendChild(this.row(v.key, formatNumber(v.value)));\r\n }\r\n }\r\n }\r\n\r\n private row(label: string, value: string, tone = ''): HTMLDivElement {\r\n const row = document.createElement('div');\r\n row.className = 'tcw-datawin-row';\r\n const l = document.createElement('span');\r\n l.className = 'tcw-datawin-label';\r\n l.textContent = label;\r\n const v = document.createElement('span');\r\n v.className = `tcw-datawin-value${tone ? ` tcw-${tone}` : ''}`;\r\n v.textContent = value;\r\n row.appendChild(l);\r\n row.appendChild(v);\r\n return row;\r\n }\r\n}\r\n\r\nfunction formatNumber(v: number): string {\r\n if (!Number.isFinite(v)) return '—';\r\n const abs = Math.abs(v);\r\n if (abs >= 1000) return v.toFixed(2);\r\n if (abs >= 1) return v.toFixed(4);\r\n return v.toPrecision(4);\r\n}\r\n\r\nfunction formatVolume(v: number): string {\r\n if (v >= 1_000_000_000) return (v / 1_000_000_000).toFixed(2) + 'B';\r\n if (v >= 1_000_000) return (v / 1_000_000).toFixed(2) + 'M';\r\n if (v >= 1_000) return (v / 1_000).toFixed(2) + 'K';\r\n return v.toFixed(0);\r\n}\r\n","import type { ChartType, TimeFrame, DrawingState, PriceScaleMode } from '@tradecanvas/commons';\r\n\r\nexport interface ShareableIndicator {\r\n id: string;\r\n params: Record<string, number | string | boolean>;\r\n}\r\n\r\nexport interface ShareableWidgetState {\r\n v: 1;\r\n symbol: string;\r\n timeframe: TimeFrame;\r\n chartType: ChartType;\r\n scaleMode: PriceScaleMode;\r\n indicators: ShareableIndicator[];\r\n drawings: DrawingState[];\r\n}\r\n\r\ninterface NodeBufferCtor {\r\n from(input: string, encoding: string): { toString(encoding: string): string };\r\n}\r\nconst nodeBuffer = (globalThis as { Buffer?: NodeBufferCtor }).Buffer;\r\n\r\nfunction utf8ToBase64(str: string): string {\r\n if (nodeBuffer) return nodeBuffer.from(str, 'utf8').toString('base64');\r\n const bytes = new TextEncoder().encode(str);\r\n let bin = '';\r\n for (const b of bytes) bin += String.fromCharCode(b);\r\n return btoa(bin);\r\n}\r\n\r\nfunction base64ToUtf8(b64: string): string {\r\n if (nodeBuffer) return nodeBuffer.from(b64, 'base64').toString('utf8');\r\n const bin = atob(b64);\r\n const bytes = new Uint8Array(bin.length);\r\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\r\n return new TextDecoder().decode(bytes);\r\n}\r\n\r\nfunction toBase64Url(b64: string): string {\r\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\r\n}\r\n\r\nfunction fromBase64Url(s: string): string {\r\n const b64 = s.replace(/-/g, '+').replace(/_/g, '/');\r\n const pad = b64.length % 4 === 0 ? '' : '='.repeat(4 - (b64.length % 4));\r\n return b64 + pad;\r\n}\r\n\r\n/** Encode a shareable widget state to a compact, URL-safe string. */\r\nexport function encodeWidgetState(state: ShareableWidgetState): string {\r\n return toBase64Url(utf8ToBase64(JSON.stringify(state)));\r\n}\r\n\r\n/**\r\n * Decode a shareable-state string. Returns null for anything malformed or of an\r\n * unknown version — callers should treat null as \"ignore and keep current view\".\r\n */\r\nexport function decodeWidgetState(encoded: string): ShareableWidgetState | null {\r\n if (!encoded) return null;\r\n try {\r\n const json = base64ToUtf8(fromBase64Url(encoded));\r\n const obj = JSON.parse(json);\r\n if (!obj || obj.v !== 1 || typeof obj.symbol !== 'string') return null;\r\n return {\r\n v: 1,\r\n symbol: obj.symbol,\r\n timeframe: obj.timeframe,\r\n chartType: obj.chartType,\r\n scaleMode: obj.scaleMode ?? 'regular',\r\n indicators: Array.isArray(obj.indicators) ? obj.indicators : [],\r\n drawings: Array.isArray(obj.drawings) ? obj.drawings : [],\r\n };\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nconst HASH_KEY = 'tcw';\r\n\r\n/** Read a `#tcw=<encoded>` fragment from a URL hash, or null. */\r\nexport function readShareHash(hash: string): string | null {\r\n const clean = hash.startsWith('#') ? hash.slice(1) : hash;\r\n for (const part of clean.split('&')) {\r\n const eq = part.indexOf('=');\r\n if (eq > 0 && part.slice(0, eq) === HASH_KEY) return decodeURIComponent(part.slice(eq + 1));\r\n }\r\n return null;\r\n}\r\n\r\n/** Build a shareable URL by replacing the `tcw` hash param on `base`. */\r\nexport function buildShareUrl(base: string, encoded: string): string {\r\n const [withoutHash] = base.split('#');\r\n return `${withoutHash}#${HASH_KEY}=${encoded}`;\r\n}\r\n","/**\r\n * i18n for ChartWidget's own chrome (toolbar, watchlist, indicator picker,\r\n * status bar, settings panel, hotkey sheet). This does NOT translate\r\n * data-driven labels sourced from `widgetConfig.ts` (the 69 indicator\r\n * display names, drawing-tool names, timezone/locale option labels) — those\r\n * stay in English for now; see README \"Widget i18n\" for the current\r\n * coverage and how to extend it via `messages`.\r\n */\r\n\r\nexport type MessageKey = typeof EN_MESSAGES extends Record<infer K, string> ? K : never;\r\n\r\nexport const EN_MESSAGES = {\r\n // Toolbar\r\n 'toolbar.indicators': 'Indicators',\r\n 'toolbar.indicators.popular': 'Popular',\r\n 'toolbar.indicators.all': 'All',\r\n 'indicatorType.overlay': 'overlay',\r\n 'indicatorType.panel': 'panel',\r\n 'toolbar.replay': 'Bar replay',\r\n 'toolbar.longBracket': 'Long bracket',\r\n 'toolbar.shortBracket': 'Short bracket',\r\n 'toolbar.depthLadder': 'Depth ladder',\r\n 'toolbar.objects': 'Objects',\r\n 'toolbar.priceAlerts': 'Price alerts',\r\n 'toolbar.screenshot': 'Screenshot',\r\n 'toolbar.settings': 'Chart Settings',\r\n 'toolbar.toggleTheme': 'Toggle theme',\r\n\r\n // Chart types\r\n 'chartType.candlestick': 'Candlestick',\r\n 'chartType.line': 'Line',\r\n 'chartType.area': 'Area',\r\n 'chartType.bar': 'Bar',\r\n 'chartType.heikinAshi': 'Heikin-Ashi',\r\n 'chartType.hollowCandle': 'Hollow Candle',\r\n 'chartType.baseline': 'Baseline',\r\n 'chartType.volumeCandles': 'Volume Candles',\r\n 'chartType.equivolume': 'Equivolume',\r\n 'chartType.hlcArea': 'HLC Area',\r\n 'chartType.stepLine': 'Step Line',\r\n 'chartType.lineWithMarkers': 'Line + Markers',\r\n\r\n // Watchlist\r\n 'watchlist.title': 'Watchlist',\r\n\r\n // Status bar / connection\r\n 'status.connecting': 'Connecting...',\r\n 'status.live': 'Live',\r\n 'status.connectionFailed': 'Connection failed',\r\n 'status.loading': 'Loading chart...',\r\n\r\n // Settings panel\r\n 'settings.title': 'Chart Settings',\r\n 'settings.tab.style': 'style',\r\n 'settings.tab.display': 'display',\r\n 'settings.tab.scale': 'scale',\r\n 'settings.resetToDefaults': 'Reset to defaults',\r\n 'settings.done': 'Done',\r\n 'settings.section.candleColors': 'Candle Colors',\r\n 'settings.section.background': 'Background',\r\n\r\n // Hotkey sheet\r\n 'hotkeys.title': 'Keyboard shortcuts',\r\n 'hotkeys.close': 'Close',\r\n 'hotkeys.gotIt': 'Got it',\r\n 'hotkeys.group.searchNavigation': 'Search & navigation',\r\n 'hotkeys.group.chartManipulation': 'Chart manipulation',\r\n 'hotkeys.group.touch': 'Touch (mobile / tablet)',\r\n 'hotkeys.group.keyboard': 'Keyboard',\r\n 'hotkeys.group.drawing': 'Drawing',\r\n} as const;\r\n\r\nexport const VI_MESSAGES: Partial<Record<MessageKey, string>> = {\r\n 'toolbar.indicators': 'Chỉ báo',\r\n 'toolbar.indicators.popular': 'Phổ biến',\r\n 'toolbar.indicators.all': 'Tất cả',\r\n 'indicatorType.overlay': 'phủ lên',\r\n 'indicatorType.panel': 'bảng riêng',\r\n 'toolbar.replay': 'Phát lại',\r\n 'toolbar.longBracket': 'Lệnh Long',\r\n 'toolbar.shortBracket': 'Lệnh Short',\r\n 'toolbar.depthLadder': 'Sổ lệnh',\r\n 'toolbar.objects': 'Đối tượng',\r\n 'toolbar.priceAlerts': 'Cảnh báo giá',\r\n 'toolbar.screenshot': 'Chụp màn hình',\r\n 'toolbar.settings': 'Cài đặt biểu đồ',\r\n 'toolbar.toggleTheme': 'Đổi giao diện',\r\n\r\n 'chartType.candlestick': 'Nến',\r\n 'chartType.line': 'Đường',\r\n 'chartType.area': 'Vùng',\r\n 'chartType.bar': 'Thanh',\r\n 'chartType.heikinAshi': 'Heikin-Ashi',\r\n 'chartType.hollowCandle': 'Nến rỗng',\r\n 'chartType.baseline': 'Đường cơ sở',\r\n 'chartType.volumeCandles': 'Nến khối lượng',\r\n 'chartType.equivolume': 'Equivolume',\r\n 'chartType.hlcArea': 'Vùng HLC',\r\n 'chartType.stepLine': 'Đường bậc thang',\r\n 'chartType.lineWithMarkers': 'Đường + điểm đánh dấu',\r\n\r\n 'watchlist.title': 'Danh mục theo dõi',\r\n\r\n 'status.connecting': 'Đang kết nối...',\r\n 'status.live': 'Trực tiếp',\r\n 'status.connectionFailed': 'Kết nối thất bại',\r\n 'status.loading': 'Đang tải biểu đồ...',\r\n\r\n 'settings.title': 'Cài đặt biểu đồ',\r\n 'settings.tab.style': 'Giao diện',\r\n 'settings.tab.display': 'Hiển thị',\r\n 'settings.tab.scale': 'Thang giá',\r\n 'settings.resetToDefaults': 'Khôi phục mặc định',\r\n 'settings.done': 'Xong',\r\n 'settings.section.candleColors': 'Màu nến',\r\n 'settings.section.background': 'Nền',\r\n\r\n 'hotkeys.title': 'Phím tắt',\r\n 'hotkeys.close': 'Đóng',\r\n 'hotkeys.gotIt': 'Đã hiểu',\r\n 'hotkeys.group.searchNavigation': 'Tìm kiếm & điều hướng',\r\n 'hotkeys.group.chartManipulation': 'Thao tác biểu đồ',\r\n 'hotkeys.group.touch': 'Cảm ứng (di động / máy tính bảng)',\r\n 'hotkeys.group.keyboard': 'Bàn phím',\r\n 'hotkeys.group.drawing': 'Vẽ',\r\n};\r\n\r\nexport const BUILTIN_LOCALES: Record<string, Partial<Record<MessageKey, string>>> = {\r\n en: EN_MESSAGES,\r\n vi: VI_MESSAGES,\r\n};\r\n\r\n/**\r\n * Resolve the widget's message table: built-in English as the base, the\r\n * requested built-in locale layered on top (falling back key-by-key to\r\n * English for anything that locale hasn't translated yet), then host\r\n * `messages` overrides layered last so they always win.\r\n */\r\nexport function resolveMessages(\r\n locale: string | undefined,\r\n overrides: Partial<Record<MessageKey, string>> | undefined,\r\n): Record<MessageKey, string> {\r\n const base = { ...EN_MESSAGES } as Record<MessageKey, string>;\r\n const localeTable = locale ? BUILTIN_LOCALES[locale] : undefined;\r\n if (localeTable) Object.assign(base, localeTable);\r\n if (overrides) Object.assign(base, overrides);\r\n return base;\r\n}\r\n\r\nexport type Translator = (key: MessageKey) => string;\r\n\r\nexport function createTranslator(messages: Record<MessageKey, string>): Translator {\r\n return (key: MessageKey) => messages[key] ?? EN_MESSAGES[key] ?? key;\r\n}\r\n","/**\r\n * How long a symbol/timeframe switch may run before the loading veil\r\n * appears. Faster loads just swap the chart in place — flashing a loader for\r\n * a 150 ms request reads as flicker, not feedback.\r\n */\r\nexport const LOADING_SHOW_DELAY_MS = 200;\r\n\r\nconst SKELETON_BARS = 20;\r\n\r\n/**\r\n * TradingView-style loading state for the chart area.\r\n *\r\n * - First load (nothing to show yet): opaque skeleton, shown immediately.\r\n * - Switch (a chart is already on screen): the old chart stays visible and is\r\n * veiled only if the load outlasts `LOADING_SHOW_DELAY_MS`.\r\n * - Failure: the label becomes the error message until the next load or a\r\n * successful retry ends it.\r\n */\r\nexport class WidgetLoadingOverlay {\r\n private readonly el: HTMLDivElement;\r\n private readonly label: HTMLDivElement;\r\n private showTimer: ReturnType<typeof setTimeout> | null = null;\r\n // Starts loading: the widget mounts before its first bars arrive.\r\n private phase: 'idle' | 'loading' | 'failed' = 'loading';\r\n\r\n constructor(parent: HTMLElement, private readonly loadingText: string) {\r\n this.el = document.createElement('div');\r\n this.el.className = 'tcw-loading-overlay';\r\n this.el.setAttribute('role', 'status');\r\n this.el.setAttribute('aria-live', 'polite');\r\n\r\n // Bars + label share a card: transparent on the opaque first-load screen,\r\n // a raised panel when veiling a chart so it reads over the candles.\r\n const card = document.createElement('div');\r\n card.className = 'tcw-loading-card';\r\n\r\n const bars = document.createElement('div');\r\n bars.className = 'tcw-loading-bars';\r\n for (let i = 0; i < SKELETON_BARS; i++) {\r\n const bar = document.createElement('span');\r\n bar.className = 'tcw-loading-bar';\r\n bar.style.height = `${20 + Math.round(Math.sin(i * 0.9) * 18 + 18)}px`;\r\n bar.style.animationDelay = `${i * 45}ms`;\r\n bars.appendChild(bar);\r\n }\r\n card.appendChild(bars);\r\n\r\n this.label = document.createElement('div');\r\n this.label.className = 'tcw-loading-label';\r\n this.label.textContent = loadingText;\r\n card.appendChild(this.label);\r\n this.el.appendChild(card);\r\n\r\n parent.appendChild(this.el);\r\n }\r\n\r\n /**\r\n * Start a load. `hasContent`: a chart is already on screen to keep showing.\r\n * `immediate`: skip the show delay — the caller knows the load is slow.\r\n */\r\n begin(hasContent: boolean, immediate = false): void {\r\n this.phase = 'loading';\r\n this.clearTimer();\r\n this.label.textContent = this.loadingText;\r\n this.el.classList.remove('tcw-loading-overlay--error');\r\n this.el.classList.toggle('tcw-loading-overlay--veil', hasContent);\r\n if (!hasContent || immediate || this.isShown()) {\r\n this.el.classList.remove('tcw-loading-overlay--hidden');\r\n return;\r\n }\r\n this.showTimer = setTimeout(() => {\r\n this.showTimer = null;\r\n this.el.classList.remove('tcw-loading-overlay--hidden');\r\n }, LOADING_SHOW_DELAY_MS);\r\n }\r\n\r\n /** The load finished: fade out, or never appear if still within the delay. */\r\n end(): void {\r\n this.phase = 'idle';\r\n this.clearTimer();\r\n this.el.classList.add('tcw-loading-overlay--hidden');\r\n }\r\n\r\n /** The current load failed (a retry may still be running): show why. */\r\n fail(message: string): void {\r\n if (this.phase === 'idle') return;\r\n this.phase = 'failed';\r\n this.clearTimer();\r\n this.label.textContent = message;\r\n this.el.classList.add('tcw-loading-overlay--error');\r\n this.el.classList.remove('tcw-loading-overlay--hidden');\r\n }\r\n\r\n /** Whether a load is in progress (begun, not yet ended) — failed included. */\r\n isActive(): boolean {\r\n return this.phase !== 'idle';\r\n }\r\n\r\n /** Whether the current load failed and is waiting on a retry. */\r\n hasFailed(): boolean {\r\n return this.phase === 'failed';\r\n }\r\n\r\n /** Whether the overlay is on screen (or fading in). */\r\n isShown(): boolean {\r\n return !this.el.classList.contains('tcw-loading-overlay--hidden');\r\n }\r\n\r\n destroy(): void {\r\n this.clearTimer();\r\n this.el.remove();\r\n }\r\n\r\n private clearTimer(): void {\r\n if (this.showTimer !== null) {\r\n clearTimeout(this.showTimer);\r\n this.showTimer = null;\r\n }\r\n }\r\n}\r\n","import type { ChartType, DrawingToolType, Theme, TimeFrame } from '@tradecanvas/commons';\r\nimport { Chart } from '../Chart.js';\r\nimport { DARK_THEME, LIGHT_THEME } from '@tradecanvas/commons';\r\nimport type { ChartWidgetOptions, WidgetState, ChartSettingsState } from './types.js';\r\nimport { TIMEFRAMES, CHART_TYPES, INDICATORS, POPULAR_INDICATORS, DRAWING_TOOL_GROUPS, DEFAULT_SYMBOLS, DEFAULT_SETTINGS } from './widgetConfig.js';\r\nimport { injectWidgetStyles, removeWidgetStyles } from './WidgetStyles.js';\r\nimport { WidgetToolbar } from './WidgetToolbar.js';\r\nimport { WidgetDrawingSidebar } from './WidgetDrawingSidebar.js';\r\nimport { WidgetSettings } from './WidgetSettings.js';\r\nimport { WidgetStatusBar } from './WidgetStatusBar.js';\r\nimport { WidgetCommandPalette } from './WidgetCommandPalette.js';\r\nimport { WidgetSymbolSearch } from './WidgetSymbolSearch.js';\r\nimport { WidgetHotkeySheet } from './WidgetHotkeySheet.js';\r\nimport { WidgetReplayBar } from './WidgetReplayBar.js';\r\nimport { WidgetWatchlist, type WatchlistEntry } from './WidgetWatchlist.js';\r\nimport { WidgetAlertsPanel } from './WidgetAlertsPanel.js';\r\nimport { WidgetObjectTree, drawingTypeLabel } from './WidgetObjectTree.js';\r\nimport { WidgetIndicatorSettings } from './WidgetIndicatorSettings.js';\r\nimport { WidgetDrawingStyle } from './WidgetDrawingStyle.js';\r\nimport { DrawingTemplateStore } from './DrawingTemplateStore.js';\r\nimport { DrawingFavoritesStore } from './DrawingFavoritesStore.js';\r\nimport { WidgetBracketBar } from './WidgetBracketBar.js';\r\nimport { AlertNotifier } from './AlertNotifier.js';\r\nimport { WidgetDepthLadder } from './WidgetDepthLadder.js';\r\nimport { WidgetDataWindow, type DataWindowModel } from './WidgetDataWindow.js';\r\nimport type { DepthData } from '@tradecanvas/commons';\r\nimport { encodeWidgetState, decodeWidgetState, readShareHash, buildShareUrl } from './widgetShareState.js';\r\nimport { DragDropImporter, resampleOHLCV, inferTimeframeMs } from '../io/index.js';\r\nimport type { DataSeries } from '@tradecanvas/commons';\r\nimport { timeframeToMs } from '@tradecanvas/commons';\r\nimport type { CommandItem } from './WidgetCommandPalette.js';\r\nimport { resolveMessages, createTranslator, type Translator } from './i18n.js';\r\nimport { WidgetLoadingOverlay } from './WidgetLoadingOverlay.js';\r\n\r\n/**\r\n * A local timeframe switch (resampling static data) that took at least this\r\n * long last time is announced with the loading veil before it runs, since the\r\n * main thread is about to be busy for several frames.\r\n */\r\nconst SLOW_LOCAL_SWITCH_MS = 48;\r\n/** Base series this long are assumed slow to resample before any timing exists. */\r\nconst LARGE_SERIES_BARS = 50_000;\r\n\r\n/** Upper bound on waiting for a paint — rAF never fires in a frame that isn't rendering. */\r\nconst PAINT_WAIT_MAX_MS = 100;\r\n\r\n/** Resolve once the browser has painted the current DOM state (or gave up waiting). */\r\nfunction afterPaint(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (typeof requestAnimationFrame !== 'function' || document.hidden) {\r\n setTimeout(resolve, 0);\r\n return;\r\n }\r\n const fallback = setTimeout(resolve, PAINT_WAIT_MAX_MS);\r\n requestAnimationFrame(() => setTimeout(() => {\r\n clearTimeout(fallback);\r\n resolve();\r\n }, 0));\r\n });\r\n}\r\n\r\n/** Distinct line colors for comparison overlays, cycled by add order. */\r\nconst COMPARE_COLORS = ['#f7931a', '#627eea', '#26a17b', '#e84142', '#8247e5', '#f3ba2f'];\r\n\r\nexport class ChartWidget {\r\n private chart: Chart;\r\n private state: WidgetState;\r\n private toolbar: WidgetToolbar | null = null;\r\n private sidebar: WidgetDrawingSidebar | null = null;\r\n private settings: WidgetSettings | null = null;\r\n private statusBar: WidgetStatusBar | null = null;\r\n private commandPalette: WidgetCommandPalette | null = null;\r\n private symbolSearch: WidgetSymbolSearch | null = null;\r\n private hotkeySheet: WidgetHotkeySheet | null = null;\r\n private replayBar: WidgetReplayBar | null = null;\r\n private dragDrop: DragDropImporter | null = null;\r\n private alertsPanel: WidgetAlertsPanel | null = null;\r\n private objectTree: WidgetObjectTree | null = null;\r\n private indicatorSettings: WidgetIndicatorSettings | null = null;\r\n private drawingStyle: WidgetDrawingStyle | null = null;\r\n private bracketBar: WidgetBracketBar | null = null;\r\n private alertNotifier: AlertNotifier | null = null;\r\n private depthLadder: WidgetDepthLadder | null = null;\r\n private dataWindow: WidgetDataWindow | null = null;\r\n private lastHoverIndex: number | null = null;\r\n private favoritesStore = new DrawingFavoritesStore();\r\n private watchlist: WidgetWatchlist | null = null;\r\n private watchlistSparkBuffer = new Map<string, number[]>();\r\n private sessionRefPrice: number | null = null;\r\n /** Per-symbol refPrice explicitly pushed by the host via `setWatchlistEntry` — takes precedence over `sessionRefPrice`. */\r\n private hostWatchlistRefPrice = new Map<string, number>();\r\n private watchlistInterval: ReturnType<typeof setInterval> | null = null;\r\n private replayOriginalData: DataSeries | null = null;\r\n private replayPollInterval: ReturnType<typeof setInterval> | null = null;\r\n private replaySpeed = 5;\r\n private layoutKeyPrefix: string | null = null;\r\n private layoutDebounceMs = 1500;\r\n private activeLayoutKey: string | null = null;\r\n private root: HTMLDivElement;\r\n private chartContainer: HTMLDivElement;\r\n private loading: WidgetLoadingOverlay;\r\n /** Bumped per stream connect; a connect that is no longer the latest leaves the UI to the newer one. */\r\n private connectSeq = 0;\r\n /** Bumped per local resample and widget.setData; a deferred local switch that is no longer the latest is skipped. */\r\n private localSeq = 0;\r\n /** Duration of the last local resample + setData, for SLOW_LOCAL_SWITCH_MS. */\r\n private lastLocalSwitchMs = 0;\r\n private destroyed = false;\r\n private options: ChartWidgetOptions;\r\n private symbols: string[];\r\n private settingsState: ChartSettingsState;\r\n private t: Translator;\r\n private adapter: import('@tradecanvas/commons').DataAdapter | null = null;\r\n private boundGlobalKeydown: ((e: KeyboardEvent) => void) | null = null;\r\n // Finest-resolution series the widget has seen. When no live adapter is\r\n // attached, switching to a coarser timeframe resamples from this base\r\n // instead of refetching. See `setData` / `applyTimeframeData`.\r\n private baseSeries: DataSeries | null = null;\r\n private baseTimeframeMs = 0;\r\n private compares: { id: string; symbol: string; color: string }[] = [];\r\n\r\n constructor(container: HTMLElement, options: ChartWidgetOptions = {}) {\r\n this.options = options;\r\n this.symbols = options.symbols ?? DEFAULT_SYMBOLS;\r\n // `numberLocale` lives in two places: the headless Chart gets it via\r\n // `chartOptions` (spread straight into `new Chart()` below) — but the\r\n // widget's own chrome (watchlist, alerts, hotkey sheet, settings panel)\r\n // reads `settingsState.numberLocale`, which otherwise stays on\r\n // DEFAULT_SETTINGS' 'en-US' until the host touches the Settings UI.\r\n // Seed it from the same option so both layers start in sync.\r\n this.settingsState = {\r\n ...DEFAULT_SETTINGS,\r\n ...(options.chartOptions?.numberLocale ? { numberLocale: options.chartOptions.numberLocale } : {}),\r\n };\r\n this.t = createTranslator(resolveMessages(options.locale, options.messages));\r\n\r\n // Resolve layout persistence config. Treated as opt-in — defaults to\r\n // `false` so existing apps don't suddenly start writing to localStorage.\r\n if (options.persistLayouts) {\r\n const cfg = options.persistLayouts === true ? {} : options.persistLayouts;\r\n this.layoutKeyPrefix = cfg.keyPrefix ?? 'tcw:layout:';\r\n this.layoutDebounceMs = cfg.debounceMs ?? 1500;\r\n }\r\n\r\n // Resolve theme\r\n const isDark = this.resolveIsDark(options.theme);\r\n const resolvedTheme = this.resolveTheme(options.theme);\r\n\r\n // Initialize state\r\n this.state = {\r\n symbol: options.symbol ?? this.symbols[0] ?? 'BTCUSDT',\r\n timeframe: options.timeframe ?? '5m',\r\n chartType: options.chartOptions?.chartType ?? 'candlestick',\r\n isDark,\r\n activeIndicators: new Map(),\r\n activeTool: null,\r\n magnetEnabled: true,\r\n // Static data (no adapter) has no connection to report.\r\n connectionState: options.adapter ? 'connecting' : 'disconnected',\r\n connectionMessage: options.adapter ? this.t('status.connecting') : '',\r\n };\r\n\r\n\r\n // 1. Inject styles\r\n injectWidgetStyles();\r\n\r\n // 2. Create DOM skeleton\r\n this.root = document.createElement('div');\r\n this.root.className = 'tcw-root';\r\n this.root.dataset.tcwTheme = isDark ? 'dark' : 'light';\r\n container.appendChild(this.root);\r\n\r\n // 3. Create toolbar\r\n if (options.toolbar !== false) {\r\n this.toolbar = new WidgetToolbar(\r\n this.root,\r\n {\r\n symbols: this.symbols,\r\n timeframes: options.timeframes\r\n ? TIMEFRAMES.filter(tf => (options.timeframes as TimeFrame[]).includes(tf.value))\r\n : TIMEFRAMES,\r\n chartTypes: options.chartTypes\r\n ? CHART_TYPES.filter(ct => (options.chartTypes as ChartType[]).includes(ct.value))\r\n : CHART_TYPES,\r\n indicators: INDICATORS,\r\n popularIndicatorIds: POPULAR_INDICATORS,\r\n },\r\n {\r\n onSymbolClick: () => this.handleSymbolClick(),\r\n onTimeframe: (tf) => this.handleTimeframe(tf),\r\n onChartType: (type) => this.handleChartType(type),\r\n onAddIndicator: (id) => this.handleAddIndicator(id),\r\n onRemoveIndicator: (iid) => this.handleRemoveIndicator(iid),\r\n onScreenshot: () => this.chart.screenshot(),\r\n onSettings: () => this.openSettings(),\r\n onToggleTheme: () => this.handleToggleTheme(),\r\n onToggleReplay: () => this.toggleReplay(),\r\n onToggleAlerts: options.alerts !== false ? () => this.toggleAlerts() : undefined,\r\n onToggleObjects: options.objectTree !== false ? () => this.toggleObjects() : undefined,\r\n onBracket: options.trading !== false ? (side) => this.startBracket(side) : undefined,\r\n onToggleLadder: options.trading !== false && options.depthLadder ? () => this.depthLadder?.toggle() : undefined,\r\n },\r\n this.t,\r\n );\r\n }\r\n\r\n // 4. Create body\r\n const body = document.createElement('div');\r\n body.className = 'tcw-body';\r\n\r\n if (options.drawingTools !== false) {\r\n if (options.drawingFavorites) this.favoritesStore.seedDefaults(options.drawingFavorites);\r\n this.sidebar = new WidgetDrawingSidebar(\r\n body,\r\n { drawingToolGroups: DRAWING_TOOL_GROUPS, favorites: this.favoritesStore.list() as DrawingToolType[] },\r\n {\r\n onDrawingTool: (tool) => this.handleDrawingTool(tool),\r\n onCancelDrawing: () => this.handleCancelDrawing(),\r\n onToggleMagnet: () => this.handleToggleMagnet(),\r\n onToggleFavorite: (tool) => this.handleToggleFavorite(tool),\r\n onUndo: () => this.chart.undo(),\r\n onRedo: () => this.chart.redo(),\r\n onClearDrawings: () => {\r\n this.chart.clearDrawings();\r\n this.state = { ...this.state, activeTool: null };\r\n this.updateUI();\r\n },\r\n onToggleStyle: () => this.drawingStyle?.toggle(),\r\n },\r\n );\r\n }\r\n\r\n this.chartContainer = document.createElement('div');\r\n this.chartContainer.className = 'tcw-chart-container';\r\n body.appendChild(this.chartContainer);\r\n\r\n // TradingView-style loading state: covers the empty chart until the first\r\n // bars land, then veils the previous chart during slow switches.\r\n this.loading = new WidgetLoadingOverlay(this.chartContainer, this.t('status.loading'));\r\n\r\n // Watchlist sidebar (right side). Appended AFTER the chart container so\r\n // it sits to the right of the canvas in the flexbox row.\r\n if (options.watchlist) {\r\n this.watchlist = new WidgetWatchlist(body, this.symbols, {\r\n onSelect: (sym) => { void this.setSymbol(sym); },\r\n }, this.t('watchlist.title'));\r\n this.watchlist.setActive(this.state.symbol);\r\n this.watchlist.setLocale(this.settingsState.numberLocale || undefined);\r\n }\r\n\r\n this.root.appendChild(body);\r\n\r\n // 5. Create chart\r\n this.chart = new Chart(this.chartContainer, {\r\n chartType: this.state.chartType,\r\n theme: resolvedTheme,\r\n autoScale: true,\r\n crosshair: { mode: 'magnet' },\r\n ...options.chartOptions,\r\n // `features` is merged explicitly (host overrides win per-key) rather\r\n // than inherited wholesale from the `...options.chartOptions` spread\r\n // above — otherwise passing e.g. `chartOptions: { features: { x } }`\r\n // would silently drop every other default below.\r\n features: {\r\n drawings: true,\r\n drawingMagnet: true,\r\n drawingUndoRedo: true,\r\n indicators: true,\r\n trading: options.trading !== false,\r\n tradingContextMenu: options.trading !== false,\r\n volume: true,\r\n legend: true,\r\n crosshair: true,\r\n // TradingView itself has no cursor-following OHLCV popup — just the\r\n // legend, which ChartWidget already renders. Off by default here\r\n // (the headless Chart's own default stays `true`); opt back in via\r\n // `chartOptions: { features: { crosshairTooltip: true } }`.\r\n crosshairTooltip: false,\r\n keyboard: true,\r\n screenshot: true,\r\n alerts: true,\r\n barCountdown: true,\r\n logScale: true,\r\n watermark: true,\r\n ...options.chartOptions?.features,\r\n },\r\n });\r\n\r\n // New bars end the loading state, whoever supplied them (stream snapshot,\r\n // widget.setData, or the host calling getChart().setData directly); stream\r\n // errors surface in the status bar and, mid-load, on the loading veil.\r\n this.chart.on('dataUpdate', (e) => this.handleDataUpdate(e.payload));\r\n\r\n // Drag-and-drop CSV / JSON onto the chart container — instant data load.\r\n // Opt-out via `dragDropImport: false`. The adapter (live stream) keeps\r\n // running but the next bar update will append to whatever we just\r\n // loaded — that's the expected behavior when overlaying historical data.\r\n if (options.dragDropImport !== false) {\r\n this.dragDrop = new DragDropImporter(this.chartContainer, {\r\n onData: (data, result, file) => {\r\n this.setData(data);\r\n this.toast(`Loaded ${result.data.length} bars from ${file.name}` + (result.skipped > 0 ? ` (${result.skipped} skipped)` : ''));\r\n },\r\n onError: (err, file) => {\r\n this.toast(`${file.name}: ${err.message}`, 'error');\r\n },\r\n });\r\n this.dragDrop.attach();\r\n }\r\n\r\n // 6. Create status bar\r\n if (options.statusBar !== false) {\r\n this.statusBar = new WidgetStatusBar(this.root);\r\n }\r\n\r\n // 7. Create settings (lazy, not appended until opened)\r\n if (options.settings !== false) {\r\n this.settings = new WidgetSettings({\r\n onChange: (patch) => this.applySettings(patch),\r\n onReset: () => this.resetSettings(),\r\n onClose: () => {},\r\n }, this.t);\r\n }\r\n\r\n // 8a. Symbol search\r\n this.symbolSearch = new WidgetSymbolSearch({\r\n onPick: (sym) => { void this.setSymbol(sym); },\r\n onClose: () => {},\r\n });\r\n this.hotkeySheet = new WidgetHotkeySheet({ onClose: () => {} }, this.t);\r\n\r\n // Replay: click a revealed bar to jump the replay cursor there.\r\n this.chart.on('barClick', (e) => {\r\n if (!this.replayBar?.isMounted()) return;\r\n const idx = (e.payload as { barIndex?: number }).barIndex;\r\n if (typeof idx !== 'number') return;\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(idx);\r\n this.replayBar.setState('paused');\r\n });\r\n\r\n // Data Window — precise OHLCV + indicator values at the hovered bar.\r\n this.dataWindow = new WidgetDataWindow(this.root, { formatPrice: (p) => this.formatAlertPrice(p) });\r\n this.chart.on('crosshairMove', (e) => {\r\n const p = e.payload as { barIndex?: number };\r\n this.lastHoverIndex = typeof p.barIndex === 'number' ? p.barIndex : null;\r\n if (this.dataWindow?.isOpen()) this.dataWindow.render(this.buildDataWindowModel());\r\n });\r\n\r\n // Drawing style + templates popover (paired with the sidebar palette button)\r\n if (options.drawingTools !== false) {\r\n this.drawingStyle = new WidgetDrawingStyle(\r\n this.root,\r\n {\r\n onStyleChange: (style) => {\r\n this.chart.setDrawingStyle(style);\r\n this.chart.setSelectedDrawingStyle(style);\r\n },\r\n getStyle: () => this.chart.getDrawingStyle(),\r\n },\r\n new DrawingTemplateStore(),\r\n );\r\n }\r\n\r\n // Bracket-order placement: floating confirm/cancel bar + event wiring.\r\n if (options.trading !== false) {\r\n this.bracketBar = new WidgetBracketBar(this.root, {\r\n onConfirm: () => this.chart.confirmBracket(),\r\n onCancel: () => {\r\n this.chart.cancelBracket();\r\n this.bracketBar?.hide();\r\n },\r\n });\r\n this.chart.on('bracketPlace', (e) => {\r\n const b = e.payload;\r\n this.bracketBar?.hide();\r\n this.toast(`${b.side === 'buy' ? 'Long' : 'Short'} bracket placed · ${b.riskReward.toFixed(2)}R`);\r\n });\r\n\r\n // Depth-of-market ladder (opt-in; fed via widget.setDepth)\r\n if (options.depthLadder) {\r\n this.depthLadder = new WidgetDepthLadder(this.root, {\r\n onTrade: (side, price) => {\r\n this.chart.placeOrderIntent({ side, type: 'limit', price });\r\n this.toast(`${side === 'buy' ? 'Buy' : 'Sell'} limit @ ${this.formatAlertPrice(price)}`);\r\n },\r\n formatPrice: (p) => this.formatAlertPrice(p),\r\n });\r\n }\r\n // Esc-cancel originates in the chart; reflect it in the bar.\r\n this.chart.on('dataUpdate', (e) => {\r\n const p = e.payload as { bracket?: string };\r\n if (p && p.bracket === 'cancelled') this.bracketBar?.hide();\r\n });\r\n }\r\n\r\n // 8a-bis. Price alerts panel (floating popover, toggled from the bell button)\r\n if (options.alerts !== false) {\r\n this.alertsPanel = new WidgetAlertsPanel(this.root, {\r\n onAdd: (price, condition, message, channel, label) => {\r\n this.chart.addAlert(price, condition, message, channel, label);\r\n },\r\n onRemove: (id) => this.chart.removeAlert(id),\r\n onClear: () => this.chart.clearAlerts(),\r\n getChannelValue: (channel) => this.getAlertChannelValue(channel),\r\n formatPrice: (p) => this.formatAlertPrice(p),\r\n });\r\n\r\n // Keep the panel list and toasts in sync with the chart's AlertManager.\r\n this.chart.on('alertAdd', () => this.refreshAlerts());\r\n this.chart.on('alertRemove', () => this.refreshAlerts());\r\n this.chart.on('alertUpdate', () => this.refreshAlerts());\r\n if (options.alertNotifications) {\r\n this.alertNotifier = new AlertNotifier(options.alertNotifications);\r\n }\r\n this.chart.on('alertTriggered', (e) => {\r\n const p = e.payload;\r\n const text = `Price ${this.formatAlertPrice(p.price)}${p.message ? ` — ${p.message}` : ''}`;\r\n this.toast(`🔔 Alert: ${text}`, 'info');\r\n this.alertNotifier?.notify(text);\r\n this.refreshAlerts();\r\n });\r\n }\r\n\r\n // 8a-ter. Object tree (indicators + drawings manager)\r\n if (options.objectTree !== false) {\r\n this.indicatorSettings = new WidgetIndicatorSettings(this.root, {\r\n onApply: (instanceId, params) => this.chart.updateIndicator(instanceId, params),\r\n onClose: () => {},\r\n });\r\n this.objectTree = new WidgetObjectTree(this.root, {\r\n onRemoveIndicator: (iid) => this.handleRemoveIndicator(iid),\r\n onConfigureIndicator: (iid) => this.openIndicatorSettings(iid),\r\n onToggleIndicatorVisible: (iid, visible) => {\r\n this.chart.setIndicatorVisible(iid, visible);\r\n this.refreshObjects();\r\n },\r\n onRemoveDrawing: (id) => {\r\n this.chart.removeDrawing(id);\r\n this.refreshObjects();\r\n },\r\n onToggleDrawingVisible: (id, visible) => {\r\n this.chart.setDrawingVisible(id, visible);\r\n this.refreshObjects();\r\n },\r\n onToggleDrawingLocked: (id, locked) => {\r\n this.chart.setDrawingLocked(id, locked);\r\n this.refreshObjects();\r\n },\r\n onAddCompare: () => this.handleAddCompare(),\r\n onRemoveCompare: (id) => this.handleRemoveCompare(id),\r\n });\r\n const refresh = () => { if (this.objectTree?.isOpen()) this.refreshObjects(); };\r\n this.chart.on('drawingCreate', refresh);\r\n this.chart.on('drawingRemove', refresh);\r\n this.chart.on('indicatorAdd', refresh);\r\n this.chart.on('indicatorRemove', refresh);\r\n }\r\n\r\n // 8b. Command palette\r\n this.commandPalette = new WidgetCommandPalette({\r\n onIndicator: (id) => this.handleAddIndicator(id),\r\n onChartType: (type) => this.handleChartType(type),\r\n onDrawingTool: (tool) => this.handleDrawingTool(tool),\r\n onTimeframe: (tf) => this.handleTimeframe(tf),\r\n onAction: (id) => this.handleAction(id),\r\n onClose: () => {},\r\n });\r\n\r\n this.boundGlobalKeydown = (e: KeyboardEvent) => {\r\n if ((e.ctrlKey || e.metaKey) && e.key === 'k') {\r\n e.preventDefault();\r\n this.toggleCommandPalette();\r\n } else if ((e.ctrlKey || e.metaKey) && (e.key === 'p' || e.key === 'P')) {\r\n // Ctrl/Cmd+P → symbol search (matches Bloomberg / many trading UIs)\r\n e.preventDefault();\r\n this.symbolSearch?.open(this.symbols, this.state.symbol);\r\n } else if (e.key === '?' && !e.ctrlKey && !e.metaKey && !e.altKey) {\r\n // Only fire when the user isn't typing into an input.\r\n const active = document.activeElement as HTMLElement | null;\r\n if (active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' || active.isContentEditable)) return;\r\n e.preventDefault();\r\n this.hotkeySheet?.open();\r\n }\r\n };\r\n document.addEventListener('keydown', this.boundGlobalKeydown);\r\n\r\n // 9. Connect stream\r\n if (options.adapter) {\r\n this.adapter = options.adapter;\r\n this.connectStream();\r\n }\r\n\r\n // Watchlist live-update loop. 1s cadence keeps DOM churn low while still\r\n // feeling responsive; for sub-second visual response, apps can call\r\n // `setWatchlistEntry` directly from their own WebSocket.\r\n if (this.watchlist) {\r\n this.watchlistInterval = setInterval(() => this.tickWatchlist(), 1000);\r\n }\r\n\r\n // Initial UI update\r\n this.updateUI();\r\n\r\n // 9. Fire onReady\r\n options.onReady?.(this.chart);\r\n\r\n // Deep-link restore: apply a `#tcw=` view from the URL when enabled.\r\n if (options.shareUrl && typeof location !== 'undefined') {\r\n const encoded = readShareHash(location.hash);\r\n if (encoded) void this.importState(encoded);\r\n }\r\n }\r\n\r\n // --- Public API ---\r\n\r\n /** Replace the searchable symbol catalog. Does not change the active symbol. */\r\n setSymbols(symbols: string[]): void {\r\n this.symbols = symbols;\r\n this.watchlist?.setSymbols(symbols);\r\n }\r\n\r\n async setSymbol(symbol: string): Promise<void> {\r\n // Flush the outgoing symbol's layout BEFORE switching state, so the\r\n // saved snapshot reflects what the user actually saw under that ticker.\r\n this.flushActiveLayout();\r\n this.state = { ...this.state, symbol };\r\n this.sessionRefPrice = null;\r\n this.options.onSymbolChange?.(symbol);\r\n this.updateUI();\r\n this.watchlist?.setActive(symbol);\r\n if (this.adapter) {\r\n await this.connectStream();\r\n }\r\n }\r\n\r\n /**\r\n * Push an entry into the watchlist (e.g., from your own WebSocket).\r\n * Call with the symbols you care about; the active symbol is updated\r\n * automatically from the chart's live data.\r\n *\r\n * A host-supplied `refPrice` takes precedence over the widget's own\r\n * session-open guess for that symbol — including the active one, so the\r\n * auto-tick loop stops clobbering it (see `tickWatchlist`).\r\n */\r\n setWatchlistEntry(symbol: string, entry: Partial<WatchlistEntry>): void {\r\n if (entry.refPrice !== undefined) {\r\n this.hostWatchlistRefPrice.set(symbol, entry.refPrice);\r\n }\r\n this.watchlist?.setEntry(symbol, entry);\r\n }\r\n\r\n private tickWatchlist(): void {\r\n if (!this.watchlist) return;\r\n const data = this.chart.getData();\r\n if (data.length === 0) return;\r\n const last = data[data.length - 1];\r\n const hostRef = this.hostWatchlistRefPrice.get(this.state.symbol);\r\n // Reference price: first bar of the loaded slice — that's the closest\r\n // approximation of \"session open\" without timezone bookkeeping. Only\r\n // used as a fallback; a refPrice the host already pushed via\r\n // `setWatchlistEntry` (even for the active symbol) always wins.\r\n if (hostRef === undefined && this.sessionRefPrice === null) {\r\n this.sessionRefPrice = data[0].open;\r\n }\r\n\r\n const buf = this.watchlistSparkBuffer.get(this.state.symbol) ?? [];\r\n buf.push(last.close);\r\n if (buf.length > 40) buf.shift();\r\n this.watchlistSparkBuffer.set(this.state.symbol, buf);\r\n\r\n this.watchlist.setEntry(this.state.symbol, {\r\n lastPrice: last.close,\r\n refPrice: hostRef ?? this.sessionRefPrice ?? data[0].open,\r\n sparkline: buf.slice(),\r\n });\r\n }\r\n\r\n async setTimeframe(tf: TimeFrame): Promise<void> {\r\n this.state = { ...this.state, timeframe: tf };\r\n this.options.onTimeframeChange?.(tf);\r\n this.updateUI();\r\n if (this.adapter) {\r\n // Live adapter owns the data — refetch at the native resolution.\r\n await this.connectStream();\r\n return;\r\n }\r\n if (this.options.resampleTimeframes === false) return;\r\n // Static data: aggregate the base series locally. Lazily adopt whatever is\r\n // currently on the chart as the base if the host fed it via getChart().\r\n if (!this.baseSeries) {\r\n const current = this.chart.getData();\r\n if (current.length > 0) {\r\n this.baseSeries = current;\r\n this.baseTimeframeMs = inferTimeframeMs(current);\r\n }\r\n }\r\n await this.switchLocalTimeframe();\r\n }\r\n\r\n setTheme(theme: import('@tradecanvas/commons').ThemeName | Theme): void {\r\n const isDark = this.resolveIsDark(theme);\r\n const resolved = this.resolveTheme(theme);\r\n this.state = { ...this.state, isDark };\r\n this.root.dataset.tcwTheme = isDark ? 'dark' : 'light';\r\n this.chart.setTheme(resolved);\r\n this.updateUI();\r\n }\r\n\r\n getChart(): Chart {\r\n return this.chart;\r\n }\r\n\r\n destroy(): void {\r\n if (this.destroyed) return;\r\n this.destroyed = true;\r\n\r\n if (this.boundGlobalKeydown) {\r\n document.removeEventListener('keydown', this.boundGlobalKeydown);\r\n }\r\n this.flushActiveLayout();\r\n this.commandPalette?.destroy();\r\n this.symbolSearch?.destroy();\r\n this.hotkeySheet?.destroy();\r\n if (this.replayPollInterval) clearInterval(this.replayPollInterval);\r\n this.replayBar?.destroy();\r\n this.dragDrop?.detach();\r\n this.alertsPanel?.destroy();\r\n this.objectTree?.destroy();\r\n this.indicatorSettings?.destroy();\r\n this.drawingStyle?.destroy();\r\n this.bracketBar?.destroy();\r\n this.alertNotifier?.destroy();\r\n this.depthLadder?.destroy();\r\n this.dataWindow?.destroy();\r\n if (this.watchlistInterval) clearInterval(this.watchlistInterval);\r\n this.watchlist?.destroy();\r\n this.toolbar?.destroy();\r\n this.sidebar?.destroy();\r\n this.settings?.destroy();\r\n this.statusBar?.destroy();\r\n this.loading.destroy();\r\n this.chart.destroy();\r\n this.root.remove();\r\n removeWidgetStyles();\r\n }\r\n\r\n // --- Internal handlers ---\r\n\r\n private handleSymbolClick(): void {\r\n // Opens the fuzzy search modal. The cycle-through behaviour the toolbar\r\n // used to do is gone — a real search scales past 3-4 symbols and matches\r\n // user expectations from TradingView, Bloomberg, etc.\r\n this.symbolSearch?.open(this.symbols, this.state.symbol);\r\n }\r\n\r\n private handleTimeframe(tf: TimeFrame): void {\r\n void this.setTimeframe(tf);\r\n }\r\n\r\n /**\r\n * Load the widget's base series. Prefer this over `getChart().setData()` so\r\n * client-side timeframe resampling has a finest-resolution source to\r\n * aggregate from. The data is rendered at the current timeframe (resampled\r\n * when that timeframe is coarser than the data's native spacing).\r\n */\r\n setData(data: DataSeries): void {\r\n this.localSeq++; // supersedes a local switch still waiting to run\r\n this.baseSeries = data;\r\n this.baseTimeframeMs = inferTimeframeMs(data);\r\n this.applyTimeframeData();\r\n // Static data is loaded the moment it's set, even an empty series. With a\r\n // live adapter the stream's own load decides (connectStream).\r\n if (!this.adapter) this.loading.end();\r\n }\r\n\r\n /**\r\n * Local timeframe switch. When it is expected to block the main thread for\r\n * several frames, veil the chart first and let that paint — otherwise the\r\n * click would look ignored until the new chart pops in.\r\n */\r\n private async switchLocalTimeframe(): Promise<void> {\r\n if (!this.baseSeries) return;\r\n const seq = ++this.localSeq;\r\n const expectSlow = this.lastLocalSwitchMs >= SLOW_LOCAL_SWITCH_MS\r\n || this.baseSeries.length >= LARGE_SERIES_BARS;\r\n try {\r\n if (expectSlow) {\r\n this.loading.begin(this.chart.getData().length > 0, true);\r\n await afterPaint();\r\n // Superseded: the newer switch or setData() ends the loading state.\r\n if (seq !== this.localSeq || this.destroyed) return;\r\n }\r\n this.applyTimeframeData();\r\n } finally {\r\n // Also on a throw (bad data, a failing custom indicator) — never leave\r\n // the veil up.\r\n if (seq === this.localSeq) this.loading.end();\r\n }\r\n }\r\n\r\n /** Render the base series at the active timeframe, resampling when coarser. */\r\n private applyTimeframeData(): void {\r\n if (!this.baseSeries) return;\r\n const started = performance.now();\r\n const targetMs = timeframeToMs(this.state.timeframe);\r\n if (this.baseTimeframeMs > 0 && targetMs > this.baseTimeframeMs) {\r\n const weekStartsOn = this.options.weekStartsOn ?? 1;\r\n this.chart.setData(resampleOHLCV(this.baseSeries, this.state.timeframe, { weekStartsOn }));\r\n } else {\r\n this.chart.setData(this.baseSeries);\r\n }\r\n this.lastLocalSwitchMs = performance.now() - started;\r\n }\r\n\r\n private handleDataUpdate(payload: unknown): void {\r\n if (!payload || typeof payload !== 'object') return;\r\n const p = payload as { length?: number; error?: string; connection?: { state?: string } };\r\n if (typeof p.length === 'number') {\r\n if (p.length > 0 && this.loading.isActive()) {\r\n this.loading.end();\r\n // A retry after a failed load just delivered history.\r\n if (this.state.connectionState === 'error') this.setConnectionState('connected', this.t('status.live'));\r\n }\r\n return;\r\n }\r\n if (p.error !== undefined) {\r\n // Only a failed *load* is reported from the error itself. Errors outside\r\n // one can be transient (a single failed poll on a healthy connection);\r\n // the status bar follows the stream's connection state below instead.\r\n if (this.loading.isActive()) {\r\n this.loading.fail(this.t('status.connectionFailed'));\r\n this.setConnectionState('error', p.error || this.t('status.connectionFailed'));\r\n }\r\n return;\r\n }\r\n switch (p.connection?.state) {\r\n case 'connected':\r\n // A retry that brought back an empty history ends a failed load too.\r\n if (this.loading.hasFailed()) this.loading.end();\r\n if (!this.loading.isActive() && this.state.connectionState !== 'connected') {\r\n this.setConnectionState('connected', this.t('status.live'));\r\n }\r\n break;\r\n case 'reconnecting':\r\n if (!this.loading.isActive()) this.setConnectionState('connecting', this.t('status.connecting'));\r\n break;\r\n case 'error':\r\n if (!this.loading.isActive()) this.setConnectionState('error', this.t('status.connectionFailed'));\r\n break;\r\n }\r\n }\r\n\r\n private setConnectionState(connectionState: WidgetState['connectionState'], connectionMessage: string): void {\r\n this.state = { ...this.state, connectionState, connectionMessage };\r\n this.updateUI();\r\n }\r\n\r\n private toggleAlerts(): void {\r\n if (!this.alertsPanel) return;\r\n this.alertsPanel.toggle();\r\n if (this.alertsPanel.isOpen()) this.refreshAlerts();\r\n }\r\n\r\n private handleToggleFavorite(tool: DrawingToolType): void {\r\n const pinned = this.favoritesStore.toggle(tool);\r\n this.sidebar?.setFavorites(this.favoritesStore.list());\r\n this.toast(pinned ? 'Pinned to favorites' : 'Unpinned');\r\n }\r\n\r\n /** Encode the current view (symbol, timeframe, chart type, scale, indicators, drawings). */\r\n exportState(): string {\r\n const indicators = this.chart.getActiveIndicators().map((i) => ({\r\n id: i.id,\r\n params: i.params as Record<string, number | string | boolean>,\r\n }));\r\n return encodeWidgetState({\r\n v: 1,\r\n symbol: this.state.symbol,\r\n timeframe: this.state.timeframe,\r\n chartType: this.state.chartType,\r\n scaleMode: this.chart.getScaleMode(),\r\n indicators,\r\n drawings: this.chart.getDrawings(),\r\n });\r\n }\r\n\r\n /** Restore a view from an `exportState()` string. Returns false if malformed. */\r\n async importState(encoded: string): Promise<boolean> {\r\n const s = decodeWidgetState(encoded);\r\n if (!s) return false;\r\n\r\n // Symbol/timeframe first so any stream/layout restore happens before we\r\n // overlay the shared view on top.\r\n if (s.symbol && s.symbol !== this.state.symbol) await this.setSymbol(s.symbol);\r\n if (s.timeframe && s.timeframe !== this.state.timeframe) await this.setTimeframe(s.timeframe);\r\n\r\n if (s.chartType) this.handleChartType(s.chartType);\r\n this.chart.setScaleMode(s.scaleMode);\r\n\r\n for (const [, instanceId] of this.state.activeIndicators) this.chart.removeIndicator(instanceId);\r\n const map = new Map<string, string>();\r\n for (const ind of s.indicators) {\r\n const iid = this.chart.addIndicator(ind.id, ind.params);\r\n if (iid) map.set(ind.id, iid);\r\n }\r\n this.state = { ...this.state, activeIndicators: map };\r\n this.chart.setDrawings(s.drawings);\r\n this.updateUI();\r\n return true;\r\n }\r\n\r\n /** Copy the chart image to the clipboard, with a toast on success/failure. */\r\n async copyChartImage(): Promise<void> {\r\n const ok = await this.chart.copyScreenshot();\r\n this.toast(ok ? 'Chart image copied' : 'Copy failed — image clipboard unavailable', ok ? 'info' : 'error');\r\n }\r\n\r\n /** Copy a shareable deep-link (current view encoded in the URL hash) to the clipboard. */\r\n async copyShareLink(): Promise<void> {\r\n const base = typeof location !== 'undefined' ? location.href : '';\r\n const url = buildShareUrl(base, this.exportState());\r\n try {\r\n await navigator.clipboard.writeText(url);\r\n this.toast('Share link copied');\r\n } catch {\r\n this.toast('Copy failed — clipboard unavailable', 'error');\r\n }\r\n }\r\n\r\n /** Feed order-book depth to the chart overlay, depth ladder, and heatmap. */\r\n setDepth(depth: DepthData | null): void {\r\n this.chart.setDepthData(depth);\r\n this.depthLadder?.setData(depth);\r\n if (depth) this.chart.pushDepthSnapshot(depth);\r\n }\r\n\r\n /** Begin a draggable bracket order at the latest price and show the action bar. */\r\n startBracket(side: 'buy' | 'sell'): void {\r\n if (this.chart.startBracket(side)) {\r\n this.bracketBar?.show(side);\r\n }\r\n }\r\n\r\n private buildDataWindowModel(): DataWindowModel {\r\n const data = this.chart.getData();\r\n const idx = this.lastHoverIndex;\r\n if (idx === null || idx < 0 || idx >= data.length) {\r\n return { ohlc: null, change: 0, changePct: 0, indicators: [] };\r\n }\r\n const bar = data[idx];\r\n const prevClose = idx > 0 ? data[idx - 1].close : bar.open;\r\n const change = bar.close - prevClose;\r\n const changePct = prevClose !== 0 ? (change / prevClose) * 100 : 0;\r\n\r\n const indicators = this.chart.getActiveIndicators().map((ind) => {\r\n const series = this.chart.getIndicatorOutput(ind.instanceId)?.series;\r\n const point = series?.[idx] ?? null;\r\n const values = point\r\n ? Object.entries(point)\r\n .filter(([, v]) => typeof v === 'number' && Number.isFinite(v))\r\n .map(([key, v]) => ({ key, value: v as number }))\r\n : [];\r\n return { name: ind.descriptor.name, values };\r\n }).filter((i) => i.values.length > 0);\r\n\r\n return {\r\n ohlc: { open: bar.open, high: bar.high, low: bar.low, close: bar.close, volume: bar.volume },\r\n change,\r\n changePct,\r\n indicators,\r\n };\r\n }\r\n\r\n private toggleDataWindow(): void {\r\n if (!this.dataWindow) return;\r\n this.dataWindow.toggle();\r\n if (this.dataWindow.isOpen()) this.dataWindow.render(this.buildDataWindowModel());\r\n }\r\n\r\n private toggleObjects(): void {\r\n if (!this.objectTree) return;\r\n this.objectTree.toggle();\r\n if (this.objectTree.isOpen()) this.refreshObjects();\r\n }\r\n\r\n private openIndicatorSettings(instanceId: string): void {\r\n if (!this.indicatorSettings) return;\r\n const ind = this.chart.getActiveIndicators().find((i) => i.instanceId === instanceId);\r\n if (!ind) return;\r\n this.indicatorSettings.open({\r\n instanceId,\r\n name: ind.descriptor.name,\r\n defaults: ind.descriptor.defaultConfig,\r\n params: ind.params,\r\n });\r\n }\r\n\r\n private refreshObjects(): void {\r\n if (!this.objectTree) return;\r\n const indicators = this.chart.getActiveIndicators().map((i) => ({\r\n instanceId: i.instanceId,\r\n name: i.descriptor.name,\r\n visible: i.visible,\r\n }));\r\n const drawings = this.chart.getDrawings().map((d) => ({\r\n id: d.id,\r\n label: drawingTypeLabel(d.type),\r\n visible: d.visible,\r\n locked: d.locked,\r\n }));\r\n const compares = this.compares.map((c) => ({ id: c.id, label: c.symbol, color: c.color }));\r\n this.objectTree.setObjects(indicators, drawings, compares);\r\n }\r\n\r\n private async handleAddCompare(): Promise<void> {\r\n if (!this.adapter) {\r\n this.toast('Comparison needs a live data adapter', 'error');\r\n return;\r\n }\r\n const taken = new Set([this.state.symbol, ...this.compares.map((c) => c.symbol)]);\r\n const options = this.symbols.filter((s) => !taken.has(s));\r\n this.symbolSearch?.open(options.length ? options : this.symbols, this.state.symbol, (symbol) => {\r\n void this.addCompareSymbol(symbol);\r\n });\r\n }\r\n\r\n /** Overlay another symbol's normalized series. Fetches history via the adapter. */\r\n async addCompareSymbol(symbol: string): Promise<void> {\r\n if (!this.adapter || this.compares.some((c) => c.symbol === symbol)) return;\r\n const color = COMPARE_COLORS[this.compares.length % COMPARE_COLORS.length];\r\n const id = `cmp_${symbol}`;\r\n try {\r\n const bars = await this.adapter.fetchHistory(symbol, this.state.timeframe, this.options.historyLimit ?? 500);\r\n // Percent mode normalizes mixed-price symbols (e.g. BTC vs a $2 alt) onto\r\n // a shared % axis — the right default for comparison.\r\n if (this.compares.length === 0) this.chart.setCompareMode('percent');\r\n this.chart.addCompareSymbol(id, symbol, bars, color);\r\n this.compares = [...this.compares, { id, symbol, color }];\r\n this.refreshObjects();\r\n this.toast(`Comparing ${symbol}`);\r\n } catch (err: unknown) {\r\n this.toast(`${symbol}: ${err instanceof Error ? err.message : 'failed to load'}`, 'error');\r\n }\r\n }\r\n\r\n private handleRemoveCompare(id: string): void {\r\n this.chart.removeCompareSymbol(id);\r\n this.compares = this.compares.filter((c) => c.id !== id);\r\n this.refreshObjects();\r\n }\r\n\r\n /** Refetch every comparison overlay at the current symbol/timeframe. */\r\n private async refetchCompares(): Promise<void> {\r\n if (!this.adapter || this.compares.length === 0) return;\r\n // A comparison against the now-active symbol is redundant — drop it.\r\n const stale = this.compares.filter((c) => c.symbol === this.state.symbol);\r\n for (const c of stale) this.handleRemoveCompare(c.id);\r\n\r\n for (const c of this.compares) {\r\n try {\r\n const bars = await this.adapter.fetchHistory(c.symbol, this.state.timeframe, this.options.historyLimit ?? 500);\r\n this.chart.updateCompareData(c.id, bars);\r\n } catch { /* leave the stale overlay in place if the refetch fails */ }\r\n }\r\n }\r\n\r\n private refreshAlerts(): void {\r\n if (!this.alertsPanel) return;\r\n this.alertsPanel.setSources(this.buildAlertSources());\r\n this.alertsPanel.setAlerts(\r\n this.chart.getAlerts().map((a) => ({\r\n id: a.id,\r\n price: a.price,\r\n condition: a.condition,\r\n message: a.message,\r\n triggered: a.triggered,\r\n channel: a.channel,\r\n label: a.label,\r\n })),\r\n );\r\n }\r\n\r\n /** Price + every active indicator line, as selectable alert sources. */\r\n private buildAlertSources(): { channel: string; label: string }[] {\r\n const sources = [{ channel: 'price', label: 'Price' }];\r\n for (const ind of this.chart.getActiveIndicators()) {\r\n // Use the latest point — multi-output indicators (MACD, Stochastic) only\r\n // have all their lines populated once warmed up; the first point may not.\r\n const series = this.chart.getIndicatorOutput(ind.instanceId)?.series;\r\n const point = series && series.length > 0 ? series[series.length - 1] : null;\r\n const keys = point ? Object.keys(point).filter((k) => typeof point[k] === 'number') : [];\r\n for (const key of keys) {\r\n const label = keys.length > 1 ? `${ind.descriptor.name} ${key}` : ind.descriptor.name;\r\n sources.push({ channel: `${ind.instanceId}:${key}`, label });\r\n }\r\n }\r\n return sources;\r\n }\r\n\r\n /** Latest value for an alert source channel (price or indicator line). */\r\n private getAlertChannelValue(channel: string): number | null {\r\n const data = this.chart.getData();\r\n if (channel === 'price') return data.length > 0 ? data[data.length - 1].close : null;\r\n const sep = channel.indexOf(':');\r\n if (sep < 0 || data.length === 0) return null;\r\n const instanceId = channel.slice(0, sep);\r\n const key = channel.slice(sep + 1);\r\n const v = this.chart.getIndicatorOutput(instanceId)?.series?.[data.length - 1]?.[key];\r\n return typeof v === 'number' && Number.isFinite(v) ? v : null;\r\n }\r\n\r\n private formatAlertPrice(price: number): string {\r\n // No fixed precision config on the widget — pick digits from magnitude so\r\n // BTC (64,200.5) and a sub-dollar alt (0.04821) both read sensibly.\r\n const abs = Math.abs(price);\r\n const digits = abs >= 1000 ? 2 : abs >= 1 ? 4 : 6;\r\n const locale = this.settingsState.numberLocale || undefined;\r\n return price.toLocaleString(locale, { minimumFractionDigits: 2, maximumFractionDigits: digits });\r\n }\r\n\r\n private handleChartType(type: ChartType): void {\r\n this.state = { ...this.state, chartType: type };\r\n this.chart.setChartType(type);\r\n this.updateUI();\r\n }\r\n\r\n private handleAddIndicator(indId: string): void {\r\n if (this.state.activeIndicators.has(indId)) {\r\n // Toggle off\r\n const instanceId = this.state.activeIndicators.get(indId)!;\r\n this.chart.removeIndicator(instanceId);\r\n const next = new Map(this.state.activeIndicators);\r\n next.delete(indId);\r\n this.state = { ...this.state, activeIndicators: next };\r\n } else {\r\n const instanceId = this.chart.addIndicator(indId);\r\n if (instanceId) {\r\n const next = new Map(this.state.activeIndicators);\r\n next.set(indId, instanceId);\r\n this.state = { ...this.state, activeIndicators: next };\r\n }\r\n }\r\n this.updateUI();\r\n }\r\n\r\n private handleRemoveIndicator(instanceId: string): void {\r\n this.chart.removeIndicator(instanceId);\r\n const next = new Map(this.state.activeIndicators);\r\n for (const [id, iid] of next.entries()) {\r\n if (iid === instanceId) {\r\n next.delete(id);\r\n break;\r\n }\r\n }\r\n this.state = { ...this.state, activeIndicators: next };\r\n this.updateUI();\r\n }\r\n\r\n private toggleCommandPalette(): void {\r\n if (this.commandPalette?.isOpen()) {\r\n this.commandPalette.close();\r\n return;\r\n }\r\n this.commandPalette?.open(this.buildCommandItems());\r\n }\r\n\r\n private buildCommandItems(): CommandItem[] {\r\n const items: CommandItem[] = [];\r\n\r\n for (const ind of INDICATORS) {\r\n items.push({\r\n id: ind.id,\r\n label: ind.name,\r\n category: 'indicator',\r\n active: this.state.activeIndicators.has(ind.id),\r\n });\r\n }\r\n\r\n for (const ct of CHART_TYPES) {\r\n items.push({\r\n id: ct.value,\r\n label: ct.label,\r\n category: 'chartType',\r\n active: this.state.chartType === ct.value,\r\n });\r\n }\r\n\r\n for (const group of DRAWING_TOOL_GROUPS) {\r\n for (const tool of group.tools) {\r\n items.push({\r\n id: tool.value,\r\n label: tool.label,\r\n category: 'drawing',\r\n active: this.state.activeTool === tool.value,\r\n });\r\n }\r\n }\r\n\r\n for (const tf of TIMEFRAMES) {\r\n items.push({\r\n id: tf.value,\r\n label: tf.label,\r\n category: 'timeframe',\r\n active: this.state.timeframe === tf.value,\r\n });\r\n }\r\n\r\n items.push(\r\n { id: 'screenshot', label: 'Screenshot', category: 'action', shortcut: '' },\r\n { id: 'copyImage', label: 'Copy Chart Image', category: 'action' },\r\n { id: 'toggleTheme', label: 'Toggle Theme', category: 'action' },\r\n { id: 'settings', label: 'Settings', category: 'action' },\r\n { id: 'shareView', label: 'Share View (copy link)', category: 'action' },\r\n { id: 'autoFib', label: 'Auto Fibonacci (visible swing)', category: 'action' },\r\n { id: 'dataWindow', label: 'Toggle Data Window', category: 'action' },\r\n { id: 'clearDrawings', label: 'Clear All Drawings', category: 'action' },\r\n );\r\n\r\n return items;\r\n }\r\n\r\n private handleAction(id: string): void {\r\n switch (id) {\r\n case 'screenshot':\r\n this.chart.screenshot();\r\n break;\r\n case 'toggleTheme':\r\n this.handleToggleTheme();\r\n break;\r\n case 'settings':\r\n this.openSettings();\r\n break;\r\n case 'copyImage':\r\n void this.copyChartImage();\r\n break;\r\n case 'shareView':\r\n void this.copyShareLink();\r\n break;\r\n case 'autoFib': {\r\n const id = this.chart.autoFib();\r\n this.toast(id ? 'Auto Fibonacci added' : 'No clear swing in view');\r\n break;\r\n }\r\n case 'dataWindow':\r\n this.toggleDataWindow();\r\n break;\r\n case 'clearDrawings':\r\n this.chart.clearDrawings();\r\n this.state = { ...this.state, activeTool: null };\r\n this.updateUI();\r\n break;\r\n }\r\n }\r\n\r\n private handleDrawingTool(tool: DrawingToolType): void {\r\n this.state = { ...this.state, activeTool: tool };\r\n this.chart.setDrawingTool(tool);\r\n this.updateUI();\r\n }\r\n\r\n private handleCancelDrawing(): void {\r\n this.state = { ...this.state, activeTool: null };\r\n this.chart.setDrawingTool(null);\r\n this.updateUI();\r\n }\r\n\r\n private handleToggleMagnet(): void {\r\n const magnetEnabled = !this.state.magnetEnabled;\r\n this.state = { ...this.state, magnetEnabled };\r\n this.chart.setDrawingMagnet(magnetEnabled);\r\n this.updateUI();\r\n }\r\n\r\n private handleToggleTheme(): void {\r\n const isDark = !this.state.isDark;\r\n this.state = { ...this.state, isDark };\r\n this.root.dataset.tcwTheme = isDark ? 'dark' : 'light';\r\n this.chart.setTheme(isDark ? DARK_THEME : LIGHT_THEME);\r\n this.chart.setWatermark(this.state.symbol.replace('USDT', ' / USDT'), {\r\n fontSize: 48,\r\n color: isDark ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.03)',\r\n });\r\n this.updateUI();\r\n }\r\n\r\n private openSettings(): void {\r\n this.settings?.open(this.settingsState);\r\n }\r\n\r\n // --- Toast ---\r\n\r\n /**\r\n * Show a transient toast inside the widget. Auto-dismisses after 3.5s.\r\n * Used by the drag-drop importer for success / failure feedback, but\r\n * exposed so apps can post their own (e.g. \"alert triggered at 64,200\").\r\n */\r\n toast(message: string, kind: 'info' | 'error' = 'info'): void {\r\n const el = document.createElement('div');\r\n el.className = `tcw-toast ${kind === 'error' ? 'tcw-toast-error' : ''}`;\r\n el.textContent = message;\r\n this.root.appendChild(el);\r\n // Trigger CSS transition on next frame\r\n requestAnimationFrame(() => el.classList.add('tcw-toast-in'));\r\n setTimeout(() => {\r\n el.classList.remove('tcw-toast-in');\r\n el.addEventListener('transitionend', () => el.remove(), { once: true });\r\n // Hard timeout in case transitionend doesn't fire (display:none, etc.)\r\n setTimeout(() => el.remove(), 400);\r\n }, 3500);\r\n }\r\n\r\n // --- Layout persistence ---\r\n\r\n /**\r\n * Wipe the layout saved for `symbol` (or the active symbol if omitted).\r\n * Useful as an \"Reset layout\" command in user-facing menus.\r\n */\r\n clearSavedLayout(symbol?: string): void {\r\n if (!this.layoutKeyPrefix) return;\r\n const target = symbol ?? this.state.symbol;\r\n try {\r\n localStorage.removeItem(this.layoutKeyPrefix + target);\r\n } catch { /* localStorage may be unavailable (private mode, SSR, etc.) */ }\r\n }\r\n\r\n private applySymbolLayout(symbol: string): void {\r\n if (!this.layoutKeyPrefix) return;\r\n const key = this.layoutKeyPrefix + symbol;\r\n this.activeLayoutKey = key;\r\n\r\n try {\r\n // Best-effort load. If parsing or any restore step throws, we silently\r\n // fall back to a fresh layout — a corrupted layout shouldn't break the\r\n // chart.\r\n const ok = this.chart.loadStateFromStorage(key);\r\n if (ok) this.rebuildActiveIndicatorsMapFromChart();\r\n } catch { /* swallow — layout will be rebuilt from user actions */ }\r\n\r\n // Wire chart-level auto-save so any further drawing/indicator change\r\n // flushes itself into this symbol's slot.\r\n this.chart.setAutoSave(key, this.layoutDebounceMs);\r\n }\r\n\r\n private flushActiveLayout(): void {\r\n if (!this.activeLayoutKey) return;\r\n try { this.chart.saveState(this.activeLayoutKey); } catch { /* same */ }\r\n this.chart.disableAutoSave();\r\n this.activeLayoutKey = null;\r\n }\r\n\r\n /**\r\n * After loading a layout, the chart restores indicator instances but our\r\n * `state.activeIndicators` map (used to render the chip strip) is stale.\r\n * Rebuild it from the live `getActiveIndicators` list.\r\n */\r\n private rebuildActiveIndicatorsMapFromChart(): void {\r\n const next = new Map<string, string>();\r\n for (const a of this.chart.getActiveIndicators()) {\r\n next.set(a.id, a.instanceId);\r\n }\r\n this.state = { ...this.state, activeIndicators: next };\r\n this.updateUI();\r\n }\r\n\r\n // --- Replay ---\r\n\r\n /** Open (or close) bar replay with its scrubber — what the toolbar's Replay button does. */\r\n toggleReplay(): void {\r\n if (this.replayBar?.isMounted()) {\r\n this.exitReplay();\r\n } else {\r\n this.enterReplay();\r\n }\r\n }\r\n\r\n private enterReplay(): void {\r\n const data = this.chart.getData();\r\n if (data.length < 2) return;\r\n\r\n // Snapshot full series so we can restore it on exit. The chart's\r\n // dataManager gets mutated to slices during replay.\r\n this.replayOriginalData = data.slice();\r\n\r\n // Mount the scrubber bar inside the chart container so it floats above the\r\n // canvas. It owns its own absolute positioning via the .tcw-replay-bar CSS.\r\n this.replayBar = new WidgetReplayBar({\r\n onPlay: () => {\r\n if (this.chart.getReplayState() === 'paused') {\r\n this.chart.replayResume();\r\n } else {\r\n this.chart.replayStart({ speed: this.replaySpeed, interval: 200 });\r\n }\r\n this.replayBar?.setState('playing');\r\n },\r\n onPause: () => {\r\n this.chart.replayPause();\r\n this.replayBar?.setState('paused');\r\n },\r\n onStop: () => {\r\n this.chart.replayStop();\r\n this.replayBar?.setState('paused');\r\n },\r\n onStepBack: () => {\r\n const p = this.chart.getReplayProgress();\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(Math.max(0, p.current - 1));\r\n this.replayBar?.setState('paused');\r\n },\r\n onStepForward: () => {\r\n const p = this.chart.getReplayProgress();\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(Math.min(p.total - 1, p.current + 1));\r\n this.replayBar?.setState('paused');\r\n },\r\n onSeek: (idx) => {\r\n if (this.chart.getReplayState() === 'playing') this.chart.replayPause();\r\n this.chart.replaySeek(idx);\r\n this.replayBar?.setState('paused');\r\n },\r\n onSpeedChange: (s) => {\r\n this.replaySpeed = s;\r\n this.chart.setReplaySpeed(s);\r\n },\r\n onClose: () => this.exitReplay(),\r\n });\r\n this.replayBar.mount(this.chartContainer, { total: data.length, speed: this.replaySpeed });\r\n\r\n // Boot replay paused at bar 1 so the user sees a starting state. Then\r\n // start polling progress for the scrubber — cheap, runs at 200ms.\r\n this.chart.replayStart({ speed: this.replaySpeed, interval: 200, startIndex: 1 });\r\n this.chart.replayPause();\r\n this.replayBar.setState('paused');\r\n\r\n this.replayPollInterval = setInterval(() => {\r\n if (!this.replayBar?.isMounted()) return;\r\n const p = this.chart.getReplayProgress();\r\n this.replayBar.setProgress(p.current, p.total);\r\n const state = this.chart.getReplayState();\r\n if (state === 'stopped') {\r\n this.replayBar.setState('paused');\r\n } else {\r\n this.replayBar.setState(state);\r\n }\r\n }, 150);\r\n }\r\n\r\n private exitReplay(): void {\r\n if (this.replayPollInterval) {\r\n clearInterval(this.replayPollInterval);\r\n this.replayPollInterval = null;\r\n }\r\n this.chart.replayStop();\r\n this.replayBar?.unmount();\r\n this.replayBar = null;\r\n if (this.replayOriginalData) {\r\n this.chart.setData(this.replayOriginalData);\r\n this.replayOriginalData = null;\r\n }\r\n }\r\n\r\n private applySettings(patch: Partial<ChartSettingsState>): void {\r\n this.settingsState = { ...this.settingsState, ...patch };\r\n\r\n if (patch.gridVisible !== undefined) this.chart.setGridVisible(patch.gridVisible);\r\n if (patch.volumeVisible !== undefined) this.chart.setVolumeVisible(patch.volumeVisible);\r\n if (patch.volumeProfileVisible !== undefined) this.chart.setVolumeProfileVisible(patch.volumeProfileVisible);\r\n if (patch.marketProfileVisible !== undefined) this.chart.setMarketProfileVisible(patch.marketProfileVisible);\r\n if (patch.marketProfileSplit !== undefined) this.chart.setMarketProfileConfig({ splitBySession: patch.marketProfileSplit });\r\n if (patch.marketProfileLetters !== undefined) this.chart.setMarketProfileConfig({ letters: patch.marketProfileLetters });\r\n if (patch.marketProfileBuckets !== undefined) this.chart.setMarketProfileConfig({ buckets: patch.marketProfileBuckets });\r\n if (patch.marketProfileOpacity !== undefined) this.chart.setMarketProfileConfig({ opacity: patch.marketProfileOpacity });\r\n if (patch.depthHeatmapVisible !== undefined) this.chart.setDepthHeatmapVisible(patch.depthHeatmapVisible);\r\n if (patch.depthHeatmapOpacity !== undefined) this.chart.setDepthHeatmapConfig({ opacity: patch.depthHeatmapOpacity });\r\n if (patch.sessionShadingVisible !== undefined) this.chart.setSessionShadingVisible(patch.sessionShadingVisible);\r\n if (patch.pivotMarkersVisible !== undefined) this.chart.setPivotMarkersVisible(patch.pivotMarkersVisible);\r\n if (patch.pivotStrength !== undefined) this.chart.setPivotMarkersConfig({ left: patch.pivotStrength, right: patch.pivotStrength });\r\n if (patch.pivotStructureLabels !== undefined) this.chart.setPivotMarkersConfig({ structureLabels: patch.pivotStructureLabels });\r\n if (patch.periodLevelsVisible !== undefined) this.chart.setPeriodLevelsVisible(patch.periodLevelsVisible);\r\n if (patch.periodLevelsPeriod !== undefined) this.chart.setPeriodLevelsPeriod(patch.periodLevelsPeriod);\r\n if (patch.crosshairMode !== undefined) this.chart.setCrosshairMode(patch.crosshairMode);\r\n if (patch.autoScale !== undefined) this.chart.setAutoScale(patch.autoScale);\r\n if (patch.scaleMode !== undefined) {\r\n this.chart.setScaleMode(patch.scaleMode);\r\n // Keep the legacy logScale flag mirrored so persisted layouts stay valid.\r\n this.settingsState = { ...this.settingsState, logScale: patch.scaleMode === 'logarithmic' };\r\n } else if (patch.logScale !== undefined) {\r\n this.chart.setLogScale(patch.logScale);\r\n this.settingsState = { ...this.settingsState, scaleMode: patch.logScale ? 'logarithmic' : 'regular' };\r\n }\r\n if (patch.numberLocale !== undefined) {\r\n this.chart.setNumberLocale(patch.numberLocale);\r\n this.watchlist?.setLocale(patch.numberLocale || undefined);\r\n }\r\n if (patch.timezone !== undefined) {\r\n this.chart.setTimezoneOffset(patch.timezone === 'local' ? null : Number(patch.timezone));\r\n }\r\n\r\n // Apply theme colors\r\n const currentTheme = this.chart.getTheme();\r\n const themeUpdate = { ...currentTheme } as Record<string, unknown>;\r\n let themeChanged = false;\r\n\r\n if (patch.candleUpColor !== undefined) { themeUpdate.candleUp = patch.candleUpColor; themeChanged = true; }\r\n if (patch.candleDownColor !== undefined) { themeUpdate.candleDown = patch.candleDownColor; themeChanged = true; }\r\n if (patch.candleUpWick !== undefined) { themeUpdate.candleUpWick = patch.candleUpWick; themeChanged = true; }\r\n if (patch.candleDownWick !== undefined) { themeUpdate.candleDownWick = patch.candleDownWick; themeChanged = true; }\r\n if (patch.backgroundColor !== undefined) { themeUpdate.background = patch.backgroundColor; themeChanged = true; }\r\n if (patch.gridColor !== undefined) { themeUpdate.grid = patch.gridColor; themeChanged = true; }\r\n\r\n if (themeChanged) {\r\n this.chart.setTheme(themeUpdate as unknown as Theme);\r\n }\r\n }\r\n\r\n private resetSettings(): void {\r\n this.settingsState = { ...DEFAULT_SETTINGS };\r\n this.applySettings(this.settingsState);\r\n }\r\n\r\n private async connectStream(): Promise<void> {\r\n if (!this.adapter) return;\r\n const seq = ++this.connectSeq;\r\n\r\n this.state = {\r\n ...this.state,\r\n connectionState: 'connecting',\r\n connectionMessage: this.t('status.connecting'),\r\n };\r\n this.updateUI();\r\n // Keep the previous chart up while the next one loads; it only gets the\r\n // veil if the request is slow (see WidgetLoadingOverlay).\r\n this.loading.begin(this.chart.getData().length > 0);\r\n\r\n try {\r\n this.chart.disconnectStream();\r\n await this.chart.connect({\r\n adapter: this.adapter,\r\n symbol: this.state.symbol,\r\n timeframe: this.state.timeframe,\r\n historyLimit: this.options.historyLimit ?? 500,\r\n });\r\n // A newer switch started while this one was loading — it owns the UI now.\r\n if (seq !== this.connectSeq || this.destroyed) return;\r\n\r\n this.chart.setWatermark(this.state.symbol.replace('USDT', ' / USDT'), {\r\n fontSize: 48,\r\n color: this.state.isDark ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.03)',\r\n });\r\n\r\n // Re-apply per-symbol layout (indicators, drawings, chart type) after\r\n // the new history is in. Doing this *after* connect ensures indicators\r\n // recalculate against the loaded data, not the previous symbol's data.\r\n this.applySymbolLayout(this.state.symbol);\r\n\r\n if (this.loading.hasFailed()) {\r\n // History failed to load; the stream keeps retrying and the next\r\n // snapshot ends the loading state (handleDataUpdate).\r\n this.state = { ...this.state, connectionState: 'error' };\r\n } else {\r\n this.loading.end();\r\n this.state = {\r\n ...this.state,\r\n connectionState: 'connected',\r\n connectionMessage: this.t('status.live'),\r\n };\r\n }\r\n\r\n // Re-pull comparison overlays at the (possibly new) timeframe so they\r\n // stay aligned with the main series. Drop the active symbol if it ended\r\n // up in the compare set after a symbol switch.\r\n void this.refetchCompares();\r\n } catch (err: unknown) {\r\n if (seq !== this.connectSeq || this.destroyed) return;\r\n this.loading.fail(this.t('status.connectionFailed'));\r\n this.state = {\r\n ...this.state,\r\n connectionState: 'error',\r\n connectionMessage: err instanceof Error ? err.message : this.t('status.connectionFailed'),\r\n };\r\n }\r\n\r\n this.updateUI();\r\n }\r\n\r\n private updateUI(): void {\r\n this.toolbar?.update(this.state);\r\n this.sidebar?.update(this.state);\r\n this.statusBar?.update({\r\n connectionState: this.state.connectionState,\r\n message: this.state.connectionMessage,\r\n symbol: this.state.symbol,\r\n timeframe: this.state.timeframe,\r\n });\r\n }\r\n\r\n private resolveIsDark(theme?: import('@tradecanvas/commons').ThemeName | Theme): boolean {\r\n if (theme === undefined || theme === 'dark') return true;\r\n if (theme === 'light') return false;\r\n // If it's a Theme object, check background color\r\n if (typeof theme === 'object' && theme.background) {\r\n return this.isColorDark(theme.background);\r\n }\r\n return true;\r\n }\r\n\r\n private resolveTheme(theme?: import('@tradecanvas/commons').ThemeName | Theme): Theme {\r\n if (theme === undefined || theme === 'dark') return DARK_THEME;\r\n if (theme === 'light') return LIGHT_THEME;\r\n if (typeof theme === 'object') return theme as Theme;\r\n return DARK_THEME;\r\n }\r\n\r\n private isColorDark(color: string): boolean {\r\n // Simple heuristic: if it starts with # and R+G+B < 384 (half of 768)\r\n if (color.startsWith('#') && color.length >= 7) {\r\n const r = parseInt(color.slice(1, 3), 16);\r\n const g = parseInt(color.slice(3, 5), 16);\r\n const b = parseInt(color.slice(5, 7), 16);\r\n return (r + g + b) < 384;\r\n }\r\n return true;\r\n }\r\n}\r\n"],"mappings":";;;AAmBA,SAAgB,EACd,GACA,GACA,IAAwB,EAAE,EACd;AACZ,KAAI,EAAK,WAAW,EAAG,QAAO,EAAE;CAChC,IAAM,IAAe,EAAK,gBAAgB,GAEpC,IAAiB,EAAE,EACrB,IAA0B,MAC1B,IAAa;AAEjB,MAAK,IAAM,KAAO,GAAM;EACtB,IAAM,IAAM,EAAqB,EAAI,MAAM,GAAQ,EAAa;AAChE,EAAI,MAAY,QAAQ,MAAQ,KAC1B,MAAY,QAAM,EAAI,KAAK,EAAQ,EACvC,IAAU;GACR,MAAM;GACN,MAAM,EAAI;GACV,MAAM,EAAI;GACV,KAAK,EAAI;GACT,OAAO,EAAI;GACX,QAAQ,EAAI;GACb,EACD,IAAa,KAEb,IAAU;GACR,MAAM,EAAQ;GACd,MAAM,EAAQ;GACd,MAAM,KAAK,IAAI,EAAQ,MAAM,EAAI,KAAK;GACtC,KAAK,KAAK,IAAI,EAAQ,KAAK,EAAI,IAAI;GACnC,OAAO,EAAI;GACX,QAAQ,EAAQ,SAAS,EAAI;GAC9B;;AAIL,QADI,MAAY,QAAM,EAAI,KAAK,EAAQ,EAChC;;AAQT,SAAgB,EAAiB,GAA0B;AACzD,KAAI,EAAK,SAAS,EAAG,QAAO;CAC5B,IAAM,IAAiB,EAAE;AACzB,MAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;EACpC,IAAM,IAAM,EAAK,GAAG,OAAO,EAAK,IAAI,GAAG;AACvC,EAAI,IAAM,KAAG,EAAK,KAAK,EAAI;;AAI7B,QAFI,EAAK,WAAW,IAAU,KAC9B,EAAK,MAAM,GAAG,MAAM,IAAI,EAAE,EACnB,EAAK,KAAK,MAAM,EAAK,SAAS,EAAE;;;;ACtEzC,IAAa,IAAoD;CAC/D;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC7B,EAEY,IAAqD;CAChE;EAAE,OAAO;EAAe,OAAO;EAAe;CAC9C;EAAE,OAAO;EAAQ,OAAO;EAAQ;CAChC;EAAE,OAAO;EAAQ,OAAO;EAAQ;CAChC;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAe,OAAO;EAAc;CAC7C;EAAE,OAAO;EAAiB,OAAO;EAAgB;CACjD;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAkB,OAAO;EAAiB;CACnD;EAAE,OAAO;EAAc,OAAO;EAAc;CAC5C;EAAE,OAAO;EAAY,OAAO;EAAW;CACvC;EAAE,OAAO;EAAa,OAAO;EAAY;CACzC;EAAE,OAAO;EAAkB,OAAO;EAAmB;CACtD,EAEY,IAA6C;CACxD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAc,OAAO;IAAgC;GAC9D;IAAE,OAAO;IAAO,OAAO;IAA0B;GACjD;IAAE,OAAO;IAAiB,OAAO;IAAmC;GACpE;IAAE,OAAO;IAAa,OAAO;IAA+B;GAC5D;IAAE,OAAO;IAAe,OAAO;IAAiC;GACjE;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAmB,OAAO;IAAqC;GACxE;IAAE,OAAO;IAAkB,OAAO;IAAoC;GACtE;IAAE,OAAO;IAAiB,OAAO;IAAmC;GACpE;IAAE,OAAO;IAAc,OAAO;IAAgC;GAC/D;EACF;CACD;EACE,OAAO;EACP,OAAO,CACL;GAAE,OAAO;GAAoB,OAAO;GAAsC,EAC1E;GAAE,OAAO;GAAsB,OAAO;GAAwC,CAC/E;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAmB,OAAO;IAAqC;GACxE;IAAE,OAAO;IAAiB,OAAO;IAAmC;GACpE;IAAE,OAAO;IAAe,OAAO;IAAiC;GAChE;IAAE,OAAO;IAAkB,OAAO;IAAmC;GACrE;IAAE,OAAO;IAA4B,OAAO;IAA4C;GACzF;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAa,OAAO;IAAgC;GAC7D;IAAE,OAAO;IAAU,OAAO;IAA6B;GACvD;IAAE,OAAO;IAAW,OAAO;IAA8B;GACzD;IAAE,OAAO;IAAY,OAAO;IAA+B;GAC5D;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAa,OAAO;IAAgC;GAC7D;IAAE,OAAO;IAAoB,OAAO;IAAsC;GAC1E;IAAE,OAAO;IAA6B,OAAO;IAA8C;GAC3F;IAAE,OAAO;IAAY,OAAO;IAA8B;GAC1D;IAAE,OAAO;IAAY,OAAO;IAA8B;GAC1D;IAAE,OAAO;IAAgB,OAAO;IAAkC;GACnE;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAiB,OAAO;IAAmC;GACpE;IAAE,OAAO;IAAgB,OAAO;IAAkC;GAClE;IAAE,OAAO;IAAsB,OAAO;IAAuC;GAC7E;IAAE,OAAO;IAAgB,OAAO;IAAkC;GACnE;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAe,OAAO;IAAiC;GAChE;IAAE,OAAO;IAAc,OAAO;IAAgC;GAC9D;IAAE,OAAO;IAAwB,OAAO;IAAwC;GAChF;IAAE,OAAO;IAAW,OAAO;IAA8B;GAC1D;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAQ,OAAO;IAA2B;GACnD;IAAE,OAAO;IAAe,OAAO;IAAiC;GAChE;IAAE,OAAO;IAAS,OAAO;IAA4B;GACtD;EACF;CACD;EACE,OAAO;EACP,OAAO;GACL;IAAE,OAAO;IAAuB,OAAO;IAAiC;GACxE;IAAE,OAAO;IAAiB,OAAO;IAAmC;GACpE;IAAE,OAAO;IAA8B,OAAO;IAAyC;GACxF;EACF;CACF,EAEY,IAA6B;CACxC;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAW;CAC3C;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAW;CAC3C;EAAE,IAAI;EAAQ,MAAM;EAAc,MAAM;EAAW;CACnD;EAAE,IAAI;EAAQ,MAAM;EAAQ,MAAM;EAAW;CAC7C;EAAE,IAAI;EAAO,MAAM;EAAe,MAAM;EAAW;CACnD;EAAE,IAAI;EAAO,MAAM;EAAW,MAAM;EAAW;CAC/C;EAAE,IAAI;EAAS,MAAM;EAAsB,MAAM;EAAW;CAC5D;EAAE,IAAI;EAAM,MAAM;EAAmB,MAAM;EAAW;CACtD;EAAE,IAAI;EAAY,MAAM;EAAY,MAAM;EAAW;CACrD;EAAE,IAAI;EAAQ,MAAM;EAAQ,MAAM;EAAW;CAC7C;EAAE,IAAI;EAAS,MAAM;EAAiB,MAAM;EAAW;CACvD;EAAE,IAAI;EAAS,MAAM;EAAgB,MAAM;EAAW;CACtD;EAAE,IAAI;EAAY,MAAM;EAAkB,MAAM;EAAW;CAC3D;EAAE,IAAI;EAAQ,MAAM;EAAiB,MAAM;EAAW;CACtD;EAAE,IAAI;EAAc,MAAM;EAAc,MAAM;EAAW;CACzD;EAAE,IAAI;EAAW,MAAM;EAAmB,MAAM;EAAW;CAC3D;EAAE,IAAI;EAAY,MAAM;EAAoB,MAAM;EAAW;CAC7D;EAAE,IAAI;EAAU,MAAM;EAAgB,MAAM;EAAW;CACvD;EAAE,IAAI;EAAU,MAAM;EAAU,MAAM;EAAW;CACjD;EAAE,IAAI;EAAO,MAAM;EAA6B,MAAM;EAAW;CACjE;EAAE,IAAI;EAAc,MAAM;EAAmB,MAAM;EAAW;CAC9D;EAAE,IAAI;EAAa,MAAM;EAAa,MAAM;EAAW;CACvD;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAQ,MAAM;EAAQ,MAAM;EAAS;CAC3C;EAAE,IAAI;EAAc,MAAM;EAAc,MAAM;EAAS;CACvD;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAa,MAAM;EAAe,MAAM;EAAS;CACvD;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAO,MAAM;EAAO,MAAM;EAAS;CACzC;EAAE,IAAI;EAAS,MAAM;EAAS,MAAM;EAAS;CAC7C;EAAE,IAAI;EAAU,MAAM;EAAiB,MAAM;EAAS;CACtD;EAAE,IAAI;EAAQ,MAAM;EAAc,MAAM;EAAS;CACjD;EAAE,IAAI;EAAM,MAAM;EAAY,MAAM;EAAS;CAC7C;EAAE,IAAI;EAAM,MAAM;EAAsB,MAAM;EAAS;CACvD;EAAE,IAAI;EAAc,MAAM;EAAsB,MAAM;EAAS;CAC/D;EAAE,IAAI;EAAY,MAAM;EAAgB,MAAM;EAAS;CACvD;EAAE,IAAI;EAAU,MAAM;EAAoB,MAAM;EAAS;CACzD;EAAE,IAAI;EAAQ,MAAM;EAAoB,MAAM;EAAS;CACvD;EAAE,IAAI;EAAM,MAAM;EAAuB,MAAM;EAAS;CACxD;EAAE,IAAI;EAAM,MAAM;EAAe,MAAM;EAAS;CAChD;EAAE,IAAI;EAAQ,MAAM;EAAe,MAAM;EAAS;CAClD;EAAE,IAAI;EAAW,MAAM;EAAiB,MAAM;EAAS;CACvD;EAAE,IAAI;EAAO,MAAM;EAAmB,MAAM;EAAS;CACrD;EAAE,IAAI;EAAY,MAAM;EAAa,MAAM;EAAS;CACpD;EAAE,IAAI;EAAO,MAAM;EAAsB,MAAM;EAAS;CACxD;EAAE,IAAI;EAAO,MAAM;EAAsB,MAAM;EAAS;CACxD;EAAE,IAAI;EAAU,MAAM;EAAoB,MAAM;EAAS;CACzD;EAAE,IAAI;EAAO,MAAM;EAAuB,MAAM;EAAS;CACzD;EAAE,IAAI;EAAO,MAAM;EAAoB,MAAM;EAAS;CACtD;EAAE,IAAI;EAAa,MAAM;EAAc,MAAM;EAAS;CACtD;EAAE,IAAI;EAAO,MAAM;EAAmB,MAAM;EAAS;CACrD;EAAE,IAAI;EAAQ,MAAM;EAAQ,MAAM;EAAS;CAC3C;EAAE,IAAI;EAAO,MAAM;EAAoB,MAAM;EAAS;CACtD;EAAE,IAAI;EAAO,MAAM;EAAsB,MAAM;EAAS;CACxD;EAAE,IAAI;EAAO,MAAM;EAAgB,MAAM;EAAS;CAClD;EAAE,IAAI;EAAc,MAAM;EAAsB,MAAM;EAAS;CAC/D;EAAE,IAAI;EAAO,MAAM;EAAwB,MAAM;EAAS;CAC1D;EAAE,IAAI;EAAY,MAAM;EAAkB,MAAM;EAAS;CACzD;EAAE,IAAI;EAAO,MAAM;EAA+B,MAAM;EAAS;CACjE;EAAE,IAAI;EAAM,MAAM;EAA0B,MAAM;EAAS;CAC3D;EAAE,IAAI;EAAO,MAAM;EAA2B,MAAM;EAAS;CAC7D;EAAE,IAAI;EAAa,MAAM;EAAmB,MAAM;EAAS;CAC3D;EAAE,IAAI;EAAU,MAAM;EAAU,MAAM;EAAS;CAC/C;EAAE,IAAI;EAAO,MAAM;EAA0B,MAAM;EAAS;CAC5D;EAAE,IAAI;EAAiB,MAAM;EAAkB,MAAM;EAAS;CAC/D,EAEY,IAAqB;CAChC;CAAO;CAAO;CAAM;CAAO;CAAQ;CACnC;CAAQ;CAAO;CAAO;CACvB,EAEY,KAAkB;CAC7B;CAAW;CAAW;CAAW;CAClC,EAEY,IAAuC;CAClD,eAAe;CACf,iBAAiB;CACjB,cAAc;CACd,gBAAgB;CAChB,iBAAiB;CACjB,WAAW;CACX,aAAa;CACb,eAAe;CACf,sBAAsB;CACtB,sBAAsB;CACtB,oBAAoB;CACpB,sBAAsB;CACtB,sBAAsB;CACtB,sBAAsB;CACtB,qBAAqB;CACrB,qBAAqB;CACrB,uBAAuB;CACvB,qBAAqB;CACrB,eAAe;CACf,sBAAsB;CACtB,qBAAqB;CACrB,oBAAoB;CACpB,eAAe;CACf,cAAc;CACd,UAAU;CACV,WAAW;CACX,WAAW;CACX,eAAe;CACf,cAAc;CACd,UAAU;CACX,wz6DCvOG,IAAW,GACT,IAAW;AAQjB,SAAgB,IAA2B;AAGzC,KAFA,KACI,IAAW,KACX,SAAS,eAAe,EAAS,CAAE;CAEvC,IAAM,IAAQ,SAAS,cAAc,QAAQ;AAG7C,CAFA,EAAM,KAAK,GACX,EAAM,cAAc,IACpB,SAAS,KAAK,YAAY,EAAM;;AAGlC,SAAgB,IAA2B;AAEzC,KADA,KACI,IAAW,EAAG;CAElB,IAAM,IAAQ,SAAS,eAAe,EAAS;AAC/C,CAAI,KACF,EAAM,QAAQ;;;;AC5BlB,IAAM,IAAqC;CACzC,QAAQ;CACR,YAAY;CACZ,OAAO;CACP,SAAS;CACT,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,WAAW;CACX,OAAO;CACP,MAAM;CACN,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;CACP,QAAQ;CACR,UAAU;CACV,MAAM;CACN,KAAK;CACL,aAAa;CACb,WAAW;CACX,UAAU;CACV,GAAG;CACH,MAAM;CACN,OAAO;CACP,MAAM;CACN,SAAS;CACT,MAAM;CACN,MAAM;CACN,QAAQ;CACR,KAAK;CACL,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,SAAS;CACT,cAAc;CACd,OAAO;CACP,QAAQ;CACT;AAED,SAAgB,EAAW,GAAc,IAAO,IAAY;CAC1D,IAAM,IAAQ,EAAW;AAEzB,QADK,IACE,kDAAkD,EAAK,YAAY,EAAK,0HAA0H,EAAM,UAD5L;;;;AC1CrB,IAAa,IAAb,MAA4B;CAC1B;CACA;CACA,UAAkB;CAClB;CACA;CACA;CAEA,YAAY,GAAsB,IAAuD,EAAE,EAAE;AAqC3F,EApCA,KAAK,UAAU,GAEf,KAAK,QAAQ,SAAS,cAAc,MAAM,EAC1C,KAAK,MAAM,YAAY,gBACvB,KAAK,MAAM,MAAM,QAAQ,EAAO,SAAS,SACrC,EAAO,UAAU,UACnB,KAAK,MAAM,MAAM,QAAQ,MAEzB,KAAK,MAAM,MAAM,OAAO,KAE1B,KAAK,MAAM,MAAM,UAAU,QAG3B,EAAQ,MAAM,WAAW,YACzB,EAAQ,YAAY,KAAK,MAAM,EAE/B,KAAK,uBAAuB;AAC1B,GAAI,KAAK,UACP,KAAK,OAAO,GAEZ,KAAK,MAAM;KAIf,KAAK,kBAAkB,MAAkB;AACvC,GAAK,KAAK,QAAQ,SAAS,EAAE,OAAe,IAC1C,KAAK,OAAO;KAIhB,KAAK,eAAe,MAAqB;AACvC,GAAI,EAAE,QAAQ,YACZ,KAAK,OAAO;KAIhB,EAAQ,iBAAiB,SAAS,KAAK,eAAe;;CAGxD,WAAW,GAAoB;AAC7B,OAAK,MAAM,YAAY;;CAGzB,OAAa;AACP,OAAK,YACT,KAAK,UAAU,IACf,KAAK,MAAM,MAAM,UAAU,IAC3B,SAAS,iBAAiB,aAAa,KAAK,eAAe,EAC3D,SAAS,iBAAiB,WAAW,KAAK,YAAY;;CAGxD,QAAc;AACP,OAAK,YACV,KAAK,UAAU,IACf,KAAK,MAAM,MAAM,UAAU,QAC3B,SAAS,oBAAoB,aAAa,KAAK,eAAe,EAC9D,SAAS,oBAAoB,WAAW,KAAK,YAAY;;CAG3D,SAAkB;AAChB,SAAO,KAAK;;CAGd,UAAgB;AAId,EAHA,KAAK,QAAQ,oBAAoB,SAAS,KAAK,eAAe,EAC9D,SAAS,oBAAoB,aAAa,KAAK,eAAe,EAC9D,SAAS,oBAAoB,WAAW,KAAK,YAAY,EACzD,KAAK,MAAM,QAAQ;;GCtEV,KAAb,MAA2B;CACzB;CACA;CACA;CACA;CACA,oBAAmD;CACnD,oBAAmD;CACnD,YAAyC,EAAE;CAC3C,iBAAgD;CAChD,WAA6C;CAE7C,YAAY,GAAmB,GAAuB,GAA6B,GAAe;AAOhG,EANA,KAAK,SAAS,GACd,KAAK,YAAY,GACjB,KAAK,IAAI,GACT,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,eACpB,KAAK,OAAO,EACZ,EAAK,YAAY,KAAK,GAAG;;CAG3B,QAAsB;EACpB,IAAM,EAAE,WAAQ,cAAW,UAAO,MAG5B,IAAY,SAAS,cAAc,SAAS;AAKlD,EAJA,EAAU,YAAY,sBACtB,EAAU,QAAQ,OAAO,UACzB,EAAU,iBAAiB,SAAS,EAAU,cAAc,EAC5D,EAAG,YAAY,EAAU,EACzB,EAAG,YAAY,KAAK,KAAK,CAAC;EAG1B,IAAM,IAAU,SAAS,cAAc,MAAM;AAC7C,IAAQ,YAAY;AACpB,OAAK,IAAM,KAAM,EAAO,YAAY;GAClC,IAAM,IAAM,SAAS,cAAc,SAAS;AAM5C,GALA,EAAI,YAAY,WAChB,EAAI,cAAc,EAAG,OACrB,EAAI,QAAQ,KAAK,EAAG,OACpB,EAAI,iBAAiB,eAAe,EAAU,YAAY,EAAG,MAAM,CAAC,EACpE,EAAQ,YAAY,EAAI,EACxB,KAAK,UAAU,KAAK,EAAI;;AAG1B,EADA,EAAG,YAAY,EAAQ,EACvB,EAAG,YAAY,KAAK,KAAK,CAAC;EAG1B,IAAM,IAAS,SAAS,cAAc,MAAM;AAE5C,EADA,EAAO,MAAM,WAAW,YACxB,EAAO,MAAM,UAAU;EAEvB,IAAM,IAAY,SAAS,cAAc,SAAS;AASlD,EARA,EAAU,YAAY,wBACtB,EAAU,QAAQ,OAAO,aACzB,EAAO,YAAY,EAAU,EAC7B,EAAG,YAAY,EAAO,EAEtB,KAAK,oBAAoB,IAAI,EAAe,GAAQ,EAAE,OAAO,SAAS,CAAC,EACvE,KAAK,oBAAoB,EAEzB,EAAG,YAAY,KAAK,KAAK,CAAC;EAG1B,IAAM,IAAU,SAAS,cAAc,MAAM;AAE7C,EADA,EAAQ,MAAM,WAAW,YACzB,EAAQ,MAAM,UAAU;EAExB,IAAM,IAAa,SAAS,cAAc,SAAS;AAkBnD,MAjBA,EAAW,YAAY,wBACvB,EAAW,QAAQ,OAAO,cAC1B,EAAQ,YAAY,EAAW,EAC/B,EAAG,YAAY,EAAQ,EAEvB,KAAK,oBAAoB,IAAI,EAAe,GAAS,EAAE,OAAO,SAAS,CAAC,EACxE,KAAK,oBAAoB,EAGzB,KAAK,iBAAiB,SAAS,cAAc,MAAM,EACnD,KAAK,eAAe,YAAY,uBAChC,EAAG,YAAY,KAAK,eAAe,EAGnC,EAAG,YAAY,KAAK,QAAQ,CAAC,EAGzB,EAAU,gBAAgB;GAC5B,IAAM,IAAY,KAAK,QAAQ,QAAQ,KAAK,EAAE,iBAAiB,EAAE,EAAU,eAAe;AAE1F,GADA,EAAU,QAAQ,OAAO,UACzB,EAAG,YAAY,EAAU;;AAG3B,MAAI,EAAU,WAAW;GACvB,IAAM,IAAY,EAAU,WACtB,IAAU,KAAK,QAAQ,cAAc,KAAK,EAAE,sBAAsB,QAAQ,EAAU,MAAM,CAAC;AAGjG,GAFA,EAAQ,QAAQ,OAAO,QACvB,EAAQ,UAAU,IAAI,eAAe,EACrC,EAAG,YAAY,EAAQ;GACvB,IAAM,IAAW,KAAK,QAAQ,gBAAgB,KAAK,EAAE,uBAAuB,QAAQ,EAAU,OAAO,CAAC;AAGtG,GAFA,EAAS,QAAQ,OAAO,SACxB,EAAS,UAAU,IAAI,gBAAgB,EACvC,EAAG,YAAY,EAAS;;AAG1B,MAAI,EAAU,gBAAgB;GAC5B,IAAM,IAAY,KAAK,QAAQ,UAAU,KAAK,EAAE,sBAAsB,EAAE,EAAU,eAAe;AAEjG,GADA,EAAU,QAAQ,OAAO,UACzB,EAAG,YAAY,EAAU;;AAG3B,MAAI,EAAU,iBAAiB;GAC7B,IAAM,IAAa,KAAK,QAAQ,UAAU,KAAK,EAAE,kBAAkB,EAAE,EAAU,gBAAgB;AAE/F,GADA,EAAW,QAAQ,OAAO,WAC1B,EAAG,YAAY,EAAW;;AAG5B,MAAI,EAAU,gBAAgB;GAC5B,IAAM,IAAY,KAAK,QAAQ,QAAQ,KAAK,EAAE,sBAAsB,EAAE,EAAU,eAAe;AAE/F,GADA,EAAU,QAAQ,OAAO,UACzB,EAAG,YAAY,EAAU;;EAG3B,IAAM,IAAgB,KAAK,QAAQ,UAAU,KAAK,EAAE,qBAAqB,EAAE,EAAU,aAAa;AAClG,IAAG,YAAY,EAAc;EAE7B,IAAM,IAAc,KAAK,QAAQ,YAAY,KAAK,EAAE,mBAAmB,EAAE,EAAU,WAAW;AAK9F,EAJA,EAAG,YAAY,EAAY,EAE3B,KAAK,WAAW,KAAK,QAAQ,QAAQ,KAAK,EAAE,sBAAsB,EAAE,EAAU,cAAc,EAC5F,KAAK,SAAS,QAAQ,OAAO,SAC7B,EAAG,YAAY,KAAK,SAAS;;CAG/B,eAAuB,GAAiD;EACtE,IAAM,IAAM,aAAa,EAAG,SACtB,IAAa,KAAK,EAAE,EAAiC;AAC3D,SAAO,MAAe,IAAM,EAAG,QAAQ;;CAGzC,qBAAmC;AACjC,MAAI,CAAC,KAAK,kBAAmB;EAC7B,IAAM,IAAQ,KAAK,OAAO,WAAW,KAAI,MACvC,8CAA8C,EAAG,MAAM,IAAI,KAAK,eAAe,EAAG,CAAC,WACpF,CAAC,KAAK,GAAG;AAII,EAHd,KAAK,kBAAkB,WAAW,EAAM,EAG1B,KAAK,kBAAkB,MAC/B,iBAAiB,qBAAqB,CAAC,SAAS,MAAQ;AAC5D,KAAI,iBAAiB,UAAU,MAAM;IACnC,IAAM,IAAS,EAAE,cAA8B,QAAQ;AAEvD,IADA,KAAK,UAAU,YAAY,EAAM,EACjC,KAAK,mBAAmB,OAAO;KAC/B;IACF;;CAGJ,qBAAmC;AACjC,MAAI,CAAC,KAAK,kBAAmB;EAC7B,IAAM,EAAE,eAAY,2BAAwB,KAAK,QAE3C,IAAU,EAAW,QAAO,MAAK,EAAoB,SAAS,EAAE,GAAG,CAAC,EACpE,IAAQ,EAAW,QAAO,MAAK,CAAC,EAAoB,SAAS,EAAE,GAAG,CAAC,EAEnE,KAAa,MAAiB,KAAK,EAAE,iBAAiB,IAAoC,EAE5F,IAAO,mCAAmC,KAAK,EAAE,6BAA6B,CAAC;AACnF,OAAK,IAAM,KAAO,EAChB,MAAQ,+CAA+C,EAAI,GAAG,UAAU,EAAI,KAAK,+BAA+B,EAAU,EAAI,KAAK,CAAC;AAGtI,EADA,KAAQ,8CACR,KAAQ,mCAAmC,KAAK,EAAE,yBAAyB,CAAC;AAC5E,OAAK,IAAM,KAAO,EAChB,MAAQ,+CAA+C,EAAI,GAAG,UAAU,EAAI,KAAK,+BAA+B,EAAU,EAAI,KAAK,CAAC;AAKxH,EAFd,KAAK,kBAAkB,WAAW,EAAK,EAEzB,KAAK,kBAAkB,MAC/B,iBAAiB,+BAA+B,CAAC,SAAS,MAAQ;AACtE,KAAI,iBAAiB,UAAU,MAAM;IACnC,IAAM,IAAM,EAAE,cAA8B,QAAQ;AACpD,SAAK,UAAU,eAAe,EAAG;KACjC;IACF;;CAGJ,OAAO,GAA0B;EAE/B,IAAM,IAAY,KAAK,GAAG,cAAc,yBAAuB;AAC/D,EAAI,MAAW,EAAU,cAAc,EAAM;AAG7C,OAAK,IAAM,KAAO,KAAK,UACrB,GAAI,UAAU,OAAO,cAAc,EAAI,QAAQ,OAAO,EAAM,UAAU;EAIxE,IAAM,IAAY,KAAK,GAAG,cAAc,4BAA0B;AAClE,MAAI,GAAW;GACb,IAAM,IAAK,KAAK,OAAO,WAAW,MAAK,MAAM,EAAG,UAAU,EAAM,UAAU,EACpE,IAAQ,IAAK,KAAK,eAAe,EAAG,GAAG,EAAM;AACnD,KAAU,YAAY,GAAG,EAAW,YAAY,GAAG,CAAC,GAAG,EAAM,GAAG,EAAW,eAAe,GAAG;;EAI/F,IAAM,IAAa,KAAK,GAAG,cAAc,6BAA2B;AACpE,MAAI,GAAY;GACd,IAAM,IAAQ,EAAM,iBAAiB,MACjC,IAAQ,GAAG,EAAW,cAAc,GAAG,CAAC,GAAG,KAAK,EAAE,qBAAqB;AAI3E,GAHI,IAAQ,MACV,KAAS,kCAAkC,EAAM,WAEnD,EAAW,YAAY;;AAIzB,MAAI,KAAK,gBAAgB;GACvB,IAAM,IAAa,KAAK,uBAAuB,EAAM;AACrD,QAAK,eAAe,YAAY;AAChC,QAAK,IAAM,KAAO,GAAY;IAC5B,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,MAAK,YAAY;IAEjB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAE5C,IADA,EAAM,cAAc,EAAI,OACxB,EAAK,YAAY,EAAM;IAEvB,IAAM,IAAY,SAAS,cAAc,SAAS;AAMlD,IALA,EAAU,YAAY,mBACtB,EAAU,YAAY,EAAW,KAAK,GAAG,EACzC,EAAU,iBAAiB,eAAe,KAAK,UAAU,kBAAkB,EAAI,WAAW,CAAC,EAC3F,EAAK,YAAY,EAAU,EAE3B,KAAK,eAAe,YAAY,EAAK;;;AAKzC,EAAI,KAAK,aACP,KAAK,SAAS,YAAY,EAAM,SAAS,EAAW,QAAQ,GAAG,GAAG,EAAW,OAAO,GAAG;;CAI3F,uBAA+B,GAAuC;EACpE,IAAM,IAA4B,EAAE;AACpC,OAAK,IAAM,CAAC,GAAI,MAAe,EAAM,iBAAiB,SAAS,CAC7D,GAAO,KAAK;GAAE;GAAY;GAAI,OAAO,EAAG,aAAa;GAAE,CAAC;AAE1D,SAAO;;CAGT,MAA+B;EAC7B,IAAM,IAAI,SAAS,cAAc,OAAO;AAExC,SADA,EAAE,YAAY,mBACP;;CAGT,SAAkC;EAChC,IAAM,IAAI,SAAS,cAAc,OAAO;AAExC,SADA,EAAE,YAAY,sBACP;;CAGT,QAAgB,GAAc,GAAe,GAAwC;EACnF,IAAM,IAAM,SAAS,cAAc,SAAS;AAK5C,SAJA,EAAI,YAAY,gBAChB,EAAI,QAAQ,GACZ,EAAI,YAAY,EAAW,GAAM,GAAG,EACpC,EAAI,iBAAiB,SAAS,EAAQ,EAC/B;;CAGT,UAAgB;AAGd,EAFA,KAAK,mBAAmB,SAAS,EACjC,KAAK,mBAAmB,SAAS,EACjC,KAAK,GAAG,QAAQ;;GCvRd,KAAc;CAClB;CAAc;CAAS;CAAW;CAAQ;CAAU;CAAa;CAAU;CAAS;CAAQ;CAC7F,EAGK,KAAqC;CACzC,WAAW;CAAc,KAAK;CAAc,cAAc;CAC1D,UAAU;CAAc,YAAY;CACpC,gBAAgB;CAAS,eAAe;CAAS,cAAc;CAAW,WAAW;CACrF,WAAW;CAAU,QAAQ;CAAU,SAAS;CAAU,UAAU;CAAU,OAAO;CACrF,iBAAiB;CAAa,mBAAmB;CACjD,WAAW;CAAa,iBAAiB;CAAa,yBAAyB;CAC/E,gBAAgB;CAAQ,cAAc;CAAQ,cAAc;CAAQ,YAAY;CAAQ,uBAAuB;CAC/G,SAAS;CAAQ,SAAS;CAAa,aAAa;CACpD,aAAa;CAAU,cAAc;CAAU,aAAa;CAAU,kBAAkB;CACxF,YAAY;CAAS,WAAW;CAAS,mBAAmB;CAAS,SAAS;CAC9E,MAAM;CAAQ,gBAAgB;CAAQ,YAAY;CAClD,cAAc;CAAc,oBAAoB;CAChD,YAAY;CACb;AAED,SAAS,GAAS,GAAsB;AACtC,QAAO,GAAW,MAAS;;AAI7B,SAAS,GAAU,GAA4C,GAAsB;AACnF,MAAK,IAAM,KAAK,GAAQ;EACtB,IAAM,IAAI,EAAE,MAAM,MAAM,MAAM,EAAE,UAAU,EAAK;AAC/C,MAAI,EAAG,QAAO,EAAE;;AAElB,QAAO;;AAGT,IAAa,KAAb,MAAkC;CAChC;CACA;CACA;CACA,aAAuC,EAAE;CACzC,eAA4C,EAAE;CAC9C,YAA8C;CAC9C,YAA8C;CAC9C,WAA0C;CAC1C,cAA6C;CAC7C,mBAAkD;CAClD,YAA8B,EAAE;CAEhC,YAAY,GAAmB,GAAuB,GAA6B;AAMjF,EALA,KAAK,SAAS,GACd,KAAK,YAAY,GACjB,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,eACpB,KAAK,OAAO,EACZ,EAAK,YAAY,KAAK,GAAG;;CAG3B,QAAsB;EACpB,IAAM,EAAE,WAAQ,cAAW,UAAO;AAwBlC,EArBA,KAAK,YAAY,SAAS,cAAc,SAAS,EACjD,KAAK,UAAU,YAAY,mBAC3B,KAAK,UAAU,QAAQ,UACvB,KAAK,UAAU,YAAY,EAAW,UAAU,GAAG,EACnD,KAAK,UAAU,iBAAiB,SAAS,EAAU,gBAAgB,EACnE,EAAG,YAAY,KAAK,UAAU,EAE9B,EAAG,YAAY,KAAK,SAAS,CAAC,EAG1B,EAAU,qBACZ,KAAK,YAAY,CAAC,GAAI,EAAO,aAAa,EAAE,CAAE,EAC9C,KAAK,cAAc,SAAS,cAAc,MAAM,EAChD,KAAK,YAAY,YAAY,yBAC7B,EAAG,YAAY,KAAK,YAAY,EAChC,KAAK,mBAAmB,KAAK,SAAS,EACtC,EAAG,YAAY,KAAK,iBAAiB,EACrC,KAAK,iBAAiB,GAIxB,EAAO,kBAAkB,SAAS,GAAO,MAAQ;GAC/C,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,KAAK,YAAY;GAEjB,IAAM,IAAM,SAAS,cAAc,SAAS;AAK5C,OAJA,EAAI,YAAY,mBAChB,EAAI,QAAQ,EAAM,OAClB,EAAI,YAAY,EAAW,GAAY,MAAQ,UAAU,GAAG,EAExD,EAAM,MAAM,SAAS,GAAG;IAC1B,IAAM,IAAM,SAAS,cAAc,OAAO;AAE1C,IADA,EAAI,YAAY,iBAChB,EAAI,YAAY,EAAI;;AAYtB,GATA,EAAI,iBAAiB,eAAe,EAAU,cAAc,EAAM,MAAM,GAAG,MAAM,CAAC,EAClF,EAAK,YAAY,EAAI,EAGrB,EAAK,iBAAiB,oBAAoB,KAAK,WAAW,EAAI,CAAC,EAC/D,EAAK,iBAAiB,oBAAoB,KAAK,YAAY,CAAC,EAE5D,EAAG,YAAY,EAAK,EACpB,KAAK,WAAW,KAAK,EAAK,EAC1B,KAAK,aAAa,KAAK,EAAI;IAC3B;EAGF,IAAM,IAAS,SAAS,cAAc,MAAM;AAO5C,MANA,EAAO,YAAY,sBACnB,EAAG,YAAY,EAAO,EAEtB,EAAG,YAAY,KAAK,SAAS,CAAC,EAG1B,EAAU,eAAe;GAC3B,IAAM,IAAW,SAAS,cAAc,SAAS;AAMjD,GALA,EAAS,YAAY,mBACrB,EAAS,QAAQ,6BACjB,EAAS,QAAQ,OAAO,SACxB,EAAS,YAAY,EAAW,WAAW,GAAG,EAC9C,EAAS,iBAAiB,SAAS,EAAU,cAAc,EAC3D,EAAG,YAAY,EAAS;;AAQ1B,EALA,KAAK,YAAY,SAAS,cAAc,SAAS,EACjD,KAAK,UAAU,YAAY,mBAC3B,KAAK,UAAU,QAAQ,UACvB,KAAK,UAAU,YAAY,EAAW,UAAU,GAAG,EACnD,KAAK,UAAU,iBAAiB,SAAS,EAAU,eAAe,EAClE,EAAG,YAAY,KAAK,UAAU;EAE9B,IAAM,IAAU,SAAS,cAAc,SAAS;AAKhD,EAJA,EAAQ,YAAY,mBACpB,EAAQ,QAAQ,QAChB,EAAQ,YAAY,EAAW,QAAQ,GAAG,EAC1C,EAAQ,iBAAiB,SAAS,EAAU,OAAO,EACnD,EAAG,YAAY,EAAQ;EAEvB,IAAM,IAAU,SAAS,cAAc,SAAS;AAKhD,EAJA,EAAQ,YAAY,mBACpB,EAAQ,QAAQ,QAChB,EAAQ,YAAY,EAAW,QAAQ,GAAG,EAC1C,EAAQ,iBAAiB,SAAS,EAAU,OAAO,EACnD,EAAG,YAAY,EAAQ;EAEvB,IAAM,IAAW,SAAS,cAAc,SAAS;AAKjD,EAJA,EAAS,YAAY,8BACrB,EAAS,QAAQ,aACjB,EAAS,YAAY,EAAW,SAAS,GAAG,EAC5C,EAAS,iBAAiB,SAAS,EAAU,gBAAgB,EAC7D,EAAG,YAAY,EAAS;;CAI1B,aAAa,GAA2B;AAEtC,EADA,KAAK,YAAY,CAAC,GAAG,EAAU,EAC/B,KAAK,iBAAiB;;CAGxB,kBAAgC;AAC9B,MAAI,CAAC,KAAK,YAAa;AACvB,OAAK,YAAY,iBAAiB;EAClC,IAAM,IAAU,KAAK,UAAU,SAAS;AAExC,EADA,KAAK,YAAY,MAAM,UAAU,IAAU,KAAK,QAC5C,KAAK,qBAAkB,KAAK,iBAAiB,MAAM,UAAU,IAAU,KAAK;AAEhF,OAAK,IAAM,KAAQ,KAAK,WAAW;GACjC,IAAM,IAAM,SAAS,cAAc,SAAS;AAU5C,GATA,EAAI,YAAY,mBAChB,EAAI,QAAQ,GAAG,GAAU,KAAK,OAAO,mBAAmB,EAAK,CAAC,0BAC9D,EAAI,QAAQ,YAAY,GACxB,EAAI,YAAY,EAAW,GAAS,EAAK,EAAE,GAAG,EAC9C,EAAI,iBAAiB,eAAe,KAAK,UAAU,cAAc,EAAc,CAAC,EAChF,EAAI,iBAAiB,gBAAgB,MAAM;AAEzC,IADA,EAAE,gBAAgB,EAClB,KAAK,UAAU,mBAAmB,EAAc;KAChD,EACF,KAAK,YAAY,YAAY,EAAI;;;CAIrC,WAAmB,GAAmB;EACpC,IAAM,IAAQ,KAAK,OAAO,kBAAkB;AAC5C,MAAI,CAAC,KAAS,EAAM,MAAM,UAAU,EAAG;AAEvC,OAAK,YAAY;EAEjB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EAEnB,IAAM,IAAS,SAAS,cAAc,MAAM;AAG5C,EAFA,EAAO,YAAY,qBACnB,EAAO,cAAc,EAAM,OAC3B,EAAO,YAAY,EAAO;AAE1B,OAAK,IAAM,KAAQ,EAAM,OAAO;GAC9B,IAAM,IAAO,SAAS,cAAc,SAAS;AAgB7C,GAfA,EAAK,YAAY,mBACjB,EAAK,cAAc,EAAK,OACxB,EAAK,QAAQ,YAAY,EAAK,OAC9B,EAAK,iBAAiB,eAAe;AAEnC,IADA,KAAK,UAAU,cAAc,EAAK,MAAM,EACxC,KAAK,YAAY;KACjB,EACE,KAAK,UAAU,qBACb,KAAK,UAAU,SAAS,EAAK,MAAM,IAAE,EAAK,UAAU,IAAI,mBAAmB,EAC/E,EAAK,QAAQ,4BACb,EAAK,iBAAiB,gBAAgB,MAAM;AAE1C,IADA,EAAE,gBAAgB,EAClB,KAAK,UAAU,mBAAmB,EAAK,MAAM;KAC7C,GAEJ,EAAO,YAAY,EAAK;;AAI1B,EADA,KAAK,WAAW,GAChB,KAAK,WAAW,GAAK,YAAY,EAAO;;CAG1C,aAA2B;AACzB,EAEE,KAAK,cADL,KAAK,SAAS,QAAQ,EACN;;CAIpB,OAAO,GAA0B;AAE/B,EAAI,KAAK,aACP,KAAK,UAAU,UAAU,OAAO,cAAc,EAAM,eAAe,KAAK;EAI1E,IAAM,EAAE,yBAAsB,KAAK;AACnC,OAAK,IAAI,IAAI,GAAG,IAAI,EAAkB,QAAQ,KAAK;GACjD,IAAM,IAAW,EAAkB,GAAG,MAAM,MAAK,MAAK,EAAE,UAAU,EAAM,WAAW;AACnF,QAAK,aAAa,GAAG,UAAU,OAAO,cAAc,EAAS;;AAY/D,EARI,KAAK,YACP,KAAK,SAAS,iBAAiB,mBAAmB,CAAC,SAAS,MAAS;GACnE,IAAM,IAAK;AACX,KAAG,UAAU,OAAO,cAAc,EAAG,QAAQ,cAAc,EAAM,WAAW;IAC5E,EAIA,KAAK,cACP,KAAK,UAAU,UAAU,OAAO,cAAc,EAAM,cAAc,EAClE,KAAK,UAAU,QAAQ,EAAM,gBAAgB,cAAc;;CAI/D,UAAkC;EAChC,IAAM,IAAI,SAAS,cAAc,MAAM;AAEvC,SADA,EAAE,YAAY,uBACP;;CAGT,UAAgB;AAEd,EADA,KAAK,YAAY,EACjB,KAAK,GAAG,QAAQ;;GCtQd,IAAc;CAAC;CAAS;CAAW;CAAQ,EAEpC,IAAb,MAA4B;CAC1B;CACA;CACA,WAA0C;CAC1C,QAAuC;CACvC,aAA0B;CAC1B,kBAAqD;CACrD,SAAwC;CACxC,aAA0C,EAAE;CAE5C,YAAY,GAA8B,GAAe;AAEvD,EADA,KAAK,YAAY,GACjB,KAAK,IAAI;;CAGX,KAAK,GAA2C;AAG9C,EAFA,KAAK,kBAAkB,EAAE,GAAG,GAAiB,EAC7C,KAAK,aAAa,SAClB,KAAK,YAAY;;CAGnB,QAAc;AAMZ,EALA,KAAK,UAAU,QAAQ,EACvB,KAAK,OAAO,QAAQ,EACpB,KAAK,WAAW,MAChB,KAAK,QAAQ,MACb,KAAK,SAAS,MACd,KAAK,aAAa,EAAE;;CAGtB,aAA2B;AAYzB,EAVA,KAAK,WAAW,SAAS,cAAc,MAAM,EAC7C,KAAK,SAAS,YAAY,sBAC1B,KAAK,SAAS,iBAAiB,eAAe;AAE5C,GADA,KAAK,UAAU,SAAS,EACxB,KAAK,OAAO;IACZ,EACF,SAAS,KAAK,YAAY,KAAK,SAAS,EAGxC,KAAK,QAAQ,SAAS,cAAc,MAAM,EAC1C,KAAK,MAAM,YAAY;EAGvB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAK,SAAS,cAAc,KAAK;AAEvC,EADA,EAAG,cAAc,KAAK,EAAE,iBAAiB,EACzC,EAAO,YAAY,EAAG;EACtB,IAAM,IAAW,SAAS,cAAc,SAAS;AAQjD,EAPA,EAAS,YAAY,mBACrB,EAAS,YAAY,EAAW,KAAK,GAAG,EACxC,EAAS,iBAAiB,eAAe;AAEvC,GADA,KAAK,UAAU,SAAS,EACxB,KAAK,OAAO;IACZ,EACF,EAAO,YAAY,EAAS,EAC5B,KAAK,MAAM,YAAY,EAAO;EAG9B,IAAM,IAAS,SAAS,cAAc,MAAM;AAE5C,EADA,EAAO,YAAY,kBACnB,KAAK,aAAa,EAAE;AACpB,OAAK,IAAM,KAAO,GAAM;GACtB,IAAM,IAAM,SAAS,cAAc,SAAS;AAW5C,GAVA,EAAI,YAAY,iBAChB,EAAI,cAAc,KAAK,EAAE,gBAAgB,IAAmC,EAC5E,EAAI,QAAQ,MAAM,GACd,MAAQ,KAAK,cAAY,EAAI,UAAU,IAAI,aAAa,EAC5D,EAAI,iBAAiB,eAAe;AAGlC,IAFA,KAAK,aAAa,GAClB,KAAK,WAAW,SAAQ,MAAK,EAAE,UAAU,OAAO,cAAc,EAAE,QAAQ,QAAQ,EAAI,CAAC,EACrF,KAAK,kBAAkB;KACvB,EACF,EAAO,YAAY,EAAI,EACvB,KAAK,WAAW,KAAK,EAAI;;AAQ3B,EANA,KAAK,MAAM,YAAY,EAAO,EAG9B,KAAK,SAAS,SAAS,cAAc,MAAM,EAC3C,KAAK,OAAO,YAAY,kBACxB,KAAK,MAAM,YAAY,KAAK,OAAO,EACnC,KAAK,kBAAkB;EAGvB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAW,SAAS,cAAc,SAAS;AAIjD,EAHA,EAAS,YAAY,kBACrB,EAAS,cAAc,KAAK,EAAE,2BAA2B,EACzD,EAAS,iBAAiB,eAAe,KAAK,UAAU,SAAS,CAAC,EAClE,EAAO,YAAY,EAAS;EAC5B,IAAM,IAAU,SAAS,cAAc,SAAS;AAUhD,EATA,EAAQ,YAAY,gBACpB,EAAQ,cAAc,KAAK,EAAE,gBAAgB,EAC7C,EAAQ,iBAAiB,eAAe;AAEtC,GADA,KAAK,UAAU,SAAS,EACxB,KAAK,OAAO;IACZ,EACF,EAAO,YAAY,EAAQ,EAC3B,KAAK,MAAM,YAAY,EAAO,EAE9B,SAAS,KAAK,YAAY,KAAK,MAAM;EAGrC,IAAM,KAAa,MAAqB;AACtC,GAAI,EAAE,QAAQ,aACZ,SAAS,oBAAoB,WAAW,EAAU,EAClD,KAAK,UAAU,SAAS,EACxB,KAAK,OAAO;;AAGhB,WAAS,iBAAiB,WAAW,EAAU;;CAGjD,mBAAiC;AAC3B,SAAC,KAAK,UAAU,CAAC,KAAK,iBAG1B,SAFA,KAAK,OAAO,YAAY,IAEhB,KAAK,YAAb;GACE,KAAK;AACH,SAAK,gBAAgB;AACrB;GACF,KAAK;AACH,SAAK,kBAAkB;AACvB;GACF,KAAK;AACH,SAAK,gBAAgB;AACrB;;;CAIN,iBAA+B;AAC7B,MAAI,CAAC,KAAK,UAAU,CAAC,KAAK,gBAAiB;EAC3C,IAAM,IAAI,KAAK,iBAGT,IAAgB,KAAK,QAAQ,KAAK,EAAE,gCAAgC,CAAC;AAK3E,EAJA,EAAc,YAAY,KAAK,SAAS,WAAW,EAAE,gBAAgB,MAAM,KAAK,MAAM,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC,EAC7G,EAAc,YAAY,KAAK,SAAS,aAAa,EAAE,kBAAkB,MAAM,KAAK,MAAM,EAAE,iBAAiB,GAAG,CAAC,CAAC,CAAC,EACnH,EAAc,YAAY,KAAK,SAAS,WAAW,EAAE,eAAe,MAAM,KAAK,MAAM,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC,EAC3G,EAAc,YAAY,KAAK,SAAS,aAAa,EAAE,iBAAiB,MAAM,KAAK,MAAM,EAAE,gBAAgB,GAAG,CAAC,CAAC,CAAC,EACjH,KAAK,OAAO,YAAY,EAAc;EAGtC,IAAM,IAAY,KAAK,QAAQ,KAAK,EAAE,8BAA8B,CAAC;AAGrE,EAFA,EAAU,YAAY,KAAK,SAAS,cAAc,EAAE,kBAAkB,MAAM,KAAK,MAAM,EAAE,iBAAiB,GAAG,CAAC,CAAC,CAAC,EAChH,EAAU,YAAY,KAAK,SAAS,QAAQ,EAAE,YAAY,MAAM,KAAK,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,EAC9F,KAAK,OAAO,YAAY,EAAU;;CAGpC,mBAAiC;AAC/B,MAAI,CAAC,KAAK,UAAU,CAAC,KAAK,gBAAiB;EAC3C,IAAM,IAAI,KAAK,iBAET,IAAU,KAAK,SAAS;AAkD9B,EAjDA,EAAQ,YAAY,KAAK,UAAU,cAAc,EAAE,cAAc,MAAM,KAAK,MAAM,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC,EACvG,EAAQ,YAAY,KAAK,UAAU,UAAU,EAAE,gBAAgB,MAAM,KAAK,MAAM,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC,EACvG,EAAQ,YAAY,KAAK,UAAU,kBAAkB,EAAE,uBAAuB,MAAM,KAAK,MAAM,EAAE,sBAAsB,GAAG,CAAC,CAAC,CAAC,EAC7H,EAAQ,YAAY,KAAK,UAAU,wBAAwB,EAAE,uBAAuB,MAAM,KAAK,MAAM,EAAE,sBAAsB,GAAG,CAAC,CAAC,CAAC,EACnI,EAAQ,YAAY,KAAK,UAAU,uBAAuB,EAAE,qBAAqB,MAAM,KAAK,MAAM,EAAE,oBAAoB,GAAG,CAAC,CAAC,CAAC,EAC9H,EAAQ,YAAY,KAAK,UAAU,oBAAoB,EAAE,uBAAuB,MAAM,KAAK,MAAM,EAAE,sBAAsB,GAAG,CAAC,CAAC,CAAC,EAC/H,EAAQ,YAAY,KAAK,SAAS,cAAc,EAAE,sBAAsB,GAAG,KAAK,IAAI,MAAM,KAAK,MAAM,EAAE,sBAAsB,GAAG,CAAC,CAAC,CAAC,EACnI,EAAQ,YAAY,KAAK,SAAS,cAAc,EAAE,sBAAsB,KAAM,GAAG,MAAO,MAAM,KAAK,MAAM,EAAE,sBAAsB,GAAG,CAAC,GAAG,MAAM,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,EACzK,EAAQ,YAAY,KAAK,UAAU,qBAAqB,EAAE,sBAAsB,MAAM,KAAK,MAAM,EAAE,qBAAqB,GAAG,CAAC,CAAC,CAAC,EAC9H,EAAQ,YAAY,KAAK,SAAS,mBAAmB,EAAE,qBAAqB,IAAK,GAAG,MAAO,MAAM,KAAK,MAAM,EAAE,qBAAqB,GAAG,CAAC,GAAG,MAAM,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,EAC3K,EAAQ,YAAY,KAAK,UAAU,iBAAiB,EAAE,sBAAsB,MAAM,KAAK,MAAM,EAAE,qBAAqB,GAAG,CAAC,CAAC,CAAC,EAC1H,EAAQ,YAAY,KAAK,SAAS,kBAAkB,EAAE,eAAe,GAAG,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC,EACxH,EAAQ,YAAY,KAAK,UAAU,2BAA2B,EAAE,uBAAuB,MAAM,KAAK,MAAM,EAAE,sBAAsB,GAAG,CAAC,CAAC,CAAC,EACtI,EAAQ,YAAY,KAAK,UAAU,yBAAyB,EAAE,wBAAwB,MAAM,KAAK,MAAM,EAAE,uBAAuB,GAAG,CAAC,CAAC,CAAC,EACtI,EAAQ,YAAY,KAAK,UAAU,uBAAuB,EAAE,sBAAsB,MAAM,KAAK,MAAM,EAAE,qBAAqB,GAAG,CAAC,CAAC,CAAC,EAChI,EAAQ,YAAY,KAAK,UAAU,uBAAuB,EAAE,oBAAoB,CAC9E;GAAE,OAAO;GAAO,OAAO;GAAuB,EAC9C;GAAE,OAAO;GAAQ,OAAO;GAAwB,CACjD,GAAG,MAAM,KAAK,MAAM,EAAE,oBAAoB,GAA+C,CAAC,CAAC,CAAC,EAC7F,EAAQ,YAAY,KAAK,UAAU,eAAe,EAAE,gBAAgB,MAAM,KAAK,MAAM,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC,EAC5G,EAAQ,YAAY,KAAK,UAAU,iBAAiB,EAAE,eAAe,MAAM,KAAK,MAAM,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC,EAG5G,EAAQ,YAAY,KAAK,UAAU,kBAAkB,EAAE,eAAe;GACpE;IAAE,OAAO;IAAU,OAAO;IAAU;GACpC;IAAE,OAAO;IAAU,OAAO;IAAU;GACpC;IAAE,OAAO;IAAU,OAAO;IAAU;GACrC,GAAG,MAAM,KAAK,MAAM,EAAE,eAAe,GAA0C,CAAC,CAAC,CAAC,EAGnF,EAAQ,YAAY,KAAK,UAAU,YAAY,EAAE,UAAU;GACzD;IAAE,OAAO;IAAS,OAAO;IAAS;GAClC;IAAE,OAAO;IAAK,OAAO;IAAgB;GACrC;IAAE,OAAO;IAAQ,OAAO;IAAoB;GAC5C;IAAE,OAAO;IAAQ,OAAO;IAAmB;GAC3C;IAAE,OAAO;IAAM,OAAO;IAAqB;GAC3C;IAAE,OAAO;IAAO,OAAO;IAAwB;GAC/C;IAAE,OAAO;IAAO,OAAO;IAAiB;GACxC;IAAE,OAAO;IAAO,OAAO;IAAqB;GAC7C,GAAG,MAAM,KAAK,MAAM,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,EACvC,EAAQ,YAAY,KAAK,UAAU,iBAAiB,EAAE,cAAc;GAClE;IAAE,OAAO;IAAqB,OAAO;IAAS;GAC9C;IAAE,OAAO;IAAqB,OAAO;IAAS;GAC9C;IAAE,OAAO;IAAqB,OAAO;IAAS;GAC9C;IAAE,OAAO;IAAqB,OAAO;IAAS;GAC9C;IAAE,OAAO;IAAqB,OAAO;IAAS;GAC9C;IAAE,OAAO;IAAqB,OAAO;IAAS;GAC/C,GAAG,MAAM,KAAK,MAAM,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC,EAE3C,KAAK,OAAO,YAAY,EAAQ;;CAGlC,iBAA+B;AAC7B,MAAI,CAAC,KAAK,UAAU,CAAC,KAAK,gBAAiB;EAC3C,IAAM,IAAI,KAAK,iBAET,IAAU,KAAK,SAAS;AAQ9B,EAPA,EAAQ,YAAY,KAAK,UAAU,cAAc,EAAE,YAAY,MAAM,KAAK,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,EACnG,EAAQ,YAAY,KAAK,UAAU,eAAe,EAAE,WAAW;GAC7D;IAAE,OAAO;IAAW,OAAO;IAAW;GACtC;IAAE,OAAO;IAAe,OAAO;IAAe;GAC9C;IAAE,OAAO;IAAc,OAAO;IAAc;GAC5C;IAAE,OAAO;IAAgB,OAAO;IAAkB;GACnD,GAAG,MAAM,KAAK,MAAM,EAAE,WAAW,GAAsC,CAAC,CAAC,CAAC,EAC3E,KAAK,OAAO,YAAY,EAAQ;;CAGlC,MAAc,GAA4C;AAIxD,EAHI,KAAK,mBACP,OAAO,OAAO,KAAK,iBAAiB,EAAQ,EAE9C,KAAK,UAAU,SAAS,EAAQ;;CAGlC,QAAgB,GAAgC;EAC9C,IAAM,IAAM,SAAS,cAAc,MAAM;AAEzC,MADA,EAAI,YAAY,wBACZ,GAAO;GACT,IAAM,IAAI,SAAS,cAAc,MAAM;AAGvC,GAFA,EAAE,YAAY,8BACd,EAAE,cAAc,GAChB,EAAI,YAAY,EAAE;;AAEpB,SAAO;;CAGT,SAAiB,GAAe,GAAe,GAA+C;EAC5F,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;EAEhB,IAAM,IAAM,SAAS,cAAc,OAAO;AAG1C,EAFA,EAAI,YAAY,sBAChB,EAAI,cAAc,GAClB,EAAI,YAAY,EAAI;EAEpB,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;EAEjB,IAAM,IAAQ,SAAS,cAAc,QAAQ;AAE7C,EADA,EAAM,OAAO,SACb,EAAM,QAAQ;EAEd,IAAM,IAAM,SAAS,cAAc,OAAO;AAY1C,SAXA,EAAI,YAAY,iBAChB,EAAI,cAAc,GAElB,EAAM,iBAAiB,eAAe;AAEpC,GADA,EAAI,cAAc,EAAM,OACxB,EAAS,EAAM,MAAM;IACrB,EAEF,EAAK,YAAY,EAAM,EACvB,EAAK,YAAY,EAAI,EACrB,EAAI,YAAY,EAAK,EACd;;CAGT,UAAkB,GAAe,GAAgB,GAAgD;EAC/F,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;EAEhB,IAAM,IAAM,SAAS,cAAc,OAAO;AAG1C,EAFA,EAAI,YAAY,sBAChB,EAAI,cAAc,GAClB,EAAI,YAAY,EAAI;EAEpB,IAAM,IAAS,SAAS,cAAc,SAAS;AAQ/C,SAPA,EAAO,YAAY,aAAa,IAAQ,YAAY,MACpD,EAAO,iBAAiB,eAAe;GACrC,IAAM,IAAS,CAAC,EAAO,UAAU,SAAS,SAAS;AAEnD,GADA,EAAO,UAAU,OAAO,UAAU,EAAO,EACzC,EAAS,EAAO;IAChB,EACF,EAAI,YAAY,EAAO,EAChB;;CAGT,UACE,GACA,GACA,GACA,GACgB;EAChB,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;EAEhB,IAAM,IAAM,SAAS,cAAc,OAAO;AAG1C,EAFA,EAAI,YAAY,sBAChB,EAAI,cAAc,GAClB,EAAI,YAAY,EAAI;EAEpB,IAAM,IAAS,SAAS,cAAc,SAAS;AAC/C,IAAO,YAAY;AACnB,OAAK,IAAM,KAAO,GAAS;GACzB,IAAM,IAAI,SAAS,cAAc,SAAS;AAI1C,GAHA,EAAE,QAAQ,EAAI,OACd,EAAE,cAAc,EAAI,OAChB,EAAI,UAAU,MAAO,EAAE,WAAW,KACtC,EAAO,YAAY,EAAE;;AAIvB,SAFA,EAAO,iBAAiB,gBAAgB,EAAS,EAAO,MAAM,CAAC,EAC/D,EAAI,YAAY,EAAO,EAChB;;CAGT,SACE,GACA,GACA,GACA,GACA,GACA,GACA,KAAiC,MAAM,OAAO,EAAE,EAChC;EAChB,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;EAEhB,IAAM,IAAM,SAAS,cAAc,OAAO;AAG1C,EAFA,EAAI,YAAY,sBAChB,EAAI,cAAc,GAClB,EAAI,YAAY,EAAI;EAEpB,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;EAEjB,IAAM,IAAQ,SAAS,cAAc,QAAQ;AAK7C,EAJA,EAAM,OAAO,SACb,EAAM,MAAM,OAAO,EAAI,EACvB,EAAM,MAAM,OAAO,EAAI,EACvB,EAAM,OAAO,OAAO,EAAK,EACzB,EAAM,QAAQ,OAAO,EAAM;EAE3B,IAAM,IAAM,SAAS,cAAc,OAAO;AAa1C,SAZA,EAAI,YAAY,0BAChB,EAAI,cAAc,EAAO,EAAM,EAE/B,EAAM,iBAAiB,eAAe;GACpC,IAAM,IAAI,OAAO,EAAM,MAAM;AAE7B,GADA,EAAI,cAAc,EAAO,EAAE,EAC3B,EAAS,EAAE;IACX,EAEF,EAAK,YAAY,EAAM,EACvB,EAAK,YAAY,EAAI,EACrB,EAAI,YAAY,EAAK,EACd;;CAGT,UAAgB;AACd,OAAK,OAAO;;GCtXH,IAAb,MAA6B;CAC3B;CACA;CACA;CACA;CAEA,YAAY,GAAmB;AAE7B,EADA,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY;EAEpB,IAAM,IAAY,SAAS,cAAc,MAAM;AAe/C,EAdA,EAAU,YAAY,wBAEtB,KAAK,QAAQ,SAAS,cAAc,OAAO,EAC3C,KAAK,MAAM,YAAY,kBACvB,EAAU,YAAY,KAAK,MAAM,EAEjC,KAAK,YAAY,SAAS,cAAc,OAAO,EAC/C,EAAU,YAAY,KAAK,UAAU,EAErC,KAAK,GAAG,YAAY,EAAU,EAE9B,KAAK,SAAS,SAAS,cAAc,OAAO,EAC5C,KAAK,GAAG,YAAY,KAAK,OAAO,EAEhC,EAAK,YAAY,KAAK,GAAG;;CAG3B,OAAO,GAA8F;AASnG,EARA,KAAK,MAAM,YAAY,kBACnB,EAAM,oBAAoB,cAC5B,KAAK,MAAM,UAAU,IAAI,gBAAgB,GAChC,EAAM,oBAAoB,WACnC,KAAK,MAAM,UAAU,IAAI,YAAY,EAGvC,KAAK,UAAU,cAAc,EAAM,SACnC,KAAK,OAAO,cAAc,GAAG,EAAM,OAAO,GAAG,EAAM;;CAGrD,UAAgB;AACd,OAAK,GAAG,QAAQ;;GCtBP,IAAb,MAAkC;CAChC,WAA0C;CAC1C,QAAuC;CACvC,QAAyC;CACzC,OAAsC;CACtC,QAA+B,EAAE;CACjC,WAAkC,EAAE;CACpC,gBAAwB;CACxB;CACA;CAEA,YAAY,GAAoC;AAE9C,EADA,KAAK,YAAY,GACjB,KAAK,eAAe,KAAK,cAAc,KAAK,KAAK;;CAGnD,KAAK,GAA4B;AAC/B,MAAI,KAAK,SAAU;AAUnB,EATA,KAAK,QAAQ,GACb,KAAK,WAAW,GAChB,KAAK,gBAAgB,GAErB,KAAK,WAAW,SAAS,cAAc,MAAM,EAC7C,KAAK,SAAS,YAAY,sBAC1B,KAAK,SAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EAE3D,KAAK,QAAQ,SAAS,cAAc,MAAM,EAC1C,KAAK,MAAM,YAAY;EAEvB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EAEnB,IAAM,IAAa,SAAS,cAAc,OAAO;AAUjD,EATA,EAAW,YAAY,gBACvB,EAAW,cAAc,KACzB,EAAO,YAAY,EAAW,EAE9B,KAAK,QAAQ,SAAS,cAAc,QAAQ,EAC5C,KAAK,MAAM,YAAY,iBACvB,KAAK,MAAM,OAAO,QAClB,KAAK,MAAM,cAAc,4CACzB,KAAK,MAAM,iBAAiB,eAAe,KAAK,QAAQ,CAAC,EACzD,EAAO,YAAY,KAAK,MAAM;EAE9B,IAAM,IAAO,SAAS,cAAc,OAAO;AAS3C,EARA,EAAK,YAAY,gBACjB,EAAK,cAAc,OACnB,EAAO,YAAY,EAAK,EAExB,KAAK,MAAM,YAAY,EAAO,EAE9B,KAAK,OAAO,SAAS,cAAc,MAAM,EACzC,KAAK,KAAK,YAAY,gBACtB,KAAK,MAAM,YAAY,KAAK,KAAK;EAEjC,IAAM,IAAS,SAAS,cAAc,MAAM;AAU5C,EATA,EAAO,YAAY,kBACnB,EAAO,YAAY,uEACnB,KAAK,MAAM,YAAY,EAAO,EAE9B,SAAS,KAAK,YAAY,KAAK,SAAS,EACxC,SAAS,KAAK,YAAY,KAAK,MAAM,EAErC,KAAK,YAAY,EACjB,KAAK,MAAM,OAAO,EAClB,SAAS,iBAAiB,WAAW,KAAK,aAAa;;CAGzD,QAAc;AAQZ,EAPA,SAAS,oBAAoB,WAAW,KAAK,aAAa,EAC1D,KAAK,UAAU,QAAQ,EACvB,KAAK,OAAO,QAAQ,EACpB,KAAK,WAAW,MAChB,KAAK,QAAQ,MACb,KAAK,QAAQ,MACb,KAAK,OAAO,MACZ,KAAK,UAAU,SAAS;;CAG1B,SAAkB;AAChB,SAAO,KAAK,aAAa;;CAG3B,SAAuB;EACrB,IAAM,IAAQ,KAAK,OAAO,MAAM,aAAa,CAAC,MAAM,IAAI;AAWxD,EAVK,IAGH,KAAK,WAAW,KAAK,MAAM,QAAO,MAChC,EAAK,MAAM,aAAa,CAAC,SAAS,EAAM,IACxC,EAAK,SAAS,aAAa,CAAC,SAAS,EAAM,IAC3C,EAAK,GAAG,aAAa,CAAC,SAAS,EAAM,CACtC,GAND,KAAK,WAAW,KAAK,OAQvB,KAAK,gBAAgB,GACrB,KAAK,YAAY;;CAGnB,aAA2B;AACzB,MAAI,CAAC,KAAK,KAAM;AAGhB,MAFA,KAAK,KAAK,YAAY,IAElB,KAAK,SAAS,WAAW,GAAG;GAC9B,IAAM,IAAQ,SAAS,cAAc,MAAM;AAG3C,GAFA,EAAM,YAAY,iBAClB,EAAM,cAAc,oBACpB,KAAK,KAAK,YAAY,EAAM;AAC5B;;EAGF,IAAI,IAAkB;AACtB,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;GAC7C,IAAM,IAAO,KAAK,SAAS;AAE3B,OAAI,EAAK,aAAa,GAAiB;AACrC,QAAkB,EAAK;IACvB,IAAM,IAAQ,SAAS,cAAc,MAAM;AAG3C,IAFA,EAAM,YAAY,oBAClB,EAAM,cAAc,KAAK,cAAc,EAAgB,EACvD,KAAK,KAAK,YAAY,EAAM;;GAG9B,IAAM,IAAM,SAAS,cAAc,SAAS;AAI5C,GAHA,EAAI,YAAY,gBACZ,MAAM,KAAK,iBAAe,EAAI,UAAU,IAAI,eAAe,EAC3D,EAAK,UAAQ,EAAI,UAAU,IAAI,aAAa,EAChD,EAAI,QAAQ,QAAQ,OAAO,EAAE;GAE7B,IAAM,IAAW,SAAS,cAAc,OAAO;AAK/C,OAJA,EAAS,YAAY,sBACrB,EAAS,cAAc,EAAK,OAC5B,EAAI,YAAY,EAAS,EAErB,EAAK,QAAQ;IACf,IAAM,IAAQ,SAAS,cAAc,OAAO;AAG5C,IAFA,EAAM,YAAY,iBAClB,EAAM,cAAc,KACpB,EAAI,YAAY,EAAM;;AAGxB,OAAI,EAAK,UAAU;IACjB,IAAM,IAAM,SAAS,cAAc,MAAM;AAGzC,IAFA,EAAI,YAAY,eAChB,EAAI,cAAc,EAAK,UACvB,EAAI,YAAY,EAAI;;AAStB,GANA,EAAI,iBAAiB,eAAe,KAAK,OAAO,EAAE,CAAC,EACnD,EAAI,iBAAiB,oBAAoB;AAEvC,IADA,KAAK,gBAAgB,GACrB,KAAK,iBAAiB;KACtB,EAEF,KAAK,KAAK,YAAY,EAAI;;;CAI9B,kBAAgC;AAC9B,MAAI,CAAC,KAAK,KAAM;EAChB,IAAM,IAAQ,KAAK,KAAK,iBAAiB,gBAAgB;AAIzD,EAHA,EAAM,SAAS,GAAI,MAAM;AACvB,KAAG,UAAU,OAAO,gBAAgB,MAAM,KAAK,cAAc;IAC7D,EACF,EAAM,KAAK,gBAAgB,eAAe,EAAE,OAAO,WAAW,CAAC;;CAGjE,OAAe,GAAqB;EAClC,IAAM,IAAO,KAAK,SAAS;AACtB,SAEL;WAAQ,EAAK,UAAb;IACE,KAAK;AACH,UAAK,UAAU,YAAY,EAAK,GAAG;AACnC;IACF,KAAK;AACH,UAAK,UAAU,YAAY,EAAK,GAAgB;AAChD;IACF,KAAK;AACH,UAAK,UAAU,cAAc,EAAK,GAAsB;AACxD;IACF,KAAK;AACH,UAAK,UAAU,YAAY,EAAK,GAAgB;AAChD;IACF,KAAK;AACH,UAAK,UAAU,SAAS,EAAK,GAAG;AAChC;;AAEJ,QAAK,OAAO;;;CAGd,cAAsB,GAAwB;AAC5C,UAAQ,EAAE,KAAV;GACE,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,KAAK,OAAO;AACZ;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EACd,KAAK,SAAS,SAAS,MACzB,KAAK,iBAAiB,KAAK,gBAAgB,KAAK,KAAK,SAAS,QAC9D,KAAK,iBAAiB;AAExB;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EACd,KAAK,SAAS,SAAS,MACzB,KAAK,iBAAiB,KAAK,gBAAgB,IAAI,KAAK,SAAS,UAAU,KAAK,SAAS,QACrF,KAAK,iBAAiB;AAExB;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,KAAK,OAAO,KAAK,cAAc;AAC/B;;;CAIN,cAAsB,GAAqB;AACzC,UAAQ,GAAR;GACE,KAAK,YAAa,QAAO;GACzB,KAAK,YAAa,QAAO;GACzB,KAAK,UAAW,QAAO;GACvB,KAAK,YAAa,QAAO;GACzB,KAAK,SAAU,QAAO;GACtB,QAAS,QAAO;;;CAIpB,UAAgB;AACd,OAAK,OAAO;;GCzOH,IAAb,MAAgC;CAC9B,WAA0C;CAC1C,QAAuC;CACvC,QAAyC;CACzC,OAAsC;CACtC,UAA4B,EAAE;CAC9B,UAA0B;CAC1B,WAAmC,EAAE;CACrC,gBAAwB;CACxB;CACA;CAEA,eAA0D;CAE1D,YAAY,GAAkC;AAE5C,EADA,KAAK,YAAY,GACjB,KAAK,eAAe,KAAK,cAAc,KAAK,KAAK;;CAGnD,KAAK,GAAmB,GAAiB,GAAyC;AAChF,MAAI,KAAK,SAAU;AAYnB,EAXA,KAAK,eAAe,KAAU,MAC9B,KAAK,UAAU,GACf,KAAK,UAAU,GACf,KAAK,WAAW,EAAQ,KAAI,OAAM;GAAE,QAAQ;GAAG,OAAO;GAAG,EAAE,EAC3D,KAAK,gBAAgB,KAAK,IAAI,GAAG,EAAQ,QAAQ,EAAQ,CAAC,EAE1D,KAAK,WAAW,SAAS,cAAc,MAAM,EAC7C,KAAK,SAAS,YAAY,sBAC1B,KAAK,SAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EAE3D,KAAK,QAAQ,SAAS,cAAc,MAAM,EAC1C,KAAK,MAAM,YAAY;EAEvB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EAEnB,IAAM,IAAO,SAAS,cAAc,OAAO;AAY3C,EAXA,EAAK,YAAY,gBACjB,EAAK,YAAY,GAAW,EAC5B,EAAO,YAAY,EAAK,EAExB,KAAK,QAAQ,SAAS,cAAc,QAAQ,EAC5C,KAAK,MAAM,YAAY,iBACvB,KAAK,MAAM,OAAO,QAClB,KAAK,MAAM,cAAc,wCACzB,KAAK,MAAM,eAAe,OAC1B,KAAK,MAAM,aAAa,IACxB,KAAK,MAAM,iBAAiB,eAAe,KAAK,QAAQ,CAAC,EACzD,EAAO,YAAY,KAAK,MAAM;EAE9B,IAAM,IAAO,SAAS,cAAc,OAAO;AAS3C,EARA,EAAK,YAAY,gBACjB,EAAK,cAAc,OACnB,EAAO,YAAY,EAAK,EAExB,KAAK,MAAM,YAAY,EAAO,EAE9B,KAAK,OAAO,SAAS,cAAc,MAAM,EACzC,KAAK,KAAK,YAAY,gBACtB,KAAK,MAAM,YAAY,KAAK,KAAK;EAEjC,IAAM,IAAS,SAAS,cAAc,MAAM;AAU5C,EATA,EAAO,YAAY,kBACnB,EAAO,YAAY,qEACnB,KAAK,MAAM,YAAY,EAAO,EAE9B,SAAS,KAAK,YAAY,KAAK,SAAS,EACxC,SAAS,KAAK,YAAY,KAAK,MAAM,EAErC,KAAK,YAAY,EACjB,KAAK,MAAM,OAAO,EAClB,SAAS,iBAAiB,WAAW,KAAK,aAAa;;CAGzD,QAAc;AASZ,EARA,SAAS,oBAAoB,WAAW,KAAK,aAAa,EAC1D,KAAK,UAAU,QAAQ,EACvB,KAAK,OAAO,QAAQ,EACpB,KAAK,WAAW,MAChB,KAAK,QAAQ,MACb,KAAK,QAAQ,MACb,KAAK,OAAO,MACZ,KAAK,eAAe,MACpB,KAAK,UAAU,SAAS;;CAG1B,SAAkB;AAChB,SAAO,KAAK,aAAa;;CAG3B,UAAgB;AACd,OAAK,OAAO;;CAGd,SAAuB;EACrB,IAAM,KAAK,KAAK,OAAO,SAAS,IAAI,aAAa,CAAC,MAAM;AAUxD,EATK,IAGH,KAAK,WAAW,KAAK,QAClB,KAAI,OAAM;GAAE,QAAQ;GAAG,OAAO,EAAW,EAAE,aAAa,EAAE,EAAE;GAAE,EAAE,CAChE,QAAO,MAAK,EAAE,QAAQ,EAAE,CACxB,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GALpC,KAAK,WAAW,KAAK,QAAQ,KAAI,OAAM;GAAE,QAAQ;GAAG,OAAO;GAAG,EAAE,EAOlE,KAAK,gBAAgB,GACrB,KAAK,YAAY;;CAGnB,aAA2B;AACzB,MAAI,CAAC,KAAK,KAAM;AAGhB,MAFA,KAAK,KAAK,YAAY,IAElB,KAAK,SAAS,WAAW,GAAG;GAC9B,IAAM,IAAQ,SAAS,cAAc,MAAM;AAG3C,GAFA,EAAM,YAAY,iBAClB,EAAM,cAAc,oBACpB,KAAK,KAAK,YAAY,EAAM;AAC5B;;EAGF,IAAM,KAAS,KAAK,OAAO,SAAS,IAAI,aAAa,CAAC,MAAM;AAC5D,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;GAC7C,IAAM,EAAE,cAAW,KAAK,SAAS,IAC3B,IAAM,SAAS,cAAc,SAAS;AAG5C,GAFA,EAAI,YAAY,gBACZ,MAAM,KAAK,iBAAe,EAAI,UAAU,IAAI,eAAe,EAC3D,MAAW,KAAK,WAAS,EAAI,UAAU,IAAI,aAAa;GAE5D,IAAM,IAAQ,SAAS,cAAc,OAAO;AAK5C,OAJA,EAAM,YAAY,sBAClB,EAAM,YAAY,EAAU,GAAQ,EAAM,EAC1C,EAAI,YAAY,EAAM,EAElB,MAAW,KAAK,SAAS;IAC3B,IAAM,IAAQ,SAAS,cAAc,OAAO;AAG5C,IAFA,EAAM,YAAY,iBAClB,EAAM,cAAc,KACpB,EAAI,YAAY,EAAM;;AASxB,GANA,EAAI,iBAAiB,eAAe,KAAK,KAAK,EAAE,CAAC,EACjD,EAAI,iBAAiB,oBAAoB;AAEvC,IADA,KAAK,gBAAgB,GACrB,KAAK,iBAAiB;KACtB,EAEF,KAAK,KAAK,YAAY,EAAI;;;CAI9B,kBAAgC;AAC9B,MAAI,CAAC,KAAK,KAAM;EAChB,IAAM,IAAQ,KAAK,KAAK,iBAAiB,gBAAgB;AAEzD,EADA,EAAM,SAAS,GAAI,MAAM,EAAG,UAAU,OAAO,gBAAgB,MAAM,KAAK,cAAc,CAAC,EACvF,EAAM,KAAK,gBAAgB,eAAe,EAAE,OAAO,WAAW,CAAC;;CAGjE,KAAa,GAAqB;EAChC,IAAM,IAAQ,KAAK,SAAS;AAC5B,MAAI,CAAC,EAAO;EACZ,IAAM,IAAW,KAAK;AAGtB,EAFI,IAAU,EAAS,EAAM,OAAO,GAC/B,KAAK,UAAU,OAAO,EAAM,OAAO,EACxC,KAAK,OAAO;;CAGd,cAAsB,GAAwB;AAC5C,UAAQ,EAAE,KAAV;GACE,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,KAAK,OAAO;AACZ;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EACd,KAAK,SAAS,SAAS,MACzB,KAAK,iBAAiB,KAAK,gBAAgB,KAAK,KAAK,SAAS,QAC9D,KAAK,iBAAiB;AAExB;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EACd,KAAK,SAAS,SAAS,MACzB,KAAK,iBAAiB,KAAK,gBAAgB,IAAI,KAAK,SAAS,UAAU,KAAK,SAAS,QACrF,KAAK,iBAAiB;AAExB;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,KAAK,KAAK,KAAK,cAAc;AAC7B;;;;AAYR,SAAS,EAAW,GAAgB,GAAuB;AACzD,KAAI,MAAW,EAAO,QAAO;AAC7B,KAAI,EAAO,WAAW,EAAM,CAAE,QAAO,OAAO,KAAK,KAAK,IAAI,IAAI,EAAO,SAAS,EAAM,OAAO;AAC3F,KAAI,EAAO,SAAS,EAAM,CAAE,QAAO,OAAO,KAAK,KAAK,IAAI,IAAI,EAAO,SAAS,EAAM,OAAO;CAEzF,IAAI,IAAK,GACL,IAAU,IACV,IAAa;AACjB,MAAK,IAAI,IAAI,GAAG,IAAI,EAAO,UAAU,IAAK,EAAM,QAAQ,IACtD,CAAI,EAAO,OAAO,EAAM,OAClB,KAAW,MAAG,KAAc,IAAI,IAAU,IAC9C,IAAU,GACV;AAIJ,QADI,IAAK,EAAM,SAAe,IACvB,MAAM,KAAK,IAAI,IAAI,EAAW;;AAGvC,SAAS,EAAU,GAAgB,GAAuB;AACxD,KAAI,CAAC,EAAO,QAAO,EAAW,EAAO;CACrC,IAAM,IAAQ,EAAO,aAAa,EAC9B,IAAM,IACN,IAAK;AACT,MAAK,IAAI,IAAI,GAAG,IAAI,EAAO,QAAQ,IACjC,CAAI,IAAK,EAAM,UAAU,EAAM,OAAO,EAAM,MAC1C,KAAO,gFAAgF,EAAW,EAAO,GAAG,CAAC,UAC7G,OAEA,KAAO,EAAW,EAAO,GAAG;AAGhC,QAAO;;AAGT,SAAS,EAAW,GAAmB;AACrC,QAAO,EAAE,QAAQ,aAAY,OAAO;EAClC,KAAK;EAAS,KAAK;EAAQ,KAAK;EAAQ,MAAK;EAAU,KAAK;EAC7D,EAA4B,GAAI;;AAGnC,SAAS,IAAoB;AAC3B,QAAO;;;;ACtPT,IAAM,IAA+C;CACnD,uBAAuB;CACvB,sBAAsB;CACtB,2BAA2B;CAC3B,UAAY;CACZ,SAAW;CACZ,EAcK,IADJ,OAAO,YAAc,OAAe,wBAAwB,KAAK,UAAU,YAAY,UAAU,UAAU,GACzF,MAAM,QAEpB,IAAwB;CAC5B;EACE,OAAO;EACP,SAAS;GACP;IAAE,MAAM,CAAC,GAAK,IAAI;IAAE,OAAO;IAAmB;GAC9C;IAAE,MAAM,CAAC,GAAK,IAAI;IAAE,OAAO;IAAiB;GAC5C;IAAE,MAAM,CAAC,IAAI;IAAE,OAAO;IAAmB;GAC1C;EACF;CACD;EACE,OAAO;EACP,SAAS;GACP;IAAE,MAAM,CAAC,SAAS,OAAO;IAAE,OAAO;IAAiC;GACnE;IAAE,MAAM,CAAC,QAAQ,aAAa;IAAE,OAAO;IAAoC;GAC3E;IAAE,MAAM,CAAC,QAAQ,YAAY;IAAE,OAAO;IAAkB;GACxD;IAAE,MAAM,CAAC,gBAAgB,aAAa;IAAE,OAAO;IAAwB;GACvE;IAAE,MAAM,CAAC,gBAAgB,YAAY;IAAE,OAAO;IAAe;GAC7D;IAAE,MAAM,CAAC,SAAS;IAAE,OAAO;IAAsB;GAClD;EACF;CACD;EACE,OAAO;EACP,SAAS;GACP;IAAE,MAAM,CAAC,YAAY,OAAO;IAAE,OAAO;IAAwB;GAC7D;IAAE,MAAM,CAAC,aAAa,QAAQ;IAAE,OAAO;IAAwB;GAC/D;IAAE,MAAM,CAAC,aAAa;IAAE,OAAO;IAA2B;GAC1D;IAAE,MAAM,CAAC,QAAQ,aAAa;IAAE,OAAO;IAA2B;GACnE;EACF;CACD;EACE,OAAO;EACP,SAAS;GACP;IAAE,MAAM,CAAC,KAAK,IAAI;IAAE,OAAO;IAAe;GAC1C;IAAE,MAAM,CAAC,KAAK,IAAI;IAAE,OAAO;IAAiB;GAC5C;IAAE,MAAM,CAAC,OAAO;IAAE,OAAO;IAAmB;GAC5C;IAAE,MAAM,CAAC,MAAM;IAAE,OAAO;IAA6B;GACrD;IAAE,MAAM,CAAC,IAAI;IAAE,OAAO;IAAe;GACtC;EACF;CACD;EACE,OAAO;EACP,SAAS;GACP;IAAE,MAAM,CAAC,GAAK,IAAI;IAAE,OAAO;IAAQ;GACnC;IAAE,MAAM;KAAC;KAAK;KAAS;KAAI;IAAE,OAAO;IAAQ;GAC5C;IAAE,MAAM,CAAC,MAAM;IAAE,OAAO;IAAyB;GAClD;EACF;CACF,EAEY,IAAb,MAA+B;CAC7B,WAA0C;CAC1C,QAAuC;CACvC;CACA;CACA;CAEA,YAAY,GAAiC,GAAe;AAG1D,EAFA,KAAK,YAAY,GACjB,KAAK,IAAI,GACT,KAAK,gBAAgB,MAAM;AACzB,GAAI,EAAE,QAAQ,aACZ,EAAE,gBAAgB,EAClB,KAAK,OAAO;;;CAKlB,OAAa;AACX,MAAI,KAAK,SAAU;AAQnB,EANA,KAAK,WAAW,SAAS,cAAc,MAAM,EAC7C,KAAK,SAAS,YAAY,sBAC1B,KAAK,SAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EAE3D,KAAK,QAAQ,SAAS,cAAc,MAAM,EAC1C,KAAK,MAAM,YAAY,8BACvB,KAAK,MAAM,MAAM,QAAQ;EAEzB,IAAM,IAAS,SAAS,cAAc,MAAM;AAE5C,EADA,EAAO,YAAY,oBACnB,EAAO,YAAY,OAAO,KAAK,EAAE,gBAAgB,CAAC;EAClD,IAAM,IAAW,SAAS,cAAc,SAAS;AAMjD,EALA,EAAS,YAAY,mBACrB,EAAS,aAAa,cAAc,KAAK,EAAE,gBAAgB,CAAC,EAC5D,EAAS,YAAY,KACrB,EAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACtD,EAAO,YAAY,EAAS,EAC5B,KAAK,MAAM,YAAY,EAAO;EAE9B,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;EAEjB,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;AAEjB,OAAK,IAAM,KAAS,GAAQ;GAC1B,IAAM,IAAU,SAAS,cAAc,UAAU;AACjD,KAAQ,YAAY;GACpB,IAAM,IAAQ,SAAS,cAAc,MAAM;AAC3C,KAAM,YAAY;GAClB,IAAM,IAAW,EAAiB,EAAM;AAExC,GADA,EAAM,cAAc,IAAW,KAAK,EAAE,EAAS,GAAG,EAAM,OACxD,EAAQ,YAAY,EAAM;AAE1B,QAAK,IAAM,KAAS,EAAM,SAAS;IACjC,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,MAAI,YAAY;IAEhB,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,MAAK,YAAY;AACjB,SAAK,IAAI,IAAI,GAAG,IAAI,EAAM,KAAK,QAAQ,KAAK;AAC1C,SAAI,IAAI,GAAG;MACT,IAAM,IAAO,SAAS,cAAc,OAAO;AAG3C,MAFA,EAAK,YAAY,kBACjB,EAAK,cAAc,KACnB,EAAK,YAAY,EAAK;;KAExB,IAAM,IAAM,SAAS,cAAc,MAAM;AAGzC,KAFA,EAAI,YAAY,eAChB,EAAI,cAAc,EAAM,KAAK,IAC7B,EAAK,YAAY,EAAI;;AAEvB,MAAI,YAAY,EAAK;IAErB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAK5C,IAJA,EAAM,YAAY,oBAClB,EAAM,cAAc,EAAM,OAC1B,EAAI,YAAY,EAAM,EAEtB,EAAQ,YAAY,EAAI;;AAG1B,KAAK,YAAY,EAAQ;;AAI3B,EADA,EAAK,YAAY,EAAK,EACtB,KAAK,MAAM,YAAY,EAAK;EAE5B,IAAM,IAAS,SAAS,cAAc,MAAM;AAE5C,EADA,EAAO,YAAY,oBACnB,EAAO,YAAY;EACnB,IAAM,IAAK,SAAS,cAAc,SAAS;AAU3C,EATA,EAAG,YAAY,gBACf,EAAG,cAAc,KAAK,EAAE,gBAAgB,EACxC,EAAG,iBAAiB,eAAe,KAAK,OAAO,CAAC,EAChD,EAAO,YAAY,EAAG,EACtB,KAAK,MAAM,YAAY,EAAO,EAE9B,SAAS,KAAK,YAAY,KAAK,SAAS,EACxC,SAAS,KAAK,YAAY,KAAK,MAAM,EAErC,SAAS,iBAAiB,WAAW,KAAK,aAAa;;CAGzD,QAAc;AAMZ,EALA,SAAS,oBAAoB,WAAW,KAAK,aAAa,EAC1D,KAAK,UAAU,QAAQ,EACvB,KAAK,OAAO,QAAQ,EACpB,KAAK,WAAW,MAChB,KAAK,QAAQ,MACb,KAAK,UAAU,SAAS;;CAG1B,SAAkB;AAChB,SAAO,KAAK,aAAa;;CAG3B,UAAgB;AACd,OAAK,OAAO;;GCxLV,IAAS;CAAC;CAAK;CAAG;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI,EAEjC,IAAb,MAA6B;CAC3B,OAAsC;CACtC,WAA4C;CAC5C,gBAAgD;CAChD,UAA4C;CAC5C,QAAgC;CAChC,QAAgB;CAChB,QAAgB;CAChB;CAEA,YAAY,GAA+B;AACzC,OAAK,YAAY;;CAGnB,MAAM,GAAmB,GAA+C;AAClE,OAAK,SACT,KAAK,QAAQ,KAAK,IAAI,GAAG,EAAK,MAAM,EACpC,KAAK,QAAQ,EAAK,SAAS,GAC3B,KAAK,QAAQ,UAEb,KAAK,OAAO,SAAS,cAAc,MAAM,EACzC,KAAK,KAAK,YAAY,kBACtB,KAAK,KAAK,YAAY,KAAK,QAAQ,EAEnC,EAAK,YAAY,KAAK,KAAK,EAC3B,KAAK,YAAY,EACjB,KAAK,QAAQ;;CAGf,UAAgB;AAMd,EALA,KAAK,MAAM,QAAQ,EACnB,KAAK,OAAO,MACZ,KAAK,WAAW,MAChB,KAAK,gBAAgB,MACrB,KAAK,UAAU,MACf,KAAK,QAAQ;;CAGf,YAAqB;AACnB,SAAO,KAAK,SAAS;;CAGvB,SAAS,GAA6B;AAEpC,EADA,KAAK,QAAQ,GACb,KAAK,QAAQ;;CAGf,YAAY,GAAiB,GAAqB;AAMhD,EALA,KAAK,QAAQ,GACT,KAAK,aACP,KAAK,SAAS,MAAM,OAAO,KAAK,IAAI,GAAG,IAAQ,EAAE,CAAC,EAClD,KAAK,SAAS,QAAQ,OAAO,EAAQ,GAEnC,KAAK,kBACP,KAAK,cAAc,cAAc,GAAG,IAAU,EAAE,KAAK;;CAIzD,UAAgB;AACd,OAAK,SAAS;;CAGhB,SAAyB;EACvB,IAAM,IAAS,EAAO,KAAI,MAAK,kBAAkB,EAAE,GAAG,MAAM,KAAK,QAAQ,cAAc,GAAG,GAAG,EAAE,mBAAmB,CAAC,KAAK,GAAG;AAC3H,SAAO;qGAC0F,GAAM,CAAC;oGACR,GAAa,CAAC;sHACI,GAAS,CAAC;6GACnB,GAAgB,CAAC;qFACzC,KAAK,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;kEAC/C,KAAK,MAAM;0DACnB,EAAO;;;CAI/D,aAA2B;AACpB,OAAK,SACV,KAAK,WAAW,KAAK,KAAK,cAAc,2BAAyB,EACjE,KAAK,gBAAgB,KAAK,KAAK,cAAc,0BAAwB,EACrE,KAAK,UAAU,KAAK,KAAK,cAAc,4BAA0B,EAEjE,KAAK,KAAK,cAAc,uBAAqB,EAAE,iBAAiB,eAAe,KAAK,UAAU,SAAS,CAAC,EACxG,KAAK,KAAK,cAAc,0BAAwB,EAAE,iBAAiB,eAAe,KAAK,UAAU,YAAY,CAAC,EAC9G,KAAK,KAAK,cAAc,6BAA2B,EAAE,iBAAiB,eAAe,KAAK,UAAU,eAAe,CAAC,EACpH,KAAK,SAAS,iBAAiB,eAAe;AAC5C,GAAI,KAAK,UAAU,YACjB,KAAK,UAAU,SAAS,GAExB,KAAK,UAAU,QAAQ;IAEzB,EACF,KAAK,UAAU,iBAAiB,eAAe;GAC7C,IAAM,IAAM,OAAO,KAAK,SAAU,MAAM;AACxC,QAAK,UAAU,OAAO,EAAI;IAC1B,EACD,KAAK,KAAK,cAAc,uBAAqB,EAA+B,iBAAiB,WAAW,MAAM;GAC7G,IAAM,IAAI,OAAQ,EAAE,OAA6B,MAAM;AAEvD,GADA,KAAK,QAAQ,GACb,KAAK,UAAU,cAAc,EAAE;IAC/B;;CAGJ,SAAuB;AAChB,OAAK,YACV,KAAK,QAAQ,YAAY,KAAK,UAAU,YAAY,GAAU,GAAG,GAAS,EAC1E,KAAK,QAAQ,QAAQ,KAAK,UAAU,YAAY,UAAU;;;AAI9D,SAAS,IAAkB;AACzB,QAAO;;AAET,SAAS,IAAmB;AAC1B,QAAO;;AAET,SAAS,IAAsB;AAC7B,QAAO;;AAET,SAAS,IAAyB;AAChC,QAAO;;AAET,SAAS,IAAe;AACtB,QAAO;;;;AC1HT,IAAa,IAAb,MAA6B;CAC3B;CACA;CACA,yBAAiB,IAAI,KAKjB;CACJ,0BAAkB,IAAI,KAA6B;CACnD,SAAgC;CAChC;CACA;CAEA,YAAY,GAAmB,GAAmB,GAA+B,IAAQ,aAAa;AAIpG,EAHA,KAAK,YAAY,GAEjB,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY;EAEpB,IAAM,IAAS,SAAS,cAAc,MAAM;AAO5C,EANA,EAAO,YAAY,wBACnB,EAAO,cAAc,GACrB,KAAK,GAAG,YAAY,EAAO,EAE3B,KAAK,SAAS,SAAS,cAAc,MAAM,EAC3C,KAAK,OAAO,YAAY,sBACxB,KAAK,GAAG,YAAY,KAAK,OAAO;AAEhC,OAAK,IAAM,KAAU,EAEnB,CADA,KAAK,QAAQ,IAAI,GAAQ,EAAE,WAAQ,CAAC,EACpC,KAAK,UAAU,EAAO;AAGxB,IAAK,YAAY,KAAK,GAAG;;CAI3B,UAAU,GAAkC;AAC1C,OAAK,SAAS;AACd,OAAK,IAAM,KAAU,KAAK,QAAQ,MAAM,CAAE,MAAK,UAAU,EAAO;;CAIlE,WAAW,GAAyB;EAClC,IAAM,IAAO,IAAI,IAAI,EAAQ;AAC7B,OAAK,IAAM,KAAO,KAAK,OAAO,MAAM,CAClC,CAAK,EAAK,IAAI,EAAI,IAAE,KAAK,UAAU,EAAI;AAEzC,OAAK,IAAM,KAAO,EAChB,CAAK,KAAK,OAAO,IAAI,EAAI,KACvB,KAAK,QAAQ,IAAI,GAAK,KAAK,QAAQ,IAAI,EAAI,IAAI,EAAE,QAAQ,GAAK,CAAC,EAC/D,KAAK,UAAU,EAAI;;CAKzB,UAAU,GAAsB;AAC9B,MAAI,KAAK,WAAW,EAAQ;AAI5B,EAHI,KAAK,UAAU,KAAK,OAAO,IAAI,KAAK,OAAO,IAC7C,KAAK,OAAO,IAAI,KAAK,OAAO,CAAE,IAAI,UAAU,OAAO,uBAAuB,EAE5E,KAAK,SAAS;EACd,IAAM,IAAM,KAAK,OAAO,IAAI,EAAO;AACnC,EAAI,KAAK,EAAI,IAAI,UAAU,IAAI,uBAAuB;;CAKxD,SAAS,GAAgB,GAAsC;EAE7D,IAAM,IAAO;GAAE,GADF,KAAK,QAAQ,IAAI,EAAO,IAAI,EAAE,WAAQ;GAC3B,GAAG;GAAO;AAElC,EADA,KAAK,QAAQ,IAAI,GAAQ,EAAK,EAC9B,KAAK,UAAU,EAAO;;CAGxB,UAAgB;AAGd,EAFA,KAAK,GAAG,QAAQ,EAChB,KAAK,OAAO,OAAO,EACnB,KAAK,QAAQ,OAAO;;CAGtB,UAAkB,GAAsB;EACtC,IAAM,IAAM,SAAS,cAAc,MAAM;AAEzC,EADA,EAAI,YAAY,qBAChB,EAAI,WAAW;EAEf,IAAM,IAAQ,SAAS,cAAc,MAAM;AAE3C,EADA,EAAM,YAAY,wBAClB,EAAM,cAAc,EAAa,EAAO;EAExC,IAAM,IAAQ,SAAS,cAAc,SAAS;AAG9C,EAFA,EAAM,YAAY,uBAClB,EAAM,QAAQ,IACd,EAAM,SAAS;EAEf,IAAM,IAAQ,SAAS,cAAc,MAAM;AAC3C,IAAM,YAAY;EAClB,IAAM,IAAU,SAAS,cAAc,OAAO;AAE9C,EADA,EAAQ,YAAY,uBACpB,EAAQ,cAAc;EACtB,IAAM,IAAW,SAAS,cAAc,OAAO;AAoB/C,EAnBA,EAAS,YAAY,wBACrB,EAAS,cAAc,IACvB,EAAM,YAAY,EAAQ,EAC1B,EAAM,YAAY,EAAS,EAE3B,EAAI,YAAY,EAAM,EACtB,EAAI,YAAY,EAAM,EACtB,EAAI,YAAY,EAAM,EAEtB,EAAI,iBAAiB,eAAe,KAAK,UAAU,SAAS,EAAO,CAAC,EACpE,EAAI,iBAAiB,YAAY,MAAM;AACrC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EAClB,KAAK,UAAU,SAAS,EAAO;IAEjC,EAEF,KAAK,OAAO,YAAY,EAAI,EAC5B,KAAK,OAAO,IAAI,GAAQ;GAAE;GAAK;GAAS;GAAU,aAAa;GAAO,CAAC,EACnE,MAAW,KAAK,UAAQ,EAAI,UAAU,IAAI,uBAAuB;;CAGvE,UAAkB,GAAsB;EACtC,IAAM,IAAM,KAAK,OAAO,IAAI,EAAO;AAC9B,QACL,EAAI,IAAI,QAAQ,EAChB,KAAK,OAAO,OAAO,EAAO;;CAG5B,UAAkB,GAAsB;EACtC,IAAM,IAAM,KAAK,OAAO,IAAI,EAAO,EAC7B,IAAQ,KAAK,QAAQ,IAAI,EAAO;AAClC,SAAC,KAAO,CAAC,IAMb;OAJI,EAAM,cAAc,KAAA,MACtB,EAAI,QAAQ,cAAc,EAAY,EAAM,WAAW,KAAK,OAAO,GAGjE,EAAM,cAAc,KAAA,KAAa,EAAM,aAAa,KAAA,KAAa,EAAM,aAAa,GAAG;IACzF,IAAM,IAAO,EAAM,YAAY,EAAM,UAC/B,IAAO,IAAO,EAAM,WAAY,KAChC,IAAO,KAAQ,IAAI,MAAM,KACzB,IAAU,KAAK,IAAI,EAAI,CAAC,eAAe,KAAK,QAAQ;KAAE,uBAAuB;KAAG,uBAAuB;KAAG,CAAC;AAEjH,IADA,EAAI,SAAS,cAAc,GAAG,IAAO,EAAQ,IAC7C,EAAI,SAAS,YAAY,wBAAwB,KAAQ,IAAI,WAAW;SAExE,GAAI,SAAS,cAAc;AAG7B,GAAI,EAAM,aAAa,EAAM,UAAU,UAAU,KAC/C,EAAc,EAAI,aAAa,EAAM,WAAW,EAAM,YAAY,EAAM,UAAU,GAAG;;;;AAK3F,SAAS,EAAa,GAAwB;AAG5C,MAAK,IAAM,KAAS;EAAC;EAAQ;EAAO;EAAO;EAAO;EAAM,CACtD,KAAI,EAAO,SAAS,EAAM,UAAU,EAAO,SAAS,EAAM,CACxD,QAAO,EAAO,MAAM,GAAG,CAAC,EAAM,OAAO,GAAG,MAAM;AAGlD,QAAO;;AAGT,SAAS,EAAY,GAAW,GAAoC;AAClE,KAAI,MAAM,EAAG,QAAO;CACpB,IAAM,IAAM,KAAK,IAAI,EAAE;AAOvB,QANI,KAAO,MAAa,EAAE,eAAe,GAAQ;EAAE,uBAAuB;EAAG,uBAAuB;EAAG,CAAC,GACpG,KAAO,IAAU,EAAE,eAAe,GAAQ;EAAE,uBAAuB;EAAG,uBAAuB;EAAG,CAAC,GAIrF,OAAO,EAAE,YAAY,EAAE,CAChC,CAAQ,eAAe,GAAQ,EAAE,uBAAuB,IAAI,CAAC;;AAGtE,SAAS,EAAc,GAA2B,GAAmB,GAAmB;CACtF,IAAM,IAAM,EAAO,WAAW,KAAK;AACnC,KAAI,CAAC,EAAK;CACV,IAAM,IAAM,OAAO,oBAAoB;AACvC,CAAI,EAAO,UAAU,EAAO,cAAc,MACxC,EAAO,SAAS,EAAO,eAAe,MAAM,GAC5C,EAAO,UAAU,EAAO,gBAAgB,MAAM;CAEhD,IAAM,IAAI,EAAO,OACX,IAAI,EAAO,QAEb,IAAK,UAAU,IAAK;AACxB,MAAK,IAAM,KAAK,EAEd,CADI,IAAI,MAAI,IAAK,IACb,IAAI,MAAI,IAAK;CAEnB,IAAM,IAAO,KAAK,IAAI,IAAK,GAAI,KAAK,EAG9B,IAFO,EAAQ,EAAQ,SAAS,MACnB,IACA,YAAY;AAK/B,CAHA,EAAI,UAAU,GAAG,GAAG,GAAG,EAAE,EACzB,EAAI,YAAY,MAAM,GACtB,EAAI,cAAc,GAClB,EAAI,WAAW;CACf,IAAM,IAAO,KAAK,EAAQ,SAAS;AACnC,MAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;EACvC,IAAM,IAAI,IAAI,GACR,IAAI,KAAM,EAAQ,KAAK,KAAM,KAAS,IAAI,KAAK;AACrD,EAAI,MAAM,IAAG,EAAI,OAAO,GAAG,EAAE,GAAO,EAAI,OAAO,GAAG,EAAE;;AAEtD,GAAI,QAAQ;;;;AC5Md,IAAM,IAAgE;CACpE;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAc,OAAO;EAAe;CAC7C;EAAE,OAAO;EAAgB,OAAO;EAAiB;CACjD;EAAE,OAAO;EAAe,OAAO;EAAgB;CAC/C;EAAE,OAAO;EAAY,OAAO;EAAa;CAC1C,EAEK,IAAkB,IAAI,IAAI,EAAkB,KAAK,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAEjF,SAAS,GAAc,GAAmB;AACxC,QAAO,KAAK,MAAM,IAAI,IAAI,GAAG;;AAG/B,SAAS,GAAY,GAAmB;CACtC,IAAM,IAAM,KAAK,IAAI,EAAE;AACvB,QAAO,KAAO,OAAsB,KAAO,IAAtB,EAAE,QAAQ,EAAE,GAA6B,EAAE,YAAY,EAAE;;AAShF,IAAa,KAAb,MAA+B;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,OAAe;CACf,SAAkC,EAAE;CACpC,UAAiC,CAAC;EAAE,SAAS;EAAS,OAAO;EAAS,CAAC;CAEvE,YAAY,GAAmB,GAAiC;AAK9D,EAJA,KAAK,YAAY,GAEjB,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,oBACpB,KAAK,GAAG,SAAS;EAGjB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAC5C,IAAM,cAAc;EACpB,IAAM,IAAW,SAAS,cAAc,SAAS;AAQjD,EAPA,EAAS,YAAY,oBACrB,EAAS,OAAO,UAChB,EAAS,aAAa,cAAc,eAAe,EACnD,EAAS,YAAY,EAAW,KAAK,GAAG,EACxC,EAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACtD,EAAO,YAAY,EAAM,EACzB,EAAO,YAAY,EAAS,EAC5B,KAAK,GAAG,YAAY,EAAO;EAG3B,IAAM,IAAO,SAAS,cAAc,OAAO;AAe3C,EAdA,EAAK,YAAY,mBAEjB,KAAK,eAAe,SAAS,cAAc,SAAS,EACpD,KAAK,aAAa,YAAY,qBAC9B,KAAK,aAAa,iBAAiB,gBAAgB,KAAK,cAAc,CAAC,EAEvE,KAAK,aAAa,SAAS,cAAc,QAAQ,EACjD,KAAK,WAAW,OAAO,UACvB,KAAK,WAAW,OAAO,OACvB,KAAK,WAAW,cAAc,SAC9B,KAAK,WAAW,YAAY,oBAC5B,KAAK,WAAW,WAAW,IAE3B,KAAK,kBAAkB,SAAS,cAAc,SAAS,EACvD,KAAK,gBAAgB,YAAY;AACjC,OAAK,IAAM,KAAO,GAAmB;GACnC,IAAM,IAAI,SAAS,cAAc,SAAS;AAG1C,GAFA,EAAE,QAAQ,EAAI,OACd,EAAE,cAAc,EAAI,OACpB,KAAK,gBAAgB,YAAY,EAAE;;AAMrC,EAHA,KAAK,eAAe,SAAS,cAAc,QAAQ,EACnD,KAAK,aAAa,OAAO,QACzB,KAAK,aAAa,cAAc,mBAChC,KAAK,aAAa,YAAY;EAE9B,IAAM,IAAS,SAAS,cAAc,SAAS;AA2B/C,EA1BA,EAAO,OAAO,UACd,EAAO,YAAY,kBACnB,EAAO,YAAY,GAAG,EAAW,QAAQ,GAAG,CAAC,yBAE7C,EAAK,YAAY,KAAK,aAAa,EACnC,EAAK,YAAY,KAAK,WAAW,EACjC,EAAK,YAAY,KAAK,gBAAgB,EACtC,EAAK,YAAY,KAAK,aAAa,EACnC,EAAK,YAAY,EAAO,EACxB,EAAK,iBAAiB,WAAW,MAAM;AAErC,GADA,EAAE,gBAAgB,EAClB,KAAK,YAAY;IACjB,EACF,KAAK,GAAG,YAAY,EAAK,EAGzB,KAAK,SAAS,SAAS,cAAc,MAAM,EAC3C,KAAK,OAAO,YAAY,mBACxB,KAAK,GAAG,YAAY,KAAK,OAAO,EAEhC,KAAK,UAAU,SAAS,cAAc,MAAM,EAC5C,KAAK,QAAQ,YAAY,oBACzB,KAAK,QAAQ,cAAc,2DAC3B,KAAK,OAAO,YAAY,KAAK,QAAQ,EAErC,KAAK,eAAe,EACpB,EAAK,YAAY,KAAK,GAAG;;CAI3B,WAAW,GAA8B;AAEvC,EADA,KAAK,UAAU,EAAQ,SAAS,IAAI,IAAU,CAAC;GAAE,SAAS;GAAS,OAAO;GAAS,CAAC,EACpF,KAAK,eAAe;;CAGtB,gBAA8B;EAC5B,IAAM,IAAU,KAAK,aAAa,SAAS;AAC3C,OAAK,aAAa,iBAAiB;AACnC,OAAK,IAAM,KAAO,KAAK,SAAS;GAC9B,IAAM,IAAI,SAAS,cAAc,SAAS;AAG1C,GAFA,EAAE,QAAQ,EAAI,SACd,EAAE,cAAc,EAAI,OACpB,KAAK,aAAa,YAAY,EAAE;;AAGlC,OAAK,aAAa,QAAQ,KAAK,QAAQ,MAAM,MAAM,EAAE,YAAY,EAAQ,GAAG,IAAU;;CAGxF,SAAkB;AAChB,SAAO,KAAK;;CAGd,SAAe;AACb,OAAK,OAAO,KAAK,OAAO,GAAG,KAAK,WAAW;;CAG7C,YAAkB;AAGhB,EAFA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS,IACb,KAAK,WAAW,UAAU,MAAI,KAAK,cAAc;;CAIvD,eAA6B;EAC3B,IAAM,IAAI,KAAK,UAAU,gBAAgB,KAAK,aAAa,SAAS,QAAQ;AAC5E,OAAK,WAAW,QAAQ,MAAM,OAAkC,KAA3B,OAAO,GAAc,EAAE,CAAC;;CAG/D,QAAc;AAEZ,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAInB,UAAU,GAA+B;AAEvC,EADA,KAAK,SAAS,GACd,KAAK,YAAY;;CAGnB,UAAgB;AACd,OAAK,GAAG,QAAQ;;CAGlB,aAA2B;EACzB,IAAM,IAAQ,OAAO,KAAK,WAAW,MAAM;AAC3C,MAAI,CAAC,OAAO,SAAS,EAAM,CAAE;EAC7B,IAAM,IAAY,KAAK,gBAAgB,OACjC,IAAU,KAAK,aAAa,MAAM,MAAM,IAAI,KAAA,GAC5C,IAAU,KAAK,aAAa,SAAS,SACrC,IAAQ,KAAK,QAAQ,MAAM,MAAM,EAAE,YAAY,EAAQ,EAAE,SAAS;AAGxE,EAFA,KAAK,UAAU,MAAM,GAAO,GAAW,GAAS,GAAS,EAAM,EAC/D,KAAK,aAAa,QAAQ,IAC1B,KAAK,cAAc;;CAGrB,aAA2B;AAIzB,MAFA,KAAK,OAAO,iBAAiB,EAEzB,KAAK,OAAO,WAAW,GAAG;AAC5B,QAAK,OAAO,YAAY,KAAK,QAAQ;AACrC;;AAIF,OAAK,IAAM,KAAS,CAAC,GAAG,KAAK,OAAO,CAAC,SAAS,EAAE;GAC9C,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,KAAI,YAAY,oBAAoB,EAAM,YAAY,0BAA0B;GAEhF,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,KAAK,YAAY;GACjB,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,KAAK,YAAY;GACjB,IAAM,IAAQ,EAAgB,IAAI,EAAM,UAA4B,IAAI,EAAM,WACxE,IAAc,EAAM,WAAW,EAAM,YAAY,SACjD,IAAW,IAAc,GAAY,EAAM,MAAM,GAAG,KAAK,UAAU,YAAY,EAAM,MAAM;AAIjG,OAFA,EAAK,cAAc,GADJ,KAAe,EAAM,QAAQ,GAAG,EAAM,MAAM,KAAK,KACjC,EAAM,GAAG,KACxC,EAAK,YAAY,EAAK,EAClB,EAAM,SAAS;IACjB,IAAM,IAAO,SAAS,cAAc,MAAM;AAG1C,IAFA,EAAK,YAAY,uBACjB,EAAK,cAAc,EAAM,SACzB,EAAK,YAAY,EAAK;;AAExB,OAAI,EAAM,WAAW;IACnB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAG5C,IAFA,EAAM,YAAY,oBAClB,EAAM,cAAc,aACpB,EAAK,YAAY,EAAM;;GAGzB,IAAM,IAAM,SAAS,cAAc,SAAS;AAS5C,GARA,EAAI,OAAO,UACX,EAAI,YAAY,kBAChB,EAAI,aAAa,cAAc,eAAe,EAC9C,EAAI,YAAY,EAAW,SAAS,GAAG,EACvC,EAAI,iBAAiB,eAAe,KAAK,UAAU,SAAS,EAAM,GAAG,CAAC,EAEtE,EAAI,YAAY,EAAK,EACrB,EAAI,YAAY,EAAI,EACpB,KAAK,OAAO,YAAY,EAAI;;;GC5NrB,KAAb,MAA8B;CAC5B;CACA;CACA;CACA,YAA2C;CAC3C;CACA,OAAe;CAEf,YAAY,GAAmB,GAAgC;AAK7D,EAJA,KAAK,YAAY,GAEjB,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,kBACpB,KAAK,GAAG,SAAS;EAEjB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAC5C,IAAM,cAAc;EACpB,IAAM,IAAW,SAAS,cAAc,SAAS;AAgBjD,EAfA,EAAS,OAAO,UAChB,EAAS,YAAY,kBACrB,EAAS,aAAa,cAAc,gBAAgB,EACpD,EAAS,YAAY,EAAW,KAAK,GAAG,EACxC,EAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACtD,EAAO,YAAY,EAAM,EACzB,EAAO,YAAY,EAAS,EAC5B,KAAK,GAAG,YAAY,EAAO,EAE3B,KAAK,eAAe,KAAK,YAAY,aAAa,EAClD,KAAK,aAAa,KAAK,YAAY,WAAW,EAC1C,KAAK,UAAU,iBACjB,KAAK,YAAY,KAAK,YAAY,iBAAiB,KAAK,UAAU,gBAAgB,CAAC,GAGrF,EAAK,YAAY,KAAK,GAAG;;CAG3B,SAAkB;AAChB,SAAO,KAAK;;CAGd,SAAe;AACb,OAAK,OAAO,KAAK,OAAO,GAAG,KAAK,WAAW;;CAG7C,YAAkB;AAEhB,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAGnB,QAAc;AAEZ,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAGnB,UAAgB;AACd,OAAK,GAAG,QAAQ;;CAIlB,WACE,GACA,GACA,IAAgC,EAAE,EAC5B;AAGN,EAFA,KAAK,iBAAiB,EAAW,EACjC,KAAK,eAAe,EAAS,EAC7B,KAAK,eAAe,EAAS;;CAG/B,YAAoB,GAAe,GAAoC;EACrE,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;EACjB,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;EACjB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAG5C,MAFA,EAAM,cAAc,GACpB,EAAK,YAAY,EAAM,EACnB,GAAO;GACT,IAAM,IAAS,SAAS,cAAc,SAAS;AAO/C,GANA,EAAO,OAAO,UACd,EAAO,YAAY,gBACnB,EAAO,aAAa,cAAc,OAAO,EAAM,aAAa,GAAG,EAC/D,EAAO,QAAQ,OAAO,EAAM,aAAa,IACzC,EAAO,YAAY,EAAW,QAAQ,GAAG,EACzC,EAAO,iBAAiB,SAAS,EAAM,EACvC,EAAK,YAAY,EAAO;;EAE1B,IAAM,IAAO,SAAS,cAAc,MAAM;AAK1C,SAJA,EAAK,YAAY,iBACjB,EAAK,YAAY,EAAK,EACtB,EAAK,YAAY,EAAK,EACtB,KAAK,GAAG,YAAY,EAAK,EAClB;;CAGT,iBAAyB,GAAyC;AAEhE,MADA,KAAK,aAAa,iBAAiB,EAC/B,EAAW,WAAW,GAAG;AAC3B,QAAK,aAAa,YAAY,KAAK,SAAS,gBAAgB,CAAC;AAC7D;;AAEF,OAAK,IAAM,KAAO,GAAY;GAC5B,IAAM,IAAM,KAAK,IAAI,EAAI,KAAK;AAC9B,GAAK,EAAI,WAAS,EAAI,UAAU,IAAI,kBAAkB;GACtD,IAAM,IAAU,SAAS,cAAc,MAAM;AAmB7C,GAlBA,EAAQ,YAAY,oBAChB,KAAK,UAAU,4BACjB,EAAQ,YAAY,KAAK,WACvB,EAAI,UAAU,QAAQ,UACtB,EAAI,UAAU,SAAS,QACvB,UACM,KAAK,UAAU,2BAA2B,EAAI,YAAY,CAAC,EAAI,QAAQ,CAC9E,CAAC,EAEA,KAAK,UAAU,wBACjB,EAAQ,YAAY,KAAK,WAAW,YAAY,sBAAsB,UACpE,KAAK,UAAU,uBAAuB,EAAI,WAAW,CACtD,CAAC,EAEJ,EAAQ,YAAY,KAAK,WAAW,SAAS,oBAAoB,sBAC/D,KAAK,UAAU,kBAAkB,EAAI,WAAW,CACjD,CAAC,EACF,EAAI,YAAY,EAAQ,EACxB,KAAK,aAAa,YAAY,EAAI;;;CAItC,eAAuB,GAAqC;AAE1D,MADA,KAAK,WAAW,iBAAiB,EAC7B,EAAS,WAAW,GAAG;AACzB,QAAK,WAAW,YAAY,KAAK,SAAS,cAAc,CAAC;AACzD;;AAEF,OAAK,IAAM,KAAK,GAAU;GACxB,IAAM,IAAM,KAAK,IAAI,EAAE,MAAM;AAC7B,GAAK,EAAE,WAAS,EAAI,UAAU,IAAI,kBAAkB;GAEpD,IAAM,IAAU,SAAS,cAAc,MAAM;AAkB7C,GAjBA,EAAQ,YAAY,oBACpB,EAAQ,YAAY,KAAK,WACvB,EAAE,UAAU,QAAQ,UACpB,EAAE,UAAU,SAAS,QACrB,UACM,KAAK,UAAU,uBAAuB,EAAE,IAAI,CAAC,EAAE,QAAQ,CAC9D,CAAC,EACF,EAAQ,YAAY,KAAK,WACvB,EAAE,SAAS,SAAS,UACpB,EAAE,SAAS,WAAW,QACtB,EAAE,SAAS,gBAAgB,UACrB,KAAK,UAAU,sBAAsB,EAAE,IAAI,CAAC,EAAE,OAAO,CAC5D,CAAC,EACF,EAAQ,YAAY,KAAK,WAAW,SAAS,kBAAkB,sBAC7D,KAAK,UAAU,gBAAgB,EAAE,GAAG,CACrC,CAAC,EACF,EAAI,YAAY,EAAQ,EACxB,KAAK,WAAW,YAAY,EAAI;;;CAIpC,eAAuB,GAAqC;AACrD,WAAK,WAEV;OADA,KAAK,UAAU,iBAAiB,EAC5B,EAAS,WAAW,GAAG;AACzB,SAAK,UAAU,YAAY,KAAK,SAAS,iBAAiB,CAAC;AAC3D;;AAEF,QAAK,IAAM,KAAK,GAAU;IACxB,IAAM,IAAM,KAAK,IAAI,EAAE,MAAM,EACvB,IAAM,SAAS,cAAc,OAAO;AAS1C,IARA,EAAI,YAAY,gBAChB,EAAI,MAAM,aAAa,EAAE,OACzB,EAAI,aAAa,GAAK,EAAI,WAAW,EACjC,KAAK,UAAU,mBACjB,EAAI,YAAY,KAAK,WAAW,SAAS,qBAAqB,sBAC5D,KAAK,UAAU,kBAAkB,EAAE,GAAG,CACvC,CAAC,EAEJ,KAAK,UAAU,YAAY,EAAI;;;;CAInC,IAAY,GAA+B;EACzC,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;EAChB,IAAM,IAAO,SAAS,cAAc,OAAO;AAK3C,SAJA,EAAK,YAAY,iBACjB,EAAK,cAAc,GACnB,EAAK,QAAQ,GACb,EAAI,YAAY,EAAK,EACd;;CAGT,SAAiB,GAA8B;EAC7C,IAAM,IAAK,SAAS,cAAc,MAAM;AAGxC,SAFA,EAAG,YAAY,kBACf,EAAG,cAAc,GACV;;CAGT,WAAmB,GAAc,GAAe,GAAoB,GAAwC;EAC1G,IAAM,IAAM,SAAS,cAAc,SAAS;AAO5C,SANA,EAAI,OAAO,UACX,EAAI,YAAY,gBAAgB,IAAa,MAAM,EACnD,EAAI,aAAa,cAAc,EAAM,EACrC,EAAI,QAAQ,GACZ,EAAI,YAAY,EAAW,GAAM,GAAG,EACpC,EAAI,iBAAiB,SAAS,EAAQ,EAC/B;;GAIL,KAA8C;CAClD,WAAW;CACX,KAAK;CACL,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,WAAW;CACX,UAAU;CACV,YAAY;CACZ,QAAQ;CACR,YAAY;CACZ,uBAAuB;CACvB,iBAAiB;CACjB,yBAAyB;CACzB,cAAc;CACd,aAAa;CACb,kBAAkB;CAClB,mBAAmB;CACnB,aAAa;CACb,YAAY;CACZ,cAAc;CACd,WAAW;CACX,SAAS;CACT,UAAU;CACV,OAAO;CACP,iBAAiB;CACjB,mBAAmB;CACnB,WAAW;CACX,gBAAgB;CAChB,cAAc;CACd,cAAc;CACd,SAAS;CACT,SAAS;CACT,aAAa;CACb,YAAY;CACZ,WAAW;CACX,SAAS;CACT,MAAM;CACN,gBAAgB;CAChB,cAAc;CACd,oBAAoB;CACpB,YAAY;CACb;AAGD,SAAgB,GAAiB,GAAsB;AACrD,QAAO,GAAoB,MAAS;;;;ACxRtC,IAAM,KAAS;AAEf,SAAS,GAAU,GAAqB;AAEtC,QAAO,EACJ,QAAQ,MAAM,IAAI,CAClB,QAAQ,sBAAsB,QAAQ,CACtC,QAAQ,OAAO,MAAM,EAAE,aAAa,CAAC;;AAQ1C,IAAa,KAAb,MAAqC;CACnC;CACA;CACA;CACA;CACA;CACA,SAAiD;CACjD,QAAqD,EAAE;CAEvD,YAAY,GAAmB,GAAuC;AAWpE,EAVA,KAAK,YAAY,GAEjB,KAAK,WAAW,SAAS,cAAc,MAAM,EAC7C,KAAK,SAAS,YAAY,sBAC1B,KAAK,SAAS,SAAS,IACvB,KAAK,SAAS,iBAAiB,UAAU,MAAM;AAC7C,GAAI,EAAE,WAAW,KAAK,YAAU,KAAK,OAAO;IAC5C,EAEF,KAAK,QAAQ,SAAS,cAAc,MAAM,EAC1C,KAAK,MAAM,YAAY;EAEvB,IAAM,IAAS,SAAS,cAAc,MAAM;AAG5C,EAFA,EAAO,YAAY,oBACnB,KAAK,UAAU,SAAS,cAAc,KAAK,EAC3C,KAAK,QAAQ,cAAc;EAC3B,IAAM,IAAW,SAAS,cAAc,SAAS;AASjD,EARA,EAAS,YAAY,mBACrB,EAAS,aAAa,cAAc,QAAQ,EAC5C,EAAS,YAAY,EAAW,KAAK,GAAG,EACxC,EAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACtD,EAAO,YAAY,KAAK,QAAQ,EAChC,EAAO,YAAY,EAAS,EAE5B,KAAK,SAAS,SAAS,cAAc,MAAM,EAC3C,KAAK,OAAO,YAAY;EAExB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAW,SAAS,cAAc,SAAS;AAGjD,EAFA,EAAS,YAAY,kBACrB,EAAS,cAAc,qBACvB,EAAS,iBAAiB,eAAe,KAAK,eAAe,CAAC;EAC9D,IAAM,IAAU,SAAS,cAAc,SAAS;AAWhD,EAVA,EAAQ,YAAY,gBACpB,EAAQ,cAAc,QACtB,EAAQ,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACrD,EAAO,YAAY,EAAS,EAC5B,EAAO,YAAY,EAAQ,EAE3B,KAAK,MAAM,YAAY,EAAO,EAC9B,KAAK,MAAM,YAAY,KAAK,OAAO,EACnC,KAAK,MAAM,YAAY,EAAO,EAC9B,KAAK,SAAS,YAAY,KAAK,MAAM,EACrC,EAAK,YAAY,KAAK,SAAS;;CAGjC,KAAK,GAAuC;AAK1C,EAJA,KAAK,SAAS,GACd,KAAK,QAAQ,cAAc,GAAG,EAAO,KAAK,YAC1C,KAAK,QAAQ,EAAE,EACf,KAAK,cAAc,EACnB,KAAK,SAAS,SAAS;;CAGzB,QAAc;AAGZ,EAFA,KAAK,SAAS,SAAS,IACvB,KAAK,SAAS,MACd,KAAK,UAAU,SAAS;;CAG1B,SAAkB;AAChB,SAAO,CAAC,KAAK,SAAS;;CAGxB,UAAgB;AACd,OAAK,SAAS,QAAQ;;CAGxB,aAAqB,GAAkC;AACrD,MAAI,KAAO,KAAK,MAAO,QAAO,KAAK,MAAM;EACzC,IAAM,IAAM,KAAK,QAAQ,OAAO,IAC1B,IAAM,KAAK,QAAQ,SAAS;AAElC,SADY,KAAO;;CAIrB,SAAiB,GAAa,GAAkC;AACzD,OAAK,WACV,KAAK,MAAM,KAAO,GAClB,KAAK,UAAU,QAAQ,KAAK,OAAO,YAAY,EAAE,GAAG,KAAK,OAAO,CAAC;;CAGnE,gBAA8B;AAC5B,MAAI,CAAC,KAAK,OAAQ;EAClB,IAAM,IAA6C,EAAE;AACrD,OAAK,IAAM,CAAC,GAAK,MAAQ,OAAO,QAAQ,KAAK,OAAO,SAAS,CAC3D,GAAM,KAAO;AAIf,EAFA,KAAK,QAAQ,GACb,KAAK,UAAU,QAAQ,KAAK,OAAO,YAAY,EAAE,GAAG,GAAO,CAAC,EAC5D,KAAK,cAAc;;CAGrB,eAA6B;AAE3B,MADA,KAAK,OAAO,iBAAiB,EACzB,CAAC,KAAK,OAAQ;EAElB,IAAM,IAAU,SAAS,cAAc,MAAM;AAC7C,IAAQ,YAAY;EAEpB,IAAM,IAAO,OAAO,KAAK,KAAK,OAAO,SAAS;AAC9C,MAAI,EAAK,WAAW,GAAG;GACrB,IAAM,IAAQ,SAAS,cAAc,MAAM;AAG3C,GAFA,EAAM,YAAY,sBAClB,EAAM,cAAc,gDACpB,EAAQ,YAAY,EAAM;;AAG5B,OAAK,IAAM,KAAO,EAChB,GAAQ,YAAY,KAAK,SAAS,EAAI,CAAC;AAEzC,OAAK,OAAO,YAAY,EAAQ;;CAGlC,SAAiB,GAA6B;EAC5C,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;EAChB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAG5C,EAFA,EAAM,YAAY,sBAClB,EAAM,cAAc,GAAU,EAAI,EAClC,EAAI,YAAY,EAAM;EAEtB,IAAM,IAAQ,KAAK,aAAa,EAAI,EAC9B,IAAU,QAAQ,KAAK,QAAQ,SAAS,MAAQ;AAWtD,SATI,MAAY,YACd,EAAI,YAAY,KAAK,cAAc,GAAK,EAAQ,EAAO,CAAC,GAC/C,MAAY,WACrB,EAAI,YAAY,KAAK,cAAc,GAAK,OAAO,EAAM,CAAC,CAAC,GAC9C,OAAO,KAAU,YAAY,GAAO,KAAK,EAAM,GACxD,EAAI,YAAY,KAAK,aAAa,GAAK,EAAM,CAAC,GAE9C,EAAI,YAAY,KAAK,YAAY,GAAK,OAAO,KAAS,GAAG,CAAC,CAAC,EAEtD;;CAGT,cAAsB,GAAa,GAAmC;EACpE,IAAM,IAAS,SAAS,cAAc,SAAS;AAQ/C,SAPA,EAAO,YAAY,aAAa,IAAQ,YAAY,MACpD,EAAO,OAAO,UACd,EAAO,iBAAiB,eAAe;GACrC,IAAM,IAAO,CAAC,EAAO,UAAU,SAAS,SAAS;AAEjD,GADA,EAAO,UAAU,OAAO,UAAU,EAAK,EACvC,KAAK,SAAS,GAAK,EAAK;IACxB,EACK;;CAGT,cAAsB,GAAa,GAAiC;EAClE,IAAM,IAAQ,SAAS,cAAc,QAAQ;AAU7C,SATA,EAAM,OAAO,UACb,EAAM,YAAY,kBAClB,EAAM,QAAQ,OAAO,EAAM,EAE3B,EAAM,OAAO,OAAO,UAAU,EAAM,GAAG,MAAM,OAC7C,EAAM,iBAAiB,gBAAgB;GACrC,IAAM,IAAI,OAAO,EAAM,MAAM;AAC7B,GAAI,OAAO,SAAS,EAAE,IAAE,KAAK,SAAS,GAAK,EAAE;IAC7C,EACK;;CAGT,aAAqB,GAAa,GAAiC;EACjE,IAAM,IAAQ,SAAS,cAAc,QAAQ;AAK7C,SAJA,EAAM,OAAO,SACb,EAAM,YAAY,kBAClB,EAAM,QAAQ,EAAM,WAAW,IAAI,GAAU,EAAM,GAAG,GACtD,EAAM,iBAAiB,eAAe,KAAK,SAAS,GAAK,EAAM,MAAM,CAAC,EAC/D;;CAGT,YAAoB,GAAa,GAAiC;EAChE,IAAM,IAAQ,SAAS,cAAc,QAAQ;AAK7C,SAJA,EAAM,OAAO,QACb,EAAM,YAAY,kBAClB,EAAM,QAAQ,GACd,EAAM,iBAAiB,gBAAgB,KAAK,SAAS,GAAK,EAAM,MAAM,CAAC,EAChE;;;AAIX,SAAS,GAAU,GAAuB;CAExC,IAAM,IAAI,EAAM,IAAI,IAAI,EAAM,IAAI,IAAI,EAAM;AAC5C,QAAO,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;;;;ACxNjC,SAAS,KAAyC;AAChD,KAAI;AACF,SAAO,OAAO,eAAiB,MAAc,eAAe;SACtD;AACN,SAAO;;;AAIX,IAAM,KAAqC;CACzC;CAAS;CAAa;CAAa;CAAa;CAAe;CAChE;AAGD,SAAS,EAAc,GAAqC;AAC1D,KAAI,CAAC,KAAO,OAAO,KAAQ,SAAU,QAAO,EAAE;CAC9C,IAAM,IAA6B,EAAE,EAC/B,IAAM;AACZ,MAAK,IAAM,KAAO,GAChB,CAAI,EAAI,OAAS,KAAA,MAAY,EAAgC,KAAO,EAAI;AAE1E,QAAO;;AAOT,IAAa,KAAb,MAAkC;CAChC,YAA4C,EAAE;CAE9C,YACE,IAAqB,sBACrB,IAA0C,IAAgB,EAC1D;AACA,EAHQ,KAAA,aAAA,GACA,KAAA,UAAA,GAER,KAAK,MAAM;;CAGb,OAA+B;AAC7B,SAAO,KAAK,UAAU,KAAK,OAAO;GAAE,MAAM,EAAE;GAAM,OAAO,EAAE,GAAG,EAAE,OAAO;GAAE,EAAE;;CAG7E,IAAI,GAA2C;EAC7C,IAAM,IAAI,KAAK,UAAU,MAAM,MAAM,EAAE,SAAS,EAAK;AACrD,SAAO,IAAI;GAAE,MAAM,EAAE;GAAM,OAAO,EAAE,GAAG,EAAE,OAAO;GAAE,GAAG;;CAIvD,KAAK,GAAc,GAAoC;EACrD,IAAM,IAAU,EAAK,MAAM;AAC3B,MAAI,CAAC,EAAS;EACd,IAAM,IAAQ,EAAc,EAAM;AAGlC,EAFA,KAAK,YAAY,KAAK,UAAU,QAAQ,MAAM,EAAE,SAAS,EAAQ,EACjE,KAAK,UAAU,KAAK;GAAE,MAAM;GAAS,OAAO;GAAO,CAAC,EACpD,KAAK,SAAS;;CAGhB,OAAO,GAAoB;EACzB,IAAM,IAAO,KAAK,UAAU,QAAQ,MAAM,EAAE,SAAS,EAAK;AACtD,IAAK,WAAW,KAAK,UAAU,WACnC,KAAK,YAAY,GACjB,KAAK,SAAS;;CAGhB,QAAc;AAEZ,EADA,KAAK,YAAY,EAAE,EACnB,KAAK,SAAS;;CAGhB,OAAqB;AACd,WAAK,QACV,KAAI;GACF,IAAM,IAAM,KAAK,QAAQ,QAAQ,KAAK,WAAW;AACjD,OAAI,CAAC,EAAK;GACV,IAAM,IAAS,KAAK,MAAM,EAAI;AAC9B,OAAI,CAAC,MAAM,QAAQ,EAAO,CAAE;AAC5B,QAAK,YAAY,EACd,QAAQ,MAAM,KAAK,OAAO,EAAE,QAAS,SAAS,CAC9C,KAAK,OAAO;IAAE,MAAM,EAAE;IAAM,OAAO,EAAc,EAAE,MAAM;IAAE,EAAE;UAC1D;;CAKV,UAAwB;AACjB,WAAK,QACV,KAAI;AACF,QAAK,QAAQ,QAAQ,KAAK,YAAY,KAAK,UAAU,KAAK,UAAU,CAAC;UAC/D;;GCzFN,KAAW;CAAC;CAAW;CAAW;CAAW;CAAW;CAAW;CAAW;CAAW;CAAU,EACnG,KAAS;CAAC;CAAG;CAAG;CAAG;CAAE,EACrB,KAA2C;CAAC;CAAS;CAAU;CAAS,EAOjE,KAAb,MAAgC;CAC9B;CACA;CACA;CACA;CACA;CACA,OAAe;CAEf,YAAY,GAAmB,GAAkC,GAA6B;AAM5F,EALA,KAAK,YAAY,GACjB,KAAK,QAAQ,GAEb,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,mBACpB,KAAK,GAAG,SAAS;EAEjB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAC5C,IAAM,cAAc;EACpB,IAAM,IAAW,SAAS,cAAc,SAAS;AAYjD,EAXA,EAAS,OAAO,UAChB,EAAS,YAAY,mBACrB,EAAS,aAAa,cAAc,QAAQ,EAC5C,EAAS,YAAY,EAAW,KAAK,GAAG,EACxC,EAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACtD,EAAO,YAAY,EAAM,EACzB,EAAO,YAAY,EAAS,EAC5B,KAAK,GAAG,YAAY,EAAO,EAE3B,KAAK,GAAG,YAAY,KAAK,UAAU,CAAC,EACpC,KAAK,GAAG,YAAY,KAAK,UAAU,CAAC,EACpC,KAAK,GAAG,YAAY,KAAK,cAAc,CAAC;EAGxC,IAAM,IAAW,SAAS,cAAc,MAAM;AAG9C,EAFA,EAAS,YAAY,qBACrB,EAAS,cAAc,aACvB,KAAK,GAAG,YAAY,EAAS;EAE7B,IAAM,IAAU,SAAS,cAAc,MAAM;AAK7C,EAJA,EAAQ,YAAY,kBACpB,KAAK,YAAY,SAAS,cAAc,QAAQ,EAChD,KAAK,UAAU,OAAO,QACtB,KAAK,UAAU,cAAc,iBAC7B,KAAK,UAAU,YAAY;EAC3B,IAAM,IAAU,SAAS,cAAc,SAAS;AAchD,EAbA,EAAQ,OAAO,UACf,EAAQ,YAAY,qBACpB,EAAQ,YAAY,GAAG,EAAW,QAAQ,GAAG,CAAC,oBAC9C,EAAQ,iBAAiB,eAAe,KAAK,cAAc,CAAC,EAC5D,EAAQ,YAAY,KAAK,UAAU,EACnC,EAAQ,YAAY,EAAQ,EAC5B,KAAK,GAAG,YAAY,EAAQ,EAE5B,KAAK,cAAc,SAAS,cAAc,MAAM,EAChD,KAAK,YAAY,YAAY,uBAC7B,KAAK,GAAG,YAAY,KAAK,YAAY,EAErC,EAAK,YAAY,KAAK,GAAG,EACzB,KAAK,iBAAiB;;CAGxB,SAAkB;AAChB,SAAO,KAAK;;CAGd,SAAe;AACb,OAAK,OAAO,KAAK,OAAO,GAAG,KAAK,WAAW;;CAG7C,YAAkB;AAIhB,EAHA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS,IACjB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB;;CAGxB,QAAc;AAEZ,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAGnB,UAAgB;AACd,OAAK,GAAG,QAAQ;;CAGlB,WAAmC;EACjC,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;AAChB,OAAK,IAAM,KAAK,IAAU;GACxB,IAAM,IAAK,SAAS,cAAc,SAAS;AAO3C,GANA,EAAG,OAAO,UACV,EAAG,YAAY,oBACf,EAAG,MAAM,aAAa,GACtB,EAAG,QAAQ,QAAQ,GACnB,EAAG,aAAa,cAAc,EAAE,EAChC,EAAG,iBAAiB,eAAe,KAAK,WAAW,EAAE,OAAO,GAAG,CAAC,CAAC,EACjE,EAAI,YAAY,EAAG;;EAErB,IAAM,IAAS,SAAS,cAAc,QAAQ;AAK9C,SAJA,EAAO,OAAO,SACd,EAAO,YAAY,oBACnB,EAAO,iBAAiB,eAAe,KAAK,WAAW,EAAE,OAAO,EAAO,OAAO,CAAC,CAAC,EAChF,EAAI,YAAY,EAAO,EAChB;;CAGT,WAAmC;EACjC,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;AAChB,OAAK,IAAM,KAAK,IAAQ;GACtB,IAAM,IAAM,SAAS,cAAc,SAAS;AAG5C,GAFA,EAAI,OAAO,UACX,EAAI,YAAY,mBAChB,EAAI,QAAQ,QAAQ,OAAO,EAAE;GAC7B,IAAM,IAAM,SAAS,cAAc,OAAO;AAI1C,GAHA,EAAI,MAAM,SAAS,GAAG,EAAE,KACxB,EAAI,YAAY,EAAI,EACpB,EAAI,iBAAiB,eAAe,KAAK,WAAW,EAAE,WAAW,GAAG,CAAC,CAAC,EACtE,EAAI,YAAY,EAAI;;AAEtB,SAAO;;CAGT,eAAuC;EACrC,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;AAChB,OAAK,IAAM,KAAM,IAAa;GAC5B,IAAM,IAAM,SAAS,cAAc,SAAS;AAO5C,GANA,EAAI,OAAO,UACX,EAAI,YAAY,kBAChB,EAAI,QAAQ,YAAY,GACxB,EAAI,cAAc,MAAO,UAAU,OAAO,MAAO,WAAW,OAAO,MACnE,EAAI,QAAQ,GACZ,EAAI,iBAAiB,eAAe,KAAK,WAAW,EAAE,WAAW,GAAI,CAAC,CAAC,EACvE,EAAI,YAAY,EAAI;;AAEtB,SAAO;;CAGT,WAAmB,GAAoC;AAErD,EADA,KAAK,UAAU,cAAc,EAAM,EACnC,KAAK,oBAAoB;;CAI3B,qBAAmC;EACjC,IAAM,IAAQ,KAAK,UAAU,UAAU;AAOvC,EANA,KAAK,GAAG,iBAA8B,oBAAoB,CAAC,SAAS,MAAO;AACzE,KAAG,UAAU,OAAO,UAAU,EAAG,QAAQ,OAAO,aAAa,KAAK,EAAM,OAAO,aAAa,CAAC;IAC7F,EACF,KAAK,GAAG,iBAA8B,mBAAmB,CAAC,SAAS,MAAM;AACvE,KAAE,UAAU,OAAO,UAAU,OAAO,EAAE,QAAQ,MAAM,KAAK,EAAM,UAAU;IACzE,EACF,KAAK,GAAG,iBAA8B,kBAAkB,CAAC,SAAS,MAAM;AACtE,KAAE,UAAU,OAAO,UAAU,EAAE,QAAQ,cAAc,EAAM,UAAU;IACrE;;CAGJ,eAA6B;EAC3B,IAAM,IAAO,KAAK,UAAU,MAAM,MAAM;AACnC,QACL,KAAK,MAAM,KAAK,GAAM,KAAK,UAAU,UAAU,CAAC,EAChD,KAAK,UAAU,QAAQ,IACvB,KAAK,iBAAiB;;CAGxB,kBAAgC;AAC9B,OAAK,YAAY,iBAAiB;EAClC,IAAM,IAAY,KAAK,MAAM,MAAM;AACnC,MAAI,EAAU,WAAW,GAAG;GAC1B,IAAM,IAAQ,SAAS,cAAc,MAAM;AAG3C,GAFA,EAAM,YAAY,mBAClB,EAAM,cAAc,sBACpB,KAAK,YAAY,YAAY,EAAM;AACnC;;AAEF,OAAK,IAAM,KAAK,GAAW;GACzB,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,KAAI,YAAY;GAEhB,IAAM,IAAQ,SAAS,cAAc,SAAS;AAE9C,GADA,EAAM,OAAO,UACb,EAAM,YAAY;GAClB,IAAM,IAAM,SAAS,cAAc,OAAO;AAE1C,GADA,EAAI,YAAY,kBAChB,EAAI,MAAM,aAAc,EAAE,MAAM,SAAoB;GACpD,IAAM,IAAQ,SAAS,cAAc,OAAO;AAI5C,GAHA,EAAM,cAAc,EAAE,MACtB,EAAM,YAAY,EAAI,EACtB,EAAM,YAAY,EAAM,EACxB,EAAM,iBAAiB,eAAe;AAEpC,IADA,KAAK,UAAU,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,EAC5C,KAAK,oBAAoB;KACzB;GAEF,IAAM,IAAM,SAAS,cAAc,SAAS;AAY5C,GAXA,EAAI,OAAO,UACX,EAAI,YAAY,kBAChB,EAAI,aAAa,cAAc,kBAAkB,EACjD,EAAI,YAAY,EAAW,SAAS,GAAG,EACvC,EAAI,iBAAiB,eAAe;AAElC,IADA,KAAK,MAAM,OAAO,EAAE,KAAK,EACzB,KAAK,iBAAiB;KACtB,EAEF,EAAI,YAAY,EAAM,EACtB,EAAI,YAAY,EAAI,EACpB,KAAK,YAAY,YAAY,EAAI;;;;;;ACnOvC,SAAS,KAAyC;AAChD,KAAI;AACF,SAAO,OAAO,eAAiB,MAAc,eAAe;SACtD;AACN,SAAO;;;AAQX,IAAa,KAAb,MAAmC;CACjC,YAA8B,EAAE;CAEhC,YACE,IAAqB,sBACrB,IAA0C,IAAgB,EAC1D;AACA,EAHQ,KAAA,aAAA,GACA,KAAA,UAAA,GAER,KAAK,MAAM;;CAGb,OAAiB;AACf,SAAO,CAAC,GAAG,KAAK,UAAU;;CAG5B,IAAI,GAAuB;AACzB,SAAO,KAAK,UAAU,SAAS,EAAK;;CAGtC,IAAI,GAAoB;AAClB,GAAC,KAAQ,KAAK,UAAU,SAAS,EAAK,KAC1C,KAAK,YAAY,CAAC,GAAG,KAAK,WAAW,EAAK,EAC1C,KAAK,SAAS;;CAGhB,OAAO,GAAoB;AACpB,OAAK,UAAU,SAAS,EAAK,KAClC,KAAK,YAAY,KAAK,UAAU,QAAQ,MAAM,MAAM,EAAK,EACzD,KAAK,SAAS;;CAIhB,OAAO,GAAuB;AAM5B,SALI,KAAK,IAAI,EAAK,IAChB,KAAK,OAAO,EAAK,EACV,OAET,KAAK,IAAI,EAAK,EACP;;CAIT,aAAa,GAAuB;AAC9B,OAAK,UAAU,SAAS,MAC5B,KAAK,YAAY,CAAC,GAAG,IAAI,IAAI,EAAM,OAAO,QAAQ,CAAC,CAAC,EACpD,KAAK,SAAS;;CAGhB,OAAqB;AACd,WAAK,QACV,KAAI;GACF,IAAM,IAAM,KAAK,QAAQ,QAAQ,KAAK,WAAW;AACjD,OAAI,CAAC,EAAK;GACV,IAAM,IAAS,KAAK,MAAM,EAAI;AAC9B,GAAI,MAAM,QAAQ,EAAO,KACvB,KAAK,YAAY,CAAC,GAAG,IAAI,IAAI,EAAO,QAAQ,MAAM,OAAO,KAAM,SAAS,CAAC,CAAC;UAEtE;;CAKV,UAAwB;AACjB,WAAK,QACV,KAAI;AACF,QAAK,QAAQ,QAAQ,KAAK,YAAY,KAAK,UAAU,KAAK,UAAU,CAAC;UAC/D;;GCnEC,KAAb,MAA8B;CAC5B;CACA;CACA;CACA,UAAkB;CAElB,YAAY,GAAmB,GAAgC;AAS7D,EARA,KAAK,YAAY,GAEjB,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,mBACpB,KAAK,GAAG,SAAS,IAEjB,KAAK,UAAU,SAAS,cAAc,OAAO,EAC7C,KAAK,QAAQ,YAAY,qBACzB,KAAK,GAAG,YAAY,KAAK,QAAQ;EAEjC,IAAM,IAAO,SAAS,cAAc,OAAO;AAG3C,EAFA,EAAK,YAAY,oBACjB,EAAK,cAAc,wBACnB,KAAK,GAAG,YAAY,EAAK;EAEzB,IAAM,IAAS,SAAS,cAAc,SAAS;AAI/C,EAHA,EAAO,OAAO,UACd,EAAO,YAAY,sBACnB,EAAO,YAAY,GAAG,EAAW,KAAK,GAAG,CAAC,sBAC1C,EAAO,iBAAiB,eAAe,KAAK,UAAU,UAAU,CAAC;EAEjE,IAAM,IAAU,SAAS,cAAc,SAAS;AAQhD,EAPA,EAAQ,OAAO,UACf,EAAQ,YAAY,uBACpB,EAAQ,YAAY,GAAG,EAAW,SAAS,GAAG,CAAC,qBAC/C,EAAQ,iBAAiB,eAAe,KAAK,UAAU,WAAW,CAAC,EAEnE,KAAK,GAAG,YAAY,EAAO,EAC3B,KAAK,GAAG,YAAY,EAAQ,EAC5B,EAAK,YAAY,KAAK,GAAG;;CAG3B,KAAK,GAA4B;AAI/B,EAHA,KAAK,UAAU,IACf,KAAK,QAAQ,cAAc,MAAS,QAAQ,iBAAiB,iBAC7D,KAAK,QAAQ,QAAQ,OAAO,GAC5B,KAAK,GAAG,SAAS;;CAGnB,OAAa;AAEX,EADA,KAAK,UAAU,IACf,KAAK,GAAG,SAAS;;CAGnB,YAAqB;AACnB,SAAO,KAAK;;CAGd,UAAgB;AACd,OAAK,GAAG,QAAQ;;GCjDP,KAAb,MAA2B;CACzB;CACA,WAAwC;CACxC,UAA2C;CAC3C,kBAA0B;CAE1B,YAAY,IAA8B,EAAE,EAAE;AAE5C,MADA,KAAK,UAAU,GACX,OAAO,EAAQ,SAAU,SAC3B,KAAI;AAEF,GADA,KAAK,UAAU,IAAI,MAAM,EAAQ,MAAM,EACvC,KAAK,QAAQ,UAAU;UACjB;AACN,QAAK,UAAU;;AAInB,EAAI,EAAQ,WAAS,KAAK,kBAAkB;;CAG9C,WAAW,GAAmC;AAC5C,OAAK,UAAU;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS;;CAIhD,OAAO,GAAuB;AAE5B,EADI,KAAK,QAAQ,SAAO,KAAK,WAAW,EACpC,KAAK,QAAQ,WAAS,KAAK,YAAY,EAAQ;;CAGrD,YAA0B;AACxB,MAAI,KAAK,SAAS;AAEX,GADL,KAAK,QAAQ,cAAc,GACtB,KAAK,QAAQ,MAAM,CAAC,YAAY,GAAG;AACxC;;AAEF,OAAK,MAAM;;CAIb,OAAqB;AACnB,MAAI;GACF,IAAM,IAAM,OAAO,gBAAiB,OAAmE;AACvG,OAAI,CAAC,EAAK;AACV,GAAoB,KAAK,aAAW,IAAI,GAAK;GAC7C,IAAM,IAAM,KAAK,UACX,IAAM,EAAI,aACV,IAAO,EAAI,YAAY;AAI7B,GAHA,EAAK,KAAK,eAAe,MAAQ,EAAI,EACrC,EAAK,KAAK,6BAA6B,IAAK,IAAM,IAAK,EACvD,EAAK,KAAK,6BAA6B,MAAQ,IAAM,IAAK,EAC1D,EAAK,QAAQ,EAAI,YAAY;GAC7B,IAAM,IAAM,EAAI,kBAAkB;AAMlC,GALA,EAAI,OAAO,QACX,EAAI,UAAU,eAAe,KAAK,EAAI,EACtC,EAAI,UAAU,eAAe,MAAM,IAAM,IAAK,EAC9C,EAAI,QAAQ,EAAK,EACjB,EAAI,MAAM,EAAI,EACd,EAAI,KAAK,IAAM,IAAK;UACd;;CAKV,mBAAiC;AAC3B,OAAK,oBACT,KAAK,kBAAkB,IACnB,SAAO,eAAiB,QACxB,aAAa,eAAe,aACzB,aAAa,mBAAmB,CAAC,YAAY,GAAG;;CAIzD,YAAoB,GAAuB;AACrC,eAAO,eAAiB,MAC5B;OAAI,aAAa,eAAe,WAAW;AACzC,SAAK,kBAAkB;AACvB;;AAEF,OAAI;AACF,QAAI,aAAa,KAAK,QAAQ,SAAS,eAAe,EAAE,MAAM,GAAS,CAAC;WAClE;;;CAKV,UAAgB;AACd,MAAI;AACG,QAAK,UAAU,OAAO;UACrB;AAIR,EADA,KAAK,WAAW,MAChB,KAAK,UAAU;;;;;AC1FnB,SAAgB,GAAgB,GAAiB,IAAY,IAAiB;CAC5E,IAAM,IAAO,CAAC,GAAG,EAAK,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,EAAU,EAC3E,IAAO,CAAC,GAAG,EAAK,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,EAAU,EAE3E,IAAU,EAAK,SAAS,IAAI,EAAK,GAAG,QAAQ,MAC5C,IAAU,EAAK,SAAS,IAAI,EAAK,GAAG,QAAQ,MAC5C,IAAM,MAAY,QAAQ,MAAY,QAAQ,IAAU,KAAW,IAAI,MAEvE,oBAAU,IAAI,KAAwB,EACtC,KAAS,MAA6B;EAC1C,IAAI,IAAM,EAAQ,IAAI,EAAM;AAK5B,SAJK,MACH,IAAM;GAAE;GAAO,WAAW;GAAG,WAAW;GAAG,EAC3C,EAAQ,IAAI,GAAO,EAAI,GAElB;;AAET,MAAK,IAAM,KAAK,EAAM,GAAM,EAAE,MAAM,CAAC,aAAa,EAAE;AACpD,MAAK,IAAM,KAAK,EAAM,GAAM,EAAE,MAAM,CAAC,aAAa,EAAE;CAEpD,IAAM,IAAO,CAAC,GAAG,EAAQ,QAAQ,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,EAChE,IAAY;AAChB,MAAK,IAAM,KAAK,EAAM,KAAY,KAAK,IAAI,GAAW,EAAE,WAAW,EAAE,UAAU;AAE/E,QAAO;EAAE;EAAM;EAAW;EAAK;;;;AC9BjC,IAAa,KAAb,MAA+B;CAC7B;CACA;CACA;CACA,OAAe;CACf;CAEA,YAAY,GAAmB,GAAiC,IAAS,IAAI;AAM3E,EALA,KAAK,YAAY,GACjB,KAAK,SAAS,GAEd,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,cACpB,KAAK,GAAG,SAAS;EAEjB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAC5C,IAAM,cAAc;EACpB,IAAM,IAAW,SAAS,cAAc,SAAS;AAQjD,EAPA,EAAS,OAAO,UAChB,EAAS,YAAY,oBACrB,EAAS,aAAa,cAAc,QAAQ,EAC5C,EAAS,YAAY,EAAW,KAAK,GAAG,EACxC,EAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACtD,EAAO,YAAY,EAAM,EACzB,EAAO,YAAY,EAAS,EAC5B,KAAK,GAAG,YAAY,EAAO;EAE3B,IAAM,IAAO,SAAS,cAAc,MAAM;AAS1C,EARA,EAAK,YAAY,mBACjB,EAAK,YAAY,sDACjB,KAAK,GAAG,YAAY,EAAK,EAEzB,KAAK,SAAS,SAAS,cAAc,MAAM,EAC3C,KAAK,OAAO,YAAY,mBACxB,KAAK,GAAG,YAAY,KAAK,OAAO,EAEhC,EAAK,YAAY,KAAK,GAAG;;CAG3B,SAAkB;AAChB,SAAO,KAAK;;CAGd,SAAe;AACb,OAAK,OAAO,KAAK,OAAO,GAAG,KAAK,WAAW;;CAG7C,YAAkB;AAEhB,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAGnB,QAAc;AAEZ,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAGnB,QAAQ,GAA+B;AACrC,MAAI,CAAC,GAAO;AACV,QAAK,aAAa;AAClB;;AAEF,OAAK,OAAO,GAAgB,GAAO,KAAK,OAAO,CAAC;;CAGlD,UAAgB;AACd,OAAK,GAAG,QAAQ;;CAGlB,cAA4B;AAC1B,OAAK,OAAO,iBAAiB;EAC7B,IAAM,IAAQ,SAAS,cAAc,MAAM;AAG3C,EAFA,EAAM,YAAY,oBAClB,EAAM,cAAc,sBACpB,KAAK,OAAO,YAAY,EAAM;;CAGhC,OAAe,GAA0B;AAEvC,MADA,KAAK,OAAO,iBAAiB,EACzB,EAAM,KAAK,WAAW,GAAG;AAC3B,QAAK,aAAa;AAClB;;EAEF,IAAM,IAAM,EAAM,YAAY,IAAI,IAAI,EAAM,YAAY;AAExD,OAAK,IAAM,KAAO,EAAM,MAAM;GAC5B,IAAM,IAAQ,EAAI,YAAY,GACxB,IAAK,SAAS,cAAc,MAAM;AACxC,KAAG,YAAY;GAGf,IAAM,IAAM,SAAS,cAAc,SAAS;AAG5C,GAFA,EAAI,OAAO,UACX,EAAI,YAAY,kCACZ,EAAI,YAAY,KAClB,EAAI,cAAc,EAAW,EAAI,UAAU,EAC3C,EAAI,MAAM,YAAY,OAAO,IAAI,EAAI,YAAY,IAAM,KAAK,QAAQ,EAAE,CAAC,GAAG,EAC1E,EAAI,QAAQ,UAAU,KAAK,UAAU,YAAY,EAAI,MAAM,IAC3D,EAAI,iBAAiB,eAAe,KAAK,UAAU,QAAQ,QAAQ,EAAI,MAAM,CAAC,IAE9E,EAAI,WAAW;GAGjB,IAAM,IAAQ,SAAS,cAAc,MAAM;AAE3C,GADA,EAAM,YAAY,oBAAoB,IAAQ,YAAY,aAC1D,EAAM,cAAc,KAAK,UAAU,YAAY,EAAI,MAAM;GAGzD,IAAM,IAAM,SAAS,cAAc,SAAS;AAe5C,GAdA,EAAI,OAAO,UACX,EAAI,YAAY,kCACZ,EAAI,YAAY,KAClB,EAAI,cAAc,EAAW,EAAI,UAAU,EAC3C,EAAI,MAAM,YAAY,OAAO,IAAI,EAAI,YAAY,IAAM,KAAK,QAAQ,EAAE,CAAC,GAAG,EAC1E,EAAI,QAAQ,SAAS,KAAK,UAAU,YAAY,EAAI,MAAM,IAC1D,EAAI,iBAAiB,eAAe,KAAK,UAAU,QAAQ,OAAO,EAAI,MAAM,CAAC,IAE7E,EAAI,WAAW,IAGjB,EAAG,YAAY,EAAI,EACnB,EAAG,YAAY,EAAM,EACrB,EAAG,YAAY,EAAI,EACnB,KAAK,OAAO,YAAY,EAAG;;;;AAKjC,SAAS,EAAW,GAAmB;AAGrC,QAFI,KAAK,OAAc,IAAI,KAAM,QAAQ,EAAE,GAAG,MAC1C,KAAK,IAAU,EAAE,QAAQ,EAAE,CAAC,QAAQ,SAAS,GAAG,GAC7C,EAAE,YAAY,EAAE;;;;AC/HzB,IAAa,KAAb,MAA8B;CAC5B;CACA;CACA;CACA,OAAe;CAEf,YAAY,GAAmB,GAAgC;AAK7D,EAJA,KAAK,YAAY,GAEjB,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,eACpB,KAAK,GAAG,SAAS;EAEjB,IAAM,IAAS,SAAS,cAAc,MAAM;AAC5C,IAAO,YAAY;EACnB,IAAM,IAAQ,SAAS,cAAc,OAAO;AAC5C,IAAM,cAAc;EACpB,IAAM,IAAW,SAAS,cAAc,SAAS;AAcjD,EAbA,EAAS,OAAO,UAChB,EAAS,YAAY,qBACrB,EAAS,aAAa,cAAc,QAAQ,EAC5C,EAAS,YAAY,EAAW,KAAK,GAAG,EACxC,EAAS,iBAAiB,eAAe,KAAK,OAAO,CAAC,EACtD,EAAO,YAAY,EAAM,EACzB,EAAO,YAAY,EAAS,EAC5B,KAAK,GAAG,YAAY,EAAO,EAE3B,KAAK,SAAS,SAAS,cAAc,MAAM,EAC3C,KAAK,OAAO,YAAY,oBACxB,KAAK,GAAG,YAAY,KAAK,OAAO,EAEhC,EAAK,YAAY,KAAK,GAAG;;CAG3B,SAAkB;AAChB,SAAO,KAAK;;CAGd,SAAe;AACb,OAAK,OAAO,KAAK,OAAO,GAAG,KAAK,WAAW;;CAG7C,YAAkB;AAEhB,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAGnB,QAAc;AAEZ,EADA,KAAK,OAAO,IACZ,KAAK,GAAG,SAAS;;CAGnB,UAAgB;AACd,OAAK,GAAG,QAAQ;;CAGlB,OAAO,GAA8B;AACnC,MAAI,CAAC,KAAK,KAAM;AAGhB,MAFA,KAAK,OAAO,iBAAiB,EAEzB,CAAC,EAAM,MAAM;GACf,IAAM,IAAQ,SAAS,cAAc,MAAM;AAG3C,GAFA,EAAM,YAAY,qBAClB,EAAM,cAAc,mBACpB,KAAK,OAAO,YAAY,EAAM;AAC9B;;EAGF,IAAM,IAAK,KAAK,UAAU,aACpB,IAAI,EAAM;AAIhB,EAHA,KAAK,OAAO,YAAY,KAAK,IAAI,QAAQ,EAAG,EAAE,KAAK,CAAC,CAAC,EACrD,KAAK,OAAO,YAAY,KAAK,IAAI,QAAQ,EAAG,EAAE,KAAK,CAAC,CAAC,EACrD,KAAK,OAAO,YAAY,KAAK,IAAI,OAAO,EAAG,EAAE,IAAI,CAAC,CAAC,EACnD,KAAK,OAAO,YAAY,KAAK,IAAI,SAAS,EAAG,EAAE,MAAM,CAAC,CAAC;EACvD,IAAM,IAAO,EAAM,SAAS,IAAI,OAAO,EAAM,SAAS,IAAI,SAAS,IAC7D,IAAO,EAAM,SAAS,IAAI,MAAM;AAEtC,EADA,KAAK,OAAO,YAAY,KAAK,IAAI,UAAU,GAAG,IAAO,EAAG,EAAM,OAAO,CAAC,IAAI,IAAO,EAAM,UAAU,QAAQ,EAAE,CAAC,KAAK,EAAK,CAAC,EACvH,KAAK,OAAO,YAAY,KAAK,IAAI,UAAU,GAAa,EAAE,OAAO,CAAC,CAAC;AAEnE,OAAK,IAAM,KAAO,EAAM,YAAY;GAClC,IAAM,IAAO,SAAS,cAAc,MAAM;AAG1C,GAFA,EAAK,YAAY,mBACjB,EAAK,cAAc,EAAI,MACvB,KAAK,OAAO,YAAY,EAAK;AAC7B,QAAK,IAAM,KAAK,EAAI,OAClB,MAAK,OAAO,YAAY,KAAK,IAAI,EAAE,KAAK,GAAa,EAAE,MAAM,CAAC,CAAC;;;CAKrE,IAAY,GAAe,GAAe,IAAO,IAAoB;EACnE,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,YAAY;EAChB,IAAM,IAAI,SAAS,cAAc,OAAO;AAExC,EADA,EAAE,YAAY,qBACd,EAAE,cAAc;EAChB,IAAM,IAAI,SAAS,cAAc,OAAO;AAKxC,SAJA,EAAE,YAAY,oBAAoB,IAAO,QAAQ,MAAS,MAC1D,EAAE,cAAc,GAChB,EAAI,YAAY,EAAE,EAClB,EAAI,YAAY,EAAE,EACX;;;AAIX,SAAS,GAAa,GAAmB;AACvC,KAAI,CAAC,OAAO,SAAS,EAAE,CAAE,QAAO;CAChC,IAAM,IAAM,KAAK,IAAI,EAAE;AAGvB,QAFI,KAAO,MAAa,EAAE,QAAQ,EAAE,GAChC,KAAO,IAAU,EAAE,QAAQ,EAAE,GAC1B,EAAE,YAAY,EAAE;;AAGzB,SAAS,GAAa,GAAmB;AAIvC,QAHI,KAAK,OAAuB,IAAI,KAAe,QAAQ,EAAE,GAAG,MAC5D,KAAK,OAAmB,IAAI,KAAW,QAAQ,EAAE,GAAG,MACpD,KAAK,OAAe,IAAI,KAAO,QAAQ,EAAE,GAAG,MACzC,EAAE,QAAQ,EAAE;;;;ACvHrB,IAAM,IAAc,WAA2C;AAE/D,SAAS,GAAa,GAAqB;AACzC,KAAI,EAAY,QAAO,EAAW,KAAK,GAAK,OAAO,CAAC,SAAS,SAAS;CACtE,IAAM,IAAQ,IAAI,aAAa,CAAC,OAAO,EAAI,EACvC,IAAM;AACV,MAAK,IAAM,KAAK,EAAO,MAAO,OAAO,aAAa,EAAE;AACpD,QAAO,KAAK,EAAI;;AAGlB,SAAS,GAAa,GAAqB;AACzC,KAAI,EAAY,QAAO,EAAW,KAAK,GAAK,SAAS,CAAC,SAAS,OAAO;CACtE,IAAM,IAAM,KAAK,EAAI,EACf,IAAQ,IAAI,WAAW,EAAI,OAAO;AACxC,MAAK,IAAI,IAAI,GAAG,IAAI,EAAI,QAAQ,IAAK,GAAM,KAAK,EAAI,WAAW,EAAE;AACjE,QAAO,IAAI,aAAa,CAAC,OAAO,EAAM;;AAGxC,SAAS,GAAY,GAAqB;AACxC,QAAO,EAAI,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;;AAGvE,SAAS,GAAc,GAAmB;CACxC,IAAM,IAAM,EAAE,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI;AAEnD,QAAO,KADK,EAAI,SAAS,KAAM,IAAI,KAAK,IAAI,OAAO,IAAK,EAAI,SAAS,EAAG;;AAK1E,SAAgB,GAAkB,GAAqC;AACrE,QAAO,GAAY,GAAa,KAAK,UAAU,EAAM,CAAC,CAAC;;AAOzD,SAAgB,GAAkB,GAA8C;AAC9E,KAAI,CAAC,EAAS,QAAO;AACrB,KAAI;EACF,IAAM,IAAO,GAAa,GAAc,EAAQ,CAAC,EAC3C,IAAM,KAAK,MAAM,EAAK;AAE5B,SADI,CAAC,KAAO,EAAI,MAAM,KAAK,OAAO,EAAI,UAAW,WAAiB,OAC3D;GACL,GAAG;GACH,QAAQ,EAAI;GACZ,WAAW,EAAI;GACf,WAAW,EAAI;GACf,WAAW,EAAI,aAAa;GAC5B,YAAY,MAAM,QAAQ,EAAI,WAAW,GAAG,EAAI,aAAa,EAAE;GAC/D,UAAU,MAAM,QAAQ,EAAI,SAAS,GAAG,EAAI,WAAW,EAAE;GAC1D;SACK;AACN,SAAO;;;AAIX,IAAM,IAAW;AAGjB,SAAgB,GAAc,GAA6B;CACzD,IAAM,IAAQ,EAAK,WAAW,IAAI,GAAG,EAAK,MAAM,EAAE,GAAG;AACrD,MAAK,IAAM,KAAQ,EAAM,MAAM,IAAI,EAAE;EACnC,IAAM,IAAK,EAAK,QAAQ,IAAI;AAC5B,MAAI,IAAK,KAAK,EAAK,MAAM,GAAG,EAAG,KAAK,EAAU,QAAO,mBAAmB,EAAK,MAAM,IAAK,EAAE,CAAC;;AAE7F,QAAO;;AAIT,SAAgB,GAAc,GAAc,GAAyB;CACnE,IAAM,CAAC,KAAe,EAAK,MAAM,IAAI;AACrC,QAAO,GAAG,EAAY,GAAG,EAAS,GAAG;;;;ACjFvC,IAAa,IAAc;CAEzB,sBAAsB;CACtB,8BAA8B;CAC9B,0BAA0B;CAC1B,yBAAyB;CACzB,uBAAuB;CACvB,kBAAkB;CAClB,uBAAuB;CACvB,wBAAwB;CACxB,uBAAuB;CACvB,mBAAmB;CACnB,uBAAuB;CACvB,sBAAsB;CACtB,oBAAoB;CACpB,uBAAuB;CAGvB,yBAAyB;CACzB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CACjB,wBAAwB;CACxB,0BAA0B;CAC1B,sBAAsB;CACtB,2BAA2B;CAC3B,wBAAwB;CACxB,qBAAqB;CACrB,sBAAsB;CACtB,6BAA6B;CAG7B,mBAAmB;CAGnB,qBAAqB;CACrB,eAAe;CACf,2BAA2B;CAC3B,kBAAkB;CAGlB,kBAAkB;CAClB,sBAAsB;CACtB,wBAAwB;CACxB,sBAAsB;CACtB,4BAA4B;CAC5B,iBAAiB;CACjB,iCAAiC;CACjC,+BAA+B;CAG/B,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,kCAAkC;CAClC,mCAAmC;CACnC,uBAAuB;CACvB,0BAA0B;CAC1B,yBAAyB;CAC1B,EAyDY,KAAuE;CAClF,IAAI;CACJ,IAAI;EAxDJ,sBAAsB;EACtB,8BAA8B;EAC9B,0BAA0B;EAC1B,yBAAyB;EACzB,uBAAuB;EACvB,kBAAkB;EAClB,uBAAuB;EACvB,wBAAwB;EACxB,uBAAuB;EACvB,mBAAmB;EACnB,uBAAuB;EACvB,sBAAsB;EACtB,oBAAoB;EACpB,uBAAuB;EAEvB,yBAAyB;EACzB,kBAAkB;EAClB,kBAAkB;EAClB,iBAAiB;EACjB,wBAAwB;EACxB,0BAA0B;EAC1B,sBAAsB;EACtB,2BAA2B;EAC3B,wBAAwB;EACxB,qBAAqB;EACrB,sBAAsB;EACtB,6BAA6B;EAE7B,mBAAmB;EAEnB,qBAAqB;EACrB,eAAe;EACf,2BAA2B;EAC3B,kBAAkB;EAElB,kBAAkB;EAClB,sBAAsB;EACtB,wBAAwB;EACxB,sBAAsB;EACtB,4BAA4B;EAC5B,iBAAiB;EACjB,iCAAiC;EACjC,+BAA+B;EAE/B,iBAAiB;EACjB,iBAAiB;EACjB,iBAAiB;EACjB,kCAAkC;EAClC,mCAAmC;EACnC,uBAAuB;EACvB,0BAA0B;EAC1B,yBAAyB;EAKrB;CACL;AAQD,SAAgB,EACd,GACA,GAC4B;CAC5B,IAAM,IAAO,EAAE,GAAG,GAAa,EACzB,IAAc,IAAS,GAAgB,KAAU,KAAA;AAGvD,QAFI,KAAa,OAAO,OAAO,GAAM,EAAY,EAC7C,KAAW,OAAO,OAAO,GAAM,EAAU,EACtC;;AAKT,SAAgB,GAAiB,GAAkD;AACjF,SAAQ,MAAoB,EAAS,MAAQ,EAAY,MAAQ;;ACjJnE,IAAM,KAAgB,IAWT,KAAb,MAAkC;CAChC;CACA;CACA,YAA0D;CAE1D,QAA+C;CAE/C,YAAY,GAAqB,GAAsC;AAIrE,EAJgD,KAAA,cAAA,GAChD,KAAK,KAAK,SAAS,cAAc,MAAM,EACvC,KAAK,GAAG,YAAY,uBACpB,KAAK,GAAG,aAAa,QAAQ,SAAS,EACtC,KAAK,GAAG,aAAa,aAAa,SAAS;EAI3C,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;EAEjB,IAAM,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAK,YAAY;AACjB,OAAK,IAAI,IAAI,GAAG,IAAI,IAAe,KAAK;GACtC,IAAM,IAAM,SAAS,cAAc,OAAO;AAI1C,GAHA,EAAI,YAAY,mBAChB,EAAI,MAAM,SAAS,GAAG,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,GAAG,KAAK,GAAG,CAAC,KACnE,EAAI,MAAM,iBAAiB,GAAG,IAAI,GAAG,KACrC,EAAK,YAAY,EAAI;;AAUvB,EARA,EAAK,YAAY,EAAK,EAEtB,KAAK,QAAQ,SAAS,cAAc,MAAM,EAC1C,KAAK,MAAM,YAAY,qBACvB,KAAK,MAAM,cAAc,GACzB,EAAK,YAAY,KAAK,MAAM,EAC5B,KAAK,GAAG,YAAY,EAAK,EAEzB,EAAO,YAAY,KAAK,GAAG;;CAO7B,MAAM,GAAqB,IAAY,IAAa;AAMlD,MALA,KAAK,QAAQ,WACb,KAAK,YAAY,EACjB,KAAK,MAAM,cAAc,KAAK,aAC9B,KAAK,GAAG,UAAU,OAAO,6BAA6B,EACtD,KAAK,GAAG,UAAU,OAAO,6BAA6B,EAAW,EAC7D,CAAC,KAAc,KAAa,KAAK,SAAS,EAAE;AAC9C,QAAK,GAAG,UAAU,OAAO,8BAA8B;AACvD;;AAEF,OAAK,YAAY,iBAAiB;AAEhC,GADA,KAAK,YAAY,MACjB,KAAK,GAAG,UAAU,OAAO,8BAA8B;SAChC;;CAI3B,MAAY;AAGV,EAFA,KAAK,QAAQ,QACb,KAAK,YAAY,EACjB,KAAK,GAAG,UAAU,IAAI,8BAA8B;;CAItD,KAAK,GAAuB;AACtB,OAAK,UAAU,WACnB,KAAK,QAAQ,UACb,KAAK,YAAY,EACjB,KAAK,MAAM,cAAc,GACzB,KAAK,GAAG,UAAU,IAAI,6BAA6B,EACnD,KAAK,GAAG,UAAU,OAAO,8BAA8B;;CAIzD,WAAoB;AAClB,SAAO,KAAK,UAAU;;CAIxB,YAAqB;AACnB,SAAO,KAAK,UAAU;;CAIxB,UAAmB;AACjB,SAAO,CAAC,KAAK,GAAG,UAAU,SAAS,8BAA8B;;CAGnE,UAAgB;AAEd,EADA,KAAK,YAAY,EACjB,KAAK,GAAG,QAAQ;;CAGlB,aAA2B;AACzB,EAAI,KAAK,cAAc,SACrB,aAAa,KAAK,UAAU,EAC5B,KAAK,YAAY;;GC7EjB,KAAuB,IAEvB,KAAoB,KAGpB,KAAoB;AAG1B,SAAS,KAA4B;AACnC,QAAO,IAAI,SAAS,MAAY;AAC9B,MAAI,OAAO,yBAA0B,cAAc,SAAS,QAAQ;AAClE,cAAW,GAAS,EAAE;AACtB;;EAEF,IAAM,IAAW,WAAW,GAAS,GAAkB;AACvD,8BAA4B,iBAAiB;AAE3C,GADA,aAAa,EAAS,EACtB,GAAS;KACR,EAAE,CAAC;GACN;;AAIJ,IAAM,IAAiB;CAAC;CAAW;CAAW;CAAW;CAAW;CAAW;CAAU,EAE5E,KAAb,MAAyB;CACvB;CACA;CACA,UAAwC;CACxC,UAA+C;CAC/C,WAA0C;CAC1C,YAA4C;CAC5C,iBAAsD;CACtD,eAAkD;CAClD,cAAgD;CAChD,YAA4C;CAC5C,WAA4C;CAC5C,cAAgD;CAChD,aAA8C;CAC9C,oBAA4D;CAC5D,eAAkD;CAClD,aAA8C;CAC9C,gBAA8C;CAC9C,cAAgD;CAChD,aAA8C;CAC9C,iBAAwC;CACxC,iBAAyB,IAAI,IAAuB;CACpD,YAA4C;CAC5C,uCAA+B,IAAI,KAAuB;CAC1D,kBAAyC;CAEzC,wCAAgC,IAAI,KAAqB;CACzD,oBAAmE;CACnE,qBAAgD;CAChD,qBAAoE;CACpE,cAAsB;CACtB,kBAAyC;CACzC,mBAA2B;CAC3B,kBAAyC;CACzC;CACA;CACA;CAEA,aAAqB;CAErB,WAAmB;CAEnB,oBAA4B;CAC5B,YAAoB;CACpB;CACA;CACA;CACA;CACA,UAAqE;CACrE,qBAAkE;CAIlE,aAAwC;CACxC,kBAA0B;CAC1B,WAAoE,EAAE;CAEtE,YAAY,GAAwB,IAA8B,EAAE,EAAE;AAiBpE,MAhBA,KAAK,UAAU,GACf,KAAK,UAAU,EAAQ,WAAW,IAOlC,KAAK,gBAAgB;GACnB,GAAG;GACH,GAAI,EAAQ,cAAc,eAAe,EAAE,cAAc,EAAQ,aAAa,cAAc,GAAG,EAAE;GAClG,EACD,KAAK,IAAI,GAAiB,EAAgB,EAAQ,QAAQ,EAAQ,SAAS,CAAC,EAIxE,EAAQ,gBAAgB;GAC1B,IAAM,IAAM,EAAQ,mBAAmB,KAAO,EAAE,GAAG,EAAQ;AAE3D,GADA,KAAK,kBAAkB,EAAI,aAAa,eACxC,KAAK,mBAAmB,EAAI,cAAc;;EAI5C,IAAM,IAAS,KAAK,cAAc,EAAQ,MAAM,EAC1C,IAAgB,KAAK,aAAa,EAAQ,MAAM;AA2BtD,EAxBA,KAAK,QAAQ;GACX,QAAQ,EAAQ,UAAU,KAAK,QAAQ,MAAM;GAC7C,WAAW,EAAQ,aAAa;GAChC,WAAW,EAAQ,cAAc,aAAa;GAC9C;GACA,kCAAkB,IAAI,KAAK;GAC3B,YAAY;GACZ,eAAe;GAEf,iBAAiB,EAAQ,UAAU,eAAe;GAClD,mBAAmB,EAAQ,UAAU,KAAK,EAAE,oBAAoB,GAAG;GACpE,EAID,GAAoB,EAGpB,KAAK,OAAO,SAAS,cAAc,MAAM,EACzC,KAAK,KAAK,YAAY,YACtB,KAAK,KAAK,QAAQ,WAAW,IAAS,SAAS,SAC/C,EAAU,YAAY,KAAK,KAAK,EAG5B,EAAQ,YAAY,OACtB,KAAK,UAAU,IAAI,GACjB,KAAK,MACL;GACE,SAAS,KAAK;GACd,YAAY,EAAQ,aAChB,EAAW,QAAO,MAAO,EAAQ,WAA2B,SAAS,EAAG,MAAM,CAAC,GAC/E;GACJ,YAAY,EAAQ,aAChB,EAAY,QAAO,MAAO,EAAQ,WAA2B,SAAS,EAAG,MAAM,CAAC,GAChF;GACJ,YAAY;GACZ,qBAAqB;GACtB,EACD;GACE,qBAAqB,KAAK,mBAAmB;GAC7C,cAAc,MAAO,KAAK,gBAAgB,EAAG;GAC7C,cAAc,MAAS,KAAK,gBAAgB,EAAK;GACjD,iBAAiB,MAAO,KAAK,mBAAmB,EAAG;GACnD,oBAAoB,MAAQ,KAAK,sBAAsB,EAAI;GAC3D,oBAAoB,KAAK,MAAM,YAAY;GAC3C,kBAAkB,KAAK,cAAc;GACrC,qBAAqB,KAAK,mBAAmB;GAC7C,sBAAsB,KAAK,cAAc;GACzC,gBAAgB,EAAQ,WAAW,KAAoC,KAAA,UAAtB,KAAK,cAAc;GACpE,iBAAiB,EAAQ,eAAe,KAAqC,KAAA,UAAvB,KAAK,eAAe;GAC1E,WAAW,EAAQ,YAAY,KAA4C,KAAA,KAAnC,MAAS,KAAK,aAAa,EAAK;GACxE,gBAAgB,EAAQ,YAAY,MAAS,EAAQ,oBAAoB,KAAK,aAAa,QAAQ,GAAG,KAAA;GACvG,EACD,KAAK,EACN;EAIH,IAAM,IAAO,SAAS,cAAc,MAAM;AA0N1C,MAzNA,EAAK,YAAY,YAEb,EAAQ,iBAAiB,OACvB,EAAQ,oBAAkB,KAAK,eAAe,aAAa,EAAQ,iBAAiB,EACxF,KAAK,UAAU,IAAI,GACjB,GACA;GAAE,mBAAmB;GAAqB,WAAW,KAAK,eAAe,MAAM;GAAuB,EACtG;GACE,gBAAgB,MAAS,KAAK,kBAAkB,EAAK;GACrD,uBAAuB,KAAK,qBAAqB;GACjD,sBAAsB,KAAK,oBAAoB;GAC/C,mBAAmB,MAAS,KAAK,qBAAqB,EAAK;GAC3D,cAAc,KAAK,MAAM,MAAM;GAC/B,cAAc,KAAK,MAAM,MAAM;GAC/B,uBAAuB;AAGrB,IAFA,KAAK,MAAM,eAAe,EAC1B,KAAK,QAAQ;KAAE,GAAG,KAAK;KAAO,YAAY;KAAM,EAChD,KAAK,UAAU;;GAEjB,qBAAqB,KAAK,cAAc,QAAQ;GACjD,CACF,GAGH,KAAK,iBAAiB,SAAS,cAAc,MAAM,EACnD,KAAK,eAAe,YAAY,uBAChC,EAAK,YAAY,KAAK,eAAe,EAIrC,KAAK,UAAU,IAAI,GAAqB,KAAK,gBAAgB,KAAK,EAAE,iBAAiB,CAAC,EAIlF,EAAQ,cACV,KAAK,YAAY,IAAI,EAAgB,GAAM,KAAK,SAAS,EACvD,WAAW,MAAQ;AAAO,QAAK,UAAU,EAAI;KAC9C,EAAE,KAAK,EAAE,kBAAkB,CAAC,EAC7B,KAAK,UAAU,UAAU,KAAK,MAAM,OAAO,EAC3C,KAAK,UAAU,UAAU,KAAK,cAAc,gBAAgB,KAAA,EAAU,GAGxE,KAAK,KAAK,YAAY,EAAK,EAG3B,KAAK,QAAQ,IAAI,EAAM,KAAK,gBAAgB;GAC1C,WAAW,KAAK,MAAM;GACtB,OAAO;GACP,WAAW;GACX,WAAW,EAAE,MAAM,UAAU;GAC7B,GAAG,EAAQ;GAKX,UAAU;IACR,UAAU;IACV,eAAe;IACf,iBAAiB;IACjB,YAAY;IACZ,SAAS,EAAQ,YAAY;IAC7B,oBAAoB,EAAQ,YAAY;IACxC,QAAQ;IACR,QAAQ;IACR,WAAW;IAKX,kBAAkB;IAClB,UAAU;IACV,YAAY;IACZ,QAAQ;IACR,cAAc;IACd,UAAU;IACV,WAAW;IACX,GAAG,EAAQ,cAAc;IAC1B;GACF,CAAC,EAKF,KAAK,MAAM,GAAG,eAAe,MAAM,KAAK,iBAAiB,EAAE,QAAQ,CAAC,EAMhE,EAAQ,mBAAmB,OAC7B,KAAK,WAAW,IAAI,EAAiB,KAAK,gBAAgB;GACxD,SAAS,GAAM,GAAQ,MAAS;AAE9B,IADA,KAAK,QAAQ,EAAK,EAClB,KAAK,MAAM,UAAU,EAAO,KAAK,OAAO,aAAa,EAAK,UAAU,EAAO,UAAU,IAAI,KAAK,EAAO,QAAQ,aAAa,IAAI;;GAEhI,UAAU,GAAK,MAAS;AACtB,SAAK,MAAM,GAAG,EAAK,KAAK,IAAI,EAAI,WAAW,QAAQ;;GAEtD,CAAC,EACF,KAAK,SAAS,QAAQ,GAIpB,EAAQ,cAAc,OACxB,KAAK,YAAY,IAAI,EAAgB,KAAK,KAAK,GAI7C,EAAQ,aAAa,OACvB,KAAK,WAAW,IAAI,EAAe;GACjC,WAAW,MAAU,KAAK,cAAc,EAAM;GAC9C,eAAe,KAAK,eAAe;GACnC,eAAe;GAChB,EAAE,KAAK,EAAE,GAIZ,KAAK,eAAe,IAAI,EAAmB;GACzC,SAAS,MAAQ;AAAO,SAAK,UAAU,EAAI;;GAC3C,eAAe;GAChB,CAAC,EACF,KAAK,cAAc,IAAI,EAAkB,EAAE,eAAe,IAAI,EAAE,KAAK,EAAE,EAGvE,KAAK,MAAM,GAAG,aAAa,MAAM;AAC/B,OAAI,CAAC,KAAK,WAAW,WAAW,CAAE;GAClC,IAAM,IAAO,EAAE,QAAkC;AAC7C,UAAO,KAAQ,aACf,KAAK,MAAM,gBAAgB,KAAK,aAAW,KAAK,MAAM,aAAa,EACvE,KAAK,MAAM,WAAW,EAAI,EAC1B,KAAK,UAAU,SAAS,SAAS;IACjC,EAGF,KAAK,aAAa,IAAI,GAAiB,KAAK,MAAM,EAAE,cAAc,MAAM,KAAK,iBAAiB,EAAE,EAAE,CAAC,EACnG,KAAK,MAAM,GAAG,kBAAkB,MAAM;GACpC,IAAM,IAAI,EAAE;AAEZ,GADA,KAAK,iBAAiB,OAAO,EAAE,YAAa,WAAW,EAAE,WAAW,MAChE,KAAK,YAAY,QAAQ,IAAE,KAAK,WAAW,OAAO,KAAK,sBAAsB,CAAC;IAClF,EAGE,EAAQ,iBAAiB,OAC3B,KAAK,eAAe,IAAI,GACtB,KAAK,MACL;GACE,gBAAgB,MAAU;AAExB,IADA,KAAK,MAAM,gBAAgB,EAAM,EACjC,KAAK,MAAM,wBAAwB,EAAM;;GAE3C,gBAAgB,KAAK,MAAM,iBAAiB;GAC7C,EACD,IAAI,IAAsB,CAC3B,GAIC,EAAQ,YAAY,OACtB,KAAK,aAAa,IAAI,GAAiB,KAAK,MAAM;GAChD,iBAAiB,KAAK,MAAM,gBAAgB;GAC5C,gBAAgB;AAEd,IADA,KAAK,MAAM,eAAe,EAC1B,KAAK,YAAY,MAAM;;GAE1B,CAAC,EACF,KAAK,MAAM,GAAG,iBAAiB,MAAM;GACnC,IAAM,IAAI,EAAE;AAEZ,GADA,KAAK,YAAY,MAAM,EACvB,KAAK,MAAM,GAAG,EAAE,SAAS,QAAQ,SAAS,QAAQ,oBAAoB,EAAE,WAAW,QAAQ,EAAE,CAAC,GAAG;IACjG,EAGE,EAAQ,gBACV,KAAK,cAAc,IAAI,GAAkB,KAAK,MAAM;GAClD,UAAU,GAAM,MAAU;AAExB,IADA,KAAK,MAAM,iBAAiB;KAAE;KAAM,MAAM;KAAS;KAAO,CAAC,EAC3D,KAAK,MAAM,GAAG,MAAS,QAAQ,QAAQ,OAAO,WAAW,KAAK,iBAAiB,EAAM,GAAG;;GAE1F,cAAc,MAAM,KAAK,iBAAiB,EAAE;GAC7C,CAAC,GAGJ,KAAK,MAAM,GAAG,eAAe,MAAM;GACjC,IAAM,IAAI,EAAE;AACZ,GAAI,KAAK,EAAE,YAAY,eAAa,KAAK,YAAY,MAAM;IAC3D,GAIA,EAAQ,WAAW,OACrB,KAAK,cAAc,IAAI,GAAkB,KAAK,MAAM;GAClD,QAAQ,GAAO,GAAW,GAAS,GAAS,MAAU;AACpD,SAAK,MAAM,SAAS,GAAO,GAAW,GAAS,GAAS,EAAM;;GAEhE,WAAW,MAAO,KAAK,MAAM,YAAY,EAAG;GAC5C,eAAe,KAAK,MAAM,aAAa;GACvC,kBAAkB,MAAY,KAAK,qBAAqB,EAAQ;GAChE,cAAc,MAAM,KAAK,iBAAiB,EAAE;GAC7C,CAAC,EAGF,KAAK,MAAM,GAAG,kBAAkB,KAAK,eAAe,CAAC,EACrD,KAAK,MAAM,GAAG,qBAAqB,KAAK,eAAe,CAAC,EACxD,KAAK,MAAM,GAAG,qBAAqB,KAAK,eAAe,CAAC,EACpD,EAAQ,uBACV,KAAK,gBAAgB,IAAI,GAAc,EAAQ,mBAAmB,GAEpE,KAAK,MAAM,GAAG,mBAAmB,MAAM;GACrC,IAAM,IAAI,EAAE,SACN,IAAO,SAAS,KAAK,iBAAiB,EAAE,MAAM,GAAG,EAAE,UAAU,MAAM,EAAE,YAAY;AAGvF,GAFA,KAAK,MAAM,aAAa,KAAQ,OAAO,EACvC,KAAK,eAAe,OAAO,EAAK,EAChC,KAAK,eAAe;IACpB,GAIA,EAAQ,eAAe,IAAO;AAKhC,GAJA,KAAK,oBAAoB,IAAI,GAAwB,KAAK,MAAM;IAC9D,UAAU,GAAY,MAAW,KAAK,MAAM,gBAAgB,GAAY,EAAO;IAC/E,eAAe;IAChB,CAAC,EACF,KAAK,aAAa,IAAI,GAAiB,KAAK,MAAM;IAChD,oBAAoB,MAAQ,KAAK,sBAAsB,EAAI;IAC3D,uBAAuB,MAAQ,KAAK,sBAAsB,EAAI;IAC9D,2BAA2B,GAAK,MAAY;AAE1C,KADA,KAAK,MAAM,oBAAoB,GAAK,EAAQ,EAC5C,KAAK,gBAAgB;;IAEvB,kBAAkB,MAAO;AAEvB,KADA,KAAK,MAAM,cAAc,EAAG,EAC5B,KAAK,gBAAgB;;IAEvB,yBAAyB,GAAI,MAAY;AAEvC,KADA,KAAK,MAAM,kBAAkB,GAAI,EAAQ,EACzC,KAAK,gBAAgB;;IAEvB,wBAAwB,GAAI,MAAW;AAErC,KADA,KAAK,MAAM,iBAAiB,GAAI,EAAO,EACvC,KAAK,gBAAgB;;IAEvB,oBAAoB,KAAK,kBAAkB;IAC3C,kBAAkB,MAAO,KAAK,oBAAoB,EAAG;IACtD,CAAC;GACF,IAAM,UAAgB;AAAE,IAAI,KAAK,YAAY,QAAQ,IAAE,KAAK,gBAAgB;;AAI5E,GAHA,KAAK,MAAM,GAAG,iBAAiB,EAAQ,EACvC,KAAK,MAAM,GAAG,iBAAiB,EAAQ,EACvC,KAAK,MAAM,GAAG,gBAAgB,EAAQ,EACtC,KAAK,MAAM,GAAG,mBAAmB,EAAQ;;AAmD3C,MA/CA,KAAK,iBAAiB,IAAI,EAAqB;GAC7C,cAAc,MAAO,KAAK,mBAAmB,EAAG;GAChD,cAAc,MAAS,KAAK,gBAAgB,EAAK;GACjD,gBAAgB,MAAS,KAAK,kBAAkB,EAAK;GACrD,cAAc,MAAO,KAAK,gBAAgB,EAAG;GAC7C,WAAW,MAAO,KAAK,aAAa,EAAG;GACvC,eAAe;GAChB,CAAC,EAEF,KAAK,sBAAsB,MAAqB;AAC9C,QAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,IAExC,CADA,EAAE,gBAAgB,EAClB,KAAK,sBAAsB;aACjB,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,OAAO,EAAE,QAAQ,KAGjE,CADA,EAAE,gBAAgB,EAClB,KAAK,cAAc,KAAK,KAAK,SAAS,KAAK,MAAM,OAAO;YAC/C,EAAE,QAAQ,OAAO,CAAC,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,EAAE,QAAQ;IAEjE,IAAM,IAAS,SAAS;AACxB,QAAI,MAAW,EAAO,YAAY,WAAW,EAAO,YAAY,cAAc,EAAO,mBAAoB;AAEzG,IADA,EAAE,gBAAgB,EAClB,KAAK,aAAa,MAAM;;KAG5B,SAAS,iBAAiB,WAAW,KAAK,mBAAmB,EAGzD,EAAQ,YACV,KAAK,UAAU,EAAQ,SACvB,KAAK,eAAe,GAMlB,KAAK,cACP,KAAK,oBAAoB,kBAAkB,KAAK,eAAe,EAAE,IAAK,GAIxE,KAAK,UAAU,EAGf,EAAQ,UAAU,KAAK,MAAM,EAGzB,EAAQ,YAAY,OAAO,WAAa,KAAa;GACvD,IAAM,IAAU,GAAc,SAAS,KAAK;AAC5C,GAAI,KAAc,KAAK,YAAY,EAAQ;;;CAO/C,WAAW,GAAyB;AAElC,EADA,KAAK,UAAU,GACf,KAAK,WAAW,WAAW,EAAQ;;CAGrC,MAAM,UAAU,GAA+B;AAS7C,EANA,KAAK,mBAAmB,EACxB,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO;GAAQ,EACtC,KAAK,kBAAkB,MACvB,KAAK,QAAQ,iBAAiB,EAAO,EACrC,KAAK,UAAU,EACf,KAAK,WAAW,UAAU,EAAO,EAC7B,KAAK,WACP,MAAM,KAAK,eAAe;;CAa9B,kBAAkB,GAAgB,GAAsC;AAItE,EAHI,EAAM,aAAa,KAAA,KACrB,KAAK,sBAAsB,IAAI,GAAQ,EAAM,SAAS,EAExD,KAAK,WAAW,SAAS,GAAQ,EAAM;;CAGzC,gBAA8B;AAC5B,MAAI,CAAC,KAAK,UAAW;EACrB,IAAM,IAAO,KAAK,MAAM,SAAS;AACjC,MAAI,EAAK,WAAW,EAAG;EACvB,IAAM,IAAO,EAAK,EAAK,SAAS,IAC1B,IAAU,KAAK,sBAAsB,IAAI,KAAK,MAAM,OAAO;AAKjE,EAAI,MAAY,KAAA,KAAa,KAAK,oBAAoB,SACpD,KAAK,kBAAkB,EAAK,GAAG;EAGjC,IAAM,IAAM,KAAK,qBAAqB,IAAI,KAAK,MAAM,OAAO,IAAI,EAAE;AAKlE,EAJA,EAAI,KAAK,EAAK,MAAM,EAChB,EAAI,SAAS,MAAI,EAAI,OAAO,EAChC,KAAK,qBAAqB,IAAI,KAAK,MAAM,QAAQ,EAAI,EAErD,KAAK,UAAU,SAAS,KAAK,MAAM,QAAQ;GACzC,WAAW,EAAK;GAChB,UAAU,KAAW,KAAK,mBAAmB,EAAK,GAAG;GACrD,WAAW,EAAI,OAAO;GACvB,CAAC;;CAGJ,MAAM,aAAa,GAA8B;AAI/C,MAHA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,WAAW;GAAI,EAC7C,KAAK,QAAQ,oBAAoB,EAAG,EACpC,KAAK,UAAU,EACX,KAAK,SAAS;AAEhB,SAAM,KAAK,eAAe;AAC1B;;AAEE,WAAK,QAAQ,uBAAuB,IAGxC;OAAI,CAAC,KAAK,YAAY;IACpB,IAAM,IAAU,KAAK,MAAM,SAAS;AACpC,IAAI,EAAQ,SAAS,MACnB,KAAK,aAAa,GAClB,KAAK,kBAAkB,EAAiB,EAAQ;;AAGpD,SAAM,KAAK,sBAAsB;;;CAGnC,SAAS,GAA+D;EACtE,IAAM,IAAS,KAAK,cAAc,EAAM,EAClC,IAAW,KAAK,aAAa,EAAM;AAIzC,EAHA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO;GAAQ,EACtC,KAAK,KAAK,QAAQ,WAAW,IAAS,SAAS,SAC/C,KAAK,MAAM,SAAS,EAAS,EAC7B,KAAK,UAAU;;CAGjB,WAAkB;AAChB,SAAO,KAAK;;CAGd,UAAgB;AACV,OAAK,cACT,KAAK,YAAY,IAEb,KAAK,sBACP,SAAS,oBAAoB,WAAW,KAAK,mBAAmB,EAElE,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,SAAS,EAC9B,KAAK,cAAc,SAAS,EAC5B,KAAK,aAAa,SAAS,EACvB,KAAK,sBAAoB,cAAc,KAAK,mBAAmB,EACnE,KAAK,WAAW,SAAS,EACzB,KAAK,UAAU,QAAQ,EACvB,KAAK,aAAa,SAAS,EAC3B,KAAK,YAAY,SAAS,EAC1B,KAAK,mBAAmB,SAAS,EACjC,KAAK,cAAc,SAAS,EAC5B,KAAK,YAAY,SAAS,EAC1B,KAAK,eAAe,SAAS,EAC7B,KAAK,aAAa,SAAS,EAC3B,KAAK,YAAY,SAAS,EACtB,KAAK,qBAAmB,cAAc,KAAK,kBAAkB,EACjE,KAAK,WAAW,SAAS,EACzB,KAAK,SAAS,SAAS,EACvB,KAAK,SAAS,SAAS,EACvB,KAAK,UAAU,SAAS,EACxB,KAAK,WAAW,SAAS,EACzB,KAAK,QAAQ,SAAS,EACtB,KAAK,MAAM,SAAS,EACpB,KAAK,KAAK,QAAQ,EAClB,GAAoB;;CAKtB,oBAAkC;AAIhC,OAAK,cAAc,KAAK,KAAK,SAAS,KAAK,MAAM,OAAO;;CAG1D,gBAAwB,GAAqB;AACtC,OAAK,aAAa,EAAG;;CAS5B,QAAQ,GAAwB;AAO9B,EANA,KAAK,YACL,KAAK,aAAa,GAClB,KAAK,kBAAkB,EAAiB,EAAK,EAC7C,KAAK,oBAAoB,EAGpB,KAAK,WAAS,KAAK,QAAQ,KAAK;;CAQvC,MAAc,uBAAsC;AAClD,MAAI,CAAC,KAAK,WAAY;EACtB,IAAM,IAAM,EAAE,KAAK,UACb,IAAa,KAAK,qBAAqB,MACxC,KAAK,WAAW,UAAU;AAC/B,MAAI;AACF,OAAI,MACF,KAAK,QAAQ,MAAM,KAAK,MAAM,SAAS,CAAC,SAAS,GAAG,GAAK,EACzD,MAAM,IAAY,EAEd,MAAQ,KAAK,YAAY,KAAK,WAAW;AAE/C,QAAK,oBAAoB;YACjB;AAGR,GAAI,MAAQ,KAAK,YAAU,KAAK,QAAQ,KAAK;;;CAKjD,qBAAmC;AACjC,MAAI,CAAC,KAAK,WAAY;EACtB,IAAM,IAAU,YAAY,KAAK,EAC3B,IAAW,EAAc,KAAK,MAAM,UAAU;AACpD,MAAI,KAAK,kBAAkB,KAAK,IAAW,KAAK,iBAAiB;GAC/D,IAAM,IAAe,KAAK,QAAQ,gBAAgB;AAClD,QAAK,MAAM,QAAQ,EAAc,KAAK,YAAY,KAAK,MAAM,WAAW,EAAE,iBAAc,CAAC,CAAC;QAE1F,MAAK,MAAM,QAAQ,KAAK,WAAW;AAErC,OAAK,oBAAoB,YAAY,KAAK,GAAG;;CAG/C,iBAAyB,GAAwB;AAC/C,MAAI,CAAC,KAAW,OAAO,KAAY,SAAU;EAC7C,IAAM,IAAI;AACV,MAAI,OAAO,EAAE,UAAW,UAAU;AAChC,GAAI,EAAE,SAAS,KAAK,KAAK,QAAQ,UAAU,KACzC,KAAK,QAAQ,KAAK,EAEd,KAAK,MAAM,oBAAoB,WAAS,KAAK,mBAAmB,aAAa,KAAK,EAAE,cAAc,CAAC;AAEzG;;AAEF,MAAI,EAAE,UAAU,KAAA,GAAW;AAIzB,GAAI,KAAK,QAAQ,UAAU,KACzB,KAAK,QAAQ,KAAK,KAAK,EAAE,0BAA0B,CAAC,EACpD,KAAK,mBAAmB,SAAS,EAAE,SAAS,KAAK,EAAE,0BAA0B,CAAC;AAEhF;;AAEF,UAAQ,EAAE,YAAY,OAAtB;GACE,KAAK;AAGH,IADI,KAAK,QAAQ,WAAW,IAAE,KAAK,QAAQ,KAAK,EAC5C,CAAC,KAAK,QAAQ,UAAU,IAAI,KAAK,MAAM,oBAAoB,eAC7D,KAAK,mBAAmB,aAAa,KAAK,EAAE,cAAc,CAAC;AAE7D;GACF,KAAK;AACH,IAAK,KAAK,QAAQ,UAAU,IAAE,KAAK,mBAAmB,cAAc,KAAK,EAAE,oBAAoB,CAAC;AAChG;GACF,KAAK;AACH,IAAK,KAAK,QAAQ,UAAU,IAAE,KAAK,mBAAmB,SAAS,KAAK,EAAE,0BAA0B,CAAC;AACjG;;;CAIN,mBAA2B,GAAiD,GAAiC;AAE3G,EADA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO;GAAiB;GAAmB,EAClE,KAAK,UAAU;;CAGjB,eAA6B;AACtB,OAAK,gBACV,KAAK,YAAY,QAAQ,EACrB,KAAK,YAAY,QAAQ,IAAE,KAAK,eAAe;;CAGrD,qBAA6B,GAA6B;EACxD,IAAM,IAAS,KAAK,eAAe,OAAO,EAAK;AAE/C,EADA,KAAK,SAAS,aAAa,KAAK,eAAe,MAAM,CAAC,EACtD,KAAK,MAAM,IAAS,wBAAwB,WAAW;;CAIzD,cAAsB;EACpB,IAAM,IAAa,KAAK,MAAM,qBAAqB,CAAC,KAAK,OAAO;GAC9D,IAAI,EAAE;GACN,QAAQ,EAAE;GACX,EAAE;AACH,SAAO,GAAkB;GACvB,GAAG;GACH,QAAQ,KAAK,MAAM;GACnB,WAAW,KAAK,MAAM;GACtB,WAAW,KAAK,MAAM;GACtB,WAAW,KAAK,MAAM,cAAc;GACpC;GACA,UAAU,KAAK,MAAM,aAAa;GACnC,CAAC;;CAIJ,MAAM,YAAY,GAAmC;EACnD,IAAM,IAAI,GAAkB,EAAQ;AACpC,MAAI,CAAC,EAAG,QAAO;AAQf,EAJI,EAAE,UAAU,EAAE,WAAW,KAAK,MAAM,UAAQ,MAAM,KAAK,UAAU,EAAE,OAAO,EAC1E,EAAE,aAAa,EAAE,cAAc,KAAK,MAAM,aAAW,MAAM,KAAK,aAAa,EAAE,UAAU,EAEzF,EAAE,aAAW,KAAK,gBAAgB,EAAE,UAAU,EAClD,KAAK,MAAM,aAAa,EAAE,UAAU;AAEpC,OAAK,IAAM,GAAG,MAAe,KAAK,MAAM,iBAAkB,MAAK,MAAM,gBAAgB,EAAW;EAChG,IAAM,oBAAM,IAAI,KAAqB;AACrC,OAAK,IAAM,KAAO,EAAE,YAAY;GAC9B,IAAM,IAAM,KAAK,MAAM,aAAa,EAAI,IAAI,EAAI,OAAO;AACvD,GAAI,KAAK,EAAI,IAAI,EAAI,IAAI,EAAI;;AAK/B,SAHA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,kBAAkB;GAAK,EACrD,KAAK,MAAM,YAAY,EAAE,SAAS,EAClC,KAAK,UAAU,EACR;;CAIT,MAAM,iBAAgC;EACpC,IAAM,IAAK,MAAM,KAAK,MAAM,gBAAgB;AAC5C,OAAK,MAAM,IAAK,uBAAuB,6CAA6C,IAAK,SAAS,QAAQ;;CAI5G,MAAM,gBAA+B;EAEnC,IAAM,IAAM,GADC,OAAO,WAAa,MAAc,SAAS,OAAO,IAC/B,KAAK,aAAa,CAAC;AACnD,MAAI;AAEF,GADA,MAAM,UAAU,UAAU,UAAU,EAAI,EACxC,KAAK,MAAM,oBAAoB;UACzB;AACN,QAAK,MAAM,uCAAuC,QAAQ;;;CAK9D,SAAS,GAA+B;AAGtC,EAFA,KAAK,MAAM,aAAa,EAAM,EAC9B,KAAK,aAAa,QAAQ,EAAM,EAC5B,KAAO,KAAK,MAAM,kBAAkB,EAAM;;CAIhD,aAAa,GAA4B;AACvC,EAAI,KAAK,MAAM,aAAa,EAAK,IAC/B,KAAK,YAAY,KAAK,EAAK;;CAI/B,uBAAgD;EAC9C,IAAM,IAAO,KAAK,MAAM,SAAS,EAC3B,IAAM,KAAK;AACjB,MAAI,MAAQ,QAAQ,IAAM,KAAK,KAAO,EAAK,OACzC,QAAO;GAAE,MAAM;GAAM,QAAQ;GAAG,WAAW;GAAG,YAAY,EAAE;GAAE;EAEhE,IAAM,IAAM,EAAK,IACX,IAAY,IAAM,IAAI,EAAK,IAAM,GAAG,QAAQ,EAAI,MAChD,IAAS,EAAI,QAAQ,GACrB,IAAY,MAAc,IAAiC,IAA5B,IAAS,IAAa,KAErD,IAAa,KAAK,MAAM,qBAAqB,CAAC,KAAK,MAAQ;GAE/D,IAAM,IADS,KAAK,MAAM,mBAAmB,EAAI,WAAW,EAAE,SACvC,MAAQ,MACzB,IAAS,IACX,OAAO,QAAQ,EAAM,CAClB,QAAQ,GAAG,OAAO,OAAO,KAAM,YAAY,OAAO,SAAS,EAAE,CAAC,CAC9D,KAAK,CAAC,GAAK,QAAQ;IAAE;IAAK,OAAO;IAAa,EAAE,GACnD,EAAE;AACN,UAAO;IAAE,MAAM,EAAI,WAAW;IAAM;IAAQ;IAC5C,CAAC,QAAQ,MAAM,EAAE,OAAO,SAAS,EAAE;AAErC,SAAO;GACL,MAAM;IAAE,MAAM,EAAI;IAAM,MAAM,EAAI;IAAM,KAAK,EAAI;IAAK,OAAO,EAAI;IAAO,QAAQ,EAAI;IAAQ;GAC5F;GACA;GACA;GACD;;CAGH,mBAAiC;AAC1B,OAAK,eACV,KAAK,WAAW,QAAQ,EACpB,KAAK,WAAW,QAAQ,IAAE,KAAK,WAAW,OAAO,KAAK,sBAAsB,CAAC;;CAGnF,gBAA8B;AACvB,OAAK,eACV,KAAK,WAAW,QAAQ,EACpB,KAAK,WAAW,QAAQ,IAAE,KAAK,gBAAgB;;CAGrD,sBAA8B,GAA0B;AACtD,MAAI,CAAC,KAAK,kBAAmB;EAC7B,IAAM,IAAM,KAAK,MAAM,qBAAqB,CAAC,MAAM,MAAM,EAAE,eAAe,EAAW;AAChF,OACL,KAAK,kBAAkB,KAAK;GAC1B;GACA,MAAM,EAAI,WAAW;GACrB,UAAU,EAAI,WAAW;GACzB,QAAQ,EAAI;GACb,CAAC;;CAGJ,iBAA+B;AAC7B,MAAI,CAAC,KAAK,WAAY;EACtB,IAAM,IAAa,KAAK,MAAM,qBAAqB,CAAC,KAAK,OAAO;GAC9D,YAAY,EAAE;GACd,MAAM,EAAE,WAAW;GACnB,SAAS,EAAE;GACZ,EAAE,EACG,IAAW,KAAK,MAAM,aAAa,CAAC,KAAK,OAAO;GACpD,IAAI,EAAE;GACN,OAAO,GAAiB,EAAE,KAAK;GAC/B,SAAS,EAAE;GACX,QAAQ,EAAE;GACX,EAAE,EACG,IAAW,KAAK,SAAS,KAAK,OAAO;GAAE,IAAI,EAAE;GAAI,OAAO,EAAE;GAAQ,OAAO,EAAE;GAAO,EAAE;AAC1F,OAAK,WAAW,WAAW,GAAY,GAAU,EAAS;;CAG5D,MAAc,mBAAkC;AAC9C,MAAI,CAAC,KAAK,SAAS;AACjB,QAAK,MAAM,wCAAwC,QAAQ;AAC3D;;EAEF,IAAM,IAAQ,IAAI,IAAI,CAAC,KAAK,MAAM,QAAQ,GAAG,KAAK,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,EAC3E,IAAU,KAAK,QAAQ,QAAQ,MAAM,CAAC,EAAM,IAAI,EAAE,CAAC;AACzD,OAAK,cAAc,KAAK,EAAQ,SAAS,IAAU,KAAK,SAAS,KAAK,MAAM,SAAS,MAAW;AACzF,QAAK,iBAAiB,EAAO;IAClC;;CAIJ,MAAM,iBAAiB,GAA+B;AACpD,MAAI,CAAC,KAAK,WAAW,KAAK,SAAS,MAAM,MAAM,EAAE,WAAW,EAAO,CAAE;EACrE,IAAM,IAAQ,EAAe,KAAK,SAAS,SAAS,EAAe,SAC7D,IAAK,OAAO;AAClB,MAAI;GACF,IAAM,IAAO,MAAM,KAAK,QAAQ,aAAa,GAAQ,KAAK,MAAM,WAAW,KAAK,QAAQ,gBAAgB,IAAI;AAO5G,GAJI,KAAK,SAAS,WAAW,KAAG,KAAK,MAAM,eAAe,UAAU,EACpE,KAAK,MAAM,iBAAiB,GAAI,GAAQ,GAAM,EAAM,EACpD,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU;IAAE;IAAI;IAAQ;IAAO,CAAC,EACzD,KAAK,gBAAgB,EACrB,KAAK,MAAM,aAAa,IAAS;WAC1B,GAAc;AACrB,QAAK,MAAM,GAAG,EAAO,IAAI,aAAe,QAAQ,EAAI,UAAU,oBAAoB,QAAQ;;;CAI9F,oBAA4B,GAAkB;AAG5C,EAFA,KAAK,MAAM,oBAAoB,EAAG,EAClC,KAAK,WAAW,KAAK,SAAS,QAAQ,MAAM,EAAE,OAAO,EAAG,EACxD,KAAK,gBAAgB;;CAIvB,MAAc,kBAAiC;AAC7C,MAAI,CAAC,KAAK,WAAW,KAAK,SAAS,WAAW,EAAG;EAEjD,IAAM,IAAQ,KAAK,SAAS,QAAQ,MAAM,EAAE,WAAW,KAAK,MAAM,OAAO;AACzE,OAAK,IAAM,KAAK,EAAO,MAAK,oBAAoB,EAAE,GAAG;AAErD,OAAK,IAAM,KAAK,KAAK,SACnB,KAAI;GACF,IAAM,IAAO,MAAM,KAAK,QAAQ,aAAa,EAAE,QAAQ,KAAK,MAAM,WAAW,KAAK,QAAQ,gBAAgB,IAAI;AAC9G,QAAK,MAAM,kBAAkB,EAAE,IAAI,EAAK;UAClC;;CAIZ,gBAA8B;AACvB,OAAK,gBACV,KAAK,YAAY,WAAW,KAAK,mBAAmB,CAAC,EACrD,KAAK,YAAY,UACf,KAAK,MAAM,WAAW,CAAC,KAAK,OAAO;GACjC,IAAI,EAAE;GACN,OAAO,EAAE;GACT,WAAW,EAAE;GACb,SAAS,EAAE;GACX,WAAW,EAAE;GACb,SAAS,EAAE;GACX,OAAO,EAAE;GACV,EAAE,CACJ;;CAIH,oBAAkE;EAChE,IAAM,IAAU,CAAC;GAAE,SAAS;GAAS,OAAO;GAAS,CAAC;AACtD,OAAK,IAAM,KAAO,KAAK,MAAM,qBAAqB,EAAE;GAGlD,IAAM,IAAS,KAAK,MAAM,mBAAmB,EAAI,WAAW,EAAE,QACxD,IAAQ,KAAU,EAAO,SAAS,IAAI,EAAO,EAAO,SAAS,KAAK,MAClE,IAAO,IAAQ,OAAO,KAAK,EAAM,CAAC,QAAQ,MAAM,OAAO,EAAM,MAAO,SAAS,GAAG,EAAE;AACxF,QAAK,IAAM,KAAO,GAAM;IACtB,IAAM,IAAQ,EAAK,SAAS,IAAI,GAAG,EAAI,WAAW,KAAK,GAAG,MAAQ,EAAI,WAAW;AACjF,MAAQ,KAAK;KAAE,SAAS,GAAG,EAAI,WAAW,GAAG;KAAO;KAAO,CAAC;;;AAGhE,SAAO;;CAIT,qBAA6B,GAAgC;EAC3D,IAAM,IAAO,KAAK,MAAM,SAAS;AACjC,MAAI,MAAY,QAAS,QAAO,EAAK,SAAS,IAAI,EAAK,EAAK,SAAS,GAAG,QAAQ;EAChF,IAAM,IAAM,EAAQ,QAAQ,IAAI;AAChC,MAAI,IAAM,KAAK,EAAK,WAAW,EAAG,QAAO;EACzC,IAAM,IAAa,EAAQ,MAAM,GAAG,EAAI,EAClC,IAAM,EAAQ,MAAM,IAAM,EAAE,EAC5B,IAAI,KAAK,MAAM,mBAAmB,EAAW,EAAE,SAAS,EAAK,SAAS,KAAK;AACjF,SAAO,OAAO,KAAM,YAAY,OAAO,SAAS,EAAE,GAAG,IAAI;;CAG3D,iBAAyB,GAAuB;EAG9C,IAAM,IAAM,KAAK,IAAI,EAAM,EACrB,IAAS,KAAO,MAAO,IAAI,KAAO,IAAI,IAAI,GAC1C,IAAS,KAAK,cAAc,gBAAgB,KAAA;AAClD,SAAO,EAAM,eAAe,GAAQ;GAAE,uBAAuB;GAAG,uBAAuB;GAAQ,CAAC;;CAGlG,gBAAwB,GAAuB;AAG7C,EAFA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,WAAW;GAAM,EAC/C,KAAK,MAAM,aAAa,EAAK,EAC7B,KAAK,UAAU;;CAGjB,mBAA2B,GAAqB;AAC9C,MAAI,KAAK,MAAM,iBAAiB,IAAI,EAAM,EAAE;GAE1C,IAAM,IAAa,KAAK,MAAM,iBAAiB,IAAI,EAAM;AACzD,QAAK,MAAM,gBAAgB,EAAW;GACtC,IAAM,IAAO,IAAI,IAAI,KAAK,MAAM,iBAAiB;AAEjD,GADA,EAAK,OAAO,EAAM,EAClB,KAAK,QAAQ;IAAE,GAAG,KAAK;IAAO,kBAAkB;IAAM;SACjD;GACL,IAAM,IAAa,KAAK,MAAM,aAAa,EAAM;AACjD,OAAI,GAAY;IACd,IAAM,IAAO,IAAI,IAAI,KAAK,MAAM,iBAAiB;AAEjD,IADA,EAAK,IAAI,GAAO,EAAW,EAC3B,KAAK,QAAQ;KAAE,GAAG,KAAK;KAAO,kBAAkB;KAAM;;;AAG1D,OAAK,UAAU;;CAGjB,sBAA8B,GAA0B;AACtD,OAAK,MAAM,gBAAgB,EAAW;EACtC,IAAM,IAAO,IAAI,IAAI,KAAK,MAAM,iBAAiB;AACjD,OAAK,IAAM,CAAC,GAAI,MAAQ,EAAK,SAAS,CACpC,KAAI,MAAQ,GAAY;AACtB,KAAK,OAAO,EAAG;AACf;;AAIJ,EADA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,kBAAkB;GAAM,EACtD,KAAK,UAAU;;CAGjB,uBAAqC;AACnC,MAAI,KAAK,gBAAgB,QAAQ,EAAE;AACjC,QAAK,eAAe,OAAO;AAC3B;;AAEF,OAAK,gBAAgB,KAAK,KAAK,mBAAmB,CAAC;;CAGrD,oBAA2C;EACzC,IAAM,IAAuB,EAAE;AAE/B,OAAK,IAAM,KAAO,EAChB,GAAM,KAAK;GACT,IAAI,EAAI;GACR,OAAO,EAAI;GACX,UAAU;GACV,QAAQ,KAAK,MAAM,iBAAiB,IAAI,EAAI,GAAG;GAChD,CAAC;AAGJ,OAAK,IAAM,KAAM,EACf,GAAM,KAAK;GACT,IAAI,EAAG;GACP,OAAO,EAAG;GACV,UAAU;GACV,QAAQ,KAAK,MAAM,cAAc,EAAG;GACrC,CAAC;AAGJ,OAAK,IAAM,KAAS,EAClB,MAAK,IAAM,KAAQ,EAAM,MACvB,GAAM,KAAK;GACT,IAAI,EAAK;GACT,OAAO,EAAK;GACZ,UAAU;GACV,QAAQ,KAAK,MAAM,eAAe,EAAK;GACxC,CAAC;AAIN,OAAK,IAAM,KAAM,EACf,GAAM,KAAK;GACT,IAAI,EAAG;GACP,OAAO,EAAG;GACV,UAAU;GACV,QAAQ,KAAK,MAAM,cAAc,EAAG;GACrC,CAAC;AAcJ,SAXA,EAAM,KACJ;GAAE,IAAI;GAAc,OAAO;GAAc,UAAU;GAAU,UAAU;GAAI,EAC3E;GAAE,IAAI;GAAa,OAAO;GAAoB,UAAU;GAAU,EAClE;GAAE,IAAI;GAAe,OAAO;GAAgB,UAAU;GAAU,EAChE;GAAE,IAAI;GAAY,OAAO;GAAY,UAAU;GAAU,EACzD;GAAE,IAAI;GAAa,OAAO;GAA0B,UAAU;GAAU,EACxE;GAAE,IAAI;GAAW,OAAO;GAAkC,UAAU;GAAU,EAC9E;GAAE,IAAI;GAAc,OAAO;GAAsB,UAAU;GAAU,EACrE;GAAE,IAAI;GAAiB,OAAO;GAAsB,UAAU;GAAU,CACzE,EAEM;;CAGT,aAAqB,GAAkB;AACrC,UAAQ,GAAR;GACE,KAAK;AACH,SAAK,MAAM,YAAY;AACvB;GACF,KAAK;AACH,SAAK,mBAAmB;AACxB;GACF,KAAK;AACH,SAAK,cAAc;AACnB;GACF,KAAK;AACE,SAAK,gBAAgB;AAC1B;GACF,KAAK;AACE,SAAK,eAAe;AACzB;GACF,KAAK,WAAW;IACd,IAAM,IAAK,KAAK,MAAM,SAAS;AAC/B,SAAK,MAAM,IAAK,yBAAyB,yBAAyB;AAClE;;GAEF,KAAK;AACH,SAAK,kBAAkB;AACvB;GACF,KAAK;AAGH,IAFA,KAAK,MAAM,eAAe,EAC1B,KAAK,QAAQ;KAAE,GAAG,KAAK;KAAO,YAAY;KAAM,EAChD,KAAK,UAAU;AACf;;;CAIN,kBAA0B,GAA6B;AAGrD,EAFA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,YAAY;GAAM,EAChD,KAAK,MAAM,eAAe,EAAK,EAC/B,KAAK,UAAU;;CAGjB,sBAAoC;AAGlC,EAFA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,YAAY;GAAM,EAChD,KAAK,MAAM,eAAe,KAAK,EAC/B,KAAK,UAAU;;CAGjB,qBAAmC;EACjC,IAAM,IAAgB,CAAC,KAAK,MAAM;AAGlC,EAFA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO;GAAe,EAC7C,KAAK,MAAM,iBAAiB,EAAc,EAC1C,KAAK,UAAU;;CAGjB,oBAAkC;EAChC,IAAM,IAAS,CAAC,KAAK,MAAM;AAQ3B,EAPA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO;GAAQ,EACtC,KAAK,KAAK,QAAQ,WAAW,IAAS,SAAS,SAC/C,KAAK,MAAM,SAAS,IAAS,IAAa,EAAY,EACtD,KAAK,MAAM,aAAa,KAAK,MAAM,OAAO,QAAQ,QAAQ,UAAU,EAAE;GACpE,UAAU;GACV,OAAO,IAAS,2BAA2B;GAC5C,CAAC,EACF,KAAK,UAAU;;CAGjB,eAA6B;AAC3B,OAAK,UAAU,KAAK,KAAK,cAAc;;CAUzC,MAAM,GAAiB,IAAyB,QAAc;EAC5D,IAAM,IAAK,SAAS,cAAc,MAAM;AAMxC,EALA,EAAG,YAAY,aAAa,MAAS,UAAU,oBAAoB,MACnE,EAAG,cAAc,GACjB,KAAK,KAAK,YAAY,EAAG,EAEzB,4BAA4B,EAAG,UAAU,IAAI,eAAe,CAAC,EAC7D,iBAAiB;AAIf,GAHA,EAAG,UAAU,OAAO,eAAe,EACnC,EAAG,iBAAiB,uBAAuB,EAAG,QAAQ,EAAE,EAAE,MAAM,IAAM,CAAC,EAEvE,iBAAiB,EAAG,QAAQ,EAAE,IAAI;KACjC,KAAK;;CASV,iBAAiB,GAAuB;AACtC,MAAI,CAAC,KAAK,gBAAiB;EAC3B,IAAM,IAAS,KAAU,KAAK,MAAM;AACpC,MAAI;AACF,gBAAa,WAAW,KAAK,kBAAkB,EAAO;UAChD;;CAGV,kBAA0B,GAAsB;AAC9C,MAAI,CAAC,KAAK,gBAAiB;EAC3B,IAAM,IAAM,KAAK,kBAAkB;AACnC,OAAK,kBAAkB;AAEvB,MAAI;AAKF,GADW,KAAK,MAAM,qBAAqB,EACvC,IAAI,KAAK,qCAAqC;UAC5C;AAIR,OAAK,MAAM,YAAY,GAAK,KAAK,iBAAiB;;CAGpD,oBAAkC;AAC3B,WAAK,iBACV;OAAI;AAAE,SAAK,MAAM,UAAU,KAAK,gBAAgB;WAAU;AAE1D,GADA,KAAK,MAAM,iBAAiB,EAC5B,KAAK,kBAAkB;;;CAQzB,sCAAoD;EAClD,IAAM,oBAAO,IAAI,KAAqB;AACtC,OAAK,IAAM,KAAK,KAAK,MAAM,qBAAqB,CAC9C,GAAK,IAAI,EAAE,IAAI,EAAE,WAAW;AAG9B,EADA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,kBAAkB;GAAM,EACtD,KAAK,UAAU;;CAMjB,eAAqB;AACnB,EAAI,KAAK,WAAW,WAAW,GAC7B,KAAK,YAAY,GAEjB,KAAK,aAAa;;CAItB,cAA4B;EAC1B,IAAM,IAAO,KAAK,MAAM,SAAS;AAC7B,IAAK,SAAS,MAIlB,KAAK,qBAAqB,EAAK,OAAO,EAItC,KAAK,YAAY,IAAI,EAAgB;GACnC,cAAc;AAMZ,IALI,KAAK,MAAM,gBAAgB,KAAK,WAClC,KAAK,MAAM,cAAc,GAEzB,KAAK,MAAM,YAAY;KAAE,OAAO,KAAK;KAAa,UAAU;KAAK,CAAC,EAEpE,KAAK,WAAW,SAAS,UAAU;;GAErC,eAAe;AAEb,IADA,KAAK,MAAM,aAAa,EACxB,KAAK,WAAW,SAAS,SAAS;;GAEpC,cAAc;AAEZ,IADA,KAAK,MAAM,YAAY,EACvB,KAAK,WAAW,SAAS,SAAS;;GAEpC,kBAAkB;IAChB,IAAM,IAAI,KAAK,MAAM,mBAAmB;AAGxC,IAFI,KAAK,MAAM,gBAAgB,KAAK,aAAW,KAAK,MAAM,aAAa,EACvE,KAAK,MAAM,WAAW,KAAK,IAAI,GAAG,EAAE,UAAU,EAAE,CAAC,EACjD,KAAK,WAAW,SAAS,SAAS;;GAEpC,qBAAqB;IACnB,IAAM,IAAI,KAAK,MAAM,mBAAmB;AAGxC,IAFI,KAAK,MAAM,gBAAgB,KAAK,aAAW,KAAK,MAAM,aAAa,EACvE,KAAK,MAAM,WAAW,KAAK,IAAI,EAAE,QAAQ,GAAG,EAAE,UAAU,EAAE,CAAC,EAC3D,KAAK,WAAW,SAAS,SAAS;;GAEpC,SAAS,MAAQ;AAGf,IAFI,KAAK,MAAM,gBAAgB,KAAK,aAAW,KAAK,MAAM,aAAa,EACvE,KAAK,MAAM,WAAW,EAAI,EAC1B,KAAK,WAAW,SAAS,SAAS;;GAEpC,gBAAgB,MAAM;AAEpB,IADA,KAAK,cAAc,GACnB,KAAK,MAAM,eAAe,EAAE;;GAE9B,eAAe,KAAK,YAAY;GACjC,CAAC,EACF,KAAK,UAAU,MAAM,KAAK,gBAAgB;GAAE,OAAO,EAAK;GAAQ,OAAO,KAAK;GAAa,CAAC,EAI1F,KAAK,MAAM,YAAY;GAAE,OAAO,KAAK;GAAa,UAAU;GAAK,YAAY;GAAG,CAAC,EACjF,KAAK,MAAM,aAAa,EACxB,KAAK,UAAU,SAAS,SAAS,EAEjC,KAAK,qBAAqB,kBAAkB;AAC1C,OAAI,CAAC,KAAK,WAAW,WAAW,CAAE;GAClC,IAAM,IAAI,KAAK,MAAM,mBAAmB;AACxC,QAAK,UAAU,YAAY,EAAE,SAAS,EAAE,MAAM;GAC9C,IAAM,IAAQ,KAAK,MAAM,gBAAgB;AACzC,GAAI,MAAU,YACZ,KAAK,UAAU,SAAS,SAAS,GAEjC,KAAK,UAAU,SAAS,EAAM;KAE/B,IAAI;;CAGT,aAA2B;AAQzB,EAPA,AAEE,KAAK,wBADL,cAAc,KAAK,mBAAmB,EACZ,OAE5B,KAAK,MAAM,YAAY,EACvB,KAAK,WAAW,SAAS,EACzB,KAAK,YAAY,MACjB,AAEE,KAAK,wBADL,KAAK,MAAM,QAAQ,KAAK,mBAAmB,EACjB;;CAI9B,cAAsB,GAA0C;AAiC9D,EAhCA,KAAK,gBAAgB;GAAE,GAAG,KAAK;GAAe,GAAG;GAAO,EAEpD,EAAM,gBAAgB,KAAA,KAAW,KAAK,MAAM,eAAe,EAAM,YAAY,EAC7E,EAAM,kBAAkB,KAAA,KAAW,KAAK,MAAM,iBAAiB,EAAM,cAAc,EACnF,EAAM,yBAAyB,KAAA,KAAW,KAAK,MAAM,wBAAwB,EAAM,qBAAqB,EACxG,EAAM,yBAAyB,KAAA,KAAW,KAAK,MAAM,wBAAwB,EAAM,qBAAqB,EACxG,EAAM,uBAAuB,KAAA,KAAW,KAAK,MAAM,uBAAuB,EAAE,gBAAgB,EAAM,oBAAoB,CAAC,EACvH,EAAM,yBAAyB,KAAA,KAAW,KAAK,MAAM,uBAAuB,EAAE,SAAS,EAAM,sBAAsB,CAAC,EACpH,EAAM,yBAAyB,KAAA,KAAW,KAAK,MAAM,uBAAuB,EAAE,SAAS,EAAM,sBAAsB,CAAC,EACpH,EAAM,yBAAyB,KAAA,KAAW,KAAK,MAAM,uBAAuB,EAAE,SAAS,EAAM,sBAAsB,CAAC,EACpH,EAAM,wBAAwB,KAAA,KAAW,KAAK,MAAM,uBAAuB,EAAM,oBAAoB,EACrG,EAAM,wBAAwB,KAAA,KAAW,KAAK,MAAM,sBAAsB,EAAE,SAAS,EAAM,qBAAqB,CAAC,EACjH,EAAM,0BAA0B,KAAA,KAAW,KAAK,MAAM,yBAAyB,EAAM,sBAAsB,EAC3G,EAAM,wBAAwB,KAAA,KAAW,KAAK,MAAM,uBAAuB,EAAM,oBAAoB,EACrG,EAAM,kBAAkB,KAAA,KAAW,KAAK,MAAM,sBAAsB;GAAE,MAAM,EAAM;GAAe,OAAO,EAAM;GAAe,CAAC,EAC9H,EAAM,yBAAyB,KAAA,KAAW,KAAK,MAAM,sBAAsB,EAAE,iBAAiB,EAAM,sBAAsB,CAAC,EAC3H,EAAM,wBAAwB,KAAA,KAAW,KAAK,MAAM,uBAAuB,EAAM,oBAAoB,EACrG,EAAM,uBAAuB,KAAA,KAAW,KAAK,MAAM,sBAAsB,EAAM,mBAAmB,EAClG,EAAM,kBAAkB,KAAA,KAAW,KAAK,MAAM,iBAAiB,EAAM,cAAc,EACnF,EAAM,cAAc,KAAA,KAAW,KAAK,MAAM,aAAa,EAAM,UAAU,EACvE,EAAM,cAAc,KAAA,IAIb,EAAM,aAAa,KAAA,MAC5B,KAAK,MAAM,YAAY,EAAM,SAAS,EACtC,KAAK,gBAAgB;GAAE,GAAG,KAAK;GAAe,WAAW,EAAM,WAAW,gBAAgB;GAAW,KALrG,KAAK,MAAM,aAAa,EAAM,UAAU,EAExC,KAAK,gBAAgB;GAAE,GAAG,KAAK;GAAe,UAAU,EAAM,cAAc;GAAe,GAKzF,EAAM,iBAAiB,KAAA,MACzB,KAAK,MAAM,gBAAgB,EAAM,aAAa,EAC9C,KAAK,WAAW,UAAU,EAAM,gBAAgB,KAAA,EAAU,GAExD,EAAM,aAAa,KAAA,KACrB,KAAK,MAAM,kBAAkB,EAAM,aAAa,UAAU,OAAO,OAAO,EAAM,SAAS,CAAC;EAK1F,IAAM,IAAc,EAAE,GADD,KAAK,MAAM,UACP,EAAc,EACnC,IAAe;AASnB,EAPI,EAAM,kBAAkB,KAAA,MAAa,EAAY,WAAW,EAAM,eAAe,IAAe,KAChG,EAAM,oBAAoB,KAAA,MAAa,EAAY,aAAa,EAAM,iBAAiB,IAAe,KACtG,EAAM,iBAAiB,KAAA,MAAa,EAAY,eAAe,EAAM,cAAc,IAAe,KAClG,EAAM,mBAAmB,KAAA,MAAa,EAAY,iBAAiB,EAAM,gBAAgB,IAAe,KACxG,EAAM,oBAAoB,KAAA,MAAa,EAAY,aAAa,EAAM,iBAAiB,IAAe,KACtG,EAAM,cAAc,KAAA,MAAa,EAAY,OAAO,EAAM,WAAW,IAAe,KAEpF,KACF,KAAK,MAAM,SAAS,EAAgC;;CAIxD,gBAA8B;AAE5B,EADA,KAAK,gBAAgB,EAAE,GAAG,GAAkB,EAC5C,KAAK,cAAc,KAAK,cAAc;;CAGxC,MAAc,gBAA+B;AAC3C,MAAI,CAAC,KAAK,QAAS;EACnB,IAAM,IAAM,EAAE,KAAK;AAUnB,EARA,KAAK,QAAQ;GACX,GAAG,KAAK;GACR,iBAAiB;GACjB,mBAAmB,KAAK,EAAE,oBAAoB;GAC/C,EACD,KAAK,UAAU,EAGf,KAAK,QAAQ,MAAM,KAAK,MAAM,SAAS,CAAC,SAAS,EAAE;AAEnD,MAAI;AASF,OARA,KAAK,MAAM,kBAAkB,EAC7B,MAAM,KAAK,MAAM,QAAQ;IACvB,SAAS,KAAK;IACd,QAAQ,KAAK,MAAM;IACnB,WAAW,KAAK,MAAM;IACtB,cAAc,KAAK,QAAQ,gBAAgB;IAC5C,CAAC,EAEE,MAAQ,KAAK,cAAc,KAAK,UAAW;AA4B1C,GA1BL,KAAK,MAAM,aAAa,KAAK,MAAM,OAAO,QAAQ,QAAQ,UAAU,EAAE;IACpE,UAAU;IACV,OAAO,KAAK,MAAM,SAAS,2BAA2B;IACvD,CAAC,EAKF,KAAK,kBAAkB,KAAK,MAAM,OAAO,EAErC,KAAK,QAAQ,WAAW,GAG1B,KAAK,QAAQ;IAAE,GAAG,KAAK;IAAO,iBAAiB;IAAS,IAExD,KAAK,QAAQ,KAAK,EAClB,KAAK,QAAQ;IACX,GAAG,KAAK;IACR,iBAAiB;IACjB,mBAAmB,KAAK,EAAE,cAAc;IACzC,GAME,KAAK,iBAAiB;WACpB,GAAc;AACrB,OAAI,MAAQ,KAAK,cAAc,KAAK,UAAW;AAE/C,GADA,KAAK,QAAQ,KAAK,KAAK,EAAE,0BAA0B,CAAC,EACpD,KAAK,QAAQ;IACX,GAAG,KAAK;IACR,iBAAiB;IACjB,mBAAmB,aAAe,QAAQ,EAAI,UAAU,KAAK,EAAE,0BAA0B;IAC1F;;AAGH,OAAK,UAAU;;CAGjB,WAAyB;AAGvB,EAFA,KAAK,SAAS,OAAO,KAAK,MAAM,EAChC,KAAK,SAAS,OAAO,KAAK,MAAM,EAChC,KAAK,WAAW,OAAO;GACrB,iBAAiB,KAAK,MAAM;GAC5B,SAAS,KAAK,MAAM;GACpB,QAAQ,KAAK,MAAM;GACnB,WAAW,KAAK,MAAM;GACvB,CAAC;;CAGJ,cAAsB,GAAmE;AAOvF,SANI,MAAU,KAAA,KAAa,MAAU,SAAe,KAChD,MAAU,UAAgB,KAE1B,OAAO,KAAU,YAAY,EAAM,aAC9B,KAAK,YAAY,EAAM,WAAW,GAEpC;;CAGT,aAAqB,GAAiE;AAIpF,SAHI,MAAU,KAAA,KAAa,MAAU,SAAe,IAChD,MAAU,UAAgB,IAC1B,OAAO,KAAU,WAAiB,IAC/B;;CAGT,YAAoB,GAAwB;AAE1C,MAAI,EAAM,WAAW,IAAI,IAAI,EAAM,UAAU,GAAG;GAC9C,IAAM,IAAI,SAAS,EAAM,MAAM,GAAG,EAAE,EAAE,GAAG,EACnC,IAAI,SAAS,EAAM,MAAM,GAAG,EAAE,EAAE,GAAG,EACnC,IAAI,SAAS,EAAM,MAAM,GAAG,EAAE,EAAE,GAAG;AACzC,UAAQ,IAAI,IAAI,IAAK;;AAEvB,SAAO"}
|