@funnest/charts-ui 0.5.2 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/context-menu.d.ts +8 -0
- package/dist/context.d.ts +20 -2
- package/dist/i18n.d.ts +48 -0
- package/dist/icons.d.ts +12 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +974 -525
- package/dist/pane.d.ts +2 -1
- package/dist/shell.d.ts +4 -0
- package/dist/trading-chart.d.ts +6 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -267,6 +267,160 @@ n = { __e: function(n2, t3, r3, u3) {
|
|
|
267
267
|
return n2.__v.__b - t3.__v.__b;
|
|
268
268
|
}, e = /* @__PURE__ */ Symbol(), l = /(PointerCapture)$|Capture$/i, c = 0, a = {}, s = 0;
|
|
269
269
|
|
|
270
|
+
// ../../node_modules/.pnpm/preact@11.2.0/node_modules/preact/hooks/dist/hooks.mjs
|
|
271
|
+
var t2;
|
|
272
|
+
var r2;
|
|
273
|
+
var u2;
|
|
274
|
+
var i2;
|
|
275
|
+
var o2 = Object.is;
|
|
276
|
+
var f2 = 0;
|
|
277
|
+
var c2 = [];
|
|
278
|
+
var e2 = [];
|
|
279
|
+
var a2 = n;
|
|
280
|
+
var v2 = a2.__b;
|
|
281
|
+
var l2 = a2.__r;
|
|
282
|
+
var m2 = a2.diffed;
|
|
283
|
+
var h2 = a2.__c;
|
|
284
|
+
var s2 = a2.unmount;
|
|
285
|
+
var p2 = a2.__;
|
|
286
|
+
function y2(n2, t3) {
|
|
287
|
+
a2.__h && a2.__h(r2, n2, f2 || t3), f2 = 0;
|
|
288
|
+
var u3 = r2.__H || (r2.__H = { __: [], __h: [] });
|
|
289
|
+
return n2 >= u3.__.length && u3.__.push({}), u3.__[n2];
|
|
290
|
+
}
|
|
291
|
+
function d2(n2) {
|
|
292
|
+
return f2 = 1, _2(G2, n2);
|
|
293
|
+
}
|
|
294
|
+
function _2(n2, u3, i3) {
|
|
295
|
+
var f4 = y2(t2++, 2);
|
|
296
|
+
if (f4.t = n2, !f4.__c && (f4.__ = [i3 ? i3(u3) : G2(void 0, u3), function(n3) {
|
|
297
|
+
var t3 = (f4.__N || f4.__)[0], r3 = f4.t(t3, n3);
|
|
298
|
+
o2(t3, r3) || (f4.__N = [r3, f4.__[1]], f4.__c.setState({}));
|
|
299
|
+
}], f4.__c = r2, !r2.__f)) {
|
|
300
|
+
r2.__f = true;
|
|
301
|
+
var c3 = r2.shouldComponentUpdate;
|
|
302
|
+
r2.shouldComponentUpdate = function(n3, t3, r3) {
|
|
303
|
+
var u4 = this.__H;
|
|
304
|
+
if (!u4) return true;
|
|
305
|
+
var i4 = false, f5 = this.props != n3;
|
|
306
|
+
if (u4.__.some(function(n4) {
|
|
307
|
+
n4.__N && (i4 = true, o2(n4.__[0], n4.__N[0]) || (f5 = true));
|
|
308
|
+
}), c3) {
|
|
309
|
+
var e3 = c3.call(this, n3, t3, r3);
|
|
310
|
+
return i4 ? e3 || f5 : e3;
|
|
311
|
+
}
|
|
312
|
+
return !i4 || f5;
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
return f4.__;
|
|
316
|
+
}
|
|
317
|
+
function A2(n2, u3) {
|
|
318
|
+
var i3 = y2(t2++, 3);
|
|
319
|
+
!a2.__s && E2(i3.__H, u3) && (i3.__P = true, i3.__ = n2, i3.u = u3, r2.__H.__h.push(i3));
|
|
320
|
+
}
|
|
321
|
+
function F2(n2, u3) {
|
|
322
|
+
var i3 = y2(t2++, 4);
|
|
323
|
+
!a2.__s && E2(i3.__H, u3) && (i3.__P = false, i3.__ = n2, i3.u = u3, r2.__h.push(i3));
|
|
324
|
+
}
|
|
325
|
+
function T2(n2) {
|
|
326
|
+
return f2 = 5, w2(function() {
|
|
327
|
+
return { current: n2 };
|
|
328
|
+
}, []);
|
|
329
|
+
}
|
|
330
|
+
function w2(n2, r3) {
|
|
331
|
+
var u3 = y2(t2++, 7);
|
|
332
|
+
return E2(u3.__H, r3) && (u3.__ = n2(), u3.__H = r3), u3.__;
|
|
333
|
+
}
|
|
334
|
+
function g2() {
|
|
335
|
+
var n2;
|
|
336
|
+
do {
|
|
337
|
+
for (; n2 = e2.shift(); ) try {
|
|
338
|
+
C2(n2);
|
|
339
|
+
} catch (t4) {
|
|
340
|
+
a2.__e(t4, { __: (n2 = n2.__P) && n2.__v });
|
|
341
|
+
}
|
|
342
|
+
for (; n2 = c2.shift(); ) {
|
|
343
|
+
var t3 = n2.__H;
|
|
344
|
+
if (n2.__P && t3) try {
|
|
345
|
+
t3.__h.some(C2), t3.__h.some(D2), t3.__h = [];
|
|
346
|
+
} catch (r3) {
|
|
347
|
+
t3.__h = [], a2.__e(r3, n2.__v);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
} while (e2.length);
|
|
351
|
+
}
|
|
352
|
+
a2.__b = function(n2) {
|
|
353
|
+
r2 = null, v2 && v2(n2);
|
|
354
|
+
}, a2.__ = function(n2, t3) {
|
|
355
|
+
n2 && t3.__k && t3.__k.__m && (n2.__m = t3.__k.__m), p2 && p2(n2, t3);
|
|
356
|
+
}, a2.__r = function(n2) {
|
|
357
|
+
l2 && l2(n2), t2 = 0;
|
|
358
|
+
var i3 = (r2 = n2.__c).__H;
|
|
359
|
+
i3 && (u2 == r2 ? r2.__h = [] : (i3.__h.some(C2), i3.__h.some(D2), t2 = 0), i3.__h = [], i3.__.some(function(n3) {
|
|
360
|
+
n3.__N && (n3.__ = n3.__N), n3.u = n3.__N = void 0;
|
|
361
|
+
})), u2 = r2;
|
|
362
|
+
}, a2.diffed = function(n2) {
|
|
363
|
+
m2 && m2(n2);
|
|
364
|
+
var t3 = n2.__c;
|
|
365
|
+
t3 && t3.__H && (t3.__H.__h.length && B2(c2.push(t3)), t3.__H.__.some(function(n3) {
|
|
366
|
+
n3.u && (n3.__H = n3.u);
|
|
367
|
+
})), u2 = r2 = null;
|
|
368
|
+
}, a2.__c = function(n2, t3) {
|
|
369
|
+
t3.some(function(n3) {
|
|
370
|
+
try {
|
|
371
|
+
n3.__h.some(C2), n3.__h = n3.__h.filter(function(n4) {
|
|
372
|
+
return !n4.__ || D2(n4);
|
|
373
|
+
});
|
|
374
|
+
} catch (t4) {
|
|
375
|
+
n3.__h = [function() {
|
|
376
|
+
throw t4;
|
|
377
|
+
}];
|
|
378
|
+
}
|
|
379
|
+
}), h2 && h2(n2, t3);
|
|
380
|
+
}, a2.unmount = function(n2) {
|
|
381
|
+
s2 && s2(n2);
|
|
382
|
+
var t3, r3, u3 = n2.__c;
|
|
383
|
+
u3 && u3.__H && (u3.__H.__.some(function(u4) {
|
|
384
|
+
try {
|
|
385
|
+
if (u4.__P && u4.__c) {
|
|
386
|
+
if (void 0 === r3) {
|
|
387
|
+
for (r3 = n2.__; r3 && (!r3.__c || !r3.__c.__P); ) r3 = r3.__;
|
|
388
|
+
r3 = r3 && r3.__c;
|
|
389
|
+
}
|
|
390
|
+
u4.__P = r3, B2(e2.push(u4));
|
|
391
|
+
} else C2(u4);
|
|
392
|
+
} catch (n3) {
|
|
393
|
+
t3 = n3;
|
|
394
|
+
}
|
|
395
|
+
}), u3.__H = void 0, t3 && a2.__e(t3, u3.__v));
|
|
396
|
+
};
|
|
397
|
+
var k = "function" == typeof requestAnimationFrame;
|
|
398
|
+
function z2(n2) {
|
|
399
|
+
var t3, r3 = function() {
|
|
400
|
+
clearTimeout(u3), k && cancelAnimationFrame(t3), setTimeout(n2);
|
|
401
|
+
}, u3 = setTimeout(r3, 35);
|
|
402
|
+
k && (t3 = requestAnimationFrame(r3));
|
|
403
|
+
}
|
|
404
|
+
function B2(n2) {
|
|
405
|
+
1 != n2 && i2 == a2.requestAnimationFrame || ((i2 = a2.requestAnimationFrame) || z2)(g2);
|
|
406
|
+
}
|
|
407
|
+
function C2(n2) {
|
|
408
|
+
var t3 = r2, u3 = n2.__c;
|
|
409
|
+
"function" == typeof u3 && (n2.__c = void 0, u3()), r2 = t3;
|
|
410
|
+
}
|
|
411
|
+
function D2(n2) {
|
|
412
|
+
var t3 = r2;
|
|
413
|
+
n2.__c = n2.__(), r2 = t3;
|
|
414
|
+
}
|
|
415
|
+
function E2(n2, t3) {
|
|
416
|
+
return !n2 || n2.length != t3.length || t3.some(function(t4, r3) {
|
|
417
|
+
return !o2(t4, n2[r3]);
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
function G2(n2, t3) {
|
|
421
|
+
return "function" == typeof t3 ? t3(n2) : t3;
|
|
422
|
+
}
|
|
423
|
+
|
|
270
424
|
// src/i18n.ts
|
|
271
425
|
var STRINGS = {
|
|
272
426
|
ko: {
|
|
@@ -310,6 +464,30 @@ var STRINGS = {
|
|
|
310
464
|
settingLastPrice: "\uD604\uC7AC\uAC00 \uC120",
|
|
311
465
|
settingVolume: "\uAC70\uB798\uB7C9",
|
|
312
466
|
settingNavButtons: "\uD655\uB300\xB7\uC774\uB3D9 \uBC84\uD2BC",
|
|
467
|
+
settingCountdown: "\uBD09 \uB9C8\uAC10\uAE4C\uC9C0 \uB0A8\uC740 \uC2DC\uAC04",
|
|
468
|
+
settingsScale: "\uAC00\uACA9 \uCD95",
|
|
469
|
+
scaleNormal: "\uC77C\uBC18",
|
|
470
|
+
scaleLog: "\uB85C\uADF8",
|
|
471
|
+
scalePercent: "%",
|
|
472
|
+
undo: "\uB418\uB3CC\uB9AC\uAE30",
|
|
473
|
+
horizontalAt: "{price}\uC5D0 \uC218\uD3C9\uC120 \uAE0B\uAE30",
|
|
474
|
+
resetChart: "\uCC28\uD2B8 \uCD08\uAE30\uD654",
|
|
475
|
+
chartSettingsMore: "\uCC28\uD2B8 \uC124\uC815\u2026",
|
|
476
|
+
redo: "\uB2E4\uC2DC \uC2E4\uD589",
|
|
477
|
+
compare: "\uBE44\uAD50",
|
|
478
|
+
compareSymbol: "\uBE44\uAD50\uD560 \uC885\uBAA9 \uCD94\uAC00",
|
|
479
|
+
removeCompare: "\uBE44\uAD50 \uD574\uC81C",
|
|
480
|
+
replay: "\uB9AC\uD50C\uB808\uC774",
|
|
481
|
+
replayPick: "\uC2DC\uC791\uD560 \uBD09\uC744 \uB204\uB974\uC138\uC694",
|
|
482
|
+
replayPlay: "\uC7AC\uC0DD",
|
|
483
|
+
replayPause: "\uC77C\uC2DC\uC815\uC9C0",
|
|
484
|
+
replayStep: "\uD55C \uBD09 \uC55E\uC73C\uB85C",
|
|
485
|
+
replayExit: "\uB9AC\uD50C\uB808\uC774 \uC885\uB8CC",
|
|
486
|
+
replaySpeed: "\uC18D\uB3C4",
|
|
487
|
+
replayRestart: "\uC2DC\uC791 \uC9C0\uC810 \uB2E4\uC2DC \uACE0\uB974\uAE30",
|
|
488
|
+
replayDone: "\uB05D\uAE4C\uC9C0 \uC7AC\uC0DD\uD588\uC5B4\uC694",
|
|
489
|
+
searchIndicators: "\uC9C0\uD45C \uAC80\uC0C9",
|
|
490
|
+
moreTools: "\uB3C4\uAD6C \uB354 \uBCF4\uAE30",
|
|
313
491
|
settingGridH: "\uAC00\uB85C \uACA9\uC790",
|
|
314
492
|
settingGridV: "\uC138\uB85C \uACA9\uC790",
|
|
315
493
|
resetDefaults: "\uAE30\uBCF8\uAC12\uC73C\uB85C",
|
|
@@ -417,6 +595,30 @@ var STRINGS = {
|
|
|
417
595
|
settingLastPrice: "Last price line",
|
|
418
596
|
settingVolume: "Volume",
|
|
419
597
|
settingNavButtons: "Zoom & scroll buttons",
|
|
598
|
+
settingCountdown: "Time to bar close",
|
|
599
|
+
settingsScale: "Price scale",
|
|
600
|
+
scaleNormal: "Regular",
|
|
601
|
+
scaleLog: "Log",
|
|
602
|
+
scalePercent: "%",
|
|
603
|
+
undo: "Undo",
|
|
604
|
+
horizontalAt: "Horizontal line at {price}",
|
|
605
|
+
resetChart: "Reset chart",
|
|
606
|
+
chartSettingsMore: "Chart settings\u2026",
|
|
607
|
+
redo: "Redo",
|
|
608
|
+
compare: "Compare",
|
|
609
|
+
compareSymbol: "Add symbol to compare",
|
|
610
|
+
removeCompare: "Remove comparison",
|
|
611
|
+
replay: "Replay",
|
|
612
|
+
replayPick: "Click the bar to start from",
|
|
613
|
+
replayPlay: "Play",
|
|
614
|
+
replayPause: "Pause",
|
|
615
|
+
replayStep: "Step forward",
|
|
616
|
+
replayExit: "Exit replay",
|
|
617
|
+
replaySpeed: "Speed",
|
|
618
|
+
replayRestart: "Pick a new start",
|
|
619
|
+
replayDone: "Reached the end",
|
|
620
|
+
searchIndicators: "Search indicators",
|
|
621
|
+
moreTools: "More tools",
|
|
420
622
|
settingGridH: "Horizontal grid",
|
|
421
623
|
settingGridV: "Vertical grid",
|
|
422
624
|
resetDefaults: "Reset",
|
|
@@ -506,19 +708,19 @@ function resolutionLabel(resolution, locale, form = "short") {
|
|
|
506
708
|
}
|
|
507
709
|
|
|
508
710
|
// ../../node_modules/.pnpm/preact@11.2.0/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs
|
|
509
|
-
var
|
|
510
|
-
var
|
|
511
|
-
function
|
|
711
|
+
var f3 = /* @__PURE__ */ Symbol.for("pv");
|
|
712
|
+
var o3 = 0;
|
|
713
|
+
function a3(t3, e3, n2, u3, a4, i3) {
|
|
512
714
|
e3 || (e3 = {});
|
|
513
715
|
var c3, l3, p3 = e3;
|
|
514
716
|
if ("ref" in p3 && "function" != typeof t3) for (l3 in p3 = {}, e3) "ref" == l3 ? c3 = e3[l3] : p3[l3] = e3[l3];
|
|
515
|
-
var s3 = { type: t3, props: p3, key: n2, ref: c3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor:
|
|
717
|
+
var s3 = { type: t3, props: p3, key: n2, ref: c3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: f3, __v: --o3, __i: -1, __u: 0 };
|
|
516
718
|
return (a4 || i3) && (s3.__source = a4, s3.__self = i3), n.vnode && n.vnode(s3), s3;
|
|
517
719
|
}
|
|
518
720
|
|
|
519
721
|
// src/icons.tsx
|
|
520
722
|
function Icon({ children, size = 20 }) {
|
|
521
|
-
return /* @__PURE__ */
|
|
723
|
+
return /* @__PURE__ */ a3(
|
|
522
724
|
"svg",
|
|
523
725
|
{
|
|
524
726
|
width: size,
|
|
@@ -534,245 +736,121 @@ function Icon({ children, size = 20 }) {
|
|
|
534
736
|
}
|
|
535
737
|
);
|
|
536
738
|
}
|
|
537
|
-
var SearchIcon = () => /* @__PURE__ */
|
|
538
|
-
/* @__PURE__ */
|
|
539
|
-
/* @__PURE__ */
|
|
739
|
+
var SearchIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: [
|
|
740
|
+
/* @__PURE__ */ a3("circle", { cx: "9", cy: "9", r: "5.5" }),
|
|
741
|
+
/* @__PURE__ */ a3("path", { d: "M13 13l3.5 3.5" })
|
|
540
742
|
] });
|
|
541
|
-
var CloseIcon = () => /* @__PURE__ */
|
|
542
|
-
var CameraIcon = () => /* @__PURE__ */
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
/* @__PURE__ */
|
|
743
|
+
var CloseIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M5.5 5.5l9 9M14.5 5.5l-9 9" }) });
|
|
744
|
+
var CameraIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
745
|
+
/* @__PURE__ */ a3("path", { d: "M3.5 7.2c0-.9.7-1.6 1.6-1.6h1.6l1.2-1.8h4.2l1.2 1.8h1.6c.9 0 1.6.7 1.6 1.6v6.6c0 .9-.7 1.6-1.6 1.6H5.1c-.9 0-1.6-.7-1.6-1.6z" }),
|
|
746
|
+
/* @__PURE__ */ a3("circle", { cx: "10", cy: "10.4", r: "2.6" })
|
|
545
747
|
] });
|
|
546
|
-
var ExpandIcon = () => /* @__PURE__ */
|
|
547
|
-
var CollapseIcon = () => /* @__PURE__ */
|
|
548
|
-
var MinusIcon = () => /* @__PURE__ */
|
|
549
|
-
var PlusIcon = () => /* @__PURE__ */
|
|
550
|
-
var ChevronLeftIcon = () => /* @__PURE__ */
|
|
551
|
-
var ChevronRightIcon = () => /* @__PURE__ */
|
|
552
|
-
var ResetIcon = () => /* @__PURE__ */
|
|
553
|
-
/* @__PURE__ */
|
|
554
|
-
/* @__PURE__ */
|
|
748
|
+
var ExpandIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M4 8V4h4M16 8V4h-4M4 12v4h4M16 12v4h-4" }) });
|
|
749
|
+
var CollapseIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M8 4v4H4M12 4v4h4M8 16v-4H4M12 16v-4h4" }) });
|
|
750
|
+
var MinusIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: /* @__PURE__ */ a3("path", { d: "M5 10h10" }) });
|
|
751
|
+
var PlusIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: /* @__PURE__ */ a3("path", { d: "M5 10h10M10 5v10" }) });
|
|
752
|
+
var ChevronLeftIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: /* @__PURE__ */ a3("path", { d: "M12 5l-5 5 5 5" }) });
|
|
753
|
+
var ChevronRightIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: /* @__PURE__ */ a3("path", { d: "M8 5l5 5-5 5" }) });
|
|
754
|
+
var ResetIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: [
|
|
755
|
+
/* @__PURE__ */ a3("path", { d: "M4.5 10a5.5 5.5 0 1 0 1.7-4" }),
|
|
756
|
+
/* @__PURE__ */ a3("path", { d: "M4.5 3.5V7H8" })
|
|
555
757
|
] });
|
|
556
|
-
var ToRealtimeIcon = () => /* @__PURE__ */
|
|
557
|
-
var ChevronDownIcon = () => /* @__PURE__ */
|
|
558
|
-
var CursorIcon = () => /* @__PURE__ */
|
|
559
|
-
var TrendLineIcon = () => /* @__PURE__ */
|
|
560
|
-
/* @__PURE__ */
|
|
561
|
-
/* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
758
|
+
var ToRealtimeIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: /* @__PURE__ */ a3("path", { d: "M5 5.5l4.5 4.5L5 14.5M10 5.5l4.5 4.5-4.5 4.5" }) });
|
|
759
|
+
var ChevronDownIcon = () => /* @__PURE__ */ a3(Icon, { size: 14, children: /* @__PURE__ */ a3("path", { d: "M5 8l5 5 5-5" }) });
|
|
760
|
+
var CursorIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M5 3.5l10 6.2-4.4 1.1-2 4.2z" }) });
|
|
761
|
+
var TrendLineIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
762
|
+
/* @__PURE__ */ a3("path", { d: "M5 15L15 5" }),
|
|
763
|
+
/* @__PURE__ */ a3("circle", { cx: "5", cy: "15", r: "1.6", fill: "currentColor" }),
|
|
764
|
+
/* @__PURE__ */ a3("circle", { cx: "15", cy: "5", r: "1.6", fill: "currentColor" })
|
|
563
765
|
] });
|
|
564
|
-
var HorizontalLineIcon = () => /* @__PURE__ */
|
|
565
|
-
/* @__PURE__ */
|
|
566
|
-
/* @__PURE__ */
|
|
766
|
+
var HorizontalLineIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
767
|
+
/* @__PURE__ */ a3("path", { d: "M3 10h14" }),
|
|
768
|
+
/* @__PURE__ */ a3("circle", { cx: "10", cy: "10", r: "1.6", fill: "currentColor" })
|
|
567
769
|
] });
|
|
568
|
-
var FibonacciIcon = () => /* @__PURE__ */
|
|
569
|
-
var TrashIcon = () => /* @__PURE__ */
|
|
570
|
-
var PencilIcon = () => /* @__PURE__ */
|
|
571
|
-
var CandlesIcon = () => /* @__PURE__ */
|
|
572
|
-
/* @__PURE__ */
|
|
573
|
-
/* @__PURE__ */
|
|
574
|
-
/* @__PURE__ */
|
|
770
|
+
var FibonacciIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M3 4.5h14M3 8.2h14M3 11.8h14M3 15.5h14" }) });
|
|
771
|
+
var TrashIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M4.5 6h11M8 6V4.5h4V6M6 6l.7 9.5h6.6L14 6" }) });
|
|
772
|
+
var PencilIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M12.8 4.2l3 3L7.5 15.5 4 16l.5-3.5z" }) });
|
|
773
|
+
var CandlesIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
774
|
+
/* @__PURE__ */ a3("path", { d: "M6.5 3.5v13M13.5 3.5v13" }),
|
|
775
|
+
/* @__PURE__ */ a3("rect", { x: "4.5", y: "6", width: "4", height: "6", rx: "0.8", fill: "currentColor" }),
|
|
776
|
+
/* @__PURE__ */ a3("rect", { x: "11.5", y: "8", width: "4", height: "5", rx: "0.8" })
|
|
575
777
|
] });
|
|
576
|
-
var LineChartIcon = () => /* @__PURE__ */
|
|
577
|
-
var AreaChartIcon = () => /* @__PURE__ */
|
|
578
|
-
/* @__PURE__ */
|
|
579
|
-
/* @__PURE__ */
|
|
778
|
+
var LineChartIcon = () => /* @__PURE__ */ a3(Icon, { children: /* @__PURE__ */ a3("path", { d: "M3 14l4.5-5 3.5 3 6-7" }) });
|
|
779
|
+
var AreaChartIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
780
|
+
/* @__PURE__ */ a3("path", { d: "M3 14l4.5-5 3.5 3 6-7" }),
|
|
781
|
+
/* @__PURE__ */ a3("path", { d: "M3 14l4.5-5 3.5 3 6-7V17H3z", fill: "currentColor", "fill-opacity": "0.25", stroke: "none" })
|
|
580
782
|
] });
|
|
581
|
-
var IndicatorIcon = () => /* @__PURE__ */
|
|
582
|
-
/* @__PURE__ */
|
|
583
|
-
/* @__PURE__ */
|
|
783
|
+
var IndicatorIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
784
|
+
/* @__PURE__ */ a3("path", { d: "M3 15.5l4-5 3 2.5 3.5-5L17 11" }),
|
|
785
|
+
/* @__PURE__ */ a3("path", { d: "M3 4.5v11.5h14" })
|
|
584
786
|
] });
|
|
585
|
-
var GearIcon = () => /* @__PURE__ */
|
|
586
|
-
/* @__PURE__ */
|
|
587
|
-
/* @__PURE__ */
|
|
787
|
+
var GearIcon = () => /* @__PURE__ */ a3(Icon, { size: 14, children: [
|
|
788
|
+
/* @__PURE__ */ a3("circle", { cx: "10", cy: "10", r: "2.4" }),
|
|
789
|
+
/* @__PURE__ */ a3("path", { d: "M10 3v2M10 15v2M3 10h2M15 10h2M5 5l1.4 1.4M13.6 13.6L15 15M5 15l1.4-1.4M13.6 6.4L15 5" })
|
|
588
790
|
] });
|
|
589
|
-
var SmallCloseIcon = () => /* @__PURE__ */
|
|
590
|
-
var EyeIcon = () => /* @__PURE__ */
|
|
591
|
-
/* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
791
|
+
var SmallCloseIcon = () => /* @__PURE__ */ a3(Icon, { size: 14, children: /* @__PURE__ */ a3("path", { d: "M6 6l8 8M14 6l-8 8" }) });
|
|
792
|
+
var EyeIcon = () => /* @__PURE__ */ a3(Icon, { size: 14, children: [
|
|
793
|
+
/* @__PURE__ */ a3("path", { d: "M2 10s3-5.5 8-5.5S18 10 18 10s-3 5.5-8 5.5S2 10 2 10z" }),
|
|
794
|
+
/* @__PURE__ */ a3("circle", { cx: "10", cy: "10", r: "2.3" })
|
|
593
795
|
] });
|
|
594
|
-
var EyeOffIcon = () => /* @__PURE__ */
|
|
595
|
-
var MagnetIcon = () => /* @__PURE__ */
|
|
596
|
-
/* @__PURE__ */
|
|
597
|
-
/* @__PURE__ */
|
|
796
|
+
var EyeOffIcon = () => /* @__PURE__ */ a3(Icon, { size: 14, children: /* @__PURE__ */ a3("path", { d: "M3 3l14 14M8.2 5a8 8 0 0 1 1.8-.5c5 0 8 5.5 8 5.5a14 14 0 0 1-2.2 2.9M5.4 6.4A14 14 0 0 0 2 10s3 5.5 8 5.5a7.7 7.7 0 0 0 3.6-.9" }) });
|
|
797
|
+
var MagnetIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
798
|
+
/* @__PURE__ */ a3("path", { d: "M5 4h3v6.5a2 2 0 0 0 4 0V4h3v6.5a5 5 0 0 1-10 0z" }),
|
|
799
|
+
/* @__PURE__ */ a3("path", { d: "M5 7h3M12 7h3" })
|
|
598
800
|
] });
|
|
599
|
-
var StarIcon = ({ filled = false }) => /* @__PURE__ */
|
|
801
|
+
var StarIcon = ({ filled = false }) => /* @__PURE__ */ a3(Icon, { size: 16, children: /* @__PURE__ */ a3(
|
|
600
802
|
"path",
|
|
601
803
|
{
|
|
602
804
|
d: "M10 3.2l2.1 4.3 4.7.7-3.4 3.3.8 4.7L10 14l-4.2 2.2.8-4.7-3.4-3.3 4.7-.7z",
|
|
603
805
|
fill: filled ? "currentColor" : "none"
|
|
604
806
|
}
|
|
605
807
|
) });
|
|
606
|
-
var CollapseLeftIcon = () => /* @__PURE__ */
|
|
607
|
-
var SettingsIcon = () => /* @__PURE__ */
|
|
608
|
-
/* @__PURE__ */
|
|
609
|
-
/* @__PURE__ */
|
|
808
|
+
var CollapseLeftIcon = () => /* @__PURE__ */ a3(Icon, { size: 14, children: /* @__PURE__ */ a3("path", { d: "M11 5l-5 5 5 5M15 5l-5 5 5 5" }) });
|
|
809
|
+
var SettingsIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
810
|
+
/* @__PURE__ */ a3("path", { d: "M10 12.6a2.6 2.6 0 1 0 0-5.2 2.6 2.6 0 0 0 0 5.2z" }),
|
|
811
|
+
/* @__PURE__ */ a3("path", { d: "M16.2 12a1.3 1.3 0 0 0 .26 1.43l.05.05a1.6 1.6 0 1 1-2.26 2.26l-.05-.05a1.3 1.3 0 0 0-1.43-.26 1.3 1.3 0 0 0-.79 1.19v.14a1.6 1.6 0 0 1-3.2 0v-.07a1.3 1.3 0 0 0-.85-1.19 1.3 1.3 0 0 0-1.43.26l-.05.05a1.6 1.6 0 1 1-2.26-2.26l.05-.05A1.3 1.3 0 0 0 4.5 12a1.3 1.3 0 0 0-1.19-.79h-.14a1.6 1.6 0 0 1 0-3.2h.07a1.3 1.3 0 0 0 1.19-.85 1.3 1.3 0 0 0-.26-1.43l-.05-.05a1.6 1.6 0 1 1 2.26-2.26l.05.05a1.3 1.3 0 0 0 1.43.26h.06a1.3 1.3 0 0 0 .79-1.19v-.14a1.6 1.6 0 0 1 3.2 0v.07a1.3 1.3 0 0 0 .79 1.19 1.3 1.3 0 0 0 1.43-.26l.05-.05a1.6 1.6 0 1 1 2.26 2.26l-.05.05a1.3 1.3 0 0 0-.26 1.43v.06a1.3 1.3 0 0 0 1.19.79h.14a1.6 1.6 0 0 1 0 3.2h-.07a1.3 1.3 0 0 0-1.19.79z" })
|
|
610
812
|
] });
|
|
611
|
-
var FunnestMark = () => /* @__PURE__ */
|
|
612
|
-
/* @__PURE__ */
|
|
613
|
-
/* @__PURE__ */
|
|
614
|
-
/* @__PURE__ */
|
|
813
|
+
var FunnestMark = () => /* @__PURE__ */ a3("svg", { width: "20", height: "20", viewBox: "0 0 32 32", fill: "none", "aria-hidden": "true", children: [
|
|
814
|
+
/* @__PURE__ */ a3("rect", { width: "32", height: "32", rx: "9", fill: "#6C4DFF" }),
|
|
815
|
+
/* @__PURE__ */ a3("path", { d: "M7 13.5C9.5 21.5 17 23.5 23.4 11.2", stroke: "#fff", "stroke-width": "3.2", "stroke-linecap": "round" }),
|
|
816
|
+
/* @__PURE__ */ a3("circle", { cx: "24.6", cy: "8.6", r: "2.9", fill: "#FFD43B" })
|
|
615
817
|
] });
|
|
616
|
-
var LinkIcon = () => /* @__PURE__ */
|
|
617
|
-
/* @__PURE__ */
|
|
618
|
-
/* @__PURE__ */
|
|
818
|
+
var LinkIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
819
|
+
/* @__PURE__ */ a3("path", { d: "M8.5 11.5a3 3 0 0 0 4.2 0l2.6-2.6a3 3 0 0 0-4.2-4.2l-1 1" }),
|
|
820
|
+
/* @__PURE__ */ a3("path", { d: "M11.5 8.5a3 3 0 0 0-4.2 0l-2.6 2.6a3 3 0 0 0 4.2 4.2l1-1" })
|
|
619
821
|
] });
|
|
620
|
-
var MaximizeIcon = () => /* @__PURE__ */
|
|
621
|
-
var RestoreIcon = () => /* @__PURE__ */
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
var
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
var
|
|
631
|
-
var
|
|
632
|
-
var
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
var
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
if (f4.t = n2, !f4.__c && (f4.__ = [i3 ? i3(u3) : G2(void 0, u3), function(n3) {
|
|
650
|
-
var t3 = (f4.__N || f4.__)[0], r3 = f4.t(t3, n3);
|
|
651
|
-
o3(t3, r3) || (f4.__N = [r3, f4.__[1]], f4.__c.setState({}));
|
|
652
|
-
}], f4.__c = r2, !r2.__f)) {
|
|
653
|
-
r2.__f = true;
|
|
654
|
-
var c3 = r2.shouldComponentUpdate;
|
|
655
|
-
r2.shouldComponentUpdate = function(n3, t3, r3) {
|
|
656
|
-
var u4 = this.__H;
|
|
657
|
-
if (!u4) return true;
|
|
658
|
-
var i4 = false, f5 = this.props != n3;
|
|
659
|
-
if (u4.__.some(function(n4) {
|
|
660
|
-
n4.__N && (i4 = true, o3(n4.__[0], n4.__N[0]) || (f5 = true));
|
|
661
|
-
}), c3) {
|
|
662
|
-
var e3 = c3.call(this, n3, t3, r3);
|
|
663
|
-
return i4 ? e3 || f5 : e3;
|
|
664
|
-
}
|
|
665
|
-
return !i4 || f5;
|
|
666
|
-
};
|
|
822
|
+
var MaximizeIcon = () => /* @__PURE__ */ a3(Icon, { size: 16, children: /* @__PURE__ */ a3("path", { d: "M11 4h5v5M9 16H4v-5M16 4l-5 5M4 16l5-5" }) });
|
|
823
|
+
var RestoreIcon = () => /* @__PURE__ */ a3(Icon, { size: 16, children: /* @__PURE__ */ a3("path", { d: "M15 9h-4V5M5 11h4v4M11 9l5-5M9 11l-5 5" }) });
|
|
824
|
+
var CompareIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
825
|
+
/* @__PURE__ */ a3("path", { d: "M3 14l4-4 3 2 7-7" }),
|
|
826
|
+
/* @__PURE__ */ a3("path", { d: "M3 9l4 2 3-3 7 5", opacity: "0.55" })
|
|
827
|
+
] });
|
|
828
|
+
var ReplayIcon = () => /* @__PURE__ */ a3(Icon, { children: [
|
|
829
|
+
/* @__PURE__ */ a3("path", { d: "M5 4v12" }),
|
|
830
|
+
/* @__PURE__ */ a3("path", { d: "M16 4.5v11L8 10z" })
|
|
831
|
+
] });
|
|
832
|
+
var PlayIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: /* @__PURE__ */ a3("path", { d: "M6 4.5v11l9-5.5z", fill: "currentColor" }) });
|
|
833
|
+
var PauseIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: /* @__PURE__ */ a3("path", { d: "M7 4.5v11M13 4.5v11", "stroke-width": "2.4" }) });
|
|
834
|
+
var StepIcon = () => /* @__PURE__ */ a3(Icon, { size: 18, children: [
|
|
835
|
+
/* @__PURE__ */ a3("path", { d: "M4.5 4.5v11l8-5.5z" }),
|
|
836
|
+
/* @__PURE__ */ a3("path", { d: "M15.5 4.5v11" })
|
|
837
|
+
] });
|
|
838
|
+
var SvgIcon = ({ markup }) => markup.trim().startsWith("<svg") ? /* @__PURE__ */ a3("span", { class: "fnc-svg-icon", dangerouslySetInnerHTML: { __html: markup } }) : /* @__PURE__ */ a3(
|
|
839
|
+
"svg",
|
|
840
|
+
{
|
|
841
|
+
width: 20,
|
|
842
|
+
height: 20,
|
|
843
|
+
viewBox: "0 0 20 20",
|
|
844
|
+
fill: "none",
|
|
845
|
+
stroke: "currentColor",
|
|
846
|
+
"stroke-width": "1.6",
|
|
847
|
+
"stroke-linecap": "round",
|
|
848
|
+
"stroke-linejoin": "round",
|
|
849
|
+
"aria-hidden": "true",
|
|
850
|
+
dangerouslySetInnerHTML: { __html: markup }
|
|
667
851
|
}
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
function A2(n2, u3) {
|
|
671
|
-
var i3 = y2(t2++, 3);
|
|
672
|
-
!a3.__s && E2(i3.__H, u3) && (i3.__P = true, i3.__ = n2, i3.u = u3, r2.__H.__h.push(i3));
|
|
673
|
-
}
|
|
674
|
-
function F2(n2, u3) {
|
|
675
|
-
var i3 = y2(t2++, 4);
|
|
676
|
-
!a3.__s && E2(i3.__H, u3) && (i3.__P = false, i3.__ = n2, i3.u = u3, r2.__h.push(i3));
|
|
677
|
-
}
|
|
678
|
-
function T2(n2) {
|
|
679
|
-
return f3 = 5, w2(function() {
|
|
680
|
-
return { current: n2 };
|
|
681
|
-
}, []);
|
|
682
|
-
}
|
|
683
|
-
function w2(n2, r3) {
|
|
684
|
-
var u3 = y2(t2++, 7);
|
|
685
|
-
return E2(u3.__H, r3) && (u3.__ = n2(), u3.__H = r3), u3.__;
|
|
686
|
-
}
|
|
687
|
-
function g2() {
|
|
688
|
-
var n2;
|
|
689
|
-
do {
|
|
690
|
-
for (; n2 = e2.shift(); ) try {
|
|
691
|
-
C2(n2);
|
|
692
|
-
} catch (t4) {
|
|
693
|
-
a3.__e(t4, { __: (n2 = n2.__P) && n2.__v });
|
|
694
|
-
}
|
|
695
|
-
for (; n2 = c2.shift(); ) {
|
|
696
|
-
var t3 = n2.__H;
|
|
697
|
-
if (n2.__P && t3) try {
|
|
698
|
-
t3.__h.some(C2), t3.__h.some(D2), t3.__h = [];
|
|
699
|
-
} catch (r3) {
|
|
700
|
-
t3.__h = [], a3.__e(r3, n2.__v);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
} while (e2.length);
|
|
704
|
-
}
|
|
705
|
-
a3.__b = function(n2) {
|
|
706
|
-
r2 = null, v2 && v2(n2);
|
|
707
|
-
}, a3.__ = function(n2, t3) {
|
|
708
|
-
n2 && t3.__k && t3.__k.__m && (n2.__m = t3.__k.__m), p2 && p2(n2, t3);
|
|
709
|
-
}, a3.__r = function(n2) {
|
|
710
|
-
l2 && l2(n2), t2 = 0;
|
|
711
|
-
var i3 = (r2 = n2.__c).__H;
|
|
712
|
-
i3 && (u2 == r2 ? r2.__h = [] : (i3.__h.some(C2), i3.__h.some(D2), t2 = 0), i3.__h = [], i3.__.some(function(n3) {
|
|
713
|
-
n3.__N && (n3.__ = n3.__N), n3.u = n3.__N = void 0;
|
|
714
|
-
})), u2 = r2;
|
|
715
|
-
}, a3.diffed = function(n2) {
|
|
716
|
-
m2 && m2(n2);
|
|
717
|
-
var t3 = n2.__c;
|
|
718
|
-
t3 && t3.__H && (t3.__H.__h.length && B2(c2.push(t3)), t3.__H.__.some(function(n3) {
|
|
719
|
-
n3.u && (n3.__H = n3.u);
|
|
720
|
-
})), u2 = r2 = null;
|
|
721
|
-
}, a3.__c = function(n2, t3) {
|
|
722
|
-
t3.some(function(n3) {
|
|
723
|
-
try {
|
|
724
|
-
n3.__h.some(C2), n3.__h = n3.__h.filter(function(n4) {
|
|
725
|
-
return !n4.__ || D2(n4);
|
|
726
|
-
});
|
|
727
|
-
} catch (t4) {
|
|
728
|
-
n3.__h = [function() {
|
|
729
|
-
throw t4;
|
|
730
|
-
}];
|
|
731
|
-
}
|
|
732
|
-
}), h2 && h2(n2, t3);
|
|
733
|
-
}, a3.unmount = function(n2) {
|
|
734
|
-
s2 && s2(n2);
|
|
735
|
-
var t3, r3, u3 = n2.__c;
|
|
736
|
-
u3 && u3.__H && (u3.__H.__.some(function(u4) {
|
|
737
|
-
try {
|
|
738
|
-
if (u4.__P && u4.__c) {
|
|
739
|
-
if (void 0 === r3) {
|
|
740
|
-
for (r3 = n2.__; r3 && (!r3.__c || !r3.__c.__P); ) r3 = r3.__;
|
|
741
|
-
r3 = r3 && r3.__c;
|
|
742
|
-
}
|
|
743
|
-
u4.__P = r3, B2(e2.push(u4));
|
|
744
|
-
} else C2(u4);
|
|
745
|
-
} catch (n3) {
|
|
746
|
-
t3 = n3;
|
|
747
|
-
}
|
|
748
|
-
}), u3.__H = void 0, t3 && a3.__e(t3, u3.__v));
|
|
749
|
-
};
|
|
750
|
-
var k = "function" == typeof requestAnimationFrame;
|
|
751
|
-
function z2(n2) {
|
|
752
|
-
var t3, r3 = function() {
|
|
753
|
-
clearTimeout(u3), k && cancelAnimationFrame(t3), setTimeout(n2);
|
|
754
|
-
}, u3 = setTimeout(r3, 35);
|
|
755
|
-
k && (t3 = requestAnimationFrame(r3));
|
|
756
|
-
}
|
|
757
|
-
function B2(n2) {
|
|
758
|
-
1 != n2 && i2 == a3.requestAnimationFrame || ((i2 = a3.requestAnimationFrame) || z2)(g2);
|
|
759
|
-
}
|
|
760
|
-
function C2(n2) {
|
|
761
|
-
var t3 = r2, u3 = n2.__c;
|
|
762
|
-
"function" == typeof u3 && (n2.__c = void 0, u3()), r2 = t3;
|
|
763
|
-
}
|
|
764
|
-
function D2(n2) {
|
|
765
|
-
var t3 = r2;
|
|
766
|
-
n2.__c = n2.__(), r2 = t3;
|
|
767
|
-
}
|
|
768
|
-
function E2(n2, t3) {
|
|
769
|
-
return !n2 || n2.length != t3.length || t3.some(function(t4, r3) {
|
|
770
|
-
return !o3(t4, n2[r3]);
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
function G2(n2, t3) {
|
|
774
|
-
return "function" == typeof t3 ? t3(n2) : t3;
|
|
775
|
-
}
|
|
852
|
+
);
|
|
853
|
+
var CornerIcon = () => /* @__PURE__ */ a3("svg", { width: "6", height: "6", viewBox: "0 0 6 6", "aria-hidden": "true", children: /* @__PURE__ */ a3("path", { d: "M6 0v6H0z", fill: "currentColor" }) });
|
|
776
854
|
|
|
777
855
|
// src/store.ts
|
|
778
856
|
var Store = class {
|
|
@@ -811,22 +889,71 @@ function useStore(store) {
|
|
|
811
889
|
}
|
|
812
890
|
|
|
813
891
|
// src/components/drawing-toolbar.tsx
|
|
814
|
-
var
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
892
|
+
var BUILTIN_ICONS = {
|
|
893
|
+
trendline: TrendLineIcon,
|
|
894
|
+
horizontal: HorizontalLineIcon,
|
|
895
|
+
fibonacci: FibonacciIcon
|
|
896
|
+
};
|
|
897
|
+
function ToolIcon({ def, locale }) {
|
|
898
|
+
const Builtin = BUILTIN_ICONS[def.type];
|
|
899
|
+
if (Builtin) return /* @__PURE__ */ a3(Builtin, {});
|
|
900
|
+
if (def.icon) return /* @__PURE__ */ a3(SvgIcon, { markup: def.icon });
|
|
901
|
+
return /* @__PURE__ */ a3("span", { class: "fnc-tool-letter", children: def.name[locale].slice(0, 1) });
|
|
902
|
+
}
|
|
903
|
+
function toolGroups(defs) {
|
|
904
|
+
const groups = /* @__PURE__ */ new Map();
|
|
905
|
+
for (const def of defs) {
|
|
906
|
+
const key = def.group ?? def.type;
|
|
907
|
+
groups.set(key, [...groups.get(key) ?? [], def]);
|
|
908
|
+
}
|
|
909
|
+
return [...groups];
|
|
910
|
+
}
|
|
911
|
+
function ToolGroup({
|
|
912
|
+
ctx,
|
|
913
|
+
tools,
|
|
914
|
+
open,
|
|
915
|
+
onOpen,
|
|
916
|
+
onPick
|
|
917
|
+
}) {
|
|
918
|
+
const s3 = useStore(ctx.store);
|
|
919
|
+
const t3 = STRINGS[s3.locale];
|
|
920
|
+
const [chosen, setChosen] = d2(tools[0].type);
|
|
921
|
+
const armed = tools.find((d3) => d3.type === s3.drawingTool);
|
|
922
|
+
const current = armed ?? tools.find((d3) => d3.type === chosen) ?? tools[0];
|
|
923
|
+
const name = current.name[s3.locale];
|
|
924
|
+
const ref = T2(null);
|
|
925
|
+
A2(() => {
|
|
926
|
+
if (!open) return;
|
|
927
|
+
const close = (e3) => !ref.current?.contains(e3.target) && onOpen(false);
|
|
928
|
+
document.addEventListener("pointerdown", close, true);
|
|
929
|
+
return () => document.removeEventListener("pointerdown", close, true);
|
|
930
|
+
}, [open]);
|
|
931
|
+
const pick = (def) => {
|
|
932
|
+
setChosen(def.type);
|
|
933
|
+
onOpen(false);
|
|
934
|
+
onPick(def.type);
|
|
935
|
+
};
|
|
936
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-tool-group", ref, "data-open": open, children: [
|
|
937
|
+
/* @__PURE__ */ a3("button", { class: "fnc-btn", "data-tip": name, "aria-label": name, "aria-pressed": !!armed, onClick: () => pick(current), children: /* @__PURE__ */ a3(ToolIcon, { def: current, locale: s3.locale }) }),
|
|
938
|
+
tools.length > 1 && /* @__PURE__ */ a3("button", { class: "fnc-tool-more", "aria-label": `${t3.moreTools}: ${name}`, "aria-haspopup": "menu", "aria-expanded": open, onClick: () => onOpen(!open), children: /* @__PURE__ */ a3(CornerIcon, {}) }),
|
|
939
|
+
open && /* @__PURE__ */ a3("div", { class: "fnc-menu fnc-tool-menu", role: "menu", children: tools.map((def) => /* @__PURE__ */ a3("button", { class: "fnc-menu-item", role: "menuitemradio", "aria-checked": def.type === current.type, onClick: () => pick(def), children: [
|
|
940
|
+
/* @__PURE__ */ a3(ToolIcon, { def, locale: s3.locale }),
|
|
941
|
+
/* @__PURE__ */ a3("span", { children: def.name[s3.locale] })
|
|
942
|
+
] })) })
|
|
943
|
+
] });
|
|
944
|
+
}
|
|
820
945
|
function DrawingToolbar({ ctx }) {
|
|
821
946
|
const s3 = useStore(ctx.store);
|
|
822
947
|
const t3 = STRINGS[s3.locale];
|
|
948
|
+
const [openGroup, setOpenGroup] = d2(null);
|
|
949
|
+
const groups = toolGroups(ctx.chart.drawingDefinitions());
|
|
823
950
|
const pick = (tool) => {
|
|
824
951
|
ctx.chart.setDrawingTool(tool);
|
|
825
952
|
if (tool && ctx.store.get().drawbarOpen) ctx.store.set({ drawbarOpen: false });
|
|
826
953
|
};
|
|
827
|
-
return /* @__PURE__ */
|
|
828
|
-
s3.drawbarCollapsed && /* @__PURE__ */
|
|
829
|
-
/* @__PURE__ */
|
|
954
|
+
return /* @__PURE__ */ a3($, { children: [
|
|
955
|
+
s3.drawbarCollapsed && /* @__PURE__ */ a3("button", { class: "fnc-drawbar-tab", "aria-label": t3.expandDrawbar, "data-tip": t3.expandDrawbar, onClick: () => ctx.setDrawbarCollapsed(false), children: /* @__PURE__ */ a3(ChevronRightIcon, {}) }),
|
|
956
|
+
/* @__PURE__ */ a3(
|
|
830
957
|
"div",
|
|
831
958
|
{
|
|
832
959
|
class: "fnc-drawbar",
|
|
@@ -836,19 +963,20 @@ function DrawingToolbar({ ctx }) {
|
|
|
836
963
|
"data-open": s3.drawbarOpen,
|
|
837
964
|
"data-collapsed": s3.drawbarCollapsed,
|
|
838
965
|
children: [
|
|
839
|
-
|
|
840
|
-
|
|
966
|
+
/* @__PURE__ */ a3("button", { class: "fnc-btn", "data-tip": t3.cursor, "aria-label": t3.cursor, "aria-pressed": s3.drawingTool === null, onClick: () => pick(null), children: /* @__PURE__ */ a3(CursorIcon, {}) }),
|
|
967
|
+
groups.map(([key, tools]) => /* @__PURE__ */ a3(
|
|
968
|
+
ToolGroup,
|
|
841
969
|
{
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
970
|
+
ctx,
|
|
971
|
+
tools,
|
|
972
|
+
open: openGroup === key,
|
|
973
|
+
onOpen: (open) => setOpenGroup(open ? key : null),
|
|
974
|
+
onPick: pick
|
|
975
|
+
},
|
|
976
|
+
key
|
|
849
977
|
)),
|
|
850
|
-
/* @__PURE__ */
|
|
851
|
-
/* @__PURE__ */
|
|
978
|
+
/* @__PURE__ */ a3("div", { class: "fnc-hsep" }),
|
|
979
|
+
/* @__PURE__ */ a3(
|
|
852
980
|
"button",
|
|
853
981
|
{
|
|
854
982
|
class: "fnc-btn",
|
|
@@ -856,10 +984,10 @@ function DrawingToolbar({ ctx }) {
|
|
|
856
984
|
"aria-label": t3.magnet,
|
|
857
985
|
"aria-pressed": s3.magnet,
|
|
858
986
|
onClick: () => ctx.chart.setMagnet(!s3.magnet),
|
|
859
|
-
children: /* @__PURE__ */
|
|
987
|
+
children: /* @__PURE__ */ a3(MagnetIcon, {})
|
|
860
988
|
}
|
|
861
989
|
),
|
|
862
|
-
/* @__PURE__ */
|
|
990
|
+
/* @__PURE__ */ a3(
|
|
863
991
|
"button",
|
|
864
992
|
{
|
|
865
993
|
class: "fnc-btn",
|
|
@@ -867,18 +995,18 @@ function DrawingToolbar({ ctx }) {
|
|
|
867
995
|
"aria-label": t3.removeAll,
|
|
868
996
|
disabled: s3.drawingCount === 0,
|
|
869
997
|
onClick: () => ctx.chart.clearDrawings(),
|
|
870
|
-
children: /* @__PURE__ */
|
|
998
|
+
children: /* @__PURE__ */ a3(TrashIcon, {})
|
|
871
999
|
}
|
|
872
1000
|
),
|
|
873
|
-
/* @__PURE__ */
|
|
874
|
-
/* @__PURE__ */
|
|
1001
|
+
/* @__PURE__ */ a3("span", { class: "fnc-spacer" }),
|
|
1002
|
+
/* @__PURE__ */ a3(
|
|
875
1003
|
"button",
|
|
876
1004
|
{
|
|
877
1005
|
class: "fnc-btn fnc-drawbar-collapse",
|
|
878
1006
|
"data-tip": t3.collapseDrawbar,
|
|
879
1007
|
"aria-label": t3.collapseDrawbar,
|
|
880
1008
|
onClick: () => ctx.setDrawbarCollapsed(true),
|
|
881
|
-
children: /* @__PURE__ */
|
|
1009
|
+
children: /* @__PURE__ */ a3(ChevronLeftIcon, {})
|
|
882
1010
|
}
|
|
883
1011
|
)
|
|
884
1012
|
]
|
|
@@ -892,8 +1020,8 @@ function SelectionBar({ ctx }) {
|
|
|
892
1020
|
const t3 = STRINGS[s3.locale];
|
|
893
1021
|
const d3 = s3.selection;
|
|
894
1022
|
if (!d3 || s3.layout.plotWidth <= 0) return null;
|
|
895
|
-
return /* @__PURE__ */
|
|
896
|
-
SWATCHES.map((color) => /* @__PURE__ */
|
|
1023
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-selbar", role: "toolbar", style: { left: `${s3.layout.plotWidth / 2}px` }, children: [
|
|
1024
|
+
SWATCHES.map((color) => /* @__PURE__ */ a3(
|
|
897
1025
|
"button",
|
|
898
1026
|
{
|
|
899
1027
|
class: "fnc-swatch",
|
|
@@ -904,8 +1032,8 @@ function SelectionBar({ ctx }) {
|
|
|
904
1032
|
onClick: () => ctx.chart.updateDrawing(d3.id, { color })
|
|
905
1033
|
}
|
|
906
1034
|
)),
|
|
907
|
-
/* @__PURE__ */
|
|
908
|
-
/* @__PURE__ */
|
|
1035
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sep" }),
|
|
1036
|
+
/* @__PURE__ */ a3("button", { class: "fnc-btn", "data-tip": t3.remove, "aria-label": t3.remove, onClick: () => ctx.chart.removeDrawing(d3.id), children: /* @__PURE__ */ a3(TrashIcon, {}) })
|
|
909
1037
|
] });
|
|
910
1038
|
}
|
|
911
1039
|
|
|
@@ -964,8 +1092,8 @@ function ChartTypeMenu({ ctx }) {
|
|
|
964
1092
|
ctx.store.set({ chartType: type });
|
|
965
1093
|
setOpen(false);
|
|
966
1094
|
};
|
|
967
|
-
return /* @__PURE__ */
|
|
968
|
-
/* @__PURE__ */
|
|
1095
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-menu-wrap fnc-chart-type", ref, children: [
|
|
1096
|
+
/* @__PURE__ */ a3(
|
|
969
1097
|
"button",
|
|
970
1098
|
{
|
|
971
1099
|
class: "fnc-btn fnc-btn-wide",
|
|
@@ -975,12 +1103,12 @@ function ChartTypeMenu({ ctx }) {
|
|
|
975
1103
|
"aria-expanded": open,
|
|
976
1104
|
onClick: () => setOpen(!open),
|
|
977
1105
|
children: [
|
|
978
|
-
/* @__PURE__ */
|
|
979
|
-
/* @__PURE__ */
|
|
1106
|
+
/* @__PURE__ */ a3(current.icon, {}),
|
|
1107
|
+
/* @__PURE__ */ a3(ChevronDownIcon, {})
|
|
980
1108
|
]
|
|
981
1109
|
}
|
|
982
1110
|
),
|
|
983
|
-
open && /* @__PURE__ */
|
|
1111
|
+
open && /* @__PURE__ */ a3("div", { class: "fnc-menu", role: "menu", ref: menuRef, children: TYPES.map(({ type, label, icon: Icon2 }) => /* @__PURE__ */ a3(
|
|
984
1112
|
"button",
|
|
985
1113
|
{
|
|
986
1114
|
class: "fnc-menu-item",
|
|
@@ -988,8 +1116,8 @@ function ChartTypeMenu({ ctx }) {
|
|
|
988
1116
|
"aria-checked": type === s3.chartType,
|
|
989
1117
|
onClick: () => choose(type),
|
|
990
1118
|
children: [
|
|
991
|
-
/* @__PURE__ */
|
|
992
|
-
/* @__PURE__ */
|
|
1119
|
+
/* @__PURE__ */ a3(Icon2, {}),
|
|
1120
|
+
/* @__PURE__ */ a3("span", { children: t3[label] })
|
|
993
1121
|
]
|
|
994
1122
|
}
|
|
995
1123
|
)) })
|
|
@@ -998,7 +1126,6 @@ function ChartTypeMenu({ ctx }) {
|
|
|
998
1126
|
|
|
999
1127
|
// src/components/indicator-dialogs.tsx
|
|
1000
1128
|
import {
|
|
1001
|
-
INDICATORS,
|
|
1002
1129
|
maLines,
|
|
1003
1130
|
PRICE_SOURCES,
|
|
1004
1131
|
SERIES_COLORS
|
|
@@ -1019,6 +1146,7 @@ var SECTIONS = [
|
|
|
1019
1146
|
toggles: [
|
|
1020
1147
|
{ key: "highLowMarkers", label: "settingHighLow" },
|
|
1021
1148
|
{ key: "lastPriceLine", label: "settingLastPrice" },
|
|
1149
|
+
{ key: "countdown", label: "settingCountdown" },
|
|
1022
1150
|
{ key: "volume", label: "settingVolume" },
|
|
1023
1151
|
{ key: "navigationButtons", label: "settingNavButtons" }
|
|
1024
1152
|
]
|
|
@@ -1031,6 +1159,11 @@ var SECTIONS = [
|
|
|
1031
1159
|
]
|
|
1032
1160
|
}
|
|
1033
1161
|
];
|
|
1162
|
+
var SCALES = [
|
|
1163
|
+
{ mode: "normal", label: "scaleNormal" },
|
|
1164
|
+
{ mode: "log", label: "scaleLog" },
|
|
1165
|
+
{ mode: "percent", label: "scalePercent" }
|
|
1166
|
+
];
|
|
1034
1167
|
function SettingsDialog({ ctx }) {
|
|
1035
1168
|
const { locale } = useStore(ctx.store);
|
|
1036
1169
|
const t3 = STRINGS[locale];
|
|
@@ -1039,16 +1172,16 @@ function SettingsDialog({ ctx }) {
|
|
|
1039
1172
|
const close = () => ctx.store.set({ dialog: null });
|
|
1040
1173
|
const set = (patch) => ctx.chart.setSettings(patch);
|
|
1041
1174
|
const themeColor = (name) => toHex(getComputedStyle(ctx.root).getPropertyValue(name).trim());
|
|
1042
|
-
return /* @__PURE__ */
|
|
1043
|
-
/* @__PURE__ */
|
|
1044
|
-
/* @__PURE__ */
|
|
1045
|
-
/* @__PURE__ */
|
|
1175
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-backdrop", onPointerDown: (e3) => e3.target === e3.currentTarget && close(), children: /* @__PURE__ */ a3("div", { class: "fnc-dialog", role: "dialog", "aria-modal": "true", "aria-label": t3.chartSettings, onKeyDown: (e3) => e3.key === "Escape" && close(), children: [
|
|
1176
|
+
/* @__PURE__ */ a3("div", { class: "fnc-dialog-head", children: [
|
|
1177
|
+
/* @__PURE__ */ a3("b", { children: t3.chartSettings }),
|
|
1178
|
+
/* @__PURE__ */ a3("button", { class: "fnc-btn", "aria-label": t3.close, onClick: close, children: /* @__PURE__ */ a3(CloseIcon, {}) })
|
|
1046
1179
|
] }),
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
["upColor", "downColor"].map((key) => /* @__PURE__ */
|
|
1050
|
-
/* @__PURE__ */
|
|
1051
|
-
/* @__PURE__ */
|
|
1180
|
+
/* @__PURE__ */ a3("form", { class: "fnc-form", onSubmit: (e3) => (e3.preventDefault(), close()), children: [
|
|
1181
|
+
/* @__PURE__ */ a3("div", { class: "fnc-section", children: t3.settingsCandles }),
|
|
1182
|
+
["upColor", "downColor"].map((key) => /* @__PURE__ */ a3("label", { class: "fnc-row", children: [
|
|
1183
|
+
/* @__PURE__ */ a3("span", { class: "fnc-row-label fnc-row-label-wide", children: key === "upColor" ? t3.settingUpColor : t3.settingDownColor }),
|
|
1184
|
+
/* @__PURE__ */ a3(
|
|
1052
1185
|
"input",
|
|
1053
1186
|
{
|
|
1054
1187
|
type: "color",
|
|
@@ -1057,13 +1190,24 @@ function SettingsDialog({ ctx }) {
|
|
|
1057
1190
|
onInput: (e3) => set({ [key]: e3.currentTarget.value })
|
|
1058
1191
|
}
|
|
1059
1192
|
),
|
|
1060
|
-
settings[key] && /* @__PURE__ */
|
|
1193
|
+
settings[key] && /* @__PURE__ */ a3("button", { type: "button", class: "fnc-link", onClick: () => set({ [key]: null }), children: t3.followTheme })
|
|
1061
1194
|
] })),
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1195
|
+
/* @__PURE__ */ a3("div", { class: "fnc-section", children: t3.settingsScale }),
|
|
1196
|
+
/* @__PURE__ */ a3("div", { class: "fnc-row", children: /* @__PURE__ */ a3("div", { class: "fnc-seg", role: "radiogroup", "aria-label": t3.settingsScale, children: SCALES.map(({ mode, label }) => /* @__PURE__ */ a3(
|
|
1197
|
+
"button",
|
|
1198
|
+
{
|
|
1199
|
+
type: "button",
|
|
1200
|
+
role: "radio",
|
|
1201
|
+
"aria-checked": settings.priceScale === mode,
|
|
1202
|
+
onClick: () => set({ priceScale: mode }),
|
|
1203
|
+
children: t3[label]
|
|
1204
|
+
}
|
|
1205
|
+
)) }) }),
|
|
1206
|
+
SECTIONS.map((section) => /* @__PURE__ */ a3($, { children: [
|
|
1207
|
+
/* @__PURE__ */ a3("div", { class: "fnc-section", children: t3[section.title] }),
|
|
1208
|
+
section.toggles.map(({ key, label }) => /* @__PURE__ */ a3("label", { class: "fnc-row fnc-toggle-row", children: [
|
|
1209
|
+
/* @__PURE__ */ a3("span", { children: t3[label] }),
|
|
1210
|
+
/* @__PURE__ */ a3(
|
|
1067
1211
|
"input",
|
|
1068
1212
|
{
|
|
1069
1213
|
type: "checkbox",
|
|
@@ -1075,9 +1219,9 @@ function SettingsDialog({ ctx }) {
|
|
|
1075
1219
|
)
|
|
1076
1220
|
] }))
|
|
1077
1221
|
] })),
|
|
1078
|
-
/* @__PURE__ */
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
/* @__PURE__ */
|
|
1222
|
+
/* @__PURE__ */ a3("div", { class: "fnc-form-actions", children: [
|
|
1223
|
+
/* @__PURE__ */ a3("button", { type: "button", class: "fnc-action fnc-action-danger", onClick: () => ctx.chart.setSettings(DEFAULT_CHART_SETTINGS), children: t3.resetDefaults }),
|
|
1224
|
+
/* @__PURE__ */ a3("button", { type: "submit", class: "fnc-action fnc-action-primary", children: t3.done })
|
|
1081
1225
|
] })
|
|
1082
1226
|
] })
|
|
1083
1227
|
] }) });
|
|
@@ -1089,7 +1233,7 @@ function Dialog({ title, onClose, children, wide }) {
|
|
|
1089
1233
|
A2(() => {
|
|
1090
1234
|
ref.current?.querySelector("input, button.fnc-sr-row")?.focus();
|
|
1091
1235
|
}, []);
|
|
1092
|
-
return /* @__PURE__ */
|
|
1236
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-backdrop", onPointerDown: (e3) => e3.target === e3.currentTarget && onClose(), children: /* @__PURE__ */ a3(
|
|
1093
1237
|
"div",
|
|
1094
1238
|
{
|
|
1095
1239
|
class: wide ? "fnc-dialog fnc-dialog-wide" : "fnc-dialog",
|
|
@@ -1099,49 +1243,71 @@ function Dialog({ title, onClose, children, wide }) {
|
|
|
1099
1243
|
ref,
|
|
1100
1244
|
onKeyDown: (e3) => e3.key === "Escape" && onClose(),
|
|
1101
1245
|
children: [
|
|
1102
|
-
/* @__PURE__ */
|
|
1103
|
-
/* @__PURE__ */
|
|
1104
|
-
/* @__PURE__ */
|
|
1246
|
+
/* @__PURE__ */ a3("div", { class: "fnc-dialog-head", children: [
|
|
1247
|
+
/* @__PURE__ */ a3("b", { children: title }),
|
|
1248
|
+
/* @__PURE__ */ a3("button", { class: "fnc-btn", "aria-label": "close", onClick: onClose, children: /* @__PURE__ */ a3(CloseIcon, {}) })
|
|
1105
1249
|
] }),
|
|
1106
1250
|
children
|
|
1107
1251
|
]
|
|
1108
1252
|
}
|
|
1109
1253
|
) });
|
|
1110
1254
|
}
|
|
1255
|
+
var SEARCH_THRESHOLD = 8;
|
|
1111
1256
|
function IndicatorPicker({ ctx }) {
|
|
1112
1257
|
const { locale } = useStore(ctx.store);
|
|
1113
1258
|
const t3 = STRINGS[locale];
|
|
1259
|
+
const [query, setQuery] = d2("");
|
|
1114
1260
|
const close = () => ctx.store.set({ dialog: null });
|
|
1115
1261
|
const add = (type) => {
|
|
1116
1262
|
ctx.chart.addIndicator(type);
|
|
1117
1263
|
close();
|
|
1118
1264
|
};
|
|
1265
|
+
const all = ctx.chart.indicatorDefinitions();
|
|
1266
|
+
const q2 = query.trim().toLowerCase();
|
|
1267
|
+
const matches = (d3) => !q2 || [d3.type, d3.name.ko, d3.name.en, d3.description[locale]].some((s3) => s3.toLowerCase().includes(q2));
|
|
1119
1268
|
const groups = [
|
|
1120
|
-
[locale === "ko" ? "\uAC00\uACA9 \uCC28\uD2B8\uC5D0 \uD45C\uC2DC" : "On price",
|
|
1121
|
-
[locale === "ko" ? "\uC544\uB798 \uC601\uC5ED\uC5D0 \uD45C\uC2DC" : "Separate pane",
|
|
1122
|
-
];
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1269
|
+
[locale === "ko" ? "\uAC00\uACA9 \uCC28\uD2B8\uC5D0 \uD45C\uC2DC" : "On price", all.filter((d3) => d3.overlay && matches(d3))],
|
|
1270
|
+
[locale === "ko" ? "\uC544\uB798 \uC601\uC5ED\uC5D0 \uD45C\uC2DC" : "Separate pane", all.filter((d3) => !d3.overlay && matches(d3))]
|
|
1271
|
+
].filter(([, defs]) => defs.length > 0);
|
|
1272
|
+
const first = groups[0]?.[1][0];
|
|
1273
|
+
return /* @__PURE__ */ a3(Dialog, { title: t3.addIndicator, onClose: close, children: [
|
|
1274
|
+
all.length > SEARCH_THRESHOLD && /* @__PURE__ */ a3("div", { class: "fnc-search fnc-ind-search", children: /* @__PURE__ */ a3(
|
|
1275
|
+
"input",
|
|
1276
|
+
{
|
|
1277
|
+
value: query,
|
|
1278
|
+
placeholder: t3.searchIndicators,
|
|
1279
|
+
"aria-label": t3.searchIndicators,
|
|
1280
|
+
autocomplete: "off",
|
|
1281
|
+
onInput: (e3) => setQuery(e3.currentTarget.value),
|
|
1282
|
+
onKeyDown: (e3) => e3.key === "Enter" && first && add(first.type)
|
|
1283
|
+
}
|
|
1284
|
+
) }),
|
|
1285
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sr-list fnc-scroll", children: [
|
|
1286
|
+
groups.length === 0 && /* @__PURE__ */ a3("div", { class: "fnc-empty", children: t3.noResults }),
|
|
1287
|
+
groups.map(([label, defs]) => /* @__PURE__ */ a3($, { children: [
|
|
1288
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sr-section", children: label }),
|
|
1289
|
+
defs.map((def) => {
|
|
1290
|
+
const type = def.type;
|
|
1291
|
+
return /* @__PURE__ */ a3("button", { class: "fnc-sr-row", onClick: () => add(type), children: /* @__PURE__ */ a3("span", { class: "fnc-sr-main", children: [
|
|
1292
|
+
/* @__PURE__ */ a3("span", { class: "fnc-sr-name", children: def.name[locale] }),
|
|
1293
|
+
/* @__PURE__ */ a3("span", { class: "fnc-sr-meta", children: def.description[locale] })
|
|
1294
|
+
] }) });
|
|
1295
|
+
})
|
|
1296
|
+
] }))
|
|
1297
|
+
] })
|
|
1298
|
+
] });
|
|
1133
1299
|
}
|
|
1134
1300
|
var WIDTHS = [1, 2, 3, 4];
|
|
1135
|
-
function defaultSeries(
|
|
1136
|
-
return
|
|
1301
|
+
function defaultSeries(def, params) {
|
|
1302
|
+
return def.compute([], params).series.filter((s3) => s3.kind === "line");
|
|
1137
1303
|
}
|
|
1138
1304
|
function StyleControls({
|
|
1139
1305
|
t: t3,
|
|
1140
1306
|
row: row2,
|
|
1141
1307
|
onChange
|
|
1142
1308
|
}) {
|
|
1143
|
-
return /* @__PURE__ */
|
|
1144
|
-
/* @__PURE__ */
|
|
1309
|
+
return /* @__PURE__ */ a3($, { children: [
|
|
1310
|
+
/* @__PURE__ */ a3(
|
|
1145
1311
|
"input",
|
|
1146
1312
|
{
|
|
1147
1313
|
type: "checkbox",
|
|
@@ -1151,7 +1317,7 @@ function StyleControls({
|
|
|
1151
1317
|
onChange: (e3) => onChange({ visible: e3.currentTarget.checked })
|
|
1152
1318
|
}
|
|
1153
1319
|
),
|
|
1154
|
-
/* @__PURE__ */
|
|
1320
|
+
/* @__PURE__ */ a3(
|
|
1155
1321
|
"input",
|
|
1156
1322
|
{
|
|
1157
1323
|
type: "color",
|
|
@@ -1161,24 +1327,24 @@ function StyleControls({
|
|
|
1161
1327
|
onInput: (e3) => onChange({ color: e3.currentTarget.value })
|
|
1162
1328
|
}
|
|
1163
1329
|
),
|
|
1164
|
-
/* @__PURE__ */
|
|
1330
|
+
/* @__PURE__ */ a3("select", { class: "fnc-select fnc-select-width", value: row2.width, "aria-label": t3.lineWidth, onChange: (e3) => onChange({ width: Number(e3.currentTarget.value) }), children: WIDTHS.map((w3) => /* @__PURE__ */ a3("option", { value: w3, children: [
|
|
1165
1331
|
w3,
|
|
1166
1332
|
"px"
|
|
1167
1333
|
] })) })
|
|
1168
1334
|
] });
|
|
1169
1335
|
}
|
|
1170
1336
|
function SourceSelect({ value, locale, label, onChange }) {
|
|
1171
|
-
return /* @__PURE__ */
|
|
1337
|
+
return /* @__PURE__ */ a3("select", { class: "fnc-select fnc-select-source", value, "aria-label": label, onChange: (e3) => onChange(e3.currentTarget.value), children: PRICE_SOURCES.map((s3) => /* @__PURE__ */ a3("option", { value: s3.value, children: s3.label[locale] })) });
|
|
1172
1338
|
}
|
|
1173
1339
|
function IndicatorSettings({ ctx, id }) {
|
|
1174
1340
|
const { locale, indicators } = useStore(ctx.store);
|
|
1175
1341
|
const t3 = STRINGS[locale];
|
|
1176
1342
|
const config = indicators.find((c3) => c3.id === id);
|
|
1177
|
-
const def = config ?
|
|
1343
|
+
const def = config ? ctx.chart.indicatorDefinition(config.type) ?? null : null;
|
|
1178
1344
|
const hasLines = !!def?.params.some((p3) => p3.kind === "lines");
|
|
1179
1345
|
const [lines, setLines] = d2(() => {
|
|
1180
|
-
if (!config || !hasLines) return [];
|
|
1181
|
-
const defaults = defaultSeries(
|
|
1346
|
+
if (!config || !def || !hasLines) return [];
|
|
1347
|
+
const defaults = defaultSeries(def, config.params);
|
|
1182
1348
|
return maLines(config.params).map((l3, i3) => {
|
|
1183
1349
|
const style = config.styles?.[`l${i3}`];
|
|
1184
1350
|
return {
|
|
@@ -1194,8 +1360,8 @@ function IndicatorSettings({ ctx, id }) {
|
|
|
1194
1360
|
() => Object.fromEntries(Object.entries(config?.params ?? {}).filter(([, v3]) => !Array.isArray(v3)).map(([k2, v3]) => [k2, String(v3)]))
|
|
1195
1361
|
);
|
|
1196
1362
|
const [styles, setStyles] = d2(() => {
|
|
1197
|
-
if (!config || hasLines) return [];
|
|
1198
|
-
return defaultSeries(
|
|
1363
|
+
if (!config || !def || hasLines) return [];
|
|
1364
|
+
return defaultSeries(def, config.params).map((s3) => {
|
|
1199
1365
|
const style = config.styles?.[s3.key];
|
|
1200
1366
|
return { key: s3.key, label: s3.label, color: style?.color ?? s3.color, width: style?.width ?? s3.width, visible: style?.visible ?? true };
|
|
1201
1367
|
});
|
|
@@ -1238,16 +1404,16 @@ function IndicatorSettings({ ctx, id }) {
|
|
|
1238
1404
|
ctx.chart.updateIndicator(id, { params, styles: nextStyles });
|
|
1239
1405
|
close();
|
|
1240
1406
|
};
|
|
1241
|
-
return /* @__PURE__ */
|
|
1242
|
-
hasLines ? /* @__PURE__ */
|
|
1243
|
-
lines.map((l3, i3) => /* @__PURE__ */
|
|
1244
|
-
/* @__PURE__ */
|
|
1407
|
+
return /* @__PURE__ */ a3(Dialog, { title: `${def.name[locale]} \xB7 ${t3.indicatorSettings}`, onClose: close, wide: true, children: /* @__PURE__ */ a3("form", { class: "fnc-form", onSubmit: apply, children: [
|
|
1408
|
+
hasLines ? /* @__PURE__ */ a3("div", { class: "fnc-rows", children: [
|
|
1409
|
+
lines.map((l3, i3) => /* @__PURE__ */ a3("div", { class: "fnc-row", children: [
|
|
1410
|
+
/* @__PURE__ */ a3("span", { class: "fnc-row-label", children: [
|
|
1245
1411
|
t3.period,
|
|
1246
1412
|
i3 + 1
|
|
1247
1413
|
] }),
|
|
1248
|
-
/* @__PURE__ */
|
|
1249
|
-
/* @__PURE__ */
|
|
1250
|
-
/* @__PURE__ */
|
|
1414
|
+
/* @__PURE__ */ a3(StyleControls, { t: t3, row: l3, onChange: (p3) => updateLine(i3, p3) }),
|
|
1415
|
+
/* @__PURE__ */ a3(SourceSelect, { value: l3.source, locale, label: t3.source, onChange: (source) => updateLine(i3, { source }) }),
|
|
1416
|
+
/* @__PURE__ */ a3(
|
|
1251
1417
|
"input",
|
|
1252
1418
|
{
|
|
1253
1419
|
class: "fnc-input fnc-input-period",
|
|
@@ -1257,17 +1423,17 @@ function IndicatorSettings({ ctx, id }) {
|
|
|
1257
1423
|
onInput: (e3) => updateLine(i3, { period: e3.currentTarget.value.replace(/\D/g, "") })
|
|
1258
1424
|
}
|
|
1259
1425
|
),
|
|
1260
|
-
/* @__PURE__ */
|
|
1426
|
+
/* @__PURE__ */ a3("button", { type: "button", class: "fnc-ind-btn", "aria-label": t3.removePeriod, "data-tip": t3.removePeriod, onClick: () => setLines(lines.filter((_3, j2) => j2 !== i3)), children: /* @__PURE__ */ a3(SmallCloseIcon, {}) })
|
|
1261
1427
|
] })),
|
|
1262
|
-
/* @__PURE__ */
|
|
1428
|
+
/* @__PURE__ */ a3("button", { type: "button", class: "fnc-add-row", onClick: addLine, children: [
|
|
1263
1429
|
"+ ",
|
|
1264
1430
|
t3.addPeriod
|
|
1265
1431
|
] })
|
|
1266
|
-
] }) : /* @__PURE__ */
|
|
1267
|
-
/* @__PURE__ */
|
|
1268
|
-
def.params.map((spec) => /* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1270
|
-
spec.kind === "source" ? /* @__PURE__ */
|
|
1432
|
+
] }) : /* @__PURE__ */ a3($, { children: [
|
|
1433
|
+
/* @__PURE__ */ a3("div", { class: "fnc-section", children: t3.inputs }),
|
|
1434
|
+
def.params.map((spec) => /* @__PURE__ */ a3("div", { class: "fnc-row", children: [
|
|
1435
|
+
/* @__PURE__ */ a3("span", { class: "fnc-row-label fnc-row-label-wide", children: spec.label[locale] }),
|
|
1436
|
+
spec.kind === "source" ? /* @__PURE__ */ a3(
|
|
1271
1437
|
SourceSelect,
|
|
1272
1438
|
{
|
|
1273
1439
|
value: values[spec.key] ?? "close",
|
|
@@ -1275,7 +1441,7 @@ function IndicatorSettings({ ctx, id }) {
|
|
|
1275
1441
|
label: spec.label[locale],
|
|
1276
1442
|
onChange: (v3) => setValues({ ...values, [spec.key]: v3 })
|
|
1277
1443
|
}
|
|
1278
|
-
) : /* @__PURE__ */
|
|
1444
|
+
) : /* @__PURE__ */ a3(
|
|
1279
1445
|
"input",
|
|
1280
1446
|
{
|
|
1281
1447
|
class: "fnc-input",
|
|
@@ -1286,14 +1452,14 @@ function IndicatorSettings({ ctx, id }) {
|
|
|
1286
1452
|
}
|
|
1287
1453
|
)
|
|
1288
1454
|
] })),
|
|
1289
|
-
styles.length > 0 && /* @__PURE__ */
|
|
1290
|
-
styles.map((row2, i3) => /* @__PURE__ */
|
|
1291
|
-
/* @__PURE__ */
|
|
1292
|
-
/* @__PURE__ */
|
|
1455
|
+
styles.length > 0 && /* @__PURE__ */ a3("div", { class: "fnc-section", children: t3.style }),
|
|
1456
|
+
styles.map((row2, i3) => /* @__PURE__ */ a3("div", { class: "fnc-row", children: [
|
|
1457
|
+
/* @__PURE__ */ a3("span", { class: "fnc-row-label fnc-row-label-wide", children: row2.label }),
|
|
1458
|
+
/* @__PURE__ */ a3(StyleControls, { t: t3, row: row2, onChange: (p3) => setStyles(styles.map((s3, j2) => j2 === i3 ? { ...s3, ...p3 } : s3)) })
|
|
1293
1459
|
] }))
|
|
1294
1460
|
] }),
|
|
1295
|
-
/* @__PURE__ */
|
|
1296
|
-
/* @__PURE__ */
|
|
1461
|
+
/* @__PURE__ */ a3("div", { class: "fnc-form-actions", children: [
|
|
1462
|
+
/* @__PURE__ */ a3(
|
|
1297
1463
|
"button",
|
|
1298
1464
|
{
|
|
1299
1465
|
type: "button",
|
|
@@ -1305,16 +1471,16 @@ function IndicatorSettings({ ctx, id }) {
|
|
|
1305
1471
|
children: t3.remove
|
|
1306
1472
|
}
|
|
1307
1473
|
),
|
|
1308
|
-
/* @__PURE__ */
|
|
1309
|
-
/* @__PURE__ */
|
|
1474
|
+
/* @__PURE__ */ a3("button", { type: "button", class: "fnc-action", onClick: close, children: t3.cancel }),
|
|
1475
|
+
/* @__PURE__ */ a3("button", { type: "submit", class: "fnc-action fnc-action-primary", children: t3.apply })
|
|
1310
1476
|
] })
|
|
1311
1477
|
] }) });
|
|
1312
1478
|
}
|
|
1313
1479
|
function Dialogs({ ctx }) {
|
|
1314
1480
|
const { dialog } = useStore(ctx.store);
|
|
1315
|
-
if (dialog?.kind === "indicators") return /* @__PURE__ */
|
|
1316
|
-
if (dialog?.kind === "indicatorSettings") return /* @__PURE__ */
|
|
1317
|
-
if (dialog?.kind === "chartSettings") return /* @__PURE__ */
|
|
1481
|
+
if (dialog?.kind === "indicators") return /* @__PURE__ */ a3(IndicatorPicker, { ctx });
|
|
1482
|
+
if (dialog?.kind === "indicatorSettings") return /* @__PURE__ */ a3(IndicatorSettings, { ctx, id: dialog.id });
|
|
1483
|
+
if (dialog?.kind === "chartSettings") return /* @__PURE__ */ a3(SettingsDialog, { ctx });
|
|
1318
1484
|
return null;
|
|
1319
1485
|
}
|
|
1320
1486
|
|
|
@@ -1349,8 +1515,8 @@ function IntervalPicker({ ctx }) {
|
|
|
1349
1515
|
setOpen(false);
|
|
1350
1516
|
ctx.selectResolution(r3);
|
|
1351
1517
|
};
|
|
1352
|
-
return /* @__PURE__ */
|
|
1353
|
-
/* @__PURE__ */
|
|
1518
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-interval-picker", ref, children: [
|
|
1519
|
+
/* @__PURE__ */ a3("div", { class: "fnc-intervals", children: favorites.map((r3) => /* @__PURE__ */ a3(
|
|
1354
1520
|
"button",
|
|
1355
1521
|
{
|
|
1356
1522
|
class: "fnc-chip",
|
|
@@ -1361,7 +1527,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1361
1527
|
children: resolutionLabel(r3, s3.locale)
|
|
1362
1528
|
}
|
|
1363
1529
|
)) }),
|
|
1364
|
-
/* @__PURE__ */
|
|
1530
|
+
/* @__PURE__ */ a3(
|
|
1365
1531
|
"button",
|
|
1366
1532
|
{
|
|
1367
1533
|
class: `fnc-btn fnc-btn-wide fnc-interval-trigger${favorites.includes(s3.resolution) ? "" : " fnc-interval-trigger-active"}`,
|
|
@@ -1371,18 +1537,18 @@ function IntervalPicker({ ctx }) {
|
|
|
1371
1537
|
"aria-expanded": open,
|
|
1372
1538
|
onClick: () => setOpen(!open),
|
|
1373
1539
|
children: [
|
|
1374
|
-
/* @__PURE__ */
|
|
1375
|
-
/* @__PURE__ */
|
|
1540
|
+
/* @__PURE__ */ a3("b", { class: "fnc-interval-current", children: resolutionLabel(s3.resolution, s3.locale) }),
|
|
1541
|
+
/* @__PURE__ */ a3(ChevronDownIcon, {})
|
|
1376
1542
|
]
|
|
1377
1543
|
}
|
|
1378
1544
|
),
|
|
1379
|
-
open && /* @__PURE__ */
|
|
1380
|
-
/* @__PURE__ */
|
|
1545
|
+
open && /* @__PURE__ */ a3("div", { class: "fnc-menu fnc-interval-menu", role: "menu", ref: menuRef, children: ctx.intervalGroups.map((group) => /* @__PURE__ */ a3("div", { class: "fnc-menu-group", role: "group", "aria-label": t3[GROUP_LABEL[group.id]], children: [
|
|
1546
|
+
/* @__PURE__ */ a3("div", { class: "fnc-menu-title", children: t3[GROUP_LABEL[group.id]] }),
|
|
1381
1547
|
group.intervals.map((r3) => {
|
|
1382
1548
|
const favorite = s3.favoriteIntervals.includes(r3);
|
|
1383
1549
|
const ok = isSupported(r3);
|
|
1384
|
-
return /* @__PURE__ */
|
|
1385
|
-
/* @__PURE__ */
|
|
1550
|
+
return /* @__PURE__ */ a3("div", { class: `fnc-menu-row${favorite ? " is-favorite" : ""}`, children: [
|
|
1551
|
+
/* @__PURE__ */ a3(
|
|
1386
1552
|
"button",
|
|
1387
1553
|
{
|
|
1388
1554
|
class: "fnc-menu-item",
|
|
@@ -1394,7 +1560,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1394
1560
|
children: resolutionLabel(r3, s3.locale, "long")
|
|
1395
1561
|
}
|
|
1396
1562
|
),
|
|
1397
|
-
/* @__PURE__ */
|
|
1563
|
+
/* @__PURE__ */ a3(
|
|
1398
1564
|
"button",
|
|
1399
1565
|
{
|
|
1400
1566
|
class: "fnc-star",
|
|
@@ -1402,7 +1568,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1402
1568
|
"aria-label": `${resolutionLabel(r3, s3.locale, "long")} ${favorite ? t3.removeFavorite : t3.addFavorite}`,
|
|
1403
1569
|
"data-tip": favorite ? t3.removeFavorite : t3.addFavorite,
|
|
1404
1570
|
onClick: () => ctx.toggleFavoriteInterval(r3),
|
|
1405
|
-
children: /* @__PURE__ */
|
|
1571
|
+
children: /* @__PURE__ */ a3(StarIcon, { filled: favorite })
|
|
1406
1572
|
}
|
|
1407
1573
|
)
|
|
1408
1574
|
] });
|
|
@@ -1480,7 +1646,7 @@ function layoutRects(node, x2 = 0, y3 = 0, w3 = 20, h3 = 16, gap = 1.6) {
|
|
|
1480
1646
|
// src/components/layout-menu.tsx
|
|
1481
1647
|
var LAYOUT_PANES = (id) => paneCount(LAYOUTS[id]);
|
|
1482
1648
|
function LayoutGlyph({ id }) {
|
|
1483
|
-
return /* @__PURE__ */
|
|
1649
|
+
return /* @__PURE__ */ a3("svg", { width: "20", height: "16", viewBox: "0 0 20 16", "aria-hidden": "true", children: layoutRects(LAYOUTS[id]).map((r3) => /* @__PURE__ */ a3("rect", { x: r3.x + 0.5, y: r3.y + 0.5, width: Math.max(0, r3.w - 1), height: Math.max(0, r3.h - 1), rx: "1.5", fill: "none", stroke: "currentColor", "stroke-width": "1.2" })) });
|
|
1484
1650
|
}
|
|
1485
1651
|
function usePopover() {
|
|
1486
1652
|
const [open, setOpen] = d2(false);
|
|
@@ -1513,9 +1679,9 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1513
1679
|
const layoutMenuRef = useKeepInView(layout.open);
|
|
1514
1680
|
const syncMenuRef = useKeepInView(sync.open);
|
|
1515
1681
|
const anySync = Object.values(m3.sync).some(Boolean);
|
|
1516
|
-
return /* @__PURE__ */
|
|
1517
|
-
/* @__PURE__ */
|
|
1518
|
-
/* @__PURE__ */
|
|
1682
|
+
return /* @__PURE__ */ a3($, { children: [
|
|
1683
|
+
/* @__PURE__ */ a3("div", { class: "fnc-menu-wrap", ref: layout.ref, children: [
|
|
1684
|
+
/* @__PURE__ */ a3(
|
|
1519
1685
|
"button",
|
|
1520
1686
|
{
|
|
1521
1687
|
class: "fnc-btn fnc-btn-wide fnc-btn-layout",
|
|
@@ -1525,14 +1691,14 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1525
1691
|
"aria-expanded": layout.open,
|
|
1526
1692
|
onClick: () => layout.setOpen(!layout.open),
|
|
1527
1693
|
children: [
|
|
1528
|
-
/* @__PURE__ */
|
|
1529
|
-
/* @__PURE__ */
|
|
1694
|
+
/* @__PURE__ */ a3(LayoutGlyph, { id: m3.layout }),
|
|
1695
|
+
/* @__PURE__ */ a3(ChevronDownIcon, {})
|
|
1530
1696
|
]
|
|
1531
1697
|
}
|
|
1532
1698
|
),
|
|
1533
|
-
layout.open && /* @__PURE__ */
|
|
1534
|
-
/* @__PURE__ */
|
|
1535
|
-
group.map((id) => /* @__PURE__ */
|
|
1699
|
+
layout.open && /* @__PURE__ */ a3("div", { class: "fnc-menu fnc-layout-menu", role: "menu", "aria-label": t3.layout, ref: layoutMenuRef, children: LAYOUT_GROUPS.map((group) => /* @__PURE__ */ a3("div", { class: "fnc-layout-row", children: [
|
|
1700
|
+
/* @__PURE__ */ a3("span", { class: "fnc-layout-count", children: group[0].split("-")[0] }),
|
|
1701
|
+
group.map((id) => /* @__PURE__ */ a3(
|
|
1536
1702
|
"button",
|
|
1537
1703
|
{
|
|
1538
1704
|
class: "fnc-layout-opt",
|
|
@@ -1544,13 +1710,13 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1544
1710
|
multi.setLayout(id);
|
|
1545
1711
|
layout.setOpen(false);
|
|
1546
1712
|
},
|
|
1547
|
-
children: /* @__PURE__ */
|
|
1713
|
+
children: /* @__PURE__ */ a3(LayoutGlyph, { id })
|
|
1548
1714
|
}
|
|
1549
1715
|
))
|
|
1550
1716
|
] })) })
|
|
1551
1717
|
] }),
|
|
1552
|
-
LAYOUT_PANES(m3.layout) > 1 && /* @__PURE__ */
|
|
1553
|
-
/* @__PURE__ */
|
|
1718
|
+
LAYOUT_PANES(m3.layout) > 1 && /* @__PURE__ */ a3("div", { class: "fnc-menu-wrap", ref: sync.ref, children: [
|
|
1719
|
+
/* @__PURE__ */ a3(
|
|
1554
1720
|
"button",
|
|
1555
1721
|
{
|
|
1556
1722
|
class: "fnc-btn fnc-btn-sync",
|
|
@@ -1560,15 +1726,15 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1560
1726
|
"aria-expanded": sync.open,
|
|
1561
1727
|
"aria-pressed": anySync,
|
|
1562
1728
|
onClick: () => sync.setOpen(!sync.open),
|
|
1563
|
-
children: /* @__PURE__ */
|
|
1729
|
+
children: /* @__PURE__ */ a3(LinkIcon, {})
|
|
1564
1730
|
}
|
|
1565
1731
|
),
|
|
1566
|
-
sync.open && /* @__PURE__ */
|
|
1567
|
-
/* @__PURE__ */
|
|
1732
|
+
sync.open && /* @__PURE__ */ a3("div", { class: "fnc-menu fnc-sync-menu", role: "menu", "aria-label": t3.sync, ref: syncMenuRef, children: [
|
|
1733
|
+
/* @__PURE__ */ a3("div", { class: "fnc-menu-title", children: [
|
|
1568
1734
|
t3.sync,
|
|
1569
|
-
/* @__PURE__ */
|
|
1735
|
+
/* @__PURE__ */ a3("small", { children: t3.syncHint })
|
|
1570
1736
|
] }),
|
|
1571
|
-
SYNC_KEYS.map(({ key, label }) => /* @__PURE__ */
|
|
1737
|
+
SYNC_KEYS.map(({ key, label }) => /* @__PURE__ */ a3(
|
|
1572
1738
|
"button",
|
|
1573
1739
|
{
|
|
1574
1740
|
class: "fnc-menu-item fnc-sync-item",
|
|
@@ -1576,8 +1742,8 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1576
1742
|
"aria-checked": m3.sync[key],
|
|
1577
1743
|
onClick: () => multi.setSync({ [key]: !m3.sync[key] }),
|
|
1578
1744
|
children: [
|
|
1579
|
-
/* @__PURE__ */
|
|
1580
|
-
/* @__PURE__ */
|
|
1745
|
+
/* @__PURE__ */ a3("span", { children: t3[label] }),
|
|
1746
|
+
/* @__PURE__ */ a3("span", { class: "fnc-switch", "data-on": m3.sync[key] ? "true" : "false", "aria-hidden": "true" })
|
|
1581
1747
|
]
|
|
1582
1748
|
}
|
|
1583
1749
|
))
|
|
@@ -1593,7 +1759,7 @@ function Slot({ el, fixed = false }) {
|
|
|
1593
1759
|
ref.current?.appendChild(el);
|
|
1594
1760
|
return () => el.remove();
|
|
1595
1761
|
}, [el]);
|
|
1596
|
-
return /* @__PURE__ */
|
|
1762
|
+
return /* @__PURE__ */ a3("div", { class: fixed ? "fnc-slot-host fnc-slot-host-fixed" : "fnc-slot-host", ref });
|
|
1597
1763
|
}
|
|
1598
1764
|
|
|
1599
1765
|
// src/components/symbol-avatar.tsx
|
|
@@ -1607,10 +1773,10 @@ function SymbolAvatar({ info, size = 24 }) {
|
|
|
1607
1773
|
A2(() => setFailed(false), [info.logoUrl]);
|
|
1608
1774
|
const style = { width: `${size}px`, height: `${size}px`, fontSize: `${Math.round(size * 0.46)}px` };
|
|
1609
1775
|
if (info.logoUrl && !failed) {
|
|
1610
|
-
return /* @__PURE__ */
|
|
1776
|
+
return /* @__PURE__ */ a3("img", { class: "fnc-avatar", src: info.logoUrl, alt: "", style, onError: () => setFailed(true) });
|
|
1611
1777
|
}
|
|
1612
1778
|
const h3 = hue(info.symbol);
|
|
1613
|
-
return /* @__PURE__ */
|
|
1779
|
+
return /* @__PURE__ */ a3(
|
|
1614
1780
|
"span",
|
|
1615
1781
|
{
|
|
1616
1782
|
class: "fnc-avatar fnc-avatar-initial",
|
|
@@ -1631,18 +1797,18 @@ var displayCode = (symbol) => symbol.slice(symbol.lastIndexOf(":") + 1);
|
|
|
1631
1797
|
var toStored = (info) => JSON.parse(JSON.stringify({ ...info, tickSize: 0, price: void 0, changePercent: void 0, sparkline: void 0 }));
|
|
1632
1798
|
function Highlight({ text, query }) {
|
|
1633
1799
|
const q2 = query.trim();
|
|
1634
|
-
if (!q2) return /* @__PURE__ */
|
|
1800
|
+
if (!q2) return /* @__PURE__ */ a3($, { children: text });
|
|
1635
1801
|
const parts = [];
|
|
1636
1802
|
const lower = text.toLowerCase();
|
|
1637
1803
|
const needle = q2.toLowerCase();
|
|
1638
1804
|
let i3 = 0;
|
|
1639
1805
|
for (let at = lower.indexOf(needle); at >= 0; at = lower.indexOf(needle, i3)) {
|
|
1640
1806
|
if (at > i3) parts.push(text.slice(i3, at));
|
|
1641
|
-
parts.push(/* @__PURE__ */
|
|
1807
|
+
parts.push(/* @__PURE__ */ a3("mark", { children: text.slice(at, at + q2.length) }));
|
|
1642
1808
|
i3 = at + q2.length;
|
|
1643
1809
|
}
|
|
1644
1810
|
parts.push(text.slice(i3));
|
|
1645
|
-
return /* @__PURE__ */
|
|
1811
|
+
return /* @__PURE__ */ a3($, { children: parts });
|
|
1646
1812
|
}
|
|
1647
1813
|
function Sparkline({ values, up }) {
|
|
1648
1814
|
if (values.length < 2) return null;
|
|
@@ -1651,10 +1817,11 @@ function Sparkline({ values, up }) {
|
|
|
1651
1817
|
const w3 = 72;
|
|
1652
1818
|
const h3 = 24;
|
|
1653
1819
|
const points = values.map((v3, i3) => `${(i3 / (values.length - 1) * w3).toFixed(1)},${(h3 - 2 - (v3 - min) / (max - min || 1) * (h3 - 4)).toFixed(1)}`).join(" ");
|
|
1654
|
-
return /* @__PURE__ */
|
|
1820
|
+
return /* @__PURE__ */ a3("svg", { class: `fnc-sr-spark ${up ? "fnc-up" : "fnc-down"}`, width: w3, height: h3, viewBox: `0 0 ${w3} ${h3}`, "aria-hidden": "true", children: /* @__PURE__ */ a3("polyline", { points, fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linejoin": "round" }) });
|
|
1655
1821
|
}
|
|
1656
1822
|
function SymbolSearch({ ctx }) {
|
|
1657
|
-
const { locale, symbol: current } = useStore(ctx.store);
|
|
1823
|
+
const { locale, symbol: current, searchTarget } = useStore(ctx.store);
|
|
1824
|
+
const comparing = searchTarget === "compare";
|
|
1658
1825
|
const t3 = STRINGS[locale];
|
|
1659
1826
|
const [query, setQuery] = d2("");
|
|
1660
1827
|
const [category, setCategory] = d2(ctx.searchCategories[0]?.id ?? "all");
|
|
@@ -1708,7 +1875,8 @@ function SymbolSearch({ ctx }) {
|
|
|
1708
1875
|
if (!info) return;
|
|
1709
1876
|
save(RECENT_KEY, [toStored(info), ...recent.filter((r3) => r3.symbol !== info.symbol)].slice(0, MAX_RECENT), setRecent);
|
|
1710
1877
|
close();
|
|
1711
|
-
ctx.
|
|
1878
|
+
if (comparing) ctx.chart.addCompare(info.symbol).catch((error) => console.error("funnest-charts: compare failed", error));
|
|
1879
|
+
else ctx.selectSymbol(info.symbol);
|
|
1712
1880
|
};
|
|
1713
1881
|
const onKeyDown = (e3) => {
|
|
1714
1882
|
const count = rows.length;
|
|
@@ -1726,7 +1894,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1726
1894
|
const change = info.changePercent ?? 0;
|
|
1727
1895
|
const up = change >= 0;
|
|
1728
1896
|
const trend = change > 0 ? "fnc-up" : change < 0 ? "fnc-down" : "fnc-flat";
|
|
1729
|
-
return /* @__PURE__ */
|
|
1897
|
+
return /* @__PURE__ */ a3(
|
|
1730
1898
|
"div",
|
|
1731
1899
|
{
|
|
1732
1900
|
class: "fnc-sr-row",
|
|
@@ -1736,7 +1904,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1736
1904
|
onPointerMove: () => setActive(index),
|
|
1737
1905
|
onClick: () => choose(info),
|
|
1738
1906
|
children: [
|
|
1739
|
-
/* @__PURE__ */
|
|
1907
|
+
/* @__PURE__ */ a3(
|
|
1740
1908
|
"button",
|
|
1741
1909
|
{
|
|
1742
1910
|
class: `fnc-sr-star${fav ? " is-on" : ""}`,
|
|
@@ -1747,32 +1915,32 @@ function SymbolSearch({ ctx }) {
|
|
|
1747
1915
|
e3.stopPropagation();
|
|
1748
1916
|
toggleFavorite(info);
|
|
1749
1917
|
},
|
|
1750
|
-
children: /* @__PURE__ */
|
|
1918
|
+
children: /* @__PURE__ */ a3(StarIcon, { filled: fav })
|
|
1751
1919
|
}
|
|
1752
1920
|
),
|
|
1753
|
-
ctx.showLogo && /* @__PURE__ */
|
|
1754
|
-
/* @__PURE__ */
|
|
1755
|
-
/* @__PURE__ */
|
|
1756
|
-
/* @__PURE__ */
|
|
1757
|
-
current?.symbol === info.symbol && /* @__PURE__ */
|
|
1921
|
+
ctx.showLogo && /* @__PURE__ */ a3(SymbolAvatar, { info, size: 32 }),
|
|
1922
|
+
/* @__PURE__ */ a3("span", { class: "fnc-sr-main", children: [
|
|
1923
|
+
/* @__PURE__ */ a3("span", { class: "fnc-sr-name", children: [
|
|
1924
|
+
/* @__PURE__ */ a3(Highlight, { text: info.name, query }),
|
|
1925
|
+
current?.symbol === info.symbol && /* @__PURE__ */ a3("span", { class: "fnc-sr-current", children: t3.current })
|
|
1758
1926
|
] }),
|
|
1759
|
-
/* @__PURE__ */
|
|
1760
|
-
/* @__PURE__ */
|
|
1927
|
+
/* @__PURE__ */ a3("span", { class: "fnc-sr-meta", children: [
|
|
1928
|
+
/* @__PURE__ */ a3(Highlight, { text: displayCode(info.symbol), query }),
|
|
1761
1929
|
" \xB7 ",
|
|
1762
1930
|
info.exchange,
|
|
1763
1931
|
cat && ` \xB7 ${cat.label[locale]}`
|
|
1764
1932
|
] })
|
|
1765
1933
|
] }),
|
|
1766
|
-
info.sparkline && /* @__PURE__ */
|
|
1767
|
-
info.price !== void 0 && /* @__PURE__ */
|
|
1768
|
-
/* @__PURE__ */
|
|
1769
|
-
info.changePercent !== void 0 && /* @__PURE__ */
|
|
1934
|
+
info.sparkline && /* @__PURE__ */ a3(Sparkline, { values: info.sparkline, up }),
|
|
1935
|
+
info.price !== void 0 && /* @__PURE__ */ a3("span", { class: "fnc-sr-quote", children: [
|
|
1936
|
+
/* @__PURE__ */ a3("b", { children: formatPrice(info.price, info.pricePrecision) }),
|
|
1937
|
+
info.changePercent !== void 0 && /* @__PURE__ */ a3("span", { class: trend, children: [
|
|
1770
1938
|
change > 0 ? "\u2191 " : change < 0 ? "\u2193 " : "",
|
|
1771
1939
|
Math.abs(info.changePercent).toFixed(2),
|
|
1772
1940
|
"%"
|
|
1773
1941
|
] })
|
|
1774
1942
|
] }),
|
|
1775
|
-
isRecent && /* @__PURE__ */
|
|
1943
|
+
isRecent && /* @__PURE__ */ a3(
|
|
1776
1944
|
"button",
|
|
1777
1945
|
{
|
|
1778
1946
|
class: "fnc-ind-btn",
|
|
@@ -1782,30 +1950,30 @@ function SymbolSearch({ ctx }) {
|
|
|
1782
1950
|
e3.stopPropagation();
|
|
1783
1951
|
save(RECENT_KEY, recent.filter((r3) => r3.symbol !== info.symbol), setRecent);
|
|
1784
1952
|
},
|
|
1785
|
-
children: /* @__PURE__ */
|
|
1953
|
+
children: /* @__PURE__ */ a3(SmallCloseIcon, {})
|
|
1786
1954
|
}
|
|
1787
1955
|
)
|
|
1788
1956
|
]
|
|
1789
1957
|
}
|
|
1790
1958
|
);
|
|
1791
1959
|
};
|
|
1792
|
-
const sideItem = (label, selected, onClick, extra) => /* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */
|
|
1960
|
+
const sideItem = (label, selected, onClick, extra) => /* @__PURE__ */ a3("button", { class: "fnc-sr-side-item", "aria-pressed": selected, onClick, children: [
|
|
1961
|
+
/* @__PURE__ */ a3("span", { children: label }),
|
|
1794
1962
|
extra
|
|
1795
1963
|
] });
|
|
1796
|
-
return /* @__PURE__ */
|
|
1797
|
-
/* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
1799
|
-
exchange && /* @__PURE__ */
|
|
1964
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-backdrop", onPointerDown: (e3) => e3.target === e3.currentTarget && close(), children: /* @__PURE__ */ a3("div", { class: "fnc-dialog fnc-search-dialog", role: "dialog", "aria-modal": "true", "aria-label": comparing ? t3.compareSymbol : t3.searchSymbol, onKeyDown, children: [
|
|
1965
|
+
/* @__PURE__ */ a3("div", { class: "fnc-search", children: [
|
|
1966
|
+
/* @__PURE__ */ a3(SearchIcon, {}),
|
|
1967
|
+
exchange && /* @__PURE__ */ a3("span", { class: "fnc-chip-token", children: [
|
|
1800
1968
|
exchange,
|
|
1801
|
-
/* @__PURE__ */
|
|
1969
|
+
/* @__PURE__ */ a3("button", { "aria-label": `${exchange} ${t3.cancel}`, onClick: () => setExchange(null), children: /* @__PURE__ */ a3(SmallCloseIcon, {}) })
|
|
1802
1970
|
] }),
|
|
1803
|
-
/* @__PURE__ */
|
|
1971
|
+
/* @__PURE__ */ a3(
|
|
1804
1972
|
"input",
|
|
1805
1973
|
{
|
|
1806
1974
|
ref: inputRef,
|
|
1807
1975
|
value: query,
|
|
1808
|
-
placeholder: t3.searchPlaceholder,
|
|
1976
|
+
placeholder: comparing ? t3.compareSymbol : t3.searchPlaceholder,
|
|
1809
1977
|
role: "combobox",
|
|
1810
1978
|
"aria-expanded": "true",
|
|
1811
1979
|
"aria-controls": "fnc-search-results",
|
|
@@ -1814,50 +1982,50 @@ function SymbolSearch({ ctx }) {
|
|
|
1814
1982
|
onInput: (e3) => setQuery(e3.currentTarget.value)
|
|
1815
1983
|
}
|
|
1816
1984
|
),
|
|
1817
|
-
query && /* @__PURE__ */
|
|
1818
|
-
/* @__PURE__ */
|
|
1985
|
+
query && /* @__PURE__ */ a3("button", { class: "fnc-ind-btn", "aria-label": t3.cancel, onClick: () => (setQuery(""), inputRef.current?.focus()), children: /* @__PURE__ */ a3(SmallCloseIcon, {}) }),
|
|
1986
|
+
/* @__PURE__ */ a3("button", { class: "fnc-kbd fnc-kbd-btn fnc-hide-mobile", "aria-label": t3.close, "data-tip": t3.close, onClick: close, children: "ESC" })
|
|
1819
1987
|
] }),
|
|
1820
|
-
/* @__PURE__ */
|
|
1821
|
-
/* @__PURE__ */
|
|
1822
|
-
/* @__PURE__ */
|
|
1823
|
-
/* @__PURE__ */
|
|
1988
|
+
/* @__PURE__ */ a3("div", { class: "fnc-tabs", role: "tablist", children: ctx.searchCategories.map((c3) => /* @__PURE__ */ a3("button", { class: "fnc-tab", role: "tab", "aria-selected": c3.id === category, onClick: () => setCategory(c3.id), children: c3.label[locale] })) }),
|
|
1989
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sr-body", children: [
|
|
1990
|
+
/* @__PURE__ */ a3("nav", { class: "fnc-sr-side fnc-scroll", "aria-label": t3.searchSymbol, children: [
|
|
1991
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sr-side-title", children: t3.browse }),
|
|
1824
1992
|
sideItem(t3.allSymbols, view.kind === "all" && !exchange, () => (setView({ kind: "all" }), setExchange(null))),
|
|
1825
|
-
sideItem(t3.favorites, view.kind === "favorites", () => (setView({ kind: "favorites" }), setExchange(null)), /* @__PURE__ */
|
|
1826
|
-
exchanges.length > 0 && /* @__PURE__ */
|
|
1993
|
+
sideItem(t3.favorites, view.kind === "favorites", () => (setView({ kind: "favorites" }), setExchange(null)), /* @__PURE__ */ a3("em", { children: favorites.length || "" })),
|
|
1994
|
+
exchanges.length > 0 && /* @__PURE__ */ a3("div", { class: "fnc-sr-side-title", children: t3.exchanges }),
|
|
1827
1995
|
exchanges.map(
|
|
1828
|
-
([name, count]) => sideItem(name, exchange === name, () => (setView({ kind: "all" }), setExchange(exchange === name ? null : name)), /* @__PURE__ */
|
|
1996
|
+
([name, count]) => sideItem(name, exchange === name, () => (setView({ kind: "all" }), setExchange(exchange === name ? null : name)), /* @__PURE__ */ a3("em", { children: count }))
|
|
1829
1997
|
)
|
|
1830
1998
|
] }),
|
|
1831
|
-
/* @__PURE__ */
|
|
1832
|
-
recentRows.length > 0 && /* @__PURE__ */
|
|
1833
|
-
/* @__PURE__ */
|
|
1834
|
-
/* @__PURE__ */
|
|
1999
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sr-list fnc-scroll", id: "fnc-search-results", role: "listbox", ref: listRef, children: [
|
|
2000
|
+
recentRows.length > 0 && /* @__PURE__ */ a3("div", { class: "fnc-sr-section", children: [
|
|
2001
|
+
/* @__PURE__ */ a3("span", { children: t3.recentSearches }),
|
|
2002
|
+
/* @__PURE__ */ a3("button", { class: "fnc-link", onClick: () => save(RECENT_KEY, [], setRecent), children: t3.clearRecent })
|
|
1835
2003
|
] }),
|
|
1836
2004
|
recentRows.map((info, i3) => row2(info, i3, true)),
|
|
1837
|
-
(recentRows.length > 0 || view.kind === "favorites") && /* @__PURE__ */
|
|
1838
|
-
loading && !results && view.kind === "all" ? Array.from({ length: 6 }, () => /* @__PURE__ */
|
|
1839
|
-
!loading && rows.length === 0 && /* @__PURE__ */
|
|
2005
|
+
(recentRows.length > 0 || view.kind === "favorites") && /* @__PURE__ */ a3("div", { class: "fnc-sr-section", children: view.kind === "favorites" ? t3.favorites : t3.symbols }),
|
|
2006
|
+
loading && !results && view.kind === "all" ? Array.from({ length: 6 }, () => /* @__PURE__ */ a3("div", { class: "fnc-sr-skeleton", "aria-hidden": "true" })) : resultRows.map((info, i3) => row2(info, recentRows.length + i3, false)),
|
|
2007
|
+
!loading && rows.length === 0 && /* @__PURE__ */ a3("div", { class: "fnc-empty", children: view.kind === "favorites" && favorites.length === 0 ? t3.noFavorites : t3.noResults })
|
|
1840
2008
|
] })
|
|
1841
2009
|
] }),
|
|
1842
|
-
/* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
1844
|
-
/* @__PURE__ */
|
|
2010
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sr-footer", children: [
|
|
2011
|
+
/* @__PURE__ */ a3("span", { children: [
|
|
2012
|
+
/* @__PURE__ */ a3("kbd", { class: "fnc-kbd", children: "\u2191\u2193" }),
|
|
1845
2013
|
" ",
|
|
1846
2014
|
t3.navigate
|
|
1847
2015
|
] }),
|
|
1848
|
-
/* @__PURE__ */
|
|
1849
|
-
/* @__PURE__ */
|
|
2016
|
+
/* @__PURE__ */ a3("span", { children: [
|
|
2017
|
+
/* @__PURE__ */ a3("kbd", { class: "fnc-kbd", children: "\u21B5" }),
|
|
1850
2018
|
" ",
|
|
1851
2019
|
t3.openAction
|
|
1852
2020
|
] }),
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
2021
|
+
/* @__PURE__ */ a3("button", { class: "fnc-sr-foot-btn", onClick: close, children: [
|
|
2022
|
+
/* @__PURE__ */ a3("kbd", { class: "fnc-kbd", children: "ESC" }),
|
|
1855
2023
|
" ",
|
|
1856
2024
|
t3.close
|
|
1857
2025
|
] }),
|
|
1858
|
-
/* @__PURE__ */
|
|
1859
|
-
/* @__PURE__ */
|
|
1860
|
-
/* @__PURE__ */
|
|
2026
|
+
/* @__PURE__ */ a3("span", { class: "fnc-spacer" }),
|
|
2027
|
+
/* @__PURE__ */ a3("span", { children: [
|
|
2028
|
+
/* @__PURE__ */ a3("kbd", { class: "fnc-kbd", children: [
|
|
1861
2029
|
/Mac|iPhone|iPad/.test(navigator.platform) ? "\u2318" : "Ctrl",
|
|
1862
2030
|
" + K"
|
|
1863
2031
|
] }),
|
|
@@ -1873,29 +2041,29 @@ function Toolbar({ ctx }) {
|
|
|
1873
2041
|
const s3 = useStore(ctx.store);
|
|
1874
2042
|
const t3 = STRINGS[s3.locale];
|
|
1875
2043
|
const canSearch = typeof ctx.datafeed.searchSymbols === "function";
|
|
1876
|
-
return /* @__PURE__ */
|
|
1877
|
-
/* @__PURE__ */
|
|
2044
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-toolbar", role: "toolbar", children: [
|
|
2045
|
+
/* @__PURE__ */ a3(
|
|
1878
2046
|
"button",
|
|
1879
2047
|
{
|
|
1880
2048
|
class: "fnc-symbol",
|
|
1881
2049
|
disabled: !canSearch,
|
|
1882
2050
|
"data-tip": canSearch ? t3.searchSymbol : void 0,
|
|
1883
2051
|
"aria-haspopup": "dialog",
|
|
1884
|
-
onClick: () => ctx.setSearchOpen(true),
|
|
2052
|
+
onClick: () => ctx.setSearchOpen(true, "symbol"),
|
|
1885
2053
|
children: [
|
|
1886
|
-
ctx.showLogo && s3.symbol ? /* @__PURE__ */
|
|
1887
|
-
/* @__PURE__ */
|
|
1888
|
-
canSearch && ctx.showLogo && /* @__PURE__ */
|
|
2054
|
+
ctx.showLogo && s3.symbol ? /* @__PURE__ */ a3(SymbolAvatar, { info: s3.symbol, size: 24 }) : canSearch && /* @__PURE__ */ a3("span", { class: "fnc-icon", children: /* @__PURE__ */ a3(SearchIcon, {}) }),
|
|
2055
|
+
/* @__PURE__ */ a3("span", { class: "fnc-symbol-name", children: s3.symbol?.name ?? "\u2014" }),
|
|
2056
|
+
canSearch && ctx.showLogo && /* @__PURE__ */ a3("span", { class: "fnc-icon", children: /* @__PURE__ */ a3(ChevronDownIcon, {}) })
|
|
1889
2057
|
]
|
|
1890
2058
|
}
|
|
1891
2059
|
),
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
/* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
/* @__PURE__ */
|
|
1897
|
-
/* @__PURE__ */
|
|
1898
|
-
/* @__PURE__ */
|
|
2060
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sep" }),
|
|
2061
|
+
/* @__PURE__ */ a3(IntervalPicker, { ctx }),
|
|
2062
|
+
/* @__PURE__ */ a3(Slot, { el: ctx.slots.toolbar }),
|
|
2063
|
+
/* @__PURE__ */ a3("div", { class: "fnc-spacer" }),
|
|
2064
|
+
/* @__PURE__ */ a3("div", { class: "fnc-tools", children: [
|
|
2065
|
+
/* @__PURE__ */ a3(ChartTypeMenu, { ctx }),
|
|
2066
|
+
/* @__PURE__ */ a3(
|
|
1899
2067
|
"button",
|
|
1900
2068
|
{
|
|
1901
2069
|
class: "fnc-btn fnc-btn-wide fnc-btn-label fnc-btn-indicators",
|
|
@@ -1904,15 +2072,38 @@ function Toolbar({ ctx }) {
|
|
|
1904
2072
|
"aria-haspopup": "dialog",
|
|
1905
2073
|
onClick: () => ctx.store.set({ dialog: { kind: "indicators" } }),
|
|
1906
2074
|
children: [
|
|
1907
|
-
/* @__PURE__ */
|
|
1908
|
-
/* @__PURE__ */
|
|
2075
|
+
/* @__PURE__ */ a3(IndicatorIcon, {}),
|
|
2076
|
+
/* @__PURE__ */ a3("span", { children: t3.indicators })
|
|
1909
2077
|
]
|
|
1910
2078
|
}
|
|
1911
2079
|
),
|
|
1912
|
-
|
|
2080
|
+
canSearch && /* @__PURE__ */ a3(
|
|
2081
|
+
"button",
|
|
2082
|
+
{
|
|
2083
|
+
class: "fnc-btn fnc-btn-compare",
|
|
2084
|
+
"data-tip": t3.compareSymbol,
|
|
2085
|
+
"aria-label": t3.compareSymbol,
|
|
2086
|
+
"aria-haspopup": "dialog",
|
|
2087
|
+
disabled: s3.compares.length >= 5,
|
|
2088
|
+
onClick: () => ctx.setSearchOpen(true, "compare"),
|
|
2089
|
+
children: /* @__PURE__ */ a3(CompareIcon, {})
|
|
2090
|
+
}
|
|
2091
|
+
),
|
|
2092
|
+
/* @__PURE__ */ a3(
|
|
2093
|
+
"button",
|
|
2094
|
+
{
|
|
2095
|
+
class: "fnc-btn fnc-btn-replay",
|
|
2096
|
+
"data-tip": s3.replay.selecting ? t3.replayPick : t3.replay,
|
|
2097
|
+
"aria-label": t3.replay,
|
|
2098
|
+
"aria-pressed": s3.replay.selecting || s3.replay.active,
|
|
2099
|
+
onClick: () => s3.replay.active ? ctx.chart.stopReplay() : ctx.chart.setReplaySelecting(!s3.replay.selecting),
|
|
2100
|
+
children: /* @__PURE__ */ a3(ReplayIcon, {})
|
|
2101
|
+
}
|
|
2102
|
+
),
|
|
2103
|
+
ctx.multi && /* @__PURE__ */ a3(LayoutMenu, { ctx, multi: ctx.multi })
|
|
1913
2104
|
] }),
|
|
1914
|
-
/* @__PURE__ */
|
|
1915
|
-
ctx.drawingToolbar && /* @__PURE__ */
|
|
2105
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sep" }),
|
|
2106
|
+
ctx.drawingToolbar && /* @__PURE__ */ a3(
|
|
1916
2107
|
"button",
|
|
1917
2108
|
{
|
|
1918
2109
|
class: "fnc-btn fnc-btn-drawbar",
|
|
@@ -1920,11 +2111,11 @@ function Toolbar({ ctx }) {
|
|
|
1920
2111
|
"aria-label": t3.drawingTools,
|
|
1921
2112
|
"aria-pressed": s3.drawbarOpen || s3.drawingTool !== null,
|
|
1922
2113
|
onClick: () => ctx.store.set({ drawbarOpen: !s3.drawbarOpen }),
|
|
1923
|
-
children: /* @__PURE__ */
|
|
2114
|
+
children: /* @__PURE__ */ a3(PencilIcon, {})
|
|
1924
2115
|
}
|
|
1925
2116
|
),
|
|
1926
|
-
/* @__PURE__ */
|
|
1927
|
-
/* @__PURE__ */
|
|
2117
|
+
/* @__PURE__ */ a3(Slot, { el: ctx.slots.toolbarEnd, fixed: true }),
|
|
2118
|
+
/* @__PURE__ */ a3(
|
|
1928
2119
|
"button",
|
|
1929
2120
|
{
|
|
1930
2121
|
class: "fnc-btn fnc-btn-settings",
|
|
@@ -1932,22 +2123,22 @@ function Toolbar({ ctx }) {
|
|
|
1932
2123
|
"aria-label": t3.chartSettings,
|
|
1933
2124
|
"aria-haspopup": "dialog",
|
|
1934
2125
|
onClick: () => ctx.store.set({ dialog: { kind: "chartSettings" } }),
|
|
1935
|
-
children: /* @__PURE__ */
|
|
2126
|
+
children: /* @__PURE__ */ a3(SettingsIcon, {})
|
|
1936
2127
|
}
|
|
1937
2128
|
),
|
|
1938
|
-
/* @__PURE__ */
|
|
1939
|
-
/* @__PURE__ */
|
|
2129
|
+
/* @__PURE__ */ a3("button", { class: "fnc-btn fnc-btn-screenshot", "data-tip": t3.screenshot, "aria-label": t3.screenshot, onClick: ctx.screenshot, children: /* @__PURE__ */ a3(CameraIcon, {}) }),
|
|
2130
|
+
/* @__PURE__ */ a3(
|
|
1940
2131
|
"button",
|
|
1941
2132
|
{
|
|
1942
2133
|
class: "fnc-btn fnc-btn-fullscreen",
|
|
1943
2134
|
"data-tip": s3.fullscreen ? t3.exitFullscreen : t3.fullscreen,
|
|
1944
2135
|
"aria-label": s3.fullscreen ? t3.exitFullscreen : t3.fullscreen,
|
|
1945
2136
|
onClick: ctx.toggleFullscreen,
|
|
1946
|
-
children: s3.fullscreen ? /* @__PURE__ */
|
|
2137
|
+
children: s3.fullscreen ? /* @__PURE__ */ a3(CollapseIcon, {}) : /* @__PURE__ */ a3(ExpandIcon, {})
|
|
1947
2138
|
}
|
|
1948
2139
|
),
|
|
1949
|
-
s3.searchOpen && canSearch && /* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
2140
|
+
s3.searchOpen && canSearch && /* @__PURE__ */ a3(SymbolSearch, { ctx }),
|
|
2141
|
+
/* @__PURE__ */ a3(Dialogs, { ctx })
|
|
1951
2142
|
] });
|
|
1952
2143
|
}
|
|
1953
2144
|
|
|
@@ -1955,13 +2146,94 @@ function Toolbar({ ctx }) {
|
|
|
1955
2146
|
import { createChart } from "@funnest/charts";
|
|
1956
2147
|
|
|
1957
2148
|
// src/components/overlay.tsx
|
|
1958
|
-
import { formatCompact, formatPrice as
|
|
2149
|
+
import { formatCompact, formatPrice as formatPrice3 } from "@funnest/charts";
|
|
2150
|
+
|
|
2151
|
+
// src/components/context-menu.tsx
|
|
2152
|
+
import { formatPrice as formatPrice2 } from "@funnest/charts";
|
|
2153
|
+
var MARGIN2 = 8;
|
|
2154
|
+
function ContextMenu({ ctx }) {
|
|
2155
|
+
const s3 = useStore(ctx.store);
|
|
2156
|
+
const t3 = STRINGS[s3.locale];
|
|
2157
|
+
const [target, setTarget] = d2(null);
|
|
2158
|
+
const ref = T2(null);
|
|
2159
|
+
A2(() => ctx.chart.on("contextMenu", setTarget), [ctx.chart]);
|
|
2160
|
+
A2(() => {
|
|
2161
|
+
if (!target) return;
|
|
2162
|
+
const close = () => setTarget(null);
|
|
2163
|
+
const onDown = (e3) => !ref.current?.contains(e3.target) && close();
|
|
2164
|
+
const onKey = (e3) => e3.key === "Escape" && close();
|
|
2165
|
+
document.addEventListener("pointerdown", onDown, true);
|
|
2166
|
+
document.addEventListener("keydown", onKey);
|
|
2167
|
+
window.addEventListener("wheel", close, { passive: true });
|
|
2168
|
+
window.addEventListener("resize", close);
|
|
2169
|
+
return () => {
|
|
2170
|
+
document.removeEventListener("pointerdown", onDown, true);
|
|
2171
|
+
document.removeEventListener("keydown", onKey);
|
|
2172
|
+
window.removeEventListener("wheel", close);
|
|
2173
|
+
window.removeEventListener("resize", close);
|
|
2174
|
+
};
|
|
2175
|
+
}, [target]);
|
|
2176
|
+
F2(() => {
|
|
2177
|
+
const el = ref.current;
|
|
2178
|
+
const stage = el?.closest(".fnc-stage");
|
|
2179
|
+
if (!el || !target || !stage) return;
|
|
2180
|
+
const w3 = el.offsetWidth;
|
|
2181
|
+
const h3 = el.offsetHeight;
|
|
2182
|
+
const { width, height } = stage.getBoundingClientRect();
|
|
2183
|
+
const x2 = target.x + w3 + MARGIN2 > width ? Math.max(MARGIN2, target.x - w3) : target.x;
|
|
2184
|
+
const y3 = target.y + h3 + MARGIN2 > height ? Math.max(MARGIN2, target.y - h3) : target.y;
|
|
2185
|
+
el.style.transform = `translate(${Math.round(x2)}px, ${Math.round(y3)}px)`;
|
|
2186
|
+
}, [target]);
|
|
2187
|
+
if (!target) return null;
|
|
2188
|
+
const mac = /Mac|iPhone|iPad/.test(navigator.platform);
|
|
2189
|
+
const mod = mac ? "\u2318" : "Ctrl+";
|
|
2190
|
+
const price = target.price;
|
|
2191
|
+
const precision = s3.symbol?.pricePrecision ?? 2;
|
|
2192
|
+
const extra = ctx.contextMenuItems?.({ ...target, chart: ctx.chart }) ?? [];
|
|
2193
|
+
const items = [
|
|
2194
|
+
{ label: t3.undo, shortcut: `${mod}Z`, disabled: !s3.canUndo, onSelect: () => ctx.chart.undo() },
|
|
2195
|
+
{ label: t3.redo, shortcut: `${mod}${mac ? "\u21E7" : "Shift+"}Z`, disabled: !s3.canRedo, onSelect: () => ctx.chart.redo() },
|
|
2196
|
+
"separator",
|
|
2197
|
+
...extra.length ? [...extra, "separator"] : []
|
|
2198
|
+
];
|
|
2199
|
+
if (price !== null) {
|
|
2200
|
+
const time = target.time ?? ctx.chart.bars[ctx.chart.bars.length - 1]?.time ?? Date.now();
|
|
2201
|
+
items.push({
|
|
2202
|
+
label: t3.horizontalAt.replace("{price}", formatPrice2(price, precision)),
|
|
2203
|
+
onSelect: () => ctx.chart.addDrawing({ type: "horizontal", points: [{ time, price }] })
|
|
2204
|
+
});
|
|
2205
|
+
}
|
|
2206
|
+
items.push(
|
|
2207
|
+
{ label: t3.resetChart, onSelect: () => ctx.chart.resetView() },
|
|
2208
|
+
{ label: t3.chartSettingsMore, onSelect: () => ctx.store.set({ dialog: { kind: "chartSettings" } }) }
|
|
2209
|
+
);
|
|
2210
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-menu fnc-ctx-menu", role: "menu", ref, onContextMenu: (e3) => e3.preventDefault(), children: items.map(
|
|
2211
|
+
(item) => item === "separator" ? /* @__PURE__ */ a3("div", { class: "fnc-ctx-sep", role: "separator" }) : /* @__PURE__ */ a3(
|
|
2212
|
+
"button",
|
|
2213
|
+
{
|
|
2214
|
+
class: "fnc-menu-item",
|
|
2215
|
+
role: "menuitem",
|
|
2216
|
+
disabled: item.disabled,
|
|
2217
|
+
onClick: () => {
|
|
2218
|
+
setTarget(null);
|
|
2219
|
+
item.onSelect();
|
|
2220
|
+
},
|
|
2221
|
+
children: [
|
|
2222
|
+
/* @__PURE__ */ a3("span", { children: item.label }),
|
|
2223
|
+
item.shortcut && /* @__PURE__ */ a3("kbd", { children: item.shortcut })
|
|
2224
|
+
]
|
|
2225
|
+
}
|
|
2226
|
+
)
|
|
2227
|
+
) });
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
// src/components/overlay.tsx
|
|
1959
2231
|
var ZOOM_STEP = 1.25;
|
|
1960
2232
|
var CONTROL_OFFSET = 52;
|
|
1961
2233
|
var dirClass = (v3) => v3 > 0 ? "fnc-up" : v3 < 0 ? "fnc-down" : "fnc-flat";
|
|
1962
2234
|
function IndicatorItem({ ctx, item }) {
|
|
1963
2235
|
const t3 = STRINGS[ctx.store.get().locale];
|
|
1964
|
-
return /* @__PURE__ */
|
|
2236
|
+
return /* @__PURE__ */ a3(
|
|
1965
2237
|
"div",
|
|
1966
2238
|
{
|
|
1967
2239
|
class: item.visible ? "fnc-ind" : "fnc-ind fnc-ind-hidden",
|
|
@@ -1974,7 +2246,7 @@ function IndicatorItem({ ctx, item }) {
|
|
|
1974
2246
|
},
|
|
1975
2247
|
onKeyDown: (e3) => e3.key === "Enter" && ctx.store.set({ dialog: { kind: "indicatorSettings", id: item.id } }),
|
|
1976
2248
|
children: [
|
|
1977
|
-
/* @__PURE__ */
|
|
2249
|
+
/* @__PURE__ */ a3(
|
|
1978
2250
|
"button",
|
|
1979
2251
|
{
|
|
1980
2252
|
class: "fnc-ind-btn fnc-ind-eye",
|
|
@@ -1985,30 +2257,30 @@ function IndicatorItem({ ctx, item }) {
|
|
|
1985
2257
|
e3.stopPropagation();
|
|
1986
2258
|
ctx.chart.setIndicatorVisible(item.id, !item.visible);
|
|
1987
2259
|
},
|
|
1988
|
-
children: item.visible ? /* @__PURE__ */
|
|
2260
|
+
children: item.visible ? /* @__PURE__ */ a3(EyeIcon, {}) : /* @__PURE__ */ a3(EyeOffIcon, {})
|
|
1989
2261
|
}
|
|
1990
2262
|
),
|
|
1991
|
-
/* @__PURE__ */
|
|
1992
|
-
item.visible && item.values.map((v3) => /* @__PURE__ */
|
|
1993
|
-
/* @__PURE__ */
|
|
1994
|
-
/* @__PURE__ */
|
|
2263
|
+
/* @__PURE__ */ a3("span", { class: "fnc-ind-title", children: item.title }),
|
|
2264
|
+
item.visible && item.values.map((v3) => /* @__PURE__ */ a3("b", { style: { color: v3.color }, "data-tip": v3.label, children: v3.value })),
|
|
2265
|
+
/* @__PURE__ */ a3("span", { class: "fnc-ind-actions", children: [
|
|
2266
|
+
/* @__PURE__ */ a3(
|
|
1995
2267
|
"button",
|
|
1996
2268
|
{
|
|
1997
2269
|
class: "fnc-ind-btn",
|
|
1998
2270
|
"data-tip": t3.indicatorSettings,
|
|
1999
2271
|
"aria-label": `${item.title} ${t3.indicatorSettings}`,
|
|
2000
2272
|
onClick: () => ctx.store.set({ dialog: { kind: "indicatorSettings", id: item.id } }),
|
|
2001
|
-
children: /* @__PURE__ */
|
|
2273
|
+
children: /* @__PURE__ */ a3(GearIcon, {})
|
|
2002
2274
|
}
|
|
2003
2275
|
),
|
|
2004
|
-
/* @__PURE__ */
|
|
2276
|
+
/* @__PURE__ */ a3(
|
|
2005
2277
|
"button",
|
|
2006
2278
|
{
|
|
2007
2279
|
class: "fnc-ind-btn",
|
|
2008
2280
|
"data-tip": t3.removeIndicator,
|
|
2009
2281
|
"aria-label": `${item.title} ${t3.removeIndicator}`,
|
|
2010
2282
|
onClick: () => ctx.chart.removeIndicator(item.id),
|
|
2011
|
-
children: /* @__PURE__ */
|
|
2283
|
+
children: /* @__PURE__ */ a3(SmallCloseIcon, {})
|
|
2012
2284
|
}
|
|
2013
2285
|
)
|
|
2014
2286
|
] })
|
|
@@ -2028,7 +2300,9 @@ function Legend({ ctx }) {
|
|
|
2028
2300
|
"crosshairMove",
|
|
2029
2301
|
(info) => setHover(info ? { bar: info.bar, prev: ctx.chart.bars[info.index - 1], index: info.index } : null)
|
|
2030
2302
|
),
|
|
2031
|
-
ctx.chart.on("dataChange", () => refresh(void 0))
|
|
2303
|
+
ctx.chart.on("dataChange", () => refresh(void 0)),
|
|
2304
|
+
// Compare values are % from the first visible bar, so they change while scrolling.
|
|
2305
|
+
ctx.chart.on("visibleRangeChange", () => ctx.store.get().compares.length > 0 && refresh(void 0))
|
|
2032
2306
|
];
|
|
2033
2307
|
return () => offs.forEach((off) => off());
|
|
2034
2308
|
}, [ctx.chart]);
|
|
@@ -2041,39 +2315,39 @@ function Legend({ ctx }) {
|
|
|
2041
2315
|
ro.observe(el);
|
|
2042
2316
|
return () => ro.disconnect();
|
|
2043
2317
|
}, [ctx.chart]);
|
|
2044
|
-
if (!s3.symbol) return /* @__PURE__ */
|
|
2318
|
+
if (!s3.symbol) return /* @__PURE__ */ a3("div", { class: "fnc-legend", ref });
|
|
2045
2319
|
const bars = ctx.chart.bars;
|
|
2046
2320
|
const bar = hover?.bar ?? bars[bars.length - 1];
|
|
2047
2321
|
const prev = hover ? hover.prev : bars[bars.length - 2];
|
|
2048
|
-
const fmt = (p3) =>
|
|
2322
|
+
const fmt = (p3) => formatPrice3(p3, s3.symbol.pricePrecision);
|
|
2049
2323
|
let values = null;
|
|
2050
2324
|
if (bar) {
|
|
2051
2325
|
const cls = dirClass(bar.close - bar.open);
|
|
2052
2326
|
const change = prev ? bar.close - prev.close : 0;
|
|
2053
2327
|
const pct = prev && prev.close ? change / prev.close * 100 : 0;
|
|
2054
2328
|
const sign = change > 0 ? "+" : "";
|
|
2055
|
-
values = /* @__PURE__ */
|
|
2056
|
-
/* @__PURE__ */
|
|
2329
|
+
values = /* @__PURE__ */ a3("div", { class: "fnc-legend-values", children: [
|
|
2330
|
+
/* @__PURE__ */ a3("span", { children: [
|
|
2057
2331
|
t3.open,
|
|
2058
2332
|
" ",
|
|
2059
|
-
/* @__PURE__ */
|
|
2333
|
+
/* @__PURE__ */ a3("b", { class: cls, children: fmt(bar.open) })
|
|
2060
2334
|
] }),
|
|
2061
|
-
/* @__PURE__ */
|
|
2335
|
+
/* @__PURE__ */ a3("span", { children: [
|
|
2062
2336
|
t3.high,
|
|
2063
2337
|
" ",
|
|
2064
|
-
/* @__PURE__ */
|
|
2338
|
+
/* @__PURE__ */ a3("b", { class: cls, children: fmt(bar.high) })
|
|
2065
2339
|
] }),
|
|
2066
|
-
/* @__PURE__ */
|
|
2340
|
+
/* @__PURE__ */ a3("span", { children: [
|
|
2067
2341
|
t3.low,
|
|
2068
2342
|
" ",
|
|
2069
|
-
/* @__PURE__ */
|
|
2343
|
+
/* @__PURE__ */ a3("b", { class: cls, children: fmt(bar.low) })
|
|
2070
2344
|
] }),
|
|
2071
|
-
/* @__PURE__ */
|
|
2345
|
+
/* @__PURE__ */ a3("span", { children: [
|
|
2072
2346
|
t3.close_,
|
|
2073
2347
|
" ",
|
|
2074
|
-
/* @__PURE__ */
|
|
2348
|
+
/* @__PURE__ */ a3("b", { class: cls, children: fmt(bar.close) })
|
|
2075
2349
|
] }),
|
|
2076
|
-
/* @__PURE__ */
|
|
2350
|
+
/* @__PURE__ */ a3("b", { class: dirClass(change), children: [
|
|
2077
2351
|
sign,
|
|
2078
2352
|
fmt(change),
|
|
2079
2353
|
" (",
|
|
@@ -2081,33 +2355,48 @@ function Legend({ ctx }) {
|
|
|
2081
2355
|
pct.toFixed(2),
|
|
2082
2356
|
"%)"
|
|
2083
2357
|
] }),
|
|
2084
|
-
bar.volume !== void 0 && /* @__PURE__ */
|
|
2358
|
+
bar.volume !== void 0 && /* @__PURE__ */ a3("span", { children: [
|
|
2085
2359
|
t3.volume,
|
|
2086
2360
|
" ",
|
|
2087
|
-
/* @__PURE__ */
|
|
2361
|
+
/* @__PURE__ */ a3("b", { class: "fnc-flat", children: formatCompact(bar.volume, s3.locale) })
|
|
2088
2362
|
] })
|
|
2089
2363
|
] });
|
|
2090
2364
|
}
|
|
2091
2365
|
const items = s3.indicators.length ? ctx.chart.indicatorLegend(hover?.index) : [];
|
|
2092
2366
|
const overlayItems = items.filter((i3) => i3.overlay);
|
|
2093
2367
|
const paneLegends = s3.layout.panes.filter((p3) => p3.kind === "indicator").map((pane) => ({ pane, item: items.find((i3) => i3.id === pane.id) }));
|
|
2094
|
-
return /* @__PURE__ */
|
|
2095
|
-
/* @__PURE__ */
|
|
2096
|
-
/* @__PURE__ */
|
|
2097
|
-
ctx.showLogo && /* @__PURE__ */
|
|
2098
|
-
/* @__PURE__ */
|
|
2099
|
-
/* @__PURE__ */
|
|
2100
|
-
/* @__PURE__ */
|
|
2101
|
-
/* @__PURE__ */
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
s3.loading && /* @__PURE__ */
|
|
2368
|
+
return /* @__PURE__ */ a3($, { children: [
|
|
2369
|
+
/* @__PURE__ */ a3("div", { class: "fnc-legend", ref, children: [
|
|
2370
|
+
/* @__PURE__ */ a3("div", { class: "fnc-legend-title", children: [
|
|
2371
|
+
ctx.showLogo && /* @__PURE__ */ a3(SymbolAvatar, { info: s3.symbol, size: 18 }),
|
|
2372
|
+
/* @__PURE__ */ a3("b", { children: s3.symbol.name }),
|
|
2373
|
+
/* @__PURE__ */ a3("span", { children: "\xB7" }),
|
|
2374
|
+
/* @__PURE__ */ a3("span", { children: resolutionLabel(s3.resolution, s3.locale) }),
|
|
2375
|
+
/* @__PURE__ */ a3("span", { children: "\xB7" }),
|
|
2376
|
+
/* @__PURE__ */ a3("span", { children: s3.symbol.exchange }),
|
|
2377
|
+
s3.loading && /* @__PURE__ */ a3("span", { class: "fnc-spinner", role: "status" })
|
|
2104
2378
|
] }),
|
|
2105
2379
|
values,
|
|
2106
|
-
|
|
2107
|
-
|
|
2380
|
+
s3.compares.length > 0 && ctx.chart.compareLegend(hover?.index).map((c3) => /* @__PURE__ */ a3("div", { class: "fnc-cmp", children: [
|
|
2381
|
+
/* @__PURE__ */ a3("i", { class: "fnc-cmp-dot", style: { background: c3.color } }),
|
|
2382
|
+
/* @__PURE__ */ a3("span", { class: "fnc-cmp-name", children: c3.name }),
|
|
2383
|
+
/* @__PURE__ */ a3("b", { children: c3.value }),
|
|
2384
|
+
/* @__PURE__ */ a3(
|
|
2385
|
+
"button",
|
|
2386
|
+
{
|
|
2387
|
+
class: "fnc-ind-btn",
|
|
2388
|
+
"data-tip": t3.removeCompare,
|
|
2389
|
+
"aria-label": `${c3.name} ${t3.removeCompare}`,
|
|
2390
|
+
onClick: () => ctx.chart.removeCompare(c3.symbol),
|
|
2391
|
+
children: /* @__PURE__ */ a3(SmallCloseIcon, {})
|
|
2392
|
+
}
|
|
2393
|
+
)
|
|
2394
|
+
] })),
|
|
2395
|
+
!collapsed && overlayItems.map((item) => /* @__PURE__ */ a3(IndicatorItem, { ctx, item })),
|
|
2396
|
+
overlayItems.length > 0 && (collapsed ? /* @__PURE__ */ a3("button", { class: "fnc-ind-handle", "aria-expanded": "false", "aria-label": t3.expand, "data-tip": t3.expand, onClick: () => setCollapsed(false), children: /* @__PURE__ */ a3("span", {}) }) : /* @__PURE__ */ a3("button", { class: "fnc-ind-collapse", "aria-expanded": "true", "aria-label": t3.collapse, "data-tip": t3.collapse, onClick: () => setCollapsed(true), children: /* @__PURE__ */ a3(CollapseLeftIcon, {}) }))
|
|
2108
2397
|
] }),
|
|
2109
2398
|
paneLegends.map(
|
|
2110
|
-
({ pane, item }) => item && /* @__PURE__ */
|
|
2399
|
+
({ pane, item }) => item && /* @__PURE__ */ a3("div", { class: "fnc-legend fnc-pane-legend", style: { top: `${pane.top + 4}px` }, children: /* @__PURE__ */ a3(IndicatorItem, { ctx, item }) })
|
|
2111
2400
|
)
|
|
2112
2401
|
] });
|
|
2113
2402
|
}
|
|
@@ -2120,16 +2409,17 @@ function NavControls({ ctx }) {
|
|
|
2120
2409
|
if (plotWidth <= 0) return null;
|
|
2121
2410
|
const top = panesHeight - CONTROL_OFFSET;
|
|
2122
2411
|
const page = () => Math.max(1, Math.round(plotWidth / ctx.chart.timeScale.barSpacing / 3));
|
|
2123
|
-
const button = (label, onClick, icon) => /* @__PURE__ */
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
button(t3.
|
|
2128
|
-
button(t3.
|
|
2129
|
-
button(t3.
|
|
2130
|
-
button(t3.
|
|
2412
|
+
const button = (label, onClick, icon) => /* @__PURE__ */ a3("button", { class: "fnc-btn", "data-tip": label, "aria-label": label, onClick, children: icon });
|
|
2413
|
+
const replaying = s3.replay.active || s3.replay.selecting;
|
|
2414
|
+
return /* @__PURE__ */ a3($, { children: [
|
|
2415
|
+
showButtons && !replaying && /* @__PURE__ */ a3("div", { class: "fnc-nav", style: { left: `${plotWidth / 2}px`, top: `${top}px` }, children: [
|
|
2416
|
+
button(t3.zoomOut, () => ctx.chart.zoom(1 / ZOOM_STEP), /* @__PURE__ */ a3(MinusIcon, {})),
|
|
2417
|
+
button(t3.zoomIn, () => ctx.chart.zoom(ZOOM_STEP), /* @__PURE__ */ a3(PlusIcon, {})),
|
|
2418
|
+
button(t3.scrollBack, () => ctx.chart.scrollBars(-page()), /* @__PURE__ */ a3(ChevronLeftIcon, {})),
|
|
2419
|
+
button(t3.scrollForward, () => ctx.chart.scrollBars(page()), /* @__PURE__ */ a3(ChevronRightIcon, {})),
|
|
2420
|
+
button(t3.resetView, () => ctx.chart.resetView(), /* @__PURE__ */ a3(ResetIcon, {}))
|
|
2131
2421
|
] }),
|
|
2132
|
-
!s3.atRealtime && /* @__PURE__ */
|
|
2422
|
+
!s3.atRealtime && /* @__PURE__ */ a3(
|
|
2133
2423
|
"button",
|
|
2134
2424
|
{
|
|
2135
2425
|
class: "fnc-realtime",
|
|
@@ -2137,7 +2427,7 @@ function NavControls({ ctx }) {
|
|
|
2137
2427
|
"data-tip": t3.toRealtime,
|
|
2138
2428
|
"aria-label": t3.toRealtime,
|
|
2139
2429
|
onClick: () => ctx.chart.scrollToRealtime(),
|
|
2140
|
-
children: /* @__PURE__ */
|
|
2430
|
+
children: /* @__PURE__ */ a3(ToRealtimeIcon, {})
|
|
2141
2431
|
}
|
|
2142
2432
|
)
|
|
2143
2433
|
] });
|
|
@@ -2148,7 +2438,7 @@ function Attribution({ ctx }) {
|
|
|
2148
2438
|
const { panesHeight, plotWidth } = s3.layout;
|
|
2149
2439
|
if (!ctx.attribution || plotWidth <= 0) return null;
|
|
2150
2440
|
const label = s3.locale === "ko" ? "Funnest \uCC28\uD2B8" : "Charts by Funnest";
|
|
2151
|
-
return /* @__PURE__ */
|
|
2441
|
+
return /* @__PURE__ */ a3(
|
|
2152
2442
|
"a",
|
|
2153
2443
|
{
|
|
2154
2444
|
class: "fnc-attribution",
|
|
@@ -2159,14 +2449,14 @@ function Attribution({ ctx }) {
|
|
|
2159
2449
|
"aria-label": label,
|
|
2160
2450
|
style: { top: `${panesHeight - 36}px` },
|
|
2161
2451
|
children: [
|
|
2162
|
-
/* @__PURE__ */
|
|
2163
|
-
/* @__PURE__ */
|
|
2452
|
+
/* @__PURE__ */ a3(FunnestMark, {}),
|
|
2453
|
+
/* @__PURE__ */ a3("span", { children: "funnest" })
|
|
2164
2454
|
]
|
|
2165
2455
|
}
|
|
2166
2456
|
);
|
|
2167
2457
|
}
|
|
2168
2458
|
function PaneTools({ ctx }) {
|
|
2169
|
-
return ctx.multi ? /* @__PURE__ */
|
|
2459
|
+
return ctx.multi ? /* @__PURE__ */ a3(PaneMaximize, { ctx, multi: ctx.multi }) : null;
|
|
2170
2460
|
}
|
|
2171
2461
|
function PaneMaximize({ ctx, multi }) {
|
|
2172
2462
|
const s3 = useStore(ctx.store);
|
|
@@ -2175,7 +2465,7 @@ function PaneMaximize({ ctx, multi }) {
|
|
|
2175
2465
|
const t3 = STRINGS[s3.locale];
|
|
2176
2466
|
const maximized = m3.maximized !== null;
|
|
2177
2467
|
const label = maximized ? t3.restorePane : t3.maximizePane;
|
|
2178
|
-
return /* @__PURE__ */
|
|
2468
|
+
return /* @__PURE__ */ a3(
|
|
2179
2469
|
"button",
|
|
2180
2470
|
{
|
|
2181
2471
|
class: "fnc-btn fnc-pane-max",
|
|
@@ -2187,17 +2477,59 @@ function PaneMaximize({ ctx, multi }) {
|
|
|
2187
2477
|
const index = multi.store.get().active;
|
|
2188
2478
|
multi.toggleMaximize(index);
|
|
2189
2479
|
},
|
|
2190
|
-
children: maximized ? /* @__PURE__ */
|
|
2480
|
+
children: maximized ? /* @__PURE__ */ a3(RestoreIcon, {}) : /* @__PURE__ */ a3(MaximizeIcon, {})
|
|
2191
2481
|
}
|
|
2192
2482
|
);
|
|
2193
2483
|
}
|
|
2484
|
+
var REPLAY_SPEEDS = [
|
|
2485
|
+
{ label: "1x", interval: 1e3 },
|
|
2486
|
+
{ label: "3x", interval: 333 },
|
|
2487
|
+
{ label: "10x", interval: 100 }
|
|
2488
|
+
];
|
|
2489
|
+
function ReplayBar({ ctx }) {
|
|
2490
|
+
const s3 = useStore(ctx.store);
|
|
2491
|
+
const t3 = STRINGS[s3.locale];
|
|
2492
|
+
const r3 = s3.replay;
|
|
2493
|
+
const { plotWidth, panesHeight } = s3.layout;
|
|
2494
|
+
if (plotWidth <= 0 || !r3.active && !r3.selecting) return null;
|
|
2495
|
+
const style = { left: `${plotWidth / 2}px`, top: `${panesHeight - CONTROL_OFFSET}px` };
|
|
2496
|
+
if (!r3.active) {
|
|
2497
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-replay fnc-replay-hint", style, role: "status", children: [
|
|
2498
|
+
/* @__PURE__ */ a3(ReplayIcon, {}),
|
|
2499
|
+
/* @__PURE__ */ a3("span", { children: t3.replayPick }),
|
|
2500
|
+
/* @__PURE__ */ a3("button", { class: "fnc-ind-btn", "aria-label": t3.cancel, "data-tip": `${t3.cancel} (Esc)`, onClick: () => ctx.chart.setReplaySelecting(false), children: /* @__PURE__ */ a3(SmallCloseIcon, {}) })
|
|
2501
|
+
] });
|
|
2502
|
+
}
|
|
2503
|
+
const done = r3.remaining === 0;
|
|
2504
|
+
const button = (label, onClick, icon, disabled = false) => /* @__PURE__ */ a3("button", { class: "fnc-btn", "data-tip": label, "aria-label": label, disabled, onClick, children: icon });
|
|
2505
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-replay", style, role: "toolbar", "aria-label": t3.replay, children: [
|
|
2506
|
+
r3.playing ? button(t3.replayPause, () => ctx.chart.replayPause(), /* @__PURE__ */ a3(PauseIcon, {})) : button(t3.replayPlay, () => ctx.chart.replayPlay(), /* @__PURE__ */ a3(PlayIcon, {}), done),
|
|
2507
|
+
button(t3.replayStep, () => ctx.chart.replayStep(), /* @__PURE__ */ a3(StepIcon, {}), done),
|
|
2508
|
+
/* @__PURE__ */ a3("div", { class: "fnc-seg fnc-seg-sm", role: "radiogroup", "aria-label": t3.replaySpeed, children: REPLAY_SPEEDS.map((speed) => /* @__PURE__ */ a3(
|
|
2509
|
+
"button",
|
|
2510
|
+
{
|
|
2511
|
+
type: "button",
|
|
2512
|
+
role: "radio",
|
|
2513
|
+
"aria-checked": r3.interval === speed.interval,
|
|
2514
|
+
onClick: () => ctx.chart.setReplayInterval(speed.interval),
|
|
2515
|
+
children: speed.label
|
|
2516
|
+
}
|
|
2517
|
+
)) }),
|
|
2518
|
+
done && /* @__PURE__ */ a3("span", { class: "fnc-replay-note", children: t3.replayDone }),
|
|
2519
|
+
/* @__PURE__ */ a3("div", { class: "fnc-sep" }),
|
|
2520
|
+
button(t3.replayRestart, () => ctx.chart.setReplaySelecting(true), /* @__PURE__ */ a3(ReplayIcon, {})),
|
|
2521
|
+
button(t3.replayExit, () => ctx.chart.stopReplay(), /* @__PURE__ */ a3(SmallCloseIcon, {}))
|
|
2522
|
+
] });
|
|
2523
|
+
}
|
|
2194
2524
|
function Overlay({ ctx }) {
|
|
2195
|
-
return /* @__PURE__ */
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
/* @__PURE__ */
|
|
2198
|
-
/* @__PURE__ */
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2525
|
+
return /* @__PURE__ */ a3($, { children: [
|
|
2526
|
+
/* @__PURE__ */ a3(Attribution, { ctx }),
|
|
2527
|
+
/* @__PURE__ */ a3(Legend, { ctx }),
|
|
2528
|
+
/* @__PURE__ */ a3(NavControls, { ctx }),
|
|
2529
|
+
/* @__PURE__ */ a3(ReplayBar, { ctx }),
|
|
2530
|
+
/* @__PURE__ */ a3(SelectionBar, { ctx }),
|
|
2531
|
+
/* @__PURE__ */ a3(PaneTools, { ctx }),
|
|
2532
|
+
/* @__PURE__ */ a3(ContextMenu, { ctx })
|
|
2201
2533
|
] });
|
|
2202
2534
|
}
|
|
2203
2535
|
|
|
@@ -2996,6 +3328,19 @@ var CSS = (
|
|
|
2996
3328
|
.fnc-action-primary { background: var(--fnc-accent); color: #fff; }
|
|
2997
3329
|
.fnc-action-danger { flex: 0 0 auto; padding: 0 16px; color: var(--fnc-danger, #F04452); background: none; }
|
|
2998
3330
|
|
|
3331
|
+
/* \u2500\u2500 Narrow widgets (split screens next to side panels): the widget's own width decides, so
|
|
3332
|
+
every toolbar button stays reachable. Ctrl/\u2318+Z still undoes when the buttons are hidden. \u2500\u2500 */
|
|
3333
|
+
.fnc-root { container: fnc / inline-size; }
|
|
3334
|
+
@container fnc (max-width: 1100px) {
|
|
3335
|
+
.fnc-btn-label span { display: none; }
|
|
3336
|
+
.fnc-toolbar .fnc-btn-label { padding: 0 6px; }
|
|
3337
|
+
}
|
|
3338
|
+
@container fnc (max-width: 940px) {
|
|
3339
|
+
.fnc-intervals { display: none; }
|
|
3340
|
+
.fnc-interval-current { display: inline; }
|
|
3341
|
+
.fnc-btn-screenshot { display: none; }
|
|
3342
|
+
}
|
|
3343
|
+
|
|
2999
3344
|
/* \u2500\u2500 Narrow phones (\u2264 400px): drop the menu chevrons and separators so every button fits \u2500\u2500 */
|
|
3000
3345
|
@media (max-width: 400px) {
|
|
3001
3346
|
.fnc-toolbar .fnc-btn-wide > svg:last-child { display: none; }
|
|
@@ -3100,8 +3445,86 @@ var CSS = (
|
|
|
3100
3445
|
.fnc-switch[data-on='true'] { background: var(--fnc-text-2); }
|
|
3101
3446
|
.fnc-switch[data-on='true']::after { transform: translateX(16px); }
|
|
3102
3447
|
|
|
3448
|
+
/* \u2500\u2500 Right-click menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3449
|
+
.fnc-ctx-menu { top: 0; left: 0; z-index: 40; min-width: 220px; pointer-events: auto; }
|
|
3450
|
+
.fnc-ctx-menu .fnc-menu-item { justify-content: space-between; gap: 24px; color: var(--fnc-text); }
|
|
3451
|
+
.fnc-ctx-menu .fnc-menu-item:disabled { color: var(--fnc-text-2); }
|
|
3452
|
+
.fnc-ctx-menu kbd { font: inherit; font-size: 12px; color: var(--fnc-text-2); }
|
|
3453
|
+
.fnc-ctx-sep { height: 1px; margin: 4px 6px; background: var(--fnc-border); }
|
|
3454
|
+
|
|
3455
|
+
/* \u2500\u2500 Drawing tool groups \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3456
|
+
.fnc-tool-group { position: relative; display: flex; }
|
|
3457
|
+
.fnc-tool-group[data-open='true'] { z-index: 30; }
|
|
3458
|
+
.fnc-tool-more {
|
|
3459
|
+
position: absolute;
|
|
3460
|
+
right: -2px;
|
|
3461
|
+
bottom: -2px;
|
|
3462
|
+
display: flex;
|
|
3463
|
+
align-items: flex-end;
|
|
3464
|
+
justify-content: flex-end;
|
|
3465
|
+
width: 14px;
|
|
3466
|
+
height: 14px;
|
|
3467
|
+
padding: 3px;
|
|
3468
|
+
color: var(--fnc-text-2);
|
|
3469
|
+
opacity: 0.7;
|
|
3470
|
+
}
|
|
3471
|
+
.fnc-tool-more:hover, .fnc-tool-more[aria-expanded='true'] { opacity: 1; color: var(--fnc-text); }
|
|
3472
|
+
.fnc-tool-menu { top: 0; left: calc(100% + 8px); min-width: 180px; }
|
|
3473
|
+
.fnc-tool-menu .fnc-menu-item { white-space: nowrap; }
|
|
3474
|
+
.fnc-tool-letter { font-size: 13px; font-weight: 700; }
|
|
3475
|
+
.fnc-svg-icon { display: inline-flex; }
|
|
3476
|
+
.fnc-svg-icon svg { width: 20px; height: 20px; }
|
|
3477
|
+
|
|
3478
|
+
/* \u2500\u2500 Segmented control (price scale, replay speed) \u2500\u2500\u2500\u2500 */
|
|
3479
|
+
.fnc-seg { display: inline-flex; gap: 2px; padding: 2px; border-radius: calc(var(--fnc-radius) + 2px); background: var(--fnc-surface); }
|
|
3480
|
+
.fnc-seg button {
|
|
3481
|
+
min-width: 56px;
|
|
3482
|
+
height: 30px;
|
|
3483
|
+
padding: 0 12px;
|
|
3484
|
+
border-radius: var(--fnc-radius);
|
|
3485
|
+
font-size: 13px;
|
|
3486
|
+
color: var(--fnc-text-2);
|
|
3487
|
+
}
|
|
3488
|
+
.fnc-seg button[aria-checked='true'] { background: var(--fnc-bg); color: var(--fnc-text); font-weight: 700; box-shadow: 0 1px 3px rgb(0 0 0 / 0.12); }
|
|
3489
|
+
.fnc-seg-sm button { min-width: 36px; height: 26px; padding: 0 6px; font-size: 12px; }
|
|
3490
|
+
|
|
3491
|
+
/* \u2500\u2500 Compare legend rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3492
|
+
.fnc-cmp { display: flex; align-items: center; gap: 6px; min-height: 22px; font-size: 12px; color: var(--fnc-text-2); pointer-events: auto; }
|
|
3493
|
+
.fnc-cmp-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
|
|
3494
|
+
.fnc-cmp-name { color: var(--fnc-text); }
|
|
3495
|
+
.fnc-cmp b { color: var(--fnc-text); font-weight: 600; font-variant-numeric: tabular-nums; }
|
|
3496
|
+
.fnc-cmp .fnc-ind-btn { opacity: 0; }
|
|
3497
|
+
.fnc-cmp:hover .fnc-ind-btn, .fnc-cmp .fnc-ind-btn:focus-visible { opacity: 1; }
|
|
3498
|
+
@media (hover: none) { .fnc-cmp .fnc-ind-btn { opacity: 1; } }
|
|
3499
|
+
|
|
3500
|
+
/* \u2500\u2500 Replay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3501
|
+
.fnc-replay {
|
|
3502
|
+
position: absolute;
|
|
3503
|
+
z-index: 6;
|
|
3504
|
+
display: flex;
|
|
3505
|
+
align-items: center;
|
|
3506
|
+
gap: 4px;
|
|
3507
|
+
padding: 4px;
|
|
3508
|
+
transform: translateX(-50%);
|
|
3509
|
+
border-radius: calc(var(--fnc-radius) + 4px);
|
|
3510
|
+
background: var(--fnc-bg);
|
|
3511
|
+
box-shadow: 0 2px 12px rgb(0 0 0 / 0.12), 0 0 0 1px var(--fnc-border);
|
|
3512
|
+
white-space: nowrap;
|
|
3513
|
+
pointer-events: auto;
|
|
3514
|
+
}
|
|
3515
|
+
.fnc-replay .fnc-btn { width: 32px; height: 32px; }
|
|
3516
|
+
.fnc-replay .fnc-sep { height: 20px; margin: 0 2px; }
|
|
3517
|
+
.fnc-replay-hint { gap: 8px; padding: 4px 4px 4px 12px; font-size: 13px; color: var(--fnc-text); }
|
|
3518
|
+
.fnc-replay-hint svg { color: var(--fnc-text-2); }
|
|
3519
|
+
.fnc-replay-note { padding: 0 6px; font-size: 12px; color: var(--fnc-text-2); }
|
|
3520
|
+
|
|
3521
|
+
/* Indicator picker search (shown when custom indicators make the list long) */
|
|
3522
|
+
.fnc-ind-search { height: 48px; padding: 0 16px; }
|
|
3523
|
+
.fnc-ind-search input { font-size: 15px; }
|
|
3524
|
+
|
|
3103
3525
|
/* \u2500\u2500 Mobile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3104
3526
|
@media (max-width: 640px) {
|
|
3527
|
+
.fnc-btn-compare, .fnc-btn-replay { display: none; }
|
|
3105
3528
|
.fnc-toolbar { padding: 0 4px; gap: 2px; }
|
|
3106
3529
|
.fnc-toolbar .fnc-btn { width: 32px; height: 32px; }
|
|
3107
3530
|
.fnc-toolbar .fnc-btn-wide, .fnc-toolbar .fnc-btn-label { width: auto; padding: 0 6px; }
|
|
@@ -3351,10 +3774,21 @@ function createShell(container, options) {
|
|
|
3351
3774
|
}
|
|
3352
3775
|
function bindWidgetKeys(shell, active, searchHotkey, extra) {
|
|
3353
3776
|
const { root } = shell;
|
|
3777
|
+
let focused = false;
|
|
3778
|
+
const onPointerDown = (e3) => focused = root.contains(e3.target);
|
|
3354
3779
|
const onKeyDown = (e3) => {
|
|
3355
3780
|
const pane = active();
|
|
3356
3781
|
if (!pane) return;
|
|
3357
3782
|
const s3 = pane.store.get();
|
|
3783
|
+
const target = e3.target;
|
|
3784
|
+
const typing = !!target && (target.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(target.tagName));
|
|
3785
|
+
const key = e3.key.toLowerCase();
|
|
3786
|
+
if (focused && !typing && !s3.dialog && !s3.searchOpen && (e3.ctrlKey || e3.metaKey) && !e3.altKey && (key === "z" || key === "y")) {
|
|
3787
|
+
e3.preventDefault();
|
|
3788
|
+
if (key === "y" || e3.shiftKey) pane.chart.redo();
|
|
3789
|
+
else pane.chart.undo();
|
|
3790
|
+
return;
|
|
3791
|
+
}
|
|
3358
3792
|
if (searchHotkey && (e3.ctrlKey || e3.metaKey) && e3.key.toLowerCase() === "k" && pane.canSearch && !s3.dialog) {
|
|
3359
3793
|
e3.preventDefault();
|
|
3360
3794
|
pane.store.set({ searchOpen: true });
|
|
@@ -3379,9 +3813,11 @@ function bindWidgetKeys(shell, active, searchHotkey, extra) {
|
|
|
3379
3813
|
};
|
|
3380
3814
|
document.addEventListener("keydown", onKeyDown);
|
|
3381
3815
|
document.addEventListener("keyup", onKeyUp);
|
|
3816
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
3382
3817
|
return () => {
|
|
3383
3818
|
document.removeEventListener("keydown", onKeyDown);
|
|
3384
3819
|
document.removeEventListener("keyup", onKeyUp);
|
|
3820
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
3385
3821
|
};
|
|
3386
3822
|
}
|
|
3387
3823
|
|
|
@@ -3405,6 +3841,11 @@ function createPane(shell, config) {
|
|
|
3405
3841
|
layout: chart.layout,
|
|
3406
3842
|
atRealtime: true,
|
|
3407
3843
|
searchOpen: false,
|
|
3844
|
+
searchTarget: "symbol",
|
|
3845
|
+
canUndo: chart.canUndo,
|
|
3846
|
+
canRedo: chart.canRedo,
|
|
3847
|
+
compares: chart.getCompares(),
|
|
3848
|
+
replay: chart.replay,
|
|
3408
3849
|
chartType: config.chartType,
|
|
3409
3850
|
drawingTool: null,
|
|
3410
3851
|
selection: null,
|
|
@@ -3427,7 +3868,10 @@ function createPane(shell, config) {
|
|
|
3427
3868
|
chart.on("drawingsChange", (drawings) => store.set({ drawingCount: drawings.length })),
|
|
3428
3869
|
chart.on("indicatorsChange", (indicators) => store.set({ indicators })),
|
|
3429
3870
|
chart.on("magnetChange", (magnet) => store.set({ magnet })),
|
|
3430
|
-
chart.on("chartTypeChange", (chartType) => store.set({ chartType }))
|
|
3871
|
+
chart.on("chartTypeChange", (chartType) => store.set({ chartType })),
|
|
3872
|
+
chart.on("historyChange", ({ canUndo, canRedo }) => store.set({ canUndo, canRedo })),
|
|
3873
|
+
chart.on("comparesChange", (compares) => store.set({ compares })),
|
|
3874
|
+
chart.on("replayChange", (replay) => store.set({ replay }))
|
|
3431
3875
|
];
|
|
3432
3876
|
const load = (sym, res) => {
|
|
3433
3877
|
store.set({ resolution: res });
|
|
@@ -3448,6 +3892,7 @@ function createPane(shell, config) {
|
|
|
3448
3892
|
showLogo: config.symbolLogo,
|
|
3449
3893
|
drawingToolbar: config.drawingToolbar,
|
|
3450
3894
|
attribution: config.attribution,
|
|
3895
|
+
contextMenuItems: config.contextMenuItems,
|
|
3451
3896
|
slots: shell.slots,
|
|
3452
3897
|
multi: config.multi,
|
|
3453
3898
|
setDrawbarCollapsed: shell.setDrawbarCollapsed,
|
|
@@ -3457,7 +3902,7 @@ function createPane(shell, config) {
|
|
|
3457
3902
|
if (current) void load(current.symbol, res);
|
|
3458
3903
|
},
|
|
3459
3904
|
toggleFavoriteInterval: shell.toggleFavoriteInterval,
|
|
3460
|
-
setSearchOpen: (open) => store.set({ searchOpen:
|
|
3905
|
+
setSearchOpen: (open, target = "symbol") => store.set(open ? { searchOpen: true, searchTarget: target } : { searchOpen: false }),
|
|
3461
3906
|
screenshot: () => {
|
|
3462
3907
|
const s3 = store.get();
|
|
3463
3908
|
chart.takeScreenshot().toBlob((blob) => {
|
|
@@ -3471,7 +3916,7 @@ function createPane(shell, config) {
|
|
|
3471
3916
|
},
|
|
3472
3917
|
toggleFullscreen: shell.toggleFullscreen
|
|
3473
3918
|
};
|
|
3474
|
-
Q(/* @__PURE__ */
|
|
3919
|
+
Q(/* @__PURE__ */ a3(Overlay, { ctx }), overlayHost);
|
|
3475
3920
|
return {
|
|
3476
3921
|
stage,
|
|
3477
3922
|
chart,
|
|
@@ -3522,6 +3967,7 @@ function createTradingChart(container, options) {
|
|
|
3522
3967
|
chartType = "candles",
|
|
3523
3968
|
attribution = true,
|
|
3524
3969
|
colorScheme = "system",
|
|
3970
|
+
contextMenuItems,
|
|
3525
3971
|
theme,
|
|
3526
3972
|
...chartOptions
|
|
3527
3973
|
} = options;
|
|
@@ -3544,13 +3990,14 @@ function createTradingChart(container, options) {
|
|
|
3544
3990
|
searchCategories,
|
|
3545
3991
|
symbolLogo,
|
|
3546
3992
|
drawingToolbar,
|
|
3547
|
-
attribution
|
|
3993
|
+
attribution,
|
|
3994
|
+
contextMenuItems
|
|
3548
3995
|
});
|
|
3549
3996
|
shell.main.insertBefore(pane.stage, shell.slots.bottom);
|
|
3550
3997
|
shell.setPanes(() => [pane]);
|
|
3551
3998
|
const unbindKeys = bindWidgetKeys(shell, () => pane, searchHotkey);
|
|
3552
|
-
Q(/* @__PURE__ */
|
|
3553
|
-
if (shell.drawbarHost) Q(/* @__PURE__ */
|
|
3999
|
+
Q(/* @__PURE__ */ a3(Toolbar, { ctx: pane.ctx }), shell.toolbarHost);
|
|
4000
|
+
if (shell.drawbarHost) Q(/* @__PURE__ */ a3(DrawingToolbar, { ctx: pane.ctx }), shell.drawbarHost);
|
|
3554
4001
|
void pane.load(symbol, resolution);
|
|
3555
4002
|
return {
|
|
3556
4003
|
chart: pane.chart,
|
|
@@ -3584,17 +4031,17 @@ var DEFAULT_SYNC = { crosshair: true, time: false, symbol: false, interval: fals
|
|
|
3584
4031
|
function PaneTab({ pane, index, active, onSelect }) {
|
|
3585
4032
|
const s3 = useStore(pane.store);
|
|
3586
4033
|
const t3 = STRINGS[s3.locale];
|
|
3587
|
-
return /* @__PURE__ */
|
|
3588
|
-
/* @__PURE__ */
|
|
4034
|
+
return /* @__PURE__ */ a3("button", { class: "fnc-pane-tab", role: "tab", "aria-selected": active, onClick: onSelect, children: [
|
|
4035
|
+
/* @__PURE__ */ a3("span", { class: "fnc-pane-tab-num", children: index + 1 }),
|
|
3589
4036
|
s3.symbol?.name ?? `${t3.pane} ${index + 1}`,
|
|
3590
|
-
/* @__PURE__ */
|
|
4037
|
+
/* @__PURE__ */ a3("small", { children: resolutionLabel(s3.resolution, s3.locale) })
|
|
3591
4038
|
] });
|
|
3592
4039
|
}
|
|
3593
4040
|
function PaneTabs({ multi, panes }) {
|
|
3594
4041
|
const m3 = useStore(multi.store);
|
|
3595
4042
|
const visible = panes().slice(0, paneCount(LAYOUTS[m3.layout]));
|
|
3596
4043
|
if (!m3.narrow || visible.length < 2) return null;
|
|
3597
|
-
return /* @__PURE__ */
|
|
4044
|
+
return /* @__PURE__ */ a3("div", { class: "fnc-pane-tabs", role: "tablist", children: visible.map((p3, i3) => /* @__PURE__ */ a3(PaneTab, { pane: p3, index: i3, active: i3 === m3.active, onSelect: () => multi.activate(i3) })) });
|
|
3598
4045
|
}
|
|
3599
4046
|
function createMultiChart(container, options) {
|
|
3600
4047
|
const {
|
|
@@ -3615,6 +4062,7 @@ function createMultiChart(container, options) {
|
|
|
3615
4062
|
chartType = "candles",
|
|
3616
4063
|
attribution = true,
|
|
3617
4064
|
colorScheme = "system",
|
|
4065
|
+
contextMenuItems,
|
|
3618
4066
|
theme,
|
|
3619
4067
|
...chartOptions
|
|
3620
4068
|
} = options;
|
|
@@ -3680,6 +4128,7 @@ function createMultiChart(container, options) {
|
|
|
3680
4128
|
drawingToolbar,
|
|
3681
4129
|
// One badge for the whole widget, not one per pane.
|
|
3682
4130
|
attribution: attribution && index === 0,
|
|
4131
|
+
contextMenuItems,
|
|
3683
4132
|
multi: controls
|
|
3684
4133
|
});
|
|
3685
4134
|
const cell = div("fnc-pane");
|
|
@@ -3799,8 +4248,8 @@ function createMultiChart(container, options) {
|
|
|
3799
4248
|
}
|
|
3800
4249
|
function bindToolbar() {
|
|
3801
4250
|
const pane = panes[store.get().active];
|
|
3802
|
-
Q(/* @__PURE__ */
|
|
3803
|
-
if (shell.drawbarHost) Q(/* @__PURE__ */
|
|
4251
|
+
Q(/* @__PURE__ */ a3(Toolbar, { ctx: pane.ctx }, store.get().active), shell.toolbarHost);
|
|
4252
|
+
if (shell.drawbarHost) Q(/* @__PURE__ */ a3(DrawingToolbar, { ctx: pane.ctx }, store.get().active), shell.drawbarHost);
|
|
3804
4253
|
}
|
|
3805
4254
|
function activate(index) {
|
|
3806
4255
|
const s3 = store.get();
|
|
@@ -3857,7 +4306,7 @@ function createMultiChart(container, options) {
|
|
|
3857
4306
|
ensurePanes(Math.max(visibleCount(), Math.min(paneSpecs.length, MAX_PANES)));
|
|
3858
4307
|
shell.setPanes(() => panes);
|
|
3859
4308
|
bindToolbar();
|
|
3860
|
-
Q(/* @__PURE__ */
|
|
4309
|
+
Q(/* @__PURE__ */ a3(PaneTabs, { multi: controls, panes: () => panes }), tabsHost);
|
|
3861
4310
|
renderGrid();
|
|
3862
4311
|
const resize = new ResizeObserver(() => {
|
|
3863
4312
|
const narrow = shell.root.clientWidth > 0 && shell.root.clientWidth < narrowWidth;
|