@tradecanvas/chart 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,740 +1,878 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../Chart-DoR8L8Uk.cjs`);let t=require(`@tradecanvas/commons`);var n=[{label:`1m`,value:`1m`},{label:`5m`,value:`5m`},{label:`15m`,value:`15m`},{label:`1H`,value:`1h`},{label:`4H`,value:`4h`},{label:`1D`,value:`1d`}],r=[{label:`Candlestick`,value:`candlestick`},{label:`Line`,value:`line`},{label:`Area`,value:`area`},{label:`Bar`,value:`bar`},{label:`Heikin-Ashi`,value:`heikinAshi`},{label:`Hollow Candle`,value:`hollowCandle`},{label:`Baseline`,value:`baseline`}],i=[{label:`Lines`,tools:[{label:`Trend Line`,value:`trendLine`},{label:`Ray`,value:`ray`},{label:`Extended Line`,value:`extendedLine`}]},{label:`Horizontal/Vertical`,tools:[{label:`Horizontal Line`,value:`horizontalLine`},{label:`Vertical Line`,value:`verticalLine`}]},{label:`Channels`,tools:[{label:`Parallel Channel`,value:`parallelChannel`},{label:`Regression Channel`,value:`regressionChannel`}]},{label:`Fibonacci`,tools:[{label:`Fib Retracement`,value:`fibRetracement`},{label:`Fib Extension`,value:`fibExtension`}]},{label:`Shapes`,tools:[{label:`Rectangle`,value:`rectangle`},{label:`Ellipse`,value:`ellipse`},{label:`Triangle`,value:`triangle`}]},{label:`Gann & Advanced`,tools:[{label:`Pitchfork`,value:`pitchfork`},{label:`Gann Fan`,value:`gannFan`},{label:`Gann Box`,value:`gannBox`},{label:`Elliott Wave`,value:`elliottWave`}]},{label:`Measure`,tools:[{label:`Price Range`,value:`priceRange`},{label:`Date Range`,value:`dateRange`},{label:`Measure`,value:`measure`}]},{label:`Annotation`,tools:[{label:`Text`,value:`text`},{label:`Arrow`,value:`arrow`}]}],a=[{id:`sma`,name:`SMA`,type:`overlay`},{id:`ema`,name:`EMA`,type:`overlay`},{id:`bb`,name:`Bollinger Bands`,type:`overlay`},{id:`vwap`,name:`VWAP`,type:`overlay`},{id:`ichimoku`,name:`Ichimoku Cloud`,type:`overlay`},{id:`psar`,name:`Parabolic SAR`,type:`overlay`},{id:`supertrend`,name:`Supertrend`,type:`overlay`},{id:`keltner`,name:`Keltner Channel`,type:`overlay`},{id:`donchian`,name:`Donchian Channel`,type:`overlay`},{id:`rsi`,name:`RSI`,type:`panel`},{id:`macd`,name:`MACD`,type:`panel`},{id:`stochastic`,name:`Stochastic`,type:`panel`},{id:`atr`,name:`ATR`,type:`panel`},{id:`adx`,name:`ADX`,type:`panel`},{id:`obv`,name:`OBV`,type:`panel`},{id:`williamsR`,name:`Williams %R`,type:`panel`},{id:`cci`,name:`CCI`,type:`panel`},{id:`mfi`,name:`MFI`,type:`panel`},{id:`roc`,name:`ROC`,type:`panel`},{id:`tsi`,name:`TSI`,type:`panel`},{id:`cmf`,name:`CMF`,type:`panel`},{id:`aroon`,name:`Aroon`,type:`panel`},{id:`stddev`,name:`Std Deviation`,type:`panel`},{id:`vroc`,name:`Volume ROC`,type:`panel`},{id:`ad`,name:`Acc/Dist`,type:`panel`},{id:`volumeProfile`,name:`Volume Profile`,type:`panel`}],o=[`sma`,`ema`,`bb`,`rsi`,`macd`,`stochastic`,`vwap`,`atr`,`obv`,`ichimoku`],s=[`BTCUSDT`,`ETHUSDT`,`SOLUSDT`,`BNBUSDT`],c={candleUpColor:`#26A69A`,candleDownColor:`#EF5350`,candleUpWick:`#26A69A`,candleDownWick:`#EF5350`,backgroundColor:`#131722`,gridColor:`#1E222D`,gridVisible:!0,volumeVisible:!0,legendVisible:!0,barCountdown:!0,logScale:!1,autoScale:!0,crosshairMode:`magnet`,numberLocale:`en-US`},l=`/* === TradeCanvas Widget Styles === */
2
-
3
- .tcw-root {
4
- display: flex;
5
- flex-direction: column;
6
- width: 100%;
7
- height: 100%;
8
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
9
- font-size: 13px;
10
- color: #d1d4dc;
11
- background: #131722;
12
- position: relative;
13
- overflow: hidden;
14
-
15
- /* Dark theme tokens (default) */
16
- --tcw-bg: #131722;
17
- --tcw-bg-elevated: #1E222D;
18
- --tcw-border: #2A2E39;
19
- --tcw-text: #d1d4dc;
20
- --tcw-text-dim: #b2b5be;
21
- --tcw-text-muted: #787b86;
22
- --tcw-accent: #2962ff;
23
- --tcw-accent-dim: rgba(41,98,255,0.15);
24
- --tcw-accent-glow: rgba(41,98,255,0.12);
25
- --tcw-red: #ef5350;
26
- --tcw-green: #26a69a;
27
- --tcw-transition: 0.15s ease;
28
- --tcw-radius-lg: 8px;
29
- --tcw-font-mono: 'SF Mono', 'Fira Code', 'Consolas', monospace;
30
- --tcw-hover-bg: rgba(255,255,255,0.04);
31
- }
32
-
33
- .tcw-root[data-tcw-theme="light"] {
34
- color: #131722;
35
- background: #ffffff;
36
-
37
- --tcw-bg: #ffffff;
38
- --tcw-bg-elevated: #f0f3fa;
39
- --tcw-border: #e0e3eb;
40
- --tcw-text: #131722;
41
- --tcw-text-dim: #434651;
42
- --tcw-text-muted: #787b86;
43
- --tcw-accent: #2962ff;
44
- --tcw-accent-dim: rgba(41,98,255,0.1);
45
- --tcw-accent-glow: rgba(41,98,255,0.08);
46
- --tcw-red: #ef5350;
47
- --tcw-green: #26a69a;
48
- --tcw-hover-bg: rgba(0,0,0,0.04);
49
- }
50
-
51
- /* === Toolbar === */
52
-
53
- .tcw-toolbar {
54
- display: flex;
55
- align-items: center;
56
- gap: 0;
57
- padding: 0 12px;
58
- height: 40px;
59
- border-bottom: 1px solid var(--tcw-border);
60
- background: var(--tcw-bg-elevated);
61
- flex-shrink: 0;
62
- position: relative;
63
- z-index: 20;
64
- }
65
-
66
- .tcw-toolbar-symbol {
67
- font-size: 13px;
68
- font-weight: 700;
69
- color: var(--tcw-text);
70
- padding: 0 10px;
71
- white-space: nowrap;
72
- letter-spacing: -0.01em;
73
- cursor: pointer;
74
- border: none;
75
- background: none;
76
- font-family: inherit;
77
- }
78
-
79
- .tcw-toolbar-sep {
80
- width: 1px;
81
- height: 20px;
82
- background: var(--tcw-border);
83
- flex-shrink: 0;
84
- }
85
-
86
- .tcw-toolbar-group {
87
- display: flex;
88
- align-items: center;
89
- gap: 2px;
90
- padding: 0 8px;
91
- }
92
-
93
- .tcw-toolbar-spacer {
94
- flex: 1;
95
- }
96
-
97
- .tcw-btn {
98
- padding: 4px 8px;
99
- font-size: 12px;
100
- font-family: inherit;
101
- border: none;
102
- border-radius: 4px;
103
- background: transparent;
104
- color: var(--tcw-text-dim);
105
- cursor: pointer;
106
- transition: all var(--tcw-transition);
107
- white-space: nowrap;
108
- line-height: 1;
109
- }
110
-
111
- .tcw-btn:hover {
112
- background: var(--tcw-hover-bg);
113
- color: var(--tcw-text);
114
- }
115
-
116
- .tcw-btn.tcw-active {
117
- background: var(--tcw-accent);
118
- color: white;
119
- }
120
-
121
- .tcw-btn-icon {
122
- width: 32px;
123
- height: 32px;
124
- display: inline-flex;
125
- align-items: center;
126
- justify-content: center;
127
- font-family: inherit;
128
- border: none;
129
- border-radius: 4px;
130
- background: transparent;
131
- color: var(--tcw-text-muted);
132
- cursor: pointer;
133
- transition: all var(--tcw-transition);
134
- line-height: 1;
135
- position: relative;
136
- }
137
-
138
- .tcw-btn-icon:hover {
139
- background: var(--tcw-hover-bg);
140
- color: var(--tcw-text);
141
- }
142
-
143
- .tcw-badge-count {
144
- font-size: 10px;
145
- color: var(--tcw-accent);
146
- background: var(--tcw-accent-dim);
147
- padding: 0 4px;
148
- border-radius: 8px;
149
- font-weight: 600;
150
- }
151
-
152
- .tcw-indicator-chips {
153
- display: flex;
154
- align-items: center;
155
- gap: 4px;
156
- padding: 0 4px;
157
- flex-wrap: nowrap;
158
- overflow: hidden;
159
- }
160
-
161
- .tcw-indicator-chip {
162
- display: inline-flex;
163
- align-items: center;
164
- gap: 4px;
165
- padding: 2px 6px 2px 8px;
166
- font-size: 11px;
167
- font-weight: 500;
168
- background: var(--tcw-accent-dim);
169
- color: var(--tcw-accent);
170
- border-radius: 4px;
171
- white-space: nowrap;
172
- line-height: 1.4;
173
- }
174
-
175
- .tcw-chip-remove {
176
- cursor: pointer;
177
- opacity: 0.6;
178
- padding: 0 2px;
179
- transition: opacity var(--tcw-transition);
180
- border: none;
181
- background: none;
182
- color: inherit;
183
- display: inline-flex;
184
- align-items: center;
185
- }
186
-
187
- .tcw-chip-remove:hover {
188
- opacity: 1;
189
- }
190
-
191
- /* === Dropdown === */
192
-
193
- .tcw-dropdown-trigger {
194
- display: inline-flex;
195
- align-items: center;
196
- gap: 4px;
197
- padding: 4px 8px;
198
- font-size: 12px;
199
- font-family: inherit;
200
- border: none;
201
- border-radius: 4px;
202
- background: transparent;
203
- color: var(--tcw-text-dim);
204
- cursor: pointer;
205
- transition: all var(--tcw-transition);
206
- white-space: nowrap;
207
- line-height: 1;
208
- }
209
-
210
- .tcw-dropdown-trigger:hover {
211
- background: var(--tcw-hover-bg);
212
- color: var(--tcw-text);
213
- }
214
-
215
- .tcw-dropdown {
216
- position: absolute;
217
- top: 100%;
218
- margin-top: 4px;
219
- background: var(--tcw-bg-elevated);
220
- border: 1px solid var(--tcw-border);
221
- border-radius: var(--tcw-radius-lg);
222
- box-shadow: 0 8px 32px rgba(0,0,0,0.4);
223
- z-index: 50;
224
- padding: 4px 0;
225
- max-height: 400px;
226
- overflow-y: auto;
227
- }
228
-
229
- .tcw-dropdown-item {
230
- display: flex;
231
- align-items: center;
232
- justify-content: space-between;
233
- padding: 6px 12px;
234
- font-size: 12px;
235
- color: var(--tcw-text-dim);
236
- cursor: pointer;
237
- transition: background var(--tcw-transition), color var(--tcw-transition);
238
- width: 100%;
239
- border: none;
240
- background: none;
241
- font-family: inherit;
242
- text-align: left;
243
- }
244
-
245
- .tcw-dropdown-item:hover {
246
- background: var(--tcw-hover-bg);
247
- color: var(--tcw-text);
248
- }
249
-
250
- .tcw-dropdown-item.tcw-active {
251
- color: var(--tcw-accent);
252
- }
253
-
254
- .tcw-dropdown-label {
255
- text-transform: uppercase;
256
- font-size: 10px;
257
- color: var(--tcw-text-muted);
258
- letter-spacing: 0.05em;
259
- padding: 6px 12px;
260
- font-weight: 600;
261
- }
262
-
263
- .tcw-dropdown-divider {
264
- border-top: 1px solid var(--tcw-border);
265
- margin: 4px 0;
266
- }
267
-
268
- .tcw-tag {
269
- font-size: 10px;
270
- color: var(--tcw-text-muted);
271
- padding: 1px 5px;
272
- border-radius: 3px;
273
- background: var(--tcw-hover-bg);
274
- }
275
-
276
- /* === Body === */
277
-
278
- .tcw-body {
279
- display: flex;
280
- flex: 1;
281
- min-height: 0;
282
- }
283
-
284
- .tcw-chart-container {
285
- flex: 1;
286
- min-width: 0;
287
- min-height: 0;
288
- width: 100%;
289
- height: 100%;
290
- }
291
-
292
- /* === Sidebar === */
293
-
294
- .tcw-sidebar {
295
- width: 36px;
296
- flex-shrink: 0;
297
- background: var(--tcw-bg-elevated);
298
- border-right: 1px solid var(--tcw-border);
299
- display: flex;
300
- flex-direction: column;
301
- align-items: center;
302
- padding: 4px 0;
303
- overflow: visible;
304
- }
305
-
306
- .tcw-tool-group-wrap {
307
- position: relative;
308
- }
309
-
310
- .tcw-sidebar-btn {
311
- width: 36px;
312
- height: 32px;
313
- display: flex;
314
- align-items: center;
315
- justify-content: center;
316
- border: none;
317
- background: transparent;
318
- color: var(--tcw-text-muted);
319
- cursor: pointer;
320
- font-family: inherit;
321
- transition: all var(--tcw-transition);
322
- position: relative;
323
- flex-shrink: 0;
324
- line-height: 1;
325
- }
326
-
327
- .tcw-sidebar-btn:hover {
328
- color: var(--tcw-text);
329
- background: var(--tcw-hover-bg);
330
- }
331
-
332
- .tcw-sidebar-btn.tcw-active {
333
- color: var(--tcw-accent);
334
- background: var(--tcw-accent-glow);
335
- }
336
-
337
- .tcw-sidebar-btn.tcw-danger:hover {
338
- color: var(--tcw-red);
339
- background: rgba(239,68,68,0.1);
340
- }
341
-
342
- .tcw-multi-dot {
343
- position: absolute;
344
- bottom: 2px;
345
- right: 2px;
346
- width: 4px;
347
- height: 4px;
348
- border-radius: 50%;
349
- background: var(--tcw-text-muted);
350
- }
351
-
352
- .tcw-sidebar-divider {
353
- width: 20px;
354
- height: 1px;
355
- background: var(--tcw-border);
356
- margin: 4px 0;
357
- flex-shrink: 0;
358
- }
359
-
360
- .tcw-sidebar-spacer {
361
- flex: 1;
362
- }
363
-
364
- /* === Flyout === */
365
-
366
- .tcw-flyout {
367
- position: absolute;
368
- left: 100%;
369
- top: 0;
370
- margin-left: 2px;
371
- min-width: 160px;
372
- background: var(--tcw-bg-elevated);
373
- border: 1px solid var(--tcw-border);
374
- border-radius: var(--tcw-radius-lg);
375
- box-shadow: 0 8px 32px rgba(0,0,0,0.4);
376
- z-index: 30;
377
- padding: 4px 0;
378
- }
379
-
380
- .tcw-flyout-header {
381
- text-transform: uppercase;
382
- font-size: 10px;
383
- color: var(--tcw-text-muted);
384
- letter-spacing: 0.05em;
385
- padding: 6px 12px;
386
- font-weight: 600;
387
- }
388
-
389
- .tcw-flyout-item {
390
- padding: 6px 12px;
391
- font-size: 12px;
392
- color: var(--tcw-text-dim);
393
- cursor: pointer;
394
- width: 100%;
395
- display: block;
396
- border: none;
397
- background: none;
398
- text-align: left;
399
- font-family: inherit;
400
- transition: background var(--tcw-transition), color var(--tcw-transition);
401
- }
402
-
403
- .tcw-flyout-item:hover {
404
- background: var(--tcw-hover-bg);
405
- color: var(--tcw-text);
406
- }
407
-
408
- .tcw-flyout-item.tcw-active {
409
- color: var(--tcw-accent);
410
- }
411
-
412
- /* === Modal === */
413
-
414
- .tcw-modal-backdrop {
415
- position: fixed;
416
- inset: 0;
417
- background: rgba(0,0,0,0.5);
418
- backdrop-filter: blur(4px);
419
- -webkit-backdrop-filter: blur(4px);
420
- z-index: 100;
421
- }
422
-
423
- .tcw-modal {
424
- position: fixed;
425
- z-index: 101;
426
- top: 50%;
427
- left: 50%;
428
- transform: translate(-50%, -50%);
429
- background: var(--tcw-bg-elevated);
430
- border: 1px solid var(--tcw-border);
431
- border-radius: var(--tcw-radius-lg);
432
- width: 480px;
433
- max-width: 90vw;
434
- max-height: 80vh;
435
- display: flex;
436
- flex-direction: column;
437
- box-shadow: 0 24px 64px rgba(0,0,0,0.5);
438
- }
439
-
440
- .tcw-modal-header {
441
- display: flex;
442
- align-items: center;
443
- justify-content: space-between;
444
- padding: 16px 20px;
445
- border-bottom: 1px solid var(--tcw-border);
446
- }
447
-
448
- .tcw-modal-header h3 {
449
- font-size: 15px;
450
- font-weight: 600;
451
- margin: 0;
452
- color: var(--tcw-text);
453
- }
454
-
455
- .tcw-modal-close {
456
- width: 28px;
457
- height: 28px;
458
- display: flex;
459
- align-items: center;
460
- justify-content: center;
461
- border: none;
462
- background: transparent;
463
- color: var(--tcw-text-muted);
464
- cursor: pointer;
465
- border-radius: 4px;
466
- transition: all var(--tcw-transition);
467
- }
468
-
469
- .tcw-modal-close:hover {
470
- background: var(--tcw-hover-bg);
471
- color: var(--tcw-text);
472
- }
473
-
474
- .tcw-modal-tabs {
475
- display: flex;
476
- gap: 0;
477
- padding: 0 20px;
478
- border-bottom: 1px solid var(--tcw-border);
479
- }
480
-
481
- .tcw-modal-tab {
482
- padding: 10px 16px;
483
- font-size: 12px;
484
- font-weight: 500;
485
- color: var(--tcw-text-muted);
486
- border: none;
487
- background: none;
488
- cursor: pointer;
489
- border-bottom: 2px solid transparent;
490
- margin-bottom: -1px;
491
- transition: color var(--tcw-transition);
492
- font-family: inherit;
493
- text-transform: capitalize;
494
- }
495
-
496
- .tcw-modal-tab:hover {
497
- color: var(--tcw-text-dim);
498
- }
499
-
500
- .tcw-modal-tab.tcw-active {
501
- color: var(--tcw-accent);
502
- border-bottom-color: var(--tcw-accent);
503
- }
504
-
505
- .tcw-modal-body {
506
- padding: 20px;
507
- overflow-y: auto;
508
- flex: 1;
509
- }
510
-
511
- .tcw-settings-section {
512
- margin-bottom: 20px;
513
- }
514
-
515
- .tcw-settings-section:last-child {
516
- margin-bottom: 0;
517
- }
518
-
519
- .tcw-settings-section-title {
520
- font-size: 11px;
521
- font-weight: 600;
522
- text-transform: uppercase;
523
- letter-spacing: 0.05em;
524
- color: var(--tcw-text-muted);
525
- margin-bottom: 12px;
526
- }
527
-
528
- .tcw-settings-row {
529
- display: flex;
530
- align-items: center;
531
- justify-content: space-between;
532
- padding: 8px 0;
533
- }
534
-
535
- .tcw-settings-row + .tcw-settings-row {
536
- border-top: 1px solid rgba(255,255,255,0.03);
537
- }
538
-
539
- .tcw-root[data-tcw-theme="light"] .tcw-settings-row + .tcw-settings-row {
540
- border-top: 1px solid rgba(0,0,0,0.04);
541
- }
542
-
543
- .tcw-settings-label {
544
- font-size: 13px;
545
- color: var(--tcw-text-dim);
546
- }
547
-
548
- .tcw-color-picker-wrap {
549
- display: flex;
550
- align-items: center;
551
- gap: 6px;
552
- }
553
-
554
- .tcw-color-picker-wrap input[type='color'] {
555
- width: 28px;
556
- height: 28px;
557
- border: 1px solid var(--tcw-border);
558
- border-radius: 4px;
559
- background: none;
560
- cursor: pointer;
561
- padding: 2px;
562
- }
563
-
564
- .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {
565
- padding: 0;
566
- }
567
-
568
- .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {
569
- border: none;
570
- border-radius: 2px;
571
- }
572
-
573
- .tcw-color-hex {
574
- font-size: 11px;
575
- font-family: var(--tcw-font-mono);
576
- color: var(--tcw-text-muted);
577
- min-width: 60px;
578
- }
579
-
580
- .tcw-toggle {
581
- width: 36px;
582
- height: 20px;
583
- background: rgba(255,255,255,0.1);
584
- border-radius: 10px;
585
- position: relative;
586
- cursor: pointer;
587
- transition: background var(--tcw-transition);
588
- border: none;
589
- padding: 0;
590
- flex-shrink: 0;
591
- }
592
-
593
- .tcw-toggle::after {
594
- content: '';
595
- position: absolute;
596
- top: 2px;
597
- left: 2px;
598
- width: 16px;
599
- height: 16px;
600
- border-radius: 50%;
601
- background: var(--tcw-text-muted);
602
- transition: all var(--tcw-transition);
603
- }
604
-
605
- .tcw-toggle.tcw-on {
606
- background: var(--tcw-accent);
607
- }
608
-
609
- .tcw-toggle.tcw-on::after {
610
- left: 18px;
611
- background: white;
612
- }
613
-
614
- .tcw-root[data-tcw-theme="light"] .tcw-toggle {
615
- background: rgba(0,0,0,0.1);
616
- }
617
-
618
- .tcw-root[data-tcw-theme="light"] .tcw-toggle::after {
619
- background: #888;
620
- }
621
-
622
- .tcw-root[data-tcw-theme="light"] .tcw-toggle.tcw-on {
623
- background: var(--tcw-accent);
624
- }
625
-
626
- .tcw-root[data-tcw-theme="light"] .tcw-toggle.tcw-on::after {
627
- background: white;
628
- }
629
-
630
- .tcw-settings-select {
631
- padding: 4px 8px;
632
- font-size: 12px;
633
- font-family: inherit;
634
- background: var(--tcw-bg);
635
- border: 1px solid var(--tcw-border);
636
- border-radius: 4px;
637
- color: var(--tcw-text);
638
- cursor: pointer;
639
- }
640
-
641
- .tcw-modal-footer {
642
- display: flex;
643
- align-items: center;
644
- justify-content: space-between;
645
- padding: 12px 20px;
646
- border-top: 1px solid var(--tcw-border);
647
- }
648
-
649
- .tcw-reset-link {
650
- font-size: 12px;
651
- color: var(--tcw-text-muted);
652
- cursor: pointer;
653
- border: none;
654
- background: none;
655
- font-family: inherit;
656
- text-decoration: underline;
657
- text-underline-offset: 2px;
658
- transition: color var(--tcw-transition);
659
- }
660
-
661
- .tcw-reset-link:hover {
662
- color: var(--tcw-text-dim);
663
- }
664
-
665
- .tcw-done-btn {
666
- padding: 6px 16px;
667
- font-size: 12px;
668
- font-weight: 500;
669
- background: var(--tcw-accent);
670
- color: white;
671
- border: none;
672
- border-radius: 4px;
673
- cursor: pointer;
674
- font-family: inherit;
675
- transition: background var(--tcw-transition);
676
- }
677
-
678
- .tcw-done-btn:hover {
679
- background: #2563eb;
680
- }
681
-
682
- /* === Status Bar === */
683
-
684
- .tcw-statusbar {
685
- display: flex;
686
- align-items: center;
687
- justify-content: space-between;
688
- padding: 6px 16px;
689
- border-top: 1px solid var(--tcw-border);
690
- background: var(--tcw-bg-elevated);
691
- font-size: 11px;
692
- color: var(--tcw-text-muted);
693
- flex-shrink: 0;
694
- }
695
-
696
- .tcw-status-indicator {
697
- display: flex;
698
- align-items: center;
699
- gap: 6px;
700
- }
701
-
702
- .tcw-status-dot {
703
- width: 6px;
704
- height: 6px;
705
- border-radius: 50%;
706
- background: var(--tcw-text-muted);
707
- transition: background 0.3s;
708
- }
709
-
710
- .tcw-status-dot.tcw-connected {
711
- background: var(--tcw-green);
712
- }
713
-
714
- .tcw-status-dot.tcw-error {
715
- background: var(--tcw-red);
716
- }
717
-
718
- /* === Responsive === */
719
-
720
- @media (max-width: 768px) {
721
- .tcw-toolbar {
722
- padding: 0 8px;
723
- height: 36px;
724
- }
725
- .tcw-toolbar-sep {
726
- display: none;
727
- }
728
- .tcw-indicator-chips {
729
- display: none;
730
- }
731
- .tcw-sidebar {
732
- width: 32px;
733
- }
734
- .tcw-sidebar-btn {
735
- width: 32px;
736
- height: 28px;
737
- }
738
- }
739
- `,u=0,d=`tcw-styles`;function f(){if(u++,u>1||document.getElementById(d))return;let e=document.createElement(`style`);e.id=d,e.textContent=l,document.head.appendChild(e)}function p(){if(u--,u>0)return;let e=document.getElementById(d);e&&e.remove()}var m={cursor:`<path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/>`,trendingUp:`<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>`,minus:`<path d="M5 12h14"/>`,penLine:`<path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/>`,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"/>`,square:`<rect width="18" height="18" x="3" y="3" rx="2"/>`,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"/>`,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"/>`,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"/>`,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"/>`,undo:`<path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/>`,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"/>`,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"/>`,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"/>`,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"/>`,moon:`<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>`,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"/>`,chevronDown:`<path d="m6 9 6 6 6-6"/>`,chevronUp:`<path d="m18 15-6-6-6 6"/>`,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"/>`,x:`<path d="M18 6 6 18"/><path d="m6 6 12 12"/>`,play:`<polygon points="6 3 20 12 6 21 6 3"/>`,pause:`<rect width="4" height="16" x="6" y="4"/><rect width="4" height="16" x="14" y="4"/>`,stop:`<rect width="14" height="14" x="5" y="5" rx="1"/>`,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"/>`};function h(e,t=14){let n=m[e];return n?`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n}</svg>`:``}var g=class{trigger;panel;_isOpen=!1;onOutsideClick;onEscapeKey;onTriggerClick;constructor(e,t={}){this.trigger=e,this.panel=document.createElement(`div`),this.panel.className=`tcw-dropdown`,this.panel.style.width=t.width??`200px`,t.align===`right`?this.panel.style.right=`0`:this.panel.style.left=`0`,this.panel.style.display=`none`,e.style.position=`relative`,e.appendChild(this.panel),this.onTriggerClick=()=>{this._isOpen?this.close():this.open()},this.onOutsideClick=e=>{this.trigger.contains(e.target)||this.close()},this.onEscapeKey=e=>{e.key===`Escape`&&this.close()},e.addEventListener(`click`,this.onTriggerClick)}setContent(e){this.panel.innerHTML=e}open(){this._isOpen||(this._isOpen=!0,this.panel.style.display=``,document.addEventListener(`mousedown`,this.onOutsideClick),document.addEventListener(`keydown`,this.onEscapeKey))}close(){this._isOpen&&(this._isOpen=!1,this.panel.style.display=`none`,document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey))}isOpen(){return this._isOpen}destroy(){this.trigger.removeEventListener(`click`,this.onTriggerClick),document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey),this.panel.remove()}},_=class{config;callbacks;el;chartTypeDropdown=null;indicatorDropdown=null;tfButtons=[];chipsContainer=null;themeBtn=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-toolbar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this,r=document.createElement(`button`);r.className=`tcw-toolbar-symbol`,r.dataset.role=`symbol`,r.addEventListener(`click`,t.onSymbolClick),n.appendChild(r),n.appendChild(this.sep());let i=document.createElement(`div`);i.className=`tcw-toolbar-group`;for(let n of e.timeframes){let e=document.createElement(`button`);e.className=`tcw-btn`,e.textContent=n.label,e.dataset.tf=n.value,e.addEventListener(`click`,()=>t.onTimeframe(n.value)),i.appendChild(e),this.tfButtons.push(e)}n.appendChild(i),n.appendChild(this.sep());let a=document.createElement(`div`);a.style.position=`relative`,a.style.display=`inline-flex`;let o=document.createElement(`button`);o.className=`tcw-dropdown-trigger`,o.dataset.role=`charttype`,a.appendChild(o),n.appendChild(a),this.chartTypeDropdown=new g(a,{width:`160px`}),this.buildChartTypeMenu(),n.appendChild(this.sep());let s=document.createElement(`div`);s.style.position=`relative`,s.style.display=`inline-flex`;let c=document.createElement(`button`);c.className=`tcw-dropdown-trigger`,c.dataset.role=`indicators`,s.appendChild(c),n.appendChild(s),this.indicatorDropdown=new g(s,{width:`280px`}),this.buildIndicatorMenu(),this.chipsContainer=document.createElement(`div`),this.chipsContainer.className=`tcw-indicator-chips`,n.appendChild(this.chipsContainer),n.appendChild(this.spacer());let l=this.iconBtn(`camera`,`Screenshot`,t.onScreenshot);n.appendChild(l);let u=this.iconBtn(`settings`,`Chart Settings`,t.onSettings);n.appendChild(u),this.themeBtn=this.iconBtn(`moon`,`Toggle theme`,t.onToggleTheme),this.themeBtn.dataset.role=`theme`,n.appendChild(this.themeBtn)}buildChartTypeMenu(){if(!this.chartTypeDropdown)return;let e=this.config.chartTypes.map(e=>`<button class="tcw-dropdown-item" data-ct="${e.value}">${e.label}</button>`).join(``);this.chartTypeDropdown.setContent(e),this.chartTypeDropdown.panel.querySelectorAll(`.tcw-dropdown-item`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ct;this.callbacks.onChartType(t),this.chartTypeDropdown?.close()})})}buildIndicatorMenu(){if(!this.indicatorDropdown)return;let{indicators:e,popularIndicatorIds:t}=this.config,n=e.filter(e=>t.includes(e.id)),r=e.filter(e=>!t.includes(e.id)),i=`<div class="tcw-dropdown-label">Popular</div>`;for(let e of n)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;i+=`<div class="tcw-dropdown-divider"></div>`,i+=`<div class="tcw-dropdown-label">All</div>`;for(let e of r)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;this.indicatorDropdown.setContent(i),this.indicatorDropdown.panel.querySelectorAll(`.tcw-dropdown-item[data-ind]`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ind;this.callbacks.onAddIndicator(t)})})}update(e){let t=this.el.querySelector(`[data-role="symbol"]`);t&&(t.textContent=e.symbol);for(let t of this.tfButtons)t.classList.toggle(`tcw-active`,t.dataset.tf===e.timeframe);let n=this.el.querySelector(`[data-role="charttype"]`);if(n){let t=this.config.chartTypes.find(t=>t.value===e.chartType)?.label??`Candles`;n.innerHTML=`${h(`barChart`,14)} ${t} ${h(`chevronDown`,12)}`}let r=this.el.querySelector(`[data-role="indicators"]`);if(r){let t=e.activeIndicators.size,n=`${h(`trendingUp`,14)} Indicators`;t>0&&(n+=` <span class="tcw-badge-count">${t}</span>`),r.innerHTML=n}if(this.chipsContainer){let t=this.getActiveIndicatorList(e);this.chipsContainer.innerHTML=``;for(let e of t){let t=document.createElement(`div`);t.className=`tcw-indicator-chip`;let n=document.createElement(`span`);n.textContent=e.label,t.appendChild(n);let r=document.createElement(`button`);r.className=`tcw-chip-remove`,r.innerHTML=h(`x`,10),r.addEventListener(`click`,()=>this.callbacks.onRemoveIndicator(e.instanceId)),t.appendChild(r),this.chipsContainer.appendChild(t)}}this.themeBtn&&(this.themeBtn.innerHTML=e.isDark?h(`moon`,14):h(`sun`,14))}getActiveIndicatorList(e){let t=[];for(let[n,r]of e.activeIndicators.entries())t.push({instanceId:r,id:n,label:n.toUpperCase()});return t}sep(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-sep`,e}spacer(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-spacer`,e}iconBtn(e,t,n){let r=document.createElement(`button`);return r.className=`tcw-btn-icon`,r.title=t,r.innerHTML=h(e,14),r.addEventListener(`click`,n),r}destroy(){this.chartTypeDropdown?.destroy(),this.indicatorDropdown?.destroy(),this.el.remove()}},v=[`trendingUp`,`minus`,`penLine`,`hash`,`square`,`gitBranch`,`ruler`,`type`],y=class{config;callbacks;el;groupWraps=[];groupButtons=[];cursorBtn=null;magnetBtn=null;flyoutEl=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-sidebar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this;this.cursorBtn=document.createElement(`button`),this.cursorBtn.className=`tcw-sidebar-btn`,this.cursorBtn.title=`Cursor`,this.cursorBtn.innerHTML=h(`cursor`,14),this.cursorBtn.addEventListener(`click`,t.onCancelDrawing),n.appendChild(this.cursorBtn),n.appendChild(this.divider()),e.drawingToolGroups.forEach((e,r)=>{let i=document.createElement(`div`);i.className=`tcw-tool-group-wrap`;let a=document.createElement(`button`);if(a.className=`tcw-sidebar-btn`,a.title=e.label,a.innerHTML=h(v[r]??`square`,14),e.tools.length>1){let e=document.createElement(`span`);e.className=`tcw-multi-dot`,a.appendChild(e)}a.addEventListener(`click`,()=>t.onDrawingTool(e.tools[0].value)),i.appendChild(a),i.addEventListener(`mouseenter`,()=>this.showFlyout(r)),i.addEventListener(`mouseleave`,()=>this.hideFlyout()),n.appendChild(i),this.groupWraps.push(i),this.groupButtons.push(a)});let r=document.createElement(`div`);r.className=`tcw-sidebar-spacer`,n.appendChild(r),n.appendChild(this.divider()),this.magnetBtn=document.createElement(`button`),this.magnetBtn.className=`tcw-sidebar-btn`,this.magnetBtn.title=`Magnet`,this.magnetBtn.innerHTML=h(`magnet`,14),this.magnetBtn.addEventListener(`click`,t.onToggleMagnet),n.appendChild(this.magnetBtn);let i=document.createElement(`button`);i.className=`tcw-sidebar-btn`,i.title=`Undo`,i.innerHTML=h(`undo`,14),i.addEventListener(`click`,t.onUndo),n.appendChild(i);let a=document.createElement(`button`);a.className=`tcw-sidebar-btn`,a.title=`Redo`,a.innerHTML=h(`redo`,14),a.addEventListener(`click`,t.onRedo),n.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-sidebar-btn tcw-danger`,o.title=`Clear all`,o.innerHTML=h(`trash`,14),o.addEventListener(`click`,t.onClearDrawings),n.appendChild(o)}showFlyout(e){let t=this.config.drawingToolGroups[e];if(!t||t.tools.length<=1)return;this.hideFlyout();let n=document.createElement(`div`);n.className=`tcw-flyout`;let r=document.createElement(`div`);r.className=`tcw-flyout-header`,r.textContent=t.label,n.appendChild(r);for(let e of t.tools){let t=document.createElement(`button`);t.className=`tcw-flyout-item`,t.textContent=e.label,t.dataset.toolValue=e.value,t.addEventListener(`click`,()=>{this.callbacks.onDrawingTool(e.value),this.hideFlyout()}),n.appendChild(t)}this.flyoutEl=n,this.groupWraps[e].appendChild(n)}hideFlyout(){this.flyoutEl&&=(this.flyoutEl.remove(),null)}update(e){this.cursorBtn&&this.cursorBtn.classList.toggle(`tcw-active`,e.activeTool===null);let{drawingToolGroups:t}=this.config;for(let n=0;n<t.length;n++){let r=t[n].tools.some(t=>t.value===e.activeTool);this.groupButtons[n].classList.toggle(`tcw-active`,r)}this.flyoutEl&&this.flyoutEl.querySelectorAll(`.tcw-flyout-item`).forEach(t=>{let n=t;n.classList.toggle(`tcw-active`,n.dataset.toolValue===e.activeTool)}),this.magnetBtn&&(this.magnetBtn.classList.toggle(`tcw-active`,e.magnetEnabled),this.magnetBtn.title=e.magnetEnabled?`Magnet ON`:`Magnet OFF`)}divider(){let e=document.createElement(`div`);return e.className=`tcw-sidebar-divider`,e}destroy(){this.hideFlyout(),this.el.remove()}},b=[`style`,`display`,`scale`],x=class{callbacks;backdrop=null;modal=null;currentTab=`style`;currentSettings=null;bodyEl=null;tabButtons=[];constructor(e){this.callbacks=e}open(e){this.currentSettings={...e},this.currentTab=`style`,this.buildModal()}close(){this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.bodyEl=null,this.tabButtons=[]}buildModal(){this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),document.body.appendChild(this.backdrop),this.modal=document.createElement(`div`),this.modal.className=`tcw-modal`;let e=document.createElement(`div`);e.className=`tcw-modal-header`;let t=document.createElement(`h3`);t.textContent=`Chart Settings`,e.appendChild(t);let n=document.createElement(`button`);n.className=`tcw-modal-close`,n.innerHTML=h(`x`,16),n.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),e.appendChild(n),this.modal.appendChild(e);let r=document.createElement(`div`);r.className=`tcw-modal-tabs`,this.tabButtons=[];for(let e of b){let t=document.createElement(`button`);t.className=`tcw-modal-tab`,t.textContent=e,t.dataset.tab=e,e===this.currentTab&&t.classList.add(`tcw-active`),t.addEventListener(`click`,()=>{this.currentTab=e,this.tabButtons.forEach(t=>t.classList.toggle(`tcw-active`,t.dataset.tab===e)),this.renderTabContent()}),r.appendChild(t),this.tabButtons.push(t)}this.modal.appendChild(r),this.bodyEl=document.createElement(`div`),this.bodyEl.className=`tcw-modal-body`,this.modal.appendChild(this.bodyEl),this.renderTabContent();let i=document.createElement(`div`);i.className=`tcw-modal-footer`;let a=document.createElement(`button`);a.className=`tcw-reset-link`,a.textContent=`Reset to defaults`,a.addEventListener(`click`,()=>this.callbacks.onReset()),i.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-done-btn`,o.textContent=`Done`,o.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),i.appendChild(o),this.modal.appendChild(i),document.body.appendChild(this.modal);let s=e=>{e.key===`Escape`&&(document.removeEventListener(`keydown`,s),this.callbacks.onClose(),this.close())};document.addEventListener(`keydown`,s)}renderTabContent(){if(!(!this.bodyEl||!this.currentSettings))switch(this.bodyEl.innerHTML=``,this.currentTab){case`style`:this.renderStyleTab();break;case`display`:this.renderDisplayTab();break;case`scale`:this.renderScaleTab();break}}renderStyleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section(`Candle Colors`);t.appendChild(this.colorRow(`Up Body`,e.candleUpColor,e=>this.patch({candleUpColor:e}))),t.appendChild(this.colorRow(`Down Body`,e.candleDownColor,e=>this.patch({candleDownColor:e}))),t.appendChild(this.colorRow(`Up Wick`,e.candleUpWick,e=>this.patch({candleUpWick:e}))),t.appendChild(this.colorRow(`Down Wick`,e.candleDownWick,e=>this.patch({candleDownWick:e}))),this.bodyEl.appendChild(t);let n=this.section(`Background`);n.appendChild(this.colorRow(`Background`,e.backgroundColor,e=>this.patch({backgroundColor:e}))),n.appendChild(this.colorRow(`Grid`,e.gridColor,e=>this.patch({gridColor:e}))),this.bodyEl.appendChild(n)}renderDisplayTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Grid Lines`,e.gridVisible,e=>this.patch({gridVisible:e}))),t.appendChild(this.toggleRow(`Volume`,e.volumeVisible,e=>this.patch({volumeVisible:e}))),t.appendChild(this.toggleRow(`OHLC Legend`,e.legendVisible,e=>this.patch({legendVisible:e}))),t.appendChild(this.toggleRow(`Bar Countdown`,e.barCountdown,e=>this.patch({barCountdown:e}))),t.appendChild(this.selectRow(`Crosshair Mode`,e.crosshairMode,[{label:`Magnet`,value:`magnet`},{label:`Normal`,value:`normal`},{label:`Hidden`,value:`hidden`}],e=>this.patch({crosshairMode:e}))),t.appendChild(this.selectRow(`Number Locale`,e.numberLocale,[{label:`en-US (65,234.00)`,value:`en-US`},{label:`de-DE (65.234,00)`,value:`de-DE`},{label:`fr-FR (65 234,00)`,value:`fr-FR`},{label:`vi-VN (65.234,00)`,value:`vi-VN`},{label:`en-IN (65,234.00)`,value:`en-IN`},{label:`ja-JP (65,234.00)`,value:`ja-JP`}],e=>this.patch({numberLocale:e}))),this.bodyEl.appendChild(t)}renderScaleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Auto Scale`,e.autoScale,e=>this.patch({autoScale:e}))),t.appendChild(this.toggleRow(`Log Scale`,e.logScale,e=>this.patch({logScale:e}))),this.bodyEl.appendChild(t)}patch(e){this.currentSettings&&Object.assign(this.currentSettings,e),this.callbacks.onChange(e)}section(e){let t=document.createElement(`div`);if(t.className=`tcw-settings-section`,e){let n=document.createElement(`div`);n.className=`tcw-settings-section-title`,n.textContent=e,t.appendChild(n)}return t}colorRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`div`);a.className=`tcw-color-picker-wrap`;let o=document.createElement(`input`);o.type=`color`,o.value=t;let s=document.createElement(`span`);return s.className=`tcw-color-hex`,s.textContent=t,o.addEventListener(`input`,()=>{s.textContent=o.value,n(o.value)}),a.appendChild(o),a.appendChild(s),r.appendChild(a),r}toggleRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`button`);return a.className=`tcw-toggle${t?` tcw-on`:``}`,a.addEventListener(`click`,()=>{let e=!a.classList.contains(`tcw-on`);a.classList.toggle(`tcw-on`,e),n(e)}),r.appendChild(a),r}selectRow(e,t,n,r){let i=document.createElement(`div`);i.className=`tcw-settings-row`;let a=document.createElement(`span`);a.className=`tcw-settings-label`,a.textContent=e,i.appendChild(a);let o=document.createElement(`select`);o.className=`tcw-settings-select`;for(let e of n){let n=document.createElement(`option`);n.value=e.value,n.textContent=e.label,e.value===t&&(n.selected=!0),o.appendChild(n)}return o.addEventListener(`change`,()=>r(o.value)),i.appendChild(o),i}destroy(){this.close()}},S=class{el;dotEl;messageEl;infoEl;constructor(e){this.el=document.createElement(`div`),this.el.className=`tcw-statusbar`;let t=document.createElement(`div`);t.className=`tcw-status-indicator`,this.dotEl=document.createElement(`span`),this.dotEl.className=`tcw-status-dot`,t.appendChild(this.dotEl),this.messageEl=document.createElement(`span`),t.appendChild(this.messageEl),this.el.appendChild(t),this.infoEl=document.createElement(`span`),this.el.appendChild(this.infoEl),e.appendChild(this.el)}update(e){this.dotEl.className=`tcw-status-dot`,e.connectionState===`connected`?this.dotEl.classList.add(`tcw-connected`):e.connectionState===`error`&&this.dotEl.classList.add(`tcw-error`),this.messageEl.textContent=e.message,this.infoEl.textContent=`${e.symbol} ${e.timeframe}`}destroy(){this.el.remove()}},C=class{chart;state;toolbar=null;sidebar=null;settings=null;statusBar=null;root;chartContainer;destroyed=!1;options;symbolIndex=0;symbols;settingsState;adapter=null;constructor(t,l={}){this.options=l,this.symbols=l.symbols??s,this.settingsState={...c};let u=this.resolveIsDark(l.theme),d=this.resolveTheme(l.theme);this.state={symbol:l.symbol??this.symbols[0]??`BTCUSDT`,timeframe:l.timeframe??`5m`,chartType:l.chartOptions?.chartType??`candlestick`,isDark:u,activeIndicators:new Map,activeTool:null,magnetEnabled:!0,connectionState:`connecting`,connectionMessage:`Connecting...`};let p=this.symbols.indexOf(this.state.symbol);p>=0&&(this.symbolIndex=p),f(),this.root=document.createElement(`div`),this.root.className=`tcw-root`,this.root.dataset.tcwTheme=u?`dark`:`light`,t.appendChild(this.root),l.toolbar!==!1&&(this.toolbar=new _(this.root,{symbols:this.symbols,timeframes:l.timeframes?n.filter(e=>l.timeframes.includes(e.value)):n,chartTypes:l.chartTypes?r.filter(e=>l.chartTypes.includes(e.value)):r,indicators:a,popularIndicatorIds:o},{onSymbolClick:()=>this.handleSymbolClick(),onTimeframe:e=>this.handleTimeframe(e),onChartType:e=>this.handleChartType(e),onAddIndicator:e=>this.handleAddIndicator(e),onRemoveIndicator:e=>this.handleRemoveIndicator(e),onScreenshot:()=>this.chart.screenshot(),onSettings:()=>this.openSettings(),onToggleTheme:()=>this.handleToggleTheme()}));let m=document.createElement(`div`);m.className=`tcw-body`,l.drawingTools!==!1&&(this.sidebar=new y(m,{drawingToolGroups:i},{onDrawingTool:e=>this.handleDrawingTool(e),onCancelDrawing:()=>this.handleCancelDrawing(),onToggleMagnet:()=>this.handleToggleMagnet(),onUndo:()=>this.chart.undo(),onRedo:()=>this.chart.redo(),onClearDrawings:()=>{this.chart.clearDrawings(),this.state={...this.state,activeTool:null},this.updateUI()}})),this.chartContainer=document.createElement(`div`),this.chartContainer.className=`tcw-chart-container`,m.appendChild(this.chartContainer),this.root.appendChild(m),this.chart=new e.t(this.chartContainer,{chartType:this.state.chartType,theme:d,autoScale:!0,crosshair:{mode:`magnet`},features:{drawings:!0,drawingMagnet:!0,drawingUndoRedo:!0,indicators:!0,trading:l.trading!==!1,tradingContextMenu:l.trading!==!1,volume:!0,legend:!0,crosshair:!0,keyboard:!0,screenshot:!0,alerts:!0,barCountdown:!0,logScale:!0,watermark:!0},...l.chartOptions}),l.statusBar!==!1&&(this.statusBar=new S(this.root)),l.settings!==!1&&(this.settings=new x({onChange:e=>this.applySettings(e),onReset:()=>this.resetSettings(),onClose:()=>{}})),l.adapter&&(this.adapter=l.adapter,this.connectStream()),this.updateUI(),l.onReady?.(this.chart)}async setSymbol(e){this.state={...this.state,symbol:e};let t=this.symbols.indexOf(e);t>=0&&(this.symbolIndex=t),this.options.onSymbolChange?.(e),this.updateUI(),this.adapter&&await this.connectStream()}async setTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&await this.connectStream()}setTheme(e){let t=this.resolveIsDark(e),n=this.resolveTheme(e);this.state={...this.state,isDark:t},this.root.dataset.tcwTheme=t?`dark`:`light`,this.chart.setTheme(n),this.updateUI()}getChart(){return this.chart}destroy(){this.destroyed||(this.destroyed=!0,this.toolbar?.destroy(),this.sidebar?.destroy(),this.settings?.destroy(),this.statusBar?.destroy(),this.chart.destroy(),this.root.remove(),p())}handleSymbolClick(){this.symbolIndex=(this.symbolIndex+1)%this.symbols.length;let e=this.symbols[this.symbolIndex];this.state={...this.state,symbol:e},this.options.onSymbolChange?.(e),this.updateUI(),this.adapter&&this.connectStream()}handleTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&this.connectStream()}handleChartType(e){this.state={...this.state,chartType:e},this.chart.setChartType(e),this.updateUI()}handleAddIndicator(e){if(this.state.activeIndicators.has(e)){let t=this.state.activeIndicators.get(e);this.chart.removeIndicator(t);let n=new Map(this.state.activeIndicators);n.delete(e),this.state={...this.state,activeIndicators:n}}else{let t=this.chart.addIndicator(e);if(t){let n=new Map(this.state.activeIndicators);n.set(e,t),this.state={...this.state,activeIndicators:n}}}this.updateUI()}handleRemoveIndicator(e){this.chart.removeIndicator(e);let t=new Map(this.state.activeIndicators);for(let[n,r]of t.entries())if(r===e){t.delete(n);break}this.state={...this.state,activeIndicators:t},this.updateUI()}handleDrawingTool(e){this.state={...this.state,activeTool:e},this.chart.setDrawingTool(e),this.updateUI()}handleCancelDrawing(){this.state={...this.state,activeTool:null},this.chart.setDrawingTool(null),this.updateUI()}handleToggleMagnet(){let e=!this.state.magnetEnabled;this.state={...this.state,magnetEnabled:e},this.chart.setDrawingMagnet(e),this.updateUI()}handleToggleTheme(){let e=!this.state.isDark;this.state={...this.state,isDark:e},this.root.dataset.tcwTheme=e?`dark`:`light`,this.chart.setTheme(e?t.DARK_THEME:t.LIGHT_THEME),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:e?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.updateUI()}openSettings(){this.settings?.open(this.settingsState)}applySettings(e){this.settingsState={...this.settingsState,...e},e.gridVisible!==void 0&&this.chart.setGridVisible(e.gridVisible),e.volumeVisible!==void 0&&this.chart.setVolumeVisible(e.volumeVisible),e.crosshairMode!==void 0&&this.chart.setCrosshairMode(e.crosshairMode),e.autoScale!==void 0&&this.chart.setAutoScale(e.autoScale),e.logScale!==void 0&&this.chart.setLogScale(e.logScale),e.numberLocale!==void 0&&this.chart.setNumberLocale(e.numberLocale);let t={...this.chart.getTheme()},n=!1;e.candleUpColor!==void 0&&(t.candleUp=e.candleUpColor,n=!0),e.candleDownColor!==void 0&&(t.candleDown=e.candleDownColor,n=!0),e.candleUpWick!==void 0&&(t.candleUpWick=e.candleUpWick,n=!0),e.candleDownWick!==void 0&&(t.candleDownWick=e.candleDownWick,n=!0),e.backgroundColor!==void 0&&(t.background=e.backgroundColor,n=!0),e.gridColor!==void 0&&(t.grid=e.gridColor,n=!0),n&&this.chart.setTheme(t)}resetSettings(){this.settingsState={...c},this.applySettings(this.settingsState)}async connectStream(){if(this.adapter){this.state={...this.state,connectionState:`connecting`,connectionMessage:`Connecting...`},this.updateUI();try{this.chart.disconnectStream(),await this.chart.connect({adapter:this.adapter,symbol:this.state.symbol,timeframe:this.state.timeframe,historyLimit:this.options.historyLimit??500}),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:this.state.isDark?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.state={...this.state,connectionState:`connected`,connectionMessage:`Live`}}catch(e){this.state={...this.state,connectionState:`error`,connectionMessage:e instanceof Error?e.message:`Connection failed`}}this.updateUI()}}updateUI(){this.toolbar?.update(this.state),this.sidebar?.update(this.state),this.statusBar?.update({connectionState:this.state.connectionState,message:this.state.connectionMessage,symbol:this.state.symbol,timeframe:this.state.timeframe})}resolveIsDark(e){return e===void 0||e===`dark`?!0:e===`light`?!1:typeof e==`object`&&e.background?this.isColorDark(e.background):!0}resolveTheme(e){return e===void 0||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:typeof e==`object`?e:t.DARK_THEME}isColorDark(e){if(e.startsWith(`#`)&&e.length>=7){let t=parseInt(e.slice(1,3),16),n=parseInt(e.slice(3,5),16),r=parseInt(e.slice(5,7),16);return t+n+r<384}return!0}};exports.ChartWidget=C;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../Chart-0R7hFD6z.cjs`);let t=require(`@tradecanvas/commons`);var n=[{label:`1m`,value:`1m`},{label:`5m`,value:`5m`},{label:`15m`,value:`15m`},{label:`1H`,value:`1h`},{label:`4H`,value:`4h`},{label:`1D`,value:`1d`}],r=[{label:`Candlestick`,value:`candlestick`},{label:`Line`,value:`line`},{label:`Area`,value:`area`},{label:`Bar`,value:`bar`},{label:`Heikin-Ashi`,value:`heikinAshi`},{label:`Hollow Candle`,value:`hollowCandle`},{label:`Baseline`,value:`baseline`},{label:`Volume Candles`,value:`volumeCandles`},{label:`HLC Area`,value:`hlcArea`},{label:`Step Line`,value:`stepLine`},{label:`Line + Markers`,value:`lineWithMarkers`}],i=[{label:`Lines`,tools:[{label:`Trend Line`,value:`trendLine`},{label:`Ray`,value:`ray`},{label:`Extended Line`,value:`extendedLine`}]},{label:`Horizontal/Vertical`,tools:[{label:`Horizontal Line`,value:`horizontalLine`},{label:`Vertical Line`,value:`verticalLine`}]},{label:`Channels`,tools:[{label:`Parallel Channel`,value:`parallelChannel`},{label:`Regression Channel`,value:`regressionChannel`}]},{label:`Fibonacci`,tools:[{label:`Fib Retracement`,value:`fibRetracement`},{label:`Fib Extension`,value:`fibExtension`}]},{label:`Shapes`,tools:[{label:`Rectangle`,value:`rectangle`},{label:`Ellipse`,value:`ellipse`},{label:`Triangle`,value:`triangle`}]},{label:`Gann & Advanced`,tools:[{label:`Pitchfork`,value:`pitchfork`},{label:`Gann Fan`,value:`gannFan`},{label:`Gann Box`,value:`gannBox`},{label:`Elliott Wave`,value:`elliottWave`}]},{label:`Measure`,tools:[{label:`Price Range`,value:`priceRange`},{label:`Date Range`,value:`dateRange`},{label:`Measure`,value:`measure`}]},{label:`Annotation`,tools:[{label:`Text`,value:`text`},{label:`Arrow`,value:`arrow`}]}],a=[{id:`sma`,name:`SMA`,type:`overlay`},{id:`ema`,name:`EMA`,type:`overlay`},{id:`hma`,name:`Hull MA`,type:`overlay`},{id:`bb`,name:`Bollinger Bands`,type:`overlay`},{id:`vwap`,name:`VWAP`,type:`overlay`},{id:`avwap`,name:`Anchored VWAP`,type:`overlay`},{id:`ichimoku`,name:`Ichimoku Cloud`,type:`overlay`},{id:`psar`,name:`Parabolic SAR`,type:`overlay`},{id:`supertrend`,name:`Supertrend`,type:`overlay`},{id:`keltner`,name:`Keltner Channel`,type:`overlay`},{id:`donchian`,name:`Donchian Channel`,type:`overlay`},{id:`pivots`,name:`Pivot Points`,type:`overlay`},{id:`zigzag`,name:`ZigZag`,type:`overlay`},{id:`lrc`,name:`Linear Regression Channel`,type:`overlay`},{id:`rsi`,name:`RSI`,type:`panel`},{id:`macd`,name:`MACD`,type:`panel`},{id:`stochastic`,name:`Stochastic`,type:`panel`},{id:`atr`,name:`ATR`,type:`panel`},{id:`adx`,name:`ADX`,type:`panel`},{id:`obv`,name:`OBV`,type:`panel`},{id:`williamsR`,name:`Williams %R`,type:`panel`},{id:`cci`,name:`CCI`,type:`panel`},{id:`mfi`,name:`MFI`,type:`panel`},{id:`roc`,name:`ROC`,type:`panel`},{id:`tsi`,name:`TSI`,type:`panel`},{id:`cmf`,name:`CMF`,type:`panel`},{id:`aroon`,name:`Aroon`,type:`panel`},{id:`stddev`,name:`Std Deviation`,type:`panel`},{id:`vroc`,name:`Volume ROC`,type:`panel`},{id:`ad`,name:`Acc/Dist`,type:`panel`},{id:`ao`,name:`Awesome Oscillator`,type:`panel`},{id:`chaikinOsc`,name:`Chaikin Oscillator`,type:`panel`},{id:`volumeProfile`,name:`Volume Profile`,type:`panel`}],o=[`sma`,`ema`,`bb`,`rsi`,`macd`,`stochastic`,`vwap`,`atr`,`obv`,`ichimoku`],s=[`BTCUSDT`,`ETHUSDT`,`SOLUSDT`,`BNBUSDT`],c={candleUpColor:`#26A69A`,candleDownColor:`#EF5350`,candleUpWick:`#26A69A`,candleDownWick:`#EF5350`,backgroundColor:`#131722`,gridColor:`#1E222D`,gridVisible:!0,volumeVisible:!0,legendVisible:!0,barCountdown:!0,logScale:!1,autoScale:!0,crosshairMode:`magnet`,numberLocale:`en-US`},l=`/* === TradeCanvas Widget Styles === */\r
2
+ \r
3
+ .tcw-root {\r
4
+ display: flex;\r
5
+ flex-direction: column;\r
6
+ width: 100%;\r
7
+ height: 100%;\r
8
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\r
9
+ font-size: 13px;\r
10
+ color: #d1d4dc;\r
11
+ background: #131722;\r
12
+ position: relative;\r
13
+ overflow: hidden;\r
14
+ \r
15
+ /* Dark theme tokens (default) */\r
16
+ --tcw-bg: #131722;\r
17
+ --tcw-bg-elevated: #1E222D;\r
18
+ --tcw-border: #2A2E39;\r
19
+ --tcw-text: #d1d4dc;\r
20
+ --tcw-text-dim: #b2b5be;\r
21
+ --tcw-text-muted: #787b86;\r
22
+ --tcw-accent: #2962ff;\r
23
+ --tcw-accent-dim: rgba(41,98,255,0.15);\r
24
+ --tcw-accent-glow: rgba(41,98,255,0.12);\r
25
+ --tcw-red: #ef5350;\r
26
+ --tcw-green: #26a69a;\r
27
+ --tcw-transition: 0.15s ease;\r
28
+ --tcw-radius-lg: 8px;\r
29
+ --tcw-font-mono: 'SF Mono', 'Fira Code', 'Consolas', monospace;\r
30
+ --tcw-hover-bg: rgba(255,255,255,0.04);\r
31
+ }\r
32
+ \r
33
+ .tcw-root[data-tcw-theme="light"] {\r
34
+ color: #131722;\r
35
+ background: #ffffff;\r
36
+ \r
37
+ --tcw-bg: #ffffff;\r
38
+ --tcw-bg-elevated: #f0f3fa;\r
39
+ --tcw-border: #e0e3eb;\r
40
+ --tcw-text: #131722;\r
41
+ --tcw-text-dim: #434651;\r
42
+ --tcw-text-muted: #787b86;\r
43
+ --tcw-accent: #2962ff;\r
44
+ --tcw-accent-dim: rgba(41,98,255,0.1);\r
45
+ --tcw-accent-glow: rgba(41,98,255,0.08);\r
46
+ --tcw-red: #ef5350;\r
47
+ --tcw-green: #26a69a;\r
48
+ --tcw-hover-bg: rgba(0,0,0,0.04);\r
49
+ }\r
50
+ \r
51
+ /* === Toolbar === */\r
52
+ \r
53
+ .tcw-toolbar {\r
54
+ display: flex;\r
55
+ align-items: center;\r
56
+ gap: 0;\r
57
+ padding: 0 12px;\r
58
+ height: 40px;\r
59
+ border-bottom: 1px solid var(--tcw-border);\r
60
+ background: var(--tcw-bg-elevated);\r
61
+ flex-shrink: 0;\r
62
+ position: relative;\r
63
+ z-index: 20;\r
64
+ }\r
65
+ \r
66
+ .tcw-toolbar-symbol {\r
67
+ font-size: 13px;\r
68
+ font-weight: 700;\r
69
+ color: var(--tcw-text);\r
70
+ padding: 0 10px;\r
71
+ white-space: nowrap;\r
72
+ letter-spacing: -0.01em;\r
73
+ cursor: pointer;\r
74
+ border: none;\r
75
+ background: none;\r
76
+ font-family: inherit;\r
77
+ }\r
78
+ \r
79
+ .tcw-toolbar-sep {\r
80
+ width: 1px;\r
81
+ height: 20px;\r
82
+ background: var(--tcw-border);\r
83
+ flex-shrink: 0;\r
84
+ }\r
85
+ \r
86
+ .tcw-toolbar-group {\r
87
+ display: flex;\r
88
+ align-items: center;\r
89
+ gap: 2px;\r
90
+ padding: 0 8px;\r
91
+ }\r
92
+ \r
93
+ .tcw-toolbar-spacer {\r
94
+ flex: 1;\r
95
+ }\r
96
+ \r
97
+ .tcw-btn {\r
98
+ padding: 4px 8px;\r
99
+ font-size: 12px;\r
100
+ font-family: inherit;\r
101
+ border: none;\r
102
+ border-radius: 4px;\r
103
+ background: transparent;\r
104
+ color: var(--tcw-text-dim);\r
105
+ cursor: pointer;\r
106
+ transition: all var(--tcw-transition);\r
107
+ white-space: nowrap;\r
108
+ line-height: 1;\r
109
+ }\r
110
+ \r
111
+ .tcw-btn:hover {\r
112
+ background: var(--tcw-hover-bg);\r
113
+ color: var(--tcw-text);\r
114
+ }\r
115
+ \r
116
+ .tcw-btn.tcw-active {\r
117
+ background: var(--tcw-accent);\r
118
+ color: white;\r
119
+ }\r
120
+ \r
121
+ .tcw-btn-icon {\r
122
+ width: 32px;\r
123
+ height: 32px;\r
124
+ display: inline-flex;\r
125
+ align-items: center;\r
126
+ justify-content: center;\r
127
+ font-family: inherit;\r
128
+ border: none;\r
129
+ border-radius: 4px;\r
130
+ background: transparent;\r
131
+ color: var(--tcw-text-muted);\r
132
+ cursor: pointer;\r
133
+ transition: all var(--tcw-transition);\r
134
+ line-height: 1;\r
135
+ position: relative;\r
136
+ }\r
137
+ \r
138
+ .tcw-btn-icon:hover {\r
139
+ background: var(--tcw-hover-bg);\r
140
+ color: var(--tcw-text);\r
141
+ }\r
142
+ \r
143
+ .tcw-badge-count {\r
144
+ font-size: 10px;\r
145
+ color: var(--tcw-accent);\r
146
+ background: var(--tcw-accent-dim);\r
147
+ padding: 0 4px;\r
148
+ border-radius: 8px;\r
149
+ font-weight: 600;\r
150
+ }\r
151
+ \r
152
+ .tcw-indicator-chips {\r
153
+ display: flex;\r
154
+ align-items: center;\r
155
+ gap: 4px;\r
156
+ padding: 0 4px;\r
157
+ flex-wrap: nowrap;\r
158
+ overflow: hidden;\r
159
+ }\r
160
+ \r
161
+ .tcw-indicator-chip {\r
162
+ display: inline-flex;\r
163
+ align-items: center;\r
164
+ gap: 4px;\r
165
+ padding: 2px 6px 2px 8px;\r
166
+ font-size: 11px;\r
167
+ font-weight: 500;\r
168
+ background: var(--tcw-accent-dim);\r
169
+ color: var(--tcw-accent);\r
170
+ border-radius: 4px;\r
171
+ white-space: nowrap;\r
172
+ line-height: 1.4;\r
173
+ }\r
174
+ \r
175
+ .tcw-chip-remove {\r
176
+ cursor: pointer;\r
177
+ opacity: 0.6;\r
178
+ padding: 0 2px;\r
179
+ transition: opacity var(--tcw-transition);\r
180
+ border: none;\r
181
+ background: none;\r
182
+ color: inherit;\r
183
+ display: inline-flex;\r
184
+ align-items: center;\r
185
+ }\r
186
+ \r
187
+ .tcw-chip-remove:hover {\r
188
+ opacity: 1;\r
189
+ }\r
190
+ \r
191
+ /* === Dropdown === */\r
192
+ \r
193
+ .tcw-dropdown-trigger {\r
194
+ display: inline-flex;\r
195
+ align-items: center;\r
196
+ gap: 4px;\r
197
+ padding: 4px 8px;\r
198
+ font-size: 12px;\r
199
+ font-family: inherit;\r
200
+ border: none;\r
201
+ border-radius: 4px;\r
202
+ background: transparent;\r
203
+ color: var(--tcw-text-dim);\r
204
+ cursor: pointer;\r
205
+ transition: all var(--tcw-transition);\r
206
+ white-space: nowrap;\r
207
+ line-height: 1;\r
208
+ }\r
209
+ \r
210
+ .tcw-dropdown-trigger:hover {\r
211
+ background: var(--tcw-hover-bg);\r
212
+ color: var(--tcw-text);\r
213
+ }\r
214
+ \r
215
+ .tcw-dropdown {\r
216
+ position: absolute;\r
217
+ top: 100%;\r
218
+ margin-top: 4px;\r
219
+ background: var(--tcw-bg-elevated);\r
220
+ border: 1px solid var(--tcw-border);\r
221
+ border-radius: var(--tcw-radius-lg);\r
222
+ box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r
223
+ z-index: 50;\r
224
+ padding: 4px 0;\r
225
+ max-height: 400px;\r
226
+ overflow-y: auto;\r
227
+ }\r
228
+ \r
229
+ .tcw-dropdown-item {\r
230
+ display: flex;\r
231
+ align-items: center;\r
232
+ justify-content: space-between;\r
233
+ padding: 6px 12px;\r
234
+ font-size: 12px;\r
235
+ color: var(--tcw-text-dim);\r
236
+ cursor: pointer;\r
237
+ transition: background var(--tcw-transition), color var(--tcw-transition);\r
238
+ width: 100%;\r
239
+ border: none;\r
240
+ background: none;\r
241
+ font-family: inherit;\r
242
+ text-align: left;\r
243
+ }\r
244
+ \r
245
+ .tcw-dropdown-item:hover {\r
246
+ background: var(--tcw-hover-bg);\r
247
+ color: var(--tcw-text);\r
248
+ }\r
249
+ \r
250
+ .tcw-dropdown-item.tcw-active {\r
251
+ color: var(--tcw-accent);\r
252
+ }\r
253
+ \r
254
+ .tcw-dropdown-label {\r
255
+ text-transform: uppercase;\r
256
+ font-size: 10px;\r
257
+ color: var(--tcw-text-muted);\r
258
+ letter-spacing: 0.05em;\r
259
+ padding: 6px 12px;\r
260
+ font-weight: 600;\r
261
+ }\r
262
+ \r
263
+ .tcw-dropdown-divider {\r
264
+ border-top: 1px solid var(--tcw-border);\r
265
+ margin: 4px 0;\r
266
+ }\r
267
+ \r
268
+ .tcw-tag {\r
269
+ font-size: 10px;\r
270
+ color: var(--tcw-text-muted);\r
271
+ padding: 1px 5px;\r
272
+ border-radius: 3px;\r
273
+ background: var(--tcw-hover-bg);\r
274
+ }\r
275
+ \r
276
+ /* === Body === */\r
277
+ \r
278
+ .tcw-body {\r
279
+ display: flex;\r
280
+ flex: 1;\r
281
+ min-height: 0;\r
282
+ }\r
283
+ \r
284
+ .tcw-chart-container {\r
285
+ flex: 1;\r
286
+ min-width: 0;\r
287
+ min-height: 0;\r
288
+ width: 100%;\r
289
+ height: 100%;\r
290
+ }\r
291
+ \r
292
+ /* === Sidebar === */\r
293
+ \r
294
+ .tcw-sidebar {\r
295
+ width: 36px;\r
296
+ flex-shrink: 0;\r
297
+ background: var(--tcw-bg-elevated);\r
298
+ border-right: 1px solid var(--tcw-border);\r
299
+ display: flex;\r
300
+ flex-direction: column;\r
301
+ align-items: center;\r
302
+ padding: 4px 0;\r
303
+ overflow: visible;\r
304
+ }\r
305
+ \r
306
+ .tcw-tool-group-wrap {\r
307
+ position: relative;\r
308
+ }\r
309
+ \r
310
+ .tcw-sidebar-btn {\r
311
+ width: 36px;\r
312
+ height: 32px;\r
313
+ display: flex;\r
314
+ align-items: center;\r
315
+ justify-content: center;\r
316
+ border: none;\r
317
+ background: transparent;\r
318
+ color: var(--tcw-text-muted);\r
319
+ cursor: pointer;\r
320
+ font-family: inherit;\r
321
+ transition: all var(--tcw-transition);\r
322
+ position: relative;\r
323
+ flex-shrink: 0;\r
324
+ line-height: 1;\r
325
+ }\r
326
+ \r
327
+ .tcw-sidebar-btn:hover {\r
328
+ color: var(--tcw-text);\r
329
+ background: var(--tcw-hover-bg);\r
330
+ }\r
331
+ \r
332
+ .tcw-sidebar-btn.tcw-active {\r
333
+ color: var(--tcw-accent);\r
334
+ background: var(--tcw-accent-glow);\r
335
+ }\r
336
+ \r
337
+ .tcw-sidebar-btn.tcw-danger:hover {\r
338
+ color: var(--tcw-red);\r
339
+ background: rgba(239,68,68,0.1);\r
340
+ }\r
341
+ \r
342
+ .tcw-multi-dot {\r
343
+ position: absolute;\r
344
+ bottom: 2px;\r
345
+ right: 2px;\r
346
+ width: 4px;\r
347
+ height: 4px;\r
348
+ border-radius: 50%;\r
349
+ background: var(--tcw-text-muted);\r
350
+ }\r
351
+ \r
352
+ .tcw-sidebar-divider {\r
353
+ width: 20px;\r
354
+ height: 1px;\r
355
+ background: var(--tcw-border);\r
356
+ margin: 4px 0;\r
357
+ flex-shrink: 0;\r
358
+ }\r
359
+ \r
360
+ .tcw-sidebar-spacer {\r
361
+ flex: 1;\r
362
+ }\r
363
+ \r
364
+ /* === Flyout === */\r
365
+ \r
366
+ .tcw-flyout {\r
367
+ position: absolute;\r
368
+ left: 100%;\r
369
+ top: 0;\r
370
+ margin-left: 2px;\r
371
+ min-width: 160px;\r
372
+ background: var(--tcw-bg-elevated);\r
373
+ border: 1px solid var(--tcw-border);\r
374
+ border-radius: var(--tcw-radius-lg);\r
375
+ box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r
376
+ z-index: 30;\r
377
+ padding: 4px 0;\r
378
+ }\r
379
+ \r
380
+ .tcw-flyout-header {\r
381
+ text-transform: uppercase;\r
382
+ font-size: 10px;\r
383
+ color: var(--tcw-text-muted);\r
384
+ letter-spacing: 0.05em;\r
385
+ padding: 6px 12px;\r
386
+ font-weight: 600;\r
387
+ }\r
388
+ \r
389
+ .tcw-flyout-item {\r
390
+ padding: 6px 12px;\r
391
+ font-size: 12px;\r
392
+ color: var(--tcw-text-dim);\r
393
+ cursor: pointer;\r
394
+ width: 100%;\r
395
+ display: block;\r
396
+ border: none;\r
397
+ background: none;\r
398
+ text-align: left;\r
399
+ font-family: inherit;\r
400
+ transition: background var(--tcw-transition), color var(--tcw-transition);\r
401
+ }\r
402
+ \r
403
+ .tcw-flyout-item:hover {\r
404
+ background: var(--tcw-hover-bg);\r
405
+ color: var(--tcw-text);\r
406
+ }\r
407
+ \r
408
+ .tcw-flyout-item.tcw-active {\r
409
+ color: var(--tcw-accent);\r
410
+ }\r
411
+ \r
412
+ /* === Modal === */\r
413
+ \r
414
+ .tcw-modal-backdrop {\r
415
+ position: fixed;\r
416
+ inset: 0;\r
417
+ background: rgba(0,0,0,0.5);\r
418
+ backdrop-filter: blur(4px);\r
419
+ -webkit-backdrop-filter: blur(4px);\r
420
+ z-index: 100;\r
421
+ }\r
422
+ \r
423
+ .tcw-modal {\r
424
+ position: fixed;\r
425
+ z-index: 101;\r
426
+ top: 50%;\r
427
+ left: 50%;\r
428
+ transform: translate(-50%, -50%);\r
429
+ background: var(--tcw-bg-elevated);\r
430
+ border: 1px solid var(--tcw-border);\r
431
+ border-radius: var(--tcw-radius-lg);\r
432
+ width: 480px;\r
433
+ max-width: 90vw;\r
434
+ max-height: 80vh;\r
435
+ display: flex;\r
436
+ flex-direction: column;\r
437
+ box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r
438
+ }\r
439
+ \r
440
+ .tcw-modal-header {\r
441
+ display: flex;\r
442
+ align-items: center;\r
443
+ justify-content: space-between;\r
444
+ padding: 16px 20px;\r
445
+ border-bottom: 1px solid var(--tcw-border);\r
446
+ }\r
447
+ \r
448
+ .tcw-modal-header h3 {\r
449
+ font-size: 15px;\r
450
+ font-weight: 600;\r
451
+ margin: 0;\r
452
+ color: var(--tcw-text);\r
453
+ }\r
454
+ \r
455
+ .tcw-modal-close {\r
456
+ width: 28px;\r
457
+ height: 28px;\r
458
+ display: flex;\r
459
+ align-items: center;\r
460
+ justify-content: center;\r
461
+ border: none;\r
462
+ background: transparent;\r
463
+ color: var(--tcw-text-muted);\r
464
+ cursor: pointer;\r
465
+ border-radius: 4px;\r
466
+ transition: all var(--tcw-transition);\r
467
+ }\r
468
+ \r
469
+ .tcw-modal-close:hover {\r
470
+ background: var(--tcw-hover-bg);\r
471
+ color: var(--tcw-text);\r
472
+ }\r
473
+ \r
474
+ .tcw-modal-tabs {\r
475
+ display: flex;\r
476
+ gap: 0;\r
477
+ padding: 0 20px;\r
478
+ border-bottom: 1px solid var(--tcw-border);\r
479
+ }\r
480
+ \r
481
+ .tcw-modal-tab {\r
482
+ padding: 10px 16px;\r
483
+ font-size: 12px;\r
484
+ font-weight: 500;\r
485
+ color: var(--tcw-text-muted);\r
486
+ border: none;\r
487
+ background: none;\r
488
+ cursor: pointer;\r
489
+ border-bottom: 2px solid transparent;\r
490
+ margin-bottom: -1px;\r
491
+ transition: color var(--tcw-transition);\r
492
+ font-family: inherit;\r
493
+ text-transform: capitalize;\r
494
+ }\r
495
+ \r
496
+ .tcw-modal-tab:hover {\r
497
+ color: var(--tcw-text-dim);\r
498
+ }\r
499
+ \r
500
+ .tcw-modal-tab.tcw-active {\r
501
+ color: var(--tcw-accent);\r
502
+ border-bottom-color: var(--tcw-accent);\r
503
+ }\r
504
+ \r
505
+ .tcw-modal-body {\r
506
+ padding: 20px;\r
507
+ overflow-y: auto;\r
508
+ flex: 1;\r
509
+ }\r
510
+ \r
511
+ .tcw-settings-section {\r
512
+ margin-bottom: 20px;\r
513
+ }\r
514
+ \r
515
+ .tcw-settings-section:last-child {\r
516
+ margin-bottom: 0;\r
517
+ }\r
518
+ \r
519
+ .tcw-settings-section-title {\r
520
+ font-size: 11px;\r
521
+ font-weight: 600;\r
522
+ text-transform: uppercase;\r
523
+ letter-spacing: 0.05em;\r
524
+ color: var(--tcw-text-muted);\r
525
+ margin-bottom: 12px;\r
526
+ }\r
527
+ \r
528
+ .tcw-settings-row {\r
529
+ display: flex;\r
530
+ align-items: center;\r
531
+ justify-content: space-between;\r
532
+ padding: 8px 0;\r
533
+ }\r
534
+ \r
535
+ .tcw-settings-row + .tcw-settings-row {\r
536
+ border-top: 1px solid rgba(255,255,255,0.03);\r
537
+ }\r
538
+ \r
539
+ .tcw-root[data-tcw-theme="light"] .tcw-settings-row + .tcw-settings-row {\r
540
+ border-top: 1px solid rgba(0,0,0,0.04);\r
541
+ }\r
542
+ \r
543
+ .tcw-settings-label {\r
544
+ font-size: 13px;\r
545
+ color: var(--tcw-text-dim);\r
546
+ }\r
547
+ \r
548
+ .tcw-color-picker-wrap {\r
549
+ display: flex;\r
550
+ align-items: center;\r
551
+ gap: 6px;\r
552
+ }\r
553
+ \r
554
+ .tcw-color-picker-wrap input[type='color'] {\r
555
+ width: 28px;\r
556
+ height: 28px;\r
557
+ border: 1px solid var(--tcw-border);\r
558
+ border-radius: 4px;\r
559
+ background: none;\r
560
+ cursor: pointer;\r
561
+ padding: 2px;\r
562
+ }\r
563
+ \r
564
+ .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\r
565
+ padding: 0;\r
566
+ }\r
567
+ \r
568
+ .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\r
569
+ border: none;\r
570
+ border-radius: 2px;\r
571
+ }\r
572
+ \r
573
+ .tcw-color-hex {\r
574
+ font-size: 11px;\r
575
+ font-family: var(--tcw-font-mono);\r
576
+ color: var(--tcw-text-muted);\r
577
+ min-width: 60px;\r
578
+ }\r
579
+ \r
580
+ .tcw-toggle {\r
581
+ width: 36px;\r
582
+ height: 20px;\r
583
+ background: rgba(255,255,255,0.1);\r
584
+ border-radius: 10px;\r
585
+ position: relative;\r
586
+ cursor: pointer;\r
587
+ transition: background var(--tcw-transition);\r
588
+ border: none;\r
589
+ padding: 0;\r
590
+ flex-shrink: 0;\r
591
+ }\r
592
+ \r
593
+ .tcw-toggle::after {\r
594
+ content: '';\r
595
+ position: absolute;\r
596
+ top: 2px;\r
597
+ left: 2px;\r
598
+ width: 16px;\r
599
+ height: 16px;\r
600
+ border-radius: 50%;\r
601
+ background: var(--tcw-text-muted);\r
602
+ transition: all var(--tcw-transition);\r
603
+ }\r
604
+ \r
605
+ .tcw-toggle.tcw-on {\r
606
+ background: var(--tcw-accent);\r
607
+ }\r
608
+ \r
609
+ .tcw-toggle.tcw-on::after {\r
610
+ left: 18px;\r
611
+ background: white;\r
612
+ }\r
613
+ \r
614
+ .tcw-root[data-tcw-theme="light"] .tcw-toggle {\r
615
+ background: rgba(0,0,0,0.1);\r
616
+ }\r
617
+ \r
618
+ .tcw-root[data-tcw-theme="light"] .tcw-toggle::after {\r
619
+ background: #888;\r
620
+ }\r
621
+ \r
622
+ .tcw-root[data-tcw-theme="light"] .tcw-toggle.tcw-on {\r
623
+ background: var(--tcw-accent);\r
624
+ }\r
625
+ \r
626
+ .tcw-root[data-tcw-theme="light"] .tcw-toggle.tcw-on::after {\r
627
+ background: white;\r
628
+ }\r
629
+ \r
630
+ .tcw-settings-select {\r
631
+ padding: 4px 8px;\r
632
+ font-size: 12px;\r
633
+ font-family: inherit;\r
634
+ background: var(--tcw-bg);\r
635
+ border: 1px solid var(--tcw-border);\r
636
+ border-radius: 4px;\r
637
+ color: var(--tcw-text);\r
638
+ cursor: pointer;\r
639
+ }\r
640
+ \r
641
+ .tcw-modal-footer {\r
642
+ display: flex;\r
643
+ align-items: center;\r
644
+ justify-content: space-between;\r
645
+ padding: 12px 20px;\r
646
+ border-top: 1px solid var(--tcw-border);\r
647
+ }\r
648
+ \r
649
+ .tcw-reset-link {\r
650
+ font-size: 12px;\r
651
+ color: var(--tcw-text-muted);\r
652
+ cursor: pointer;\r
653
+ border: none;\r
654
+ background: none;\r
655
+ font-family: inherit;\r
656
+ text-decoration: underline;\r
657
+ text-underline-offset: 2px;\r
658
+ transition: color var(--tcw-transition);\r
659
+ }\r
660
+ \r
661
+ .tcw-reset-link:hover {\r
662
+ color: var(--tcw-text-dim);\r
663
+ }\r
664
+ \r
665
+ .tcw-done-btn {\r
666
+ padding: 6px 16px;\r
667
+ font-size: 12px;\r
668
+ font-weight: 500;\r
669
+ background: var(--tcw-accent);\r
670
+ color: white;\r
671
+ border: none;\r
672
+ border-radius: 4px;\r
673
+ cursor: pointer;\r
674
+ font-family: inherit;\r
675
+ transition: background var(--tcw-transition);\r
676
+ }\r
677
+ \r
678
+ .tcw-done-btn:hover {\r
679
+ background: #2563eb;\r
680
+ }\r
681
+ \r
682
+ /* === Status Bar === */\r
683
+ \r
684
+ .tcw-statusbar {\r
685
+ display: flex;\r
686
+ align-items: center;\r
687
+ justify-content: space-between;\r
688
+ padding: 6px 16px;\r
689
+ border-top: 1px solid var(--tcw-border);\r
690
+ background: var(--tcw-bg-elevated);\r
691
+ font-size: 11px;\r
692
+ color: var(--tcw-text-muted);\r
693
+ flex-shrink: 0;\r
694
+ }\r
695
+ \r
696
+ .tcw-status-indicator {\r
697
+ display: flex;\r
698
+ align-items: center;\r
699
+ gap: 6px;\r
700
+ }\r
701
+ \r
702
+ .tcw-status-dot {\r
703
+ width: 6px;\r
704
+ height: 6px;\r
705
+ border-radius: 50%;\r
706
+ background: var(--tcw-text-muted);\r
707
+ transition: background 0.3s;\r
708
+ }\r
709
+ \r
710
+ .tcw-status-dot.tcw-connected {\r
711
+ background: var(--tcw-green);\r
712
+ }\r
713
+ \r
714
+ .tcw-status-dot.tcw-error {\r
715
+ background: var(--tcw-red);\r
716
+ }\r
717
+ \r
718
+ /* === Command Palette === */\r
719
+ \r
720
+ .tcw-cmd-palette {\r
721
+ position: fixed;\r
722
+ z-index: 102;\r
723
+ top: 20%;\r
724
+ left: 50%;\r
725
+ transform: translateX(-50%);\r
726
+ background: var(--tcw-bg-elevated);\r
727
+ border: 1px solid var(--tcw-border);\r
728
+ border-radius: var(--tcw-radius-lg);\r
729
+ width: 520px;\r
730
+ max-width: 90vw;\r
731
+ max-height: 60vh;\r
732
+ display: flex;\r
733
+ flex-direction: column;\r
734
+ box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r
735
+ overflow: hidden;\r
736
+ }\r
737
+ \r
738
+ .tcw-cmd-header {\r
739
+ display: flex;\r
740
+ align-items: center;\r
741
+ padding: 12px 16px;\r
742
+ border-bottom: 1px solid var(--tcw-border);\r
743
+ gap: 10px;\r
744
+ }\r
745
+ \r
746
+ .tcw-cmd-icon {\r
747
+ font-size: 18px;\r
748
+ color: var(--tcw-text-muted);\r
749
+ flex-shrink: 0;\r
750
+ }\r
751
+ \r
752
+ .tcw-cmd-input {\r
753
+ flex: 1;\r
754
+ background: none;\r
755
+ border: none;\r
756
+ outline: none;\r
757
+ font-size: 14px;\r
758
+ font-family: inherit;\r
759
+ color: var(--tcw-text);\r
760
+ caret-color: var(--tcw-accent);\r
761
+ }\r
762
+ \r
763
+ .tcw-cmd-input::placeholder {\r
764
+ color: var(--tcw-text-muted);\r
765
+ }\r
766
+ \r
767
+ .tcw-cmd-hint {\r
768
+ font-size: 10px;\r
769
+ color: var(--tcw-text-muted);\r
770
+ border: 1px solid var(--tcw-border);\r
771
+ padding: 2px 6px;\r
772
+ border-radius: 3px;\r
773
+ flex-shrink: 0;\r
774
+ }\r
775
+ \r
776
+ .tcw-cmd-list {\r
777
+ overflow-y: auto;\r
778
+ flex: 1;\r
779
+ padding: 4px 0;\r
780
+ max-height: 360px;\r
781
+ }\r
782
+ \r
783
+ .tcw-cmd-category {\r
784
+ text-transform: uppercase;\r
785
+ font-size: 10px;\r
786
+ color: var(--tcw-text-muted);\r
787
+ letter-spacing: 0.05em;\r
788
+ padding: 8px 16px 4px;\r
789
+ font-weight: 600;\r
790
+ }\r
791
+ \r
792
+ .tcw-cmd-item {\r
793
+ display: flex;\r
794
+ align-items: center;\r
795
+ justify-content: space-between;\r
796
+ padding: 8px 16px;\r
797
+ font-size: 13px;\r
798
+ color: var(--tcw-text-dim);\r
799
+ cursor: pointer;\r
800
+ width: 100%;\r
801
+ border: none;\r
802
+ background: none;\r
803
+ font-family: inherit;\r
804
+ text-align: left;\r
805
+ transition: background 80ms ease;\r
806
+ gap: 8px;\r
807
+ }\r
808
+ \r
809
+ .tcw-cmd-item:hover,\r
810
+ .tcw-cmd-item.tcw-selected {\r
811
+ background: var(--tcw-hover-bg);\r
812
+ color: var(--tcw-text);\r
813
+ }\r
814
+ \r
815
+ .tcw-cmd-item.tcw-active .tcw-cmd-item-label {\r
816
+ color: var(--tcw-accent);\r
817
+ }\r
818
+ \r
819
+ .tcw-cmd-item-label {\r
820
+ flex: 1;\r
821
+ }\r
822
+ \r
823
+ .tcw-cmd-check {\r
824
+ color: var(--tcw-accent);\r
825
+ font-size: 14px;\r
826
+ font-weight: 600;\r
827
+ }\r
828
+ \r
829
+ .tcw-cmd-kbd {\r
830
+ font-size: 10px;\r
831
+ font-family: var(--tcw-font-mono);\r
832
+ color: var(--tcw-text-muted);\r
833
+ background: var(--tcw-bg);\r
834
+ border: 1px solid var(--tcw-border);\r
835
+ padding: 1px 5px;\r
836
+ border-radius: 3px;\r
837
+ }\r
838
+ \r
839
+ .tcw-cmd-empty {\r
840
+ padding: 24px 16px;\r
841
+ text-align: center;\r
842
+ color: var(--tcw-text-muted);\r
843
+ font-size: 13px;\r
844
+ }\r
845
+ \r
846
+ .tcw-cmd-footer {\r
847
+ display: flex;\r
848
+ align-items: center;\r
849
+ gap: 16px;\r
850
+ padding: 8px 16px;\r
851
+ border-top: 1px solid var(--tcw-border);\r
852
+ font-size: 11px;\r
853
+ color: var(--tcw-text-muted);\r
854
+ }\r
855
+ \r
856
+ /* === Responsive === */\r
857
+ \r
858
+ @media (max-width: 768px) {\r
859
+ .tcw-toolbar {\r
860
+ padding: 0 8px;\r
861
+ height: 36px;\r
862
+ }\r
863
+ .tcw-toolbar-sep {\r
864
+ display: none;\r
865
+ }\r
866
+ .tcw-indicator-chips {\r
867
+ display: none;\r
868
+ }\r
869
+ .tcw-sidebar {\r
870
+ width: 32px;\r
871
+ }\r
872
+ .tcw-sidebar-btn {\r
873
+ width: 32px;\r
874
+ height: 28px;\r
875
+ }\r
876
+ }\r
877
+ `,u=0,d=`tcw-styles`;function f(){if(u++,u>1||document.getElementById(d))return;let e=document.createElement(`style`);e.id=d,e.textContent=l,document.head.appendChild(e)}function p(){if(u--,u>0)return;let e=document.getElementById(d);e&&e.remove()}var m={cursor:`<path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/>`,trendingUp:`<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>`,minus:`<path d="M5 12h14"/>`,penLine:`<path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/>`,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"/>`,square:`<rect width="18" height="18" x="3" y="3" rx="2"/>`,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"/>`,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"/>`,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"/>`,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"/>`,undo:`<path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/>`,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"/>`,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"/>`,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"/>`,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"/>`,moon:`<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>`,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"/>`,chevronDown:`<path d="m6 9 6 6 6-6"/>`,chevronUp:`<path d="m18 15-6-6-6 6"/>`,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"/>`,x:`<path d="M18 6 6 18"/><path d="m6 6 12 12"/>`,play:`<polygon points="6 3 20 12 6 21 6 3"/>`,pause:`<rect width="4" height="16" x="6" y="4"/><rect width="4" height="16" x="14" y="4"/>`,stop:`<rect width="14" height="14" x="5" y="5" rx="1"/>`,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"/>`};function h(e,t=14){let n=m[e];return n?`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n}</svg>`:``}var g=class{trigger;panel;_isOpen=!1;onOutsideClick;onEscapeKey;onTriggerClick;constructor(e,t={}){this.trigger=e,this.panel=document.createElement(`div`),this.panel.className=`tcw-dropdown`,this.panel.style.width=t.width??`200px`,t.align===`right`?this.panel.style.right=`0`:this.panel.style.left=`0`,this.panel.style.display=`none`,e.style.position=`relative`,e.appendChild(this.panel),this.onTriggerClick=()=>{this._isOpen?this.close():this.open()},this.onOutsideClick=e=>{this.trigger.contains(e.target)||this.close()},this.onEscapeKey=e=>{e.key===`Escape`&&this.close()},e.addEventListener(`click`,this.onTriggerClick)}setContent(e){this.panel.innerHTML=e}open(){this._isOpen||(this._isOpen=!0,this.panel.style.display=``,document.addEventListener(`mousedown`,this.onOutsideClick),document.addEventListener(`keydown`,this.onEscapeKey))}close(){this._isOpen&&(this._isOpen=!1,this.panel.style.display=`none`,document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey))}isOpen(){return this._isOpen}destroy(){this.trigger.removeEventListener(`click`,this.onTriggerClick),document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey),this.panel.remove()}},_=class{config;callbacks;el;chartTypeDropdown=null;indicatorDropdown=null;tfButtons=[];chipsContainer=null;themeBtn=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-toolbar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this,r=document.createElement(`button`);r.className=`tcw-toolbar-symbol`,r.dataset.role=`symbol`,r.addEventListener(`click`,t.onSymbolClick),n.appendChild(r),n.appendChild(this.sep());let i=document.createElement(`div`);i.className=`tcw-toolbar-group`;for(let n of e.timeframes){let e=document.createElement(`button`);e.className=`tcw-btn`,e.textContent=n.label,e.dataset.tf=n.value,e.addEventListener(`click`,()=>t.onTimeframe(n.value)),i.appendChild(e),this.tfButtons.push(e)}n.appendChild(i),n.appendChild(this.sep());let a=document.createElement(`div`);a.style.position=`relative`,a.style.display=`inline-flex`;let o=document.createElement(`button`);o.className=`tcw-dropdown-trigger`,o.dataset.role=`charttype`,a.appendChild(o),n.appendChild(a),this.chartTypeDropdown=new g(a,{width:`160px`}),this.buildChartTypeMenu(),n.appendChild(this.sep());let s=document.createElement(`div`);s.style.position=`relative`,s.style.display=`inline-flex`;let c=document.createElement(`button`);c.className=`tcw-dropdown-trigger`,c.dataset.role=`indicators`,s.appendChild(c),n.appendChild(s),this.indicatorDropdown=new g(s,{width:`280px`}),this.buildIndicatorMenu(),this.chipsContainer=document.createElement(`div`),this.chipsContainer.className=`tcw-indicator-chips`,n.appendChild(this.chipsContainer),n.appendChild(this.spacer());let l=this.iconBtn(`camera`,`Screenshot`,t.onScreenshot);n.appendChild(l);let u=this.iconBtn(`settings`,`Chart Settings`,t.onSettings);n.appendChild(u),this.themeBtn=this.iconBtn(`moon`,`Toggle theme`,t.onToggleTheme),this.themeBtn.dataset.role=`theme`,n.appendChild(this.themeBtn)}buildChartTypeMenu(){if(!this.chartTypeDropdown)return;let e=this.config.chartTypes.map(e=>`<button class="tcw-dropdown-item" data-ct="${e.value}">${e.label}</button>`).join(``);this.chartTypeDropdown.setContent(e),this.chartTypeDropdown.panel.querySelectorAll(`.tcw-dropdown-item`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ct;this.callbacks.onChartType(t),this.chartTypeDropdown?.close()})})}buildIndicatorMenu(){if(!this.indicatorDropdown)return;let{indicators:e,popularIndicatorIds:t}=this.config,n=e.filter(e=>t.includes(e.id)),r=e.filter(e=>!t.includes(e.id)),i=`<div class="tcw-dropdown-label">Popular</div>`;for(let e of n)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;i+=`<div class="tcw-dropdown-divider"></div>`,i+=`<div class="tcw-dropdown-label">All</div>`;for(let e of r)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;this.indicatorDropdown.setContent(i),this.indicatorDropdown.panel.querySelectorAll(`.tcw-dropdown-item[data-ind]`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ind;this.callbacks.onAddIndicator(t)})})}update(e){let t=this.el.querySelector(`[data-role="symbol"]`);t&&(t.textContent=e.symbol);for(let t of this.tfButtons)t.classList.toggle(`tcw-active`,t.dataset.tf===e.timeframe);let n=this.el.querySelector(`[data-role="charttype"]`);if(n){let t=this.config.chartTypes.find(t=>t.value===e.chartType)?.label??`Candles`;n.innerHTML=`${h(`barChart`,14)} ${t} ${h(`chevronDown`,12)}`}let r=this.el.querySelector(`[data-role="indicators"]`);if(r){let t=e.activeIndicators.size,n=`${h(`trendingUp`,14)} Indicators`;t>0&&(n+=` <span class="tcw-badge-count">${t}</span>`),r.innerHTML=n}if(this.chipsContainer){let t=this.getActiveIndicatorList(e);this.chipsContainer.innerHTML=``;for(let e of t){let t=document.createElement(`div`);t.className=`tcw-indicator-chip`;let n=document.createElement(`span`);n.textContent=e.label,t.appendChild(n);let r=document.createElement(`button`);r.className=`tcw-chip-remove`,r.innerHTML=h(`x`,10),r.addEventListener(`click`,()=>this.callbacks.onRemoveIndicator(e.instanceId)),t.appendChild(r),this.chipsContainer.appendChild(t)}}this.themeBtn&&(this.themeBtn.innerHTML=e.isDark?h(`moon`,14):h(`sun`,14))}getActiveIndicatorList(e){let t=[];for(let[n,r]of e.activeIndicators.entries())t.push({instanceId:r,id:n,label:n.toUpperCase()});return t}sep(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-sep`,e}spacer(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-spacer`,e}iconBtn(e,t,n){let r=document.createElement(`button`);return r.className=`tcw-btn-icon`,r.title=t,r.innerHTML=h(e,14),r.addEventListener(`click`,n),r}destroy(){this.chartTypeDropdown?.destroy(),this.indicatorDropdown?.destroy(),this.el.remove()}},v=[`trendingUp`,`minus`,`penLine`,`hash`,`square`,`gitBranch`,`ruler`,`type`],y=class{config;callbacks;el;groupWraps=[];groupButtons=[];cursorBtn=null;magnetBtn=null;flyoutEl=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-sidebar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this;this.cursorBtn=document.createElement(`button`),this.cursorBtn.className=`tcw-sidebar-btn`,this.cursorBtn.title=`Cursor`,this.cursorBtn.innerHTML=h(`cursor`,14),this.cursorBtn.addEventListener(`click`,t.onCancelDrawing),n.appendChild(this.cursorBtn),n.appendChild(this.divider()),e.drawingToolGroups.forEach((e,r)=>{let i=document.createElement(`div`);i.className=`tcw-tool-group-wrap`;let a=document.createElement(`button`);if(a.className=`tcw-sidebar-btn`,a.title=e.label,a.innerHTML=h(v[r]??`square`,14),e.tools.length>1){let e=document.createElement(`span`);e.className=`tcw-multi-dot`,a.appendChild(e)}a.addEventListener(`click`,()=>t.onDrawingTool(e.tools[0].value)),i.appendChild(a),i.addEventListener(`mouseenter`,()=>this.showFlyout(r)),i.addEventListener(`mouseleave`,()=>this.hideFlyout()),n.appendChild(i),this.groupWraps.push(i),this.groupButtons.push(a)});let r=document.createElement(`div`);r.className=`tcw-sidebar-spacer`,n.appendChild(r),n.appendChild(this.divider()),this.magnetBtn=document.createElement(`button`),this.magnetBtn.className=`tcw-sidebar-btn`,this.magnetBtn.title=`Magnet`,this.magnetBtn.innerHTML=h(`magnet`,14),this.magnetBtn.addEventListener(`click`,t.onToggleMagnet),n.appendChild(this.magnetBtn);let i=document.createElement(`button`);i.className=`tcw-sidebar-btn`,i.title=`Undo`,i.innerHTML=h(`undo`,14),i.addEventListener(`click`,t.onUndo),n.appendChild(i);let a=document.createElement(`button`);a.className=`tcw-sidebar-btn`,a.title=`Redo`,a.innerHTML=h(`redo`,14),a.addEventListener(`click`,t.onRedo),n.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-sidebar-btn tcw-danger`,o.title=`Clear all`,o.innerHTML=h(`trash`,14),o.addEventListener(`click`,t.onClearDrawings),n.appendChild(o)}showFlyout(e){let t=this.config.drawingToolGroups[e];if(!t||t.tools.length<=1)return;this.hideFlyout();let n=document.createElement(`div`);n.className=`tcw-flyout`;let r=document.createElement(`div`);r.className=`tcw-flyout-header`,r.textContent=t.label,n.appendChild(r);for(let e of t.tools){let t=document.createElement(`button`);t.className=`tcw-flyout-item`,t.textContent=e.label,t.dataset.toolValue=e.value,t.addEventListener(`click`,()=>{this.callbacks.onDrawingTool(e.value),this.hideFlyout()}),n.appendChild(t)}this.flyoutEl=n,this.groupWraps[e].appendChild(n)}hideFlyout(){this.flyoutEl&&=(this.flyoutEl.remove(),null)}update(e){this.cursorBtn&&this.cursorBtn.classList.toggle(`tcw-active`,e.activeTool===null);let{drawingToolGroups:t}=this.config;for(let n=0;n<t.length;n++){let r=t[n].tools.some(t=>t.value===e.activeTool);this.groupButtons[n].classList.toggle(`tcw-active`,r)}this.flyoutEl&&this.flyoutEl.querySelectorAll(`.tcw-flyout-item`).forEach(t=>{let n=t;n.classList.toggle(`tcw-active`,n.dataset.toolValue===e.activeTool)}),this.magnetBtn&&(this.magnetBtn.classList.toggle(`tcw-active`,e.magnetEnabled),this.magnetBtn.title=e.magnetEnabled?`Magnet ON`:`Magnet OFF`)}divider(){let e=document.createElement(`div`);return e.className=`tcw-sidebar-divider`,e}destroy(){this.hideFlyout(),this.el.remove()}},b=[`style`,`display`,`scale`],x=class{callbacks;backdrop=null;modal=null;currentTab=`style`;currentSettings=null;bodyEl=null;tabButtons=[];constructor(e){this.callbacks=e}open(e){this.currentSettings={...e},this.currentTab=`style`,this.buildModal()}close(){this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.bodyEl=null,this.tabButtons=[]}buildModal(){this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),document.body.appendChild(this.backdrop),this.modal=document.createElement(`div`),this.modal.className=`tcw-modal`;let e=document.createElement(`div`);e.className=`tcw-modal-header`;let t=document.createElement(`h3`);t.textContent=`Chart Settings`,e.appendChild(t);let n=document.createElement(`button`);n.className=`tcw-modal-close`,n.innerHTML=h(`x`,16),n.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),e.appendChild(n),this.modal.appendChild(e);let r=document.createElement(`div`);r.className=`tcw-modal-tabs`,this.tabButtons=[];for(let e of b){let t=document.createElement(`button`);t.className=`tcw-modal-tab`,t.textContent=e,t.dataset.tab=e,e===this.currentTab&&t.classList.add(`tcw-active`),t.addEventListener(`click`,()=>{this.currentTab=e,this.tabButtons.forEach(t=>t.classList.toggle(`tcw-active`,t.dataset.tab===e)),this.renderTabContent()}),r.appendChild(t),this.tabButtons.push(t)}this.modal.appendChild(r),this.bodyEl=document.createElement(`div`),this.bodyEl.className=`tcw-modal-body`,this.modal.appendChild(this.bodyEl),this.renderTabContent();let i=document.createElement(`div`);i.className=`tcw-modal-footer`;let a=document.createElement(`button`);a.className=`tcw-reset-link`,a.textContent=`Reset to defaults`,a.addEventListener(`click`,()=>this.callbacks.onReset()),i.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-done-btn`,o.textContent=`Done`,o.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),i.appendChild(o),this.modal.appendChild(i),document.body.appendChild(this.modal);let s=e=>{e.key===`Escape`&&(document.removeEventListener(`keydown`,s),this.callbacks.onClose(),this.close())};document.addEventListener(`keydown`,s)}renderTabContent(){if(!(!this.bodyEl||!this.currentSettings))switch(this.bodyEl.innerHTML=``,this.currentTab){case`style`:this.renderStyleTab();break;case`display`:this.renderDisplayTab();break;case`scale`:this.renderScaleTab();break}}renderStyleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section(`Candle Colors`);t.appendChild(this.colorRow(`Up Body`,e.candleUpColor,e=>this.patch({candleUpColor:e}))),t.appendChild(this.colorRow(`Down Body`,e.candleDownColor,e=>this.patch({candleDownColor:e}))),t.appendChild(this.colorRow(`Up Wick`,e.candleUpWick,e=>this.patch({candleUpWick:e}))),t.appendChild(this.colorRow(`Down Wick`,e.candleDownWick,e=>this.patch({candleDownWick:e}))),this.bodyEl.appendChild(t);let n=this.section(`Background`);n.appendChild(this.colorRow(`Background`,e.backgroundColor,e=>this.patch({backgroundColor:e}))),n.appendChild(this.colorRow(`Grid`,e.gridColor,e=>this.patch({gridColor:e}))),this.bodyEl.appendChild(n)}renderDisplayTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Grid Lines`,e.gridVisible,e=>this.patch({gridVisible:e}))),t.appendChild(this.toggleRow(`Volume`,e.volumeVisible,e=>this.patch({volumeVisible:e}))),t.appendChild(this.toggleRow(`OHLC Legend`,e.legendVisible,e=>this.patch({legendVisible:e}))),t.appendChild(this.toggleRow(`Bar Countdown`,e.barCountdown,e=>this.patch({barCountdown:e}))),t.appendChild(this.selectRow(`Crosshair Mode`,e.crosshairMode,[{label:`Magnet`,value:`magnet`},{label:`Normal`,value:`normal`},{label:`Hidden`,value:`hidden`}],e=>this.patch({crosshairMode:e}))),t.appendChild(this.selectRow(`Number Locale`,e.numberLocale,[{label:`en-US (65,234.00)`,value:`en-US`},{label:`de-DE (65.234,00)`,value:`de-DE`},{label:`fr-FR (65 234,00)`,value:`fr-FR`},{label:`vi-VN (65.234,00)`,value:`vi-VN`},{label:`en-IN (65,234.00)`,value:`en-IN`},{label:`ja-JP (65,234.00)`,value:`ja-JP`}],e=>this.patch({numberLocale:e}))),this.bodyEl.appendChild(t)}renderScaleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Auto Scale`,e.autoScale,e=>this.patch({autoScale:e}))),t.appendChild(this.toggleRow(`Log Scale`,e.logScale,e=>this.patch({logScale:e}))),this.bodyEl.appendChild(t)}patch(e){this.currentSettings&&Object.assign(this.currentSettings,e),this.callbacks.onChange(e)}section(e){let t=document.createElement(`div`);if(t.className=`tcw-settings-section`,e){let n=document.createElement(`div`);n.className=`tcw-settings-section-title`,n.textContent=e,t.appendChild(n)}return t}colorRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`div`);a.className=`tcw-color-picker-wrap`;let o=document.createElement(`input`);o.type=`color`,o.value=t;let s=document.createElement(`span`);return s.className=`tcw-color-hex`,s.textContent=t,o.addEventListener(`input`,()=>{s.textContent=o.value,n(o.value)}),a.appendChild(o),a.appendChild(s),r.appendChild(a),r}toggleRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`button`);return a.className=`tcw-toggle${t?` tcw-on`:``}`,a.addEventListener(`click`,()=>{let e=!a.classList.contains(`tcw-on`);a.classList.toggle(`tcw-on`,e),n(e)}),r.appendChild(a),r}selectRow(e,t,n,r){let i=document.createElement(`div`);i.className=`tcw-settings-row`;let a=document.createElement(`span`);a.className=`tcw-settings-label`,a.textContent=e,i.appendChild(a);let o=document.createElement(`select`);o.className=`tcw-settings-select`;for(let e of n){let n=document.createElement(`option`);n.value=e.value,n.textContent=e.label,e.value===t&&(n.selected=!0),o.appendChild(n)}return o.addEventListener(`change`,()=>r(o.value)),i.appendChild(o),i}destroy(){this.close()}},S=class{el;dotEl;messageEl;infoEl;constructor(e){this.el=document.createElement(`div`),this.el.className=`tcw-statusbar`;let t=document.createElement(`div`);t.className=`tcw-status-indicator`,this.dotEl=document.createElement(`span`),this.dotEl.className=`tcw-status-dot`,t.appendChild(this.dotEl),this.messageEl=document.createElement(`span`),t.appendChild(this.messageEl),this.el.appendChild(t),this.infoEl=document.createElement(`span`),this.el.appendChild(this.infoEl),e.appendChild(this.el)}update(e){this.dotEl.className=`tcw-status-dot`,e.connectionState===`connected`?this.dotEl.classList.add(`tcw-connected`):e.connectionState===`error`&&this.dotEl.classList.add(`tcw-error`),this.messageEl.textContent=e.message,this.infoEl.textContent=`${e.symbol} ${e.timeframe}`}destroy(){this.el.remove()}},C=class{backdrop=null;modal=null;input=null;list=null;items=[];filtered=[];selectedIndex=0;callbacks;boundKeydown;constructor(e){this.callbacks=e,this.boundKeydown=this.handleKeydown.bind(this)}open(e){if(this.backdrop)return;this.items=e,this.filtered=e,this.selectedIndex=0,this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>this.close()),this.modal=document.createElement(`div`),this.modal.className=`tcw-cmd-palette`;let t=document.createElement(`div`);t.className=`tcw-cmd-header`;let n=document.createElement(`span`);n.className=`tcw-cmd-icon`,n.textContent=`⌕`,t.appendChild(n),this.input=document.createElement(`input`),this.input.className=`tcw-cmd-input`,this.input.type=`text`,this.input.placeholder=`Search indicators, chart types, tools...`,this.input.addEventListener(`input`,()=>this.filter()),t.appendChild(this.input);let r=document.createElement(`span`);r.className=`tcw-cmd-hint`,r.textContent=`ESC`,t.appendChild(r),this.modal.appendChild(t),this.list=document.createElement(`div`),this.list.className=`tcw-cmd-list`,this.modal.appendChild(this.list);let i=document.createElement(`div`);i.className=`tcw-cmd-footer`,i.innerHTML=`<span>↑↓ Navigate</span><span>⏎ Select</span><span>Esc Close</span>`,this.modal.appendChild(i),document.body.appendChild(this.backdrop),document.body.appendChild(this.modal),this.renderList(),this.input.focus(),document.addEventListener(`keydown`,this.boundKeydown)}close(){document.removeEventListener(`keydown`,this.boundKeydown),this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.input=null,this.list=null,this.callbacks.onClose()}isOpen(){return this.backdrop!==null}filter(){let e=this.input?.value.toLowerCase().trim()??``;e?this.filtered=this.items.filter(t=>t.label.toLowerCase().includes(e)||t.category.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)):this.filtered=this.items,this.selectedIndex=0,this.renderList()}renderList(){if(!this.list)return;if(this.list.innerHTML=``,this.filtered.length===0){let e=document.createElement(`div`);e.className=`tcw-cmd-empty`,e.textContent=`No results found`,this.list.appendChild(e);return}let e=``;for(let t=0;t<this.filtered.length;t++){let n=this.filtered[t];if(n.category!==e){e=n.category;let t=document.createElement(`div`);t.className=`tcw-cmd-category`,t.textContent=this.categoryLabel(e),this.list.appendChild(t)}let r=document.createElement(`button`);r.className=`tcw-cmd-item`,t===this.selectedIndex&&r.classList.add(`tcw-selected`),n.active&&r.classList.add(`tcw-active`),r.dataset.index=String(t);let i=document.createElement(`span`);if(i.className=`tcw-cmd-item-label`,i.textContent=n.label,r.appendChild(i),n.active){let e=document.createElement(`span`);e.className=`tcw-cmd-check`,e.textContent=`✓`,r.appendChild(e)}if(n.shortcut){let e=document.createElement(`kbd`);e.className=`tcw-cmd-kbd`,e.textContent=n.shortcut,r.appendChild(e)}r.addEventListener(`click`,()=>this.select(t)),r.addEventListener(`mouseenter`,()=>{this.selectedIndex=t,this.updateSelection()}),this.list.appendChild(r)}}updateSelection(){if(!this.list)return;let e=this.list.querySelectorAll(`.tcw-cmd-item`);e.forEach((e,t)=>{e.classList.toggle(`tcw-selected`,t===this.selectedIndex)}),e[this.selectedIndex]?.scrollIntoView({block:`nearest`})}select(e){let t=this.filtered[e];if(t){switch(t.category){case`indicator`:this.callbacks.onIndicator(t.id);break;case`chartType`:this.callbacks.onChartType(t.id);break;case`drawing`:this.callbacks.onDrawingTool(t.id);break;case`timeframe`:this.callbacks.onTimeframe(t.id);break;case`action`:this.callbacks.onAction(t.id);break}this.close()}}handleKeydown(e){switch(e.key){case`Escape`:e.preventDefault(),this.close();break;case`ArrowDown`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex+1)%this.filtered.length,this.updateSelection());break;case`ArrowUp`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex-1+this.filtered.length)%this.filtered.length,this.updateSelection());break;case`Enter`:e.preventDefault(),this.select(this.selectedIndex);break}}categoryLabel(e){switch(e){case`indicator`:return`Indicators`;case`chartType`:return`Chart Types`;case`drawing`:return`Drawing Tools`;case`timeframe`:return`Timeframes`;case`action`:return`Actions`;default:return e}}destroy(){this.close()}},w=class{chart;state;toolbar=null;sidebar=null;settings=null;statusBar=null;commandPalette=null;root;chartContainer;destroyed=!1;options;symbolIndex=0;symbols;settingsState;adapter=null;boundGlobalKeydown=null;constructor(t,l={}){this.options=l,this.symbols=l.symbols??s,this.settingsState={...c};let u=this.resolveIsDark(l.theme),d=this.resolveTheme(l.theme);this.state={symbol:l.symbol??this.symbols[0]??`BTCUSDT`,timeframe:l.timeframe??`5m`,chartType:l.chartOptions?.chartType??`candlestick`,isDark:u,activeIndicators:new Map,activeTool:null,magnetEnabled:!0,connectionState:`connecting`,connectionMessage:`Connecting...`};let p=this.symbols.indexOf(this.state.symbol);p>=0&&(this.symbolIndex=p),f(),this.root=document.createElement(`div`),this.root.className=`tcw-root`,this.root.dataset.tcwTheme=u?`dark`:`light`,t.appendChild(this.root),l.toolbar!==!1&&(this.toolbar=new _(this.root,{symbols:this.symbols,timeframes:l.timeframes?n.filter(e=>l.timeframes.includes(e.value)):n,chartTypes:l.chartTypes?r.filter(e=>l.chartTypes.includes(e.value)):r,indicators:a,popularIndicatorIds:o},{onSymbolClick:()=>this.handleSymbolClick(),onTimeframe:e=>this.handleTimeframe(e),onChartType:e=>this.handleChartType(e),onAddIndicator:e=>this.handleAddIndicator(e),onRemoveIndicator:e=>this.handleRemoveIndicator(e),onScreenshot:()=>this.chart.screenshot(),onSettings:()=>this.openSettings(),onToggleTheme:()=>this.handleToggleTheme()}));let m=document.createElement(`div`);m.className=`tcw-body`,l.drawingTools!==!1&&(this.sidebar=new y(m,{drawingToolGroups:i},{onDrawingTool:e=>this.handleDrawingTool(e),onCancelDrawing:()=>this.handleCancelDrawing(),onToggleMagnet:()=>this.handleToggleMagnet(),onUndo:()=>this.chart.undo(),onRedo:()=>this.chart.redo(),onClearDrawings:()=>{this.chart.clearDrawings(),this.state={...this.state,activeTool:null},this.updateUI()}})),this.chartContainer=document.createElement(`div`),this.chartContainer.className=`tcw-chart-container`,m.appendChild(this.chartContainer),this.root.appendChild(m),this.chart=new e.t(this.chartContainer,{chartType:this.state.chartType,theme:d,autoScale:!0,crosshair:{mode:`magnet`},features:{drawings:!0,drawingMagnet:!0,drawingUndoRedo:!0,indicators:!0,trading:l.trading!==!1,tradingContextMenu:l.trading!==!1,volume:!0,legend:!0,crosshair:!0,keyboard:!0,screenshot:!0,alerts:!0,barCountdown:!0,logScale:!0,watermark:!0},...l.chartOptions}),l.statusBar!==!1&&(this.statusBar=new S(this.root)),l.settings!==!1&&(this.settings=new x({onChange:e=>this.applySettings(e),onReset:()=>this.resetSettings(),onClose:()=>{}})),this.commandPalette=new C({onIndicator:e=>this.handleAddIndicator(e),onChartType:e=>this.handleChartType(e),onDrawingTool:e=>this.handleDrawingTool(e),onTimeframe:e=>this.handleTimeframe(e),onAction:e=>this.handleAction(e),onClose:()=>{}}),this.boundGlobalKeydown=e=>{(e.ctrlKey||e.metaKey)&&e.key===`k`&&(e.preventDefault(),this.toggleCommandPalette())},document.addEventListener(`keydown`,this.boundGlobalKeydown),l.adapter&&(this.adapter=l.adapter,this.connectStream()),this.updateUI(),l.onReady?.(this.chart)}async setSymbol(e){this.state={...this.state,symbol:e};let t=this.symbols.indexOf(e);t>=0&&(this.symbolIndex=t),this.options.onSymbolChange?.(e),this.updateUI(),this.adapter&&await this.connectStream()}async setTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&await this.connectStream()}setTheme(e){let t=this.resolveIsDark(e),n=this.resolveTheme(e);this.state={...this.state,isDark:t},this.root.dataset.tcwTheme=t?`dark`:`light`,this.chart.setTheme(n),this.updateUI()}getChart(){return this.chart}destroy(){this.destroyed||(this.destroyed=!0,this.boundGlobalKeydown&&document.removeEventListener(`keydown`,this.boundGlobalKeydown),this.commandPalette?.destroy(),this.toolbar?.destroy(),this.sidebar?.destroy(),this.settings?.destroy(),this.statusBar?.destroy(),this.chart.destroy(),this.root.remove(),p())}handleSymbolClick(){this.symbolIndex=(this.symbolIndex+1)%this.symbols.length;let e=this.symbols[this.symbolIndex];this.state={...this.state,symbol:e},this.options.onSymbolChange?.(e),this.updateUI(),this.adapter&&this.connectStream()}handleTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&this.connectStream()}handleChartType(e){this.state={...this.state,chartType:e},this.chart.setChartType(e),this.updateUI()}handleAddIndicator(e){if(this.state.activeIndicators.has(e)){let t=this.state.activeIndicators.get(e);this.chart.removeIndicator(t);let n=new Map(this.state.activeIndicators);n.delete(e),this.state={...this.state,activeIndicators:n}}else{let t=this.chart.addIndicator(e);if(t){let n=new Map(this.state.activeIndicators);n.set(e,t),this.state={...this.state,activeIndicators:n}}}this.updateUI()}handleRemoveIndicator(e){this.chart.removeIndicator(e);let t=new Map(this.state.activeIndicators);for(let[n,r]of t.entries())if(r===e){t.delete(n);break}this.state={...this.state,activeIndicators:t},this.updateUI()}toggleCommandPalette(){if(this.commandPalette?.isOpen()){this.commandPalette.close();return}this.commandPalette?.open(this.buildCommandItems())}buildCommandItems(){let e=[];for(let t of a)e.push({id:t.id,label:t.name,category:`indicator`,active:this.state.activeIndicators.has(t.id)});for(let t of r)e.push({id:t.value,label:t.label,category:`chartType`,active:this.state.chartType===t.value});for(let t of i)for(let n of t.tools)e.push({id:n.value,label:n.label,category:`drawing`,active:this.state.activeTool===n.value});for(let t of n)e.push({id:t.value,label:t.label,category:`timeframe`,active:this.state.timeframe===t.value});return e.push({id:`screenshot`,label:`Screenshot`,category:`action`,shortcut:``},{id:`toggleTheme`,label:`Toggle Theme`,category:`action`},{id:`settings`,label:`Settings`,category:`action`},{id:`clearDrawings`,label:`Clear All Drawings`,category:`action`}),e}handleAction(e){switch(e){case`screenshot`:this.chart.screenshot();break;case`toggleTheme`:this.handleToggleTheme();break;case`settings`:this.openSettings();break;case`clearDrawings`:this.chart.clearDrawings(),this.state={...this.state,activeTool:null},this.updateUI();break}}handleDrawingTool(e){this.state={...this.state,activeTool:e},this.chart.setDrawingTool(e),this.updateUI()}handleCancelDrawing(){this.state={...this.state,activeTool:null},this.chart.setDrawingTool(null),this.updateUI()}handleToggleMagnet(){let e=!this.state.magnetEnabled;this.state={...this.state,magnetEnabled:e},this.chart.setDrawingMagnet(e),this.updateUI()}handleToggleTheme(){let e=!this.state.isDark;this.state={...this.state,isDark:e},this.root.dataset.tcwTheme=e?`dark`:`light`,this.chart.setTheme(e?t.DARK_THEME:t.LIGHT_THEME),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:e?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.updateUI()}openSettings(){this.settings?.open(this.settingsState)}applySettings(e){this.settingsState={...this.settingsState,...e},e.gridVisible!==void 0&&this.chart.setGridVisible(e.gridVisible),e.volumeVisible!==void 0&&this.chart.setVolumeVisible(e.volumeVisible),e.crosshairMode!==void 0&&this.chart.setCrosshairMode(e.crosshairMode),e.autoScale!==void 0&&this.chart.setAutoScale(e.autoScale),e.logScale!==void 0&&this.chart.setLogScale(e.logScale),e.numberLocale!==void 0&&this.chart.setNumberLocale(e.numberLocale);let t={...this.chart.getTheme()},n=!1;e.candleUpColor!==void 0&&(t.candleUp=e.candleUpColor,n=!0),e.candleDownColor!==void 0&&(t.candleDown=e.candleDownColor,n=!0),e.candleUpWick!==void 0&&(t.candleUpWick=e.candleUpWick,n=!0),e.candleDownWick!==void 0&&(t.candleDownWick=e.candleDownWick,n=!0),e.backgroundColor!==void 0&&(t.background=e.backgroundColor,n=!0),e.gridColor!==void 0&&(t.grid=e.gridColor,n=!0),n&&this.chart.setTheme(t)}resetSettings(){this.settingsState={...c},this.applySettings(this.settingsState)}async connectStream(){if(this.adapter){this.state={...this.state,connectionState:`connecting`,connectionMessage:`Connecting...`},this.updateUI();try{this.chart.disconnectStream(),await this.chart.connect({adapter:this.adapter,symbol:this.state.symbol,timeframe:this.state.timeframe,historyLimit:this.options.historyLimit??500}),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:this.state.isDark?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.state={...this.state,connectionState:`connected`,connectionMessage:`Live`}}catch(e){this.state={...this.state,connectionState:`error`,connectionMessage:e instanceof Error?e.message:`Connection failed`}}this.updateUI()}}updateUI(){this.toolbar?.update(this.state),this.sidebar?.update(this.state),this.statusBar?.update({connectionState:this.state.connectionState,message:this.state.connectionMessage,symbol:this.state.symbol,timeframe:this.state.timeframe})}resolveIsDark(e){return e===void 0||e===`dark`?!0:e===`light`?!1:typeof e==`object`&&e.background?this.isColorDark(e.background):!0}resolveTheme(e){return e===void 0||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:typeof e==`object`?e:t.DARK_THEME}isColorDark(e){if(e.startsWith(`#`)&&e.length>=7){let t=parseInt(e.slice(1,3),16),n=parseInt(e.slice(3,5),16),r=parseInt(e.slice(5,7),16);return t+n+r<384}return!0}};exports.ChartWidget=w;
740
878
  //# sourceMappingURL=index.cjs.map