acttrader-charts 1.2.0-beta.9 → 1.3.0-beta.2

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/index.cjs CHANGED
@@ -1890,6 +1890,8 @@ var FONT_BRACKET = "12px 'Inter', system-ui, sans-serif";
1890
1890
  var BRACKET_BASE_RATIO = 0.68;
1891
1891
  var BRACKET_COL_OFFSETS = [0, -0.08, 0.08];
1892
1892
  var ADD_BRACKET_BTN_OFFSET_PX = 30;
1893
+ var __bracketDraws = [];
1894
+ var __lastDupeSignature = "";
1893
1895
  function hasPnl(level) {
1894
1896
  return level.type === "position" && !!level.pnlText;
1895
1897
  }
@@ -1934,8 +1936,9 @@ function getLevelDisplayText(level, price, precision, omitLots = false) {
1934
1936
  }
1935
1937
  function computeBracketLineX(levels, scale, priceRange, priceH, chartW, draggingLabel, dragNewPrice, hoveredLabel, selectedLabel, bracketBoxH = BRACKET_BOX_H) {
1936
1938
  const items = [];
1939
+ const lineXOwner = hoveredLabel ?? selectedLabel;
1937
1940
  for (const level of levels) {
1938
- if (level.label !== hoveredLabel && level.label !== selectedLabel) continue;
1941
+ if (level.label !== lineXOwner) continue;
1939
1942
  const bh = level;
1940
1943
  if (bh.stopLossPrice !== void 0) {
1941
1944
  const key = `${level.label}:stopLoss`;
@@ -2031,6 +2034,9 @@ function isDraggable(level) {
2031
2034
  return !!level.entryPriceEditable;
2032
2035
  return false;
2033
2036
  }
2037
+ function passiveBracketsVisible(alwaysShowBrackets, activeLabel) {
2038
+ return alwaysShowBrackets && activeLabel === null;
2039
+ }
2034
2040
  function renderTradeLevels(ctx, levels, scale, priceRange, theme, chartW, priceH, precision, hoveredLabel = null, draggingLabel = null, dragNewPrice = null, selectedLabel = null, pendingLabels = /* @__PURE__ */ new Set(), positionStyle = "line", hideConfirmCancel = false, draftOrderLabel = null, draftBracketPnl = {}, expandedClusters = /* @__PURE__ */ new Set(), clusterThresholdPx = 0, showQuantityField = false, dragNewSLPrice = null, dragNewTPPrice = null, buttonScale = 1, alwaysShowBrackets = false, anchorXResolver = null, timeDragEnabled = false) {
2035
2041
  if (levels.length === 0)
2036
2042
  return {
@@ -2044,6 +2050,7 @@ function renderTradeLevels(ctx, levels, scale, priceRange, theme, chartW, priceH
2044
2050
  clusters: []
2045
2051
  };
2046
2052
  const colors = theme.tradeLevels;
2053
+ __bracketDraws = [];
2047
2054
  const s = Math.min(Math.max(buttonScale, 1), 3);
2048
2055
  const closeR = CLOSE_R * s;
2049
2056
  const editR = EDIT_R * s;
@@ -2144,8 +2151,9 @@ function renderTradeLevels(ctx, levels, scale, priceRange, theme, chartW, priceH
2144
2151
  );
2145
2152
  const bracketItems = [];
2146
2153
  const fallbackX = chartW * BRACKET_BASE_RATIO;
2154
+ const cascadeOwner = hoveredLabel ?? selectedLabel;
2147
2155
  for (const level of levels) {
2148
- if (level.label !== hoveredLabel && level.label !== selectedLabel) continue;
2156
+ if (level.label !== cascadeOwner) continue;
2149
2157
  const bh = level;
2150
2158
  const mainDrag = draggingLabel === level.label;
2151
2159
  if (bh.stopLossPrice !== void 0) {
@@ -2192,6 +2200,10 @@ function renderTradeLevels(ctx, levels, scale, priceRange, theme, chartW, priceH
2192
2200
  }
2193
2201
  const activeLabel = hoveredLabel ?? selectedLabel;
2194
2202
  const bracketPnlHostLabel = draftOrderLabel ?? selectedLabel;
2203
+ const effectiveAlwaysShowBrackets = passiveBracketsVisible(
2204
+ alwaysShowBrackets,
2205
+ activeLabel
2206
+ );
2195
2207
  const visibleMeasured = measured.filter((m) => !collapsedLabels.has(m.level.label));
2196
2208
  const drawOrder = [
2197
2209
  ...visibleMeasured.filter((m) => m.level.label !== activeLabel),
@@ -2243,9 +2255,10 @@ function renderTradeLevels(ctx, levels, scale, priceRange, theme, chartW, priceH
2243
2255
  dragNewTPPrice,
2244
2256
  buttonScale,
2245
2257
  bracketBoxYMap,
2246
- alwaysShowBrackets,
2258
+ effectiveAlwaysShowBrackets,
2247
2259
  timeDragEnabled && anchorXResolver ? anchorXResolver(level) : null,
2248
- timeDragEnabled
2260
+ timeDragEnabled,
2261
+ level.label === activeLabel
2249
2262
  );
2250
2263
  const ec = labelToExpandedCluster.get(level.label);
2251
2264
  if (ec && layout.boxY !== layout.y - boxH / 2) {
@@ -2327,6 +2340,50 @@ function renderTradeLevels(ctx, levels, scale, priceRange, theme, chartW, priceH
2327
2340
  }
2328
2341
  }
2329
2342
  }
2343
+ {
2344
+ globalThis.__bracketDrawsLast = __bracketDraws.slice();
2345
+ const counts = /* @__PURE__ */ new Map();
2346
+ for (const d of __bracketDraws) {
2347
+ const k = `${d.bracketType}@${d.price}`;
2348
+ counts.set(k, (counts.get(k) ?? 0) + 1);
2349
+ }
2350
+ const dupeKeys = [...counts.entries()].filter(([, n]) => n > 1).map(([k]) => k);
2351
+ if (dupeKeys.length > 0) {
2352
+ const signature = dupeKeys.join(",") + "|" + __bracketDraws.map((d) => `${d.label}/${d.levelType}/${d.bW}`).join(",");
2353
+ if (signature !== __lastDupeSignature) {
2354
+ __lastDupeSignature = signature;
2355
+ const frame = {
2356
+ hoveredLabel,
2357
+ selectedLabel,
2358
+ draftOrderLabel,
2359
+ draftBracketPnl,
2360
+ levels: levels.map((l) => ({
2361
+ label: l.label,
2362
+ type: l.type,
2363
+ price: l.price,
2364
+ sl: l.stopLossPrice,
2365
+ tp: l.takeProfitPrice,
2366
+ isDraft: !!l.data?._isDraft
2367
+ }))
2368
+ };
2369
+ console.warn(
2370
+ `[ActCharts] DUPLICATE BRACKET BOX \u2192 ${dupeKeys.join(", ")}
2371
+ hovered=${hoveredLabel ?? "null"} selected=${selectedLabel ?? "null"} draft=${draftOrderLabel ?? "null"}
2372
+ ` + __bracketDraws.map(
2373
+ (d, i) => ` box#${i + 1} label=${d.label} type=${d.levelType} draft=${d.isDraft} ${d.bracketType}@${d.price} bX=${d.bX} bW=${d.bW} right=${d.rightEdge} boxY=${d.boxY} pnl=${d.pnlText === null ? "none" : JSON.stringify(d.pnlText)} hideCC=${d.hideConfirmCancel}`
2374
+ ).join("\n") + `
2375
+ levels this frame: ` + frame.levels.map((l) => `${l.label}/${l.type}${l.isDraft ? "/DRAFT" : ""} price=${l.price} sl=${l.sl} tp=${l.tp}`).join(" | ")
2376
+ );
2377
+ if (typeof window !== "undefined") {
2378
+ window.__bracketDupe = {
2379
+ dupeKeys,
2380
+ frame,
2381
+ draws: __bracketDraws.slice()
2382
+ };
2383
+ }
2384
+ }
2385
+ }
2386
+ }
2330
2387
  ctx.restore();
2331
2388
  return {
2332
2389
  hitAreas,
@@ -2482,7 +2539,7 @@ function drawDotHoverBox(ctx, level, y, dotX, dotR, theme, precision) {
2482
2539
  });
2483
2540
  ctx.restore();
2484
2541
  }
2485
- function drawLevel(ctx, level, layout, chartW, colors, theme, precision, hovered, selected, scale, priceRange, priceH, draggingLabel, dragNewPrice, bracketLineXMap, hasPendingChanges, positionStyle, hitAreas, editAreas, hoverAreas, dragAreas, confirmAreas, addBracketAreas, hideConfirmCancel = false, draftBracketPnl, showQuantityField = false, draftQtyPillAreas, dragNewSLPrice = null, dragNewTPPrice = null, buttonScale = 1, bracketBoxYMap, alwaysShowBrackets = false, anchorX = null, timeDragEnabled = false) {
2542
+ function drawLevel(ctx, level, layout, chartW, colors, theme, precision, hovered, selected, scale, priceRange, priceH, draggingLabel, dragNewPrice, bracketLineXMap, hasPendingChanges, positionStyle, hitAreas, editAreas, hoverAreas, dragAreas, confirmAreas, addBracketAreas, hideConfirmCancel = false, draftBracketPnl, showQuantityField = false, draftQtyPillAreas, dragNewSLPrice = null, dragNewTPPrice = null, buttonScale = 1, bracketBoxYMap, alwaysShowBrackets = false, anchorX = null, timeDragEnabled = false, isBracketOwner) {
2486
2543
  const { y, boxY, boxW, boxH } = layout;
2487
2544
  const color = levelColor(level, colors, theme);
2488
2545
  const active = hovered || selected;
@@ -2532,7 +2589,8 @@ function drawLevel(ctx, level, layout, chartW, colors, theme, precision, hovered
2532
2589
  const boxX = draggable ? groupX + GRIP_W + 2 : groupX;
2533
2590
  const badgeTimeDrag = timeDragEnabled && level.timeDraggable === true;
2534
2591
  const bracketHost = level;
2535
- if (active || isMarketDraft || passiveBracketShow) {
2592
+ const bracketOwner = isBracketOwner ?? active;
2593
+ if (bracketOwner || isMarketDraft || passiveBracketShow) {
2536
2594
  const slDragKey = `${level.label}:stopLoss`;
2537
2595
  const tpDragKey = `${level.label}:takeProfit`;
2538
2596
  const mainDragActive = draggingLabel === level.label;
@@ -2994,6 +3052,19 @@ function drawBracketLine(ctx, level, bracketType, bracketPrice, scale, priceRang
2994
3052
  const bY = boxYOverride ?? naturalBoxY;
2995
3053
  const boxCenterY = bY + bH / 2;
2996
3054
  const displaced = Math.abs(bY - naturalBoxY) >= 2;
3055
+ __bracketDraws.push({
3056
+ label: level.label,
3057
+ levelType: level.type,
3058
+ isDraft: !!level.data?._isDraft,
3059
+ bracketType,
3060
+ price,
3061
+ bX: Math.round(bX),
3062
+ bW: Math.round(bW),
3063
+ rightEdge: Math.round(bX + bW),
3064
+ boxY: Math.round(bY),
3065
+ pnlText: pnlText ?? null,
3066
+ hideConfirmCancel
3067
+ });
2997
3068
  if (displaced) {
2998
3069
  drawBracketLeader(ctx, bX + bW / 2, boxCenterY, y, theme);
2999
3070
  }
@@ -6574,6 +6645,21 @@ var MobileToolsSheet = class {
6574
6645
  };
6575
6646
 
6576
6647
  // src/ui/MobileHeader.ts
6648
+ var SERIES_OPTIONS = [
6649
+ { value: "candlestick", label: "Candlestick" },
6650
+ { value: "hollow", label: "Hollow Candles" },
6651
+ { value: "ohlc", label: "OHLC Bars" },
6652
+ { value: "line", label: "Line" },
6653
+ { value: "area", label: "Area" },
6654
+ { value: "heikinashi", label: "Heikin Ashi" },
6655
+ { value: "volumecandles", label: "Volume Candles" },
6656
+ { value: "linemarkers", label: "Line with Markers" },
6657
+ { value: "step", label: "Step Line" },
6658
+ { value: "hlcarea", label: "HLC Area" },
6659
+ { value: "baseline", label: "Baseline" },
6660
+ { value: "columns", label: "Columns" },
6661
+ { value: "highlow", label: "High Low" }
6662
+ ];
6577
6663
  var TF_PILLS3 = ["1m", "5m", "15m", "1h", "4h", "1D", "1W"];
6578
6664
  var TF_LABEL3 = {
6579
6665
  "1m": "1m",
@@ -6618,14 +6704,21 @@ var IC_SETTINGS2 = (sz = 16) => lucide4(
6618
6704
  1.75
6619
6705
  );
6620
6706
  var MobileHeader = class {
6621
- constructor(onTimeframeChange, toolsController, onAskAiClick, onSettingsClick, currentTf, theme, fontFamily) {
6707
+ constructor(onTimeframeChange, toolsController, onAskAiClick, onSettingsClick, onSeriesChange, currentTf, currentSeries, theme, fontFamily) {
6622
6708
  this.toolsBtn = null;
6623
6709
  this.tfBtns = /* @__PURE__ */ new Map();
6624
6710
  this.toolsActive = false;
6711
+ this.seriesBtn = null;
6712
+ this.seriesMenu = null;
6713
+ this.seriesMenuOpen = false;
6714
+ this.onDocPointerDown = null;
6715
+ this.onWinReposition = null;
6625
6716
  this.onTimeframeChange = onTimeframeChange;
6626
6717
  this.onAskAiClick = onAskAiClick;
6627
6718
  this.onSettingsClick = onSettingsClick;
6719
+ this.onSeriesChange = onSeriesChange;
6628
6720
  this.currentTf = currentTf;
6721
+ this.currentSeries = currentSeries;
6629
6722
  this.theme = theme;
6630
6723
  this.fontFamily = fontFamily ?? MONO_FONT2;
6631
6724
  this.sheet = toolsController ? new MobileToolsSheet(theme, toolsController, this.fontFamily) : null;
@@ -6636,9 +6729,11 @@ var MobileHeader = class {
6636
6729
  }
6637
6730
  // ── Build ──────────────────────────────────────────────────────────────────
6638
6731
  build() {
6732
+ this.closeSeriesMenu();
6639
6733
  this.el.innerHTML = "";
6640
6734
  this.tfBtns.clear();
6641
6735
  this.toolsBtn = null;
6736
+ this.seriesBtn = null;
6642
6737
  Object.assign(this.el.style, {
6643
6738
  display: "flex",
6644
6739
  alignItems: "center",
@@ -6692,6 +6787,41 @@ var MobileHeader = class {
6692
6787
  });
6693
6788
  this.el.appendChild(divider);
6694
6789
  }
6790
+ if (this.onSeriesChange) {
6791
+ const btn = document.createElement("button");
6792
+ btn.setAttribute("data-testid", "m-chart-type-btn");
6793
+ btn.title = "Chart type";
6794
+ btn.innerHTML = this.seriesIconHtml(this.currentSeries);
6795
+ Object.assign(btn.style, {
6796
+ display: "flex",
6797
+ alignItems: "center",
6798
+ justifyContent: "center",
6799
+ padding: "6px",
6800
+ borderRadius: "4px",
6801
+ border: "none",
6802
+ whiteSpace: "nowrap",
6803
+ flexShrink: "0",
6804
+ cursor: "pointer",
6805
+ outline: "none",
6806
+ background: "transparent",
6807
+ color: this.theme.axisText,
6808
+ transition: "color 0.15s, background 0.15s"
6809
+ });
6810
+ btn.addEventListener("click", (e) => {
6811
+ e.stopPropagation();
6812
+ this.toggleSeriesMenu();
6813
+ });
6814
+ this.seriesBtn = btn;
6815
+ this.el.appendChild(btn);
6816
+ const d2 = document.createElement("div");
6817
+ Object.assign(d2.style, {
6818
+ width: "1px",
6819
+ height: "20px",
6820
+ background: this.theme.axisBorder,
6821
+ flexShrink: "0"
6822
+ });
6823
+ this.el.appendChild(d2);
6824
+ }
6695
6825
  for (const tf of TF_PILLS3) {
6696
6826
  const btn = document.createElement("button");
6697
6827
  btn.setAttribute("data-testid", `m-tf-${TF_LABEL3[tf] ?? tf}`);
@@ -6792,6 +6922,135 @@ var MobileHeader = class {
6792
6922
  btn.style.color = active ? t.ui.accent : t.topBar.btnColor;
6793
6923
  }
6794
6924
  }
6925
+ // ── Chart-type (series) picker ───────────────────────────────────────────────
6926
+ /** Current-series icon, sized for the header button (mirrors AdvancedToolbar). */
6927
+ seriesIconHtml(series) {
6928
+ const raw = ICON_SERIES[series] ?? ICON_SERIES.candlestick;
6929
+ return raw.replace(/width="\d+" height="\d+"/, 'width="18" height="18"');
6930
+ }
6931
+ toggleSeriesMenu() {
6932
+ if (this.seriesMenuOpen) this.closeSeriesMenu();
6933
+ else this.openSeriesMenu();
6934
+ }
6935
+ openSeriesMenu() {
6936
+ if (this.seriesMenuOpen || !this.seriesBtn || typeof document === "undefined") return;
6937
+ this.seriesMenu = this.buildSeriesMenu();
6938
+ document.body.appendChild(this.seriesMenu);
6939
+ this.seriesMenuOpen = true;
6940
+ this.positionSeriesMenu();
6941
+ this.styleSeriesBtnActive(true);
6942
+ this.onDocPointerDown = (e) => {
6943
+ const t = e.target;
6944
+ if (this.seriesMenu?.contains(t) || this.seriesBtn?.contains(t)) return;
6945
+ this.closeSeriesMenu();
6946
+ };
6947
+ this.onWinReposition = () => this.closeSeriesMenu();
6948
+ setTimeout(() => {
6949
+ if (!this.seriesMenuOpen) return;
6950
+ document.addEventListener("pointerdown", this.onDocPointerDown, true);
6951
+ window.addEventListener("resize", this.onWinReposition, true);
6952
+ window.addEventListener("scroll", this.onWinReposition, true);
6953
+ this.el.addEventListener("scroll", this.onWinReposition, true);
6954
+ }, 0);
6955
+ }
6956
+ closeSeriesMenu() {
6957
+ if (this.onDocPointerDown) {
6958
+ document.removeEventListener("pointerdown", this.onDocPointerDown, true);
6959
+ this.onDocPointerDown = null;
6960
+ }
6961
+ if (this.onWinReposition) {
6962
+ window.removeEventListener("resize", this.onWinReposition, true);
6963
+ window.removeEventListener("scroll", this.onWinReposition, true);
6964
+ this.el.removeEventListener("scroll", this.onWinReposition, true);
6965
+ this.onWinReposition = null;
6966
+ }
6967
+ this.seriesMenu?.remove();
6968
+ this.seriesMenu = null;
6969
+ this.seriesMenuOpen = false;
6970
+ this.styleSeriesBtnActive(false);
6971
+ }
6972
+ buildSeriesMenu() {
6973
+ const t = this.theme;
6974
+ const menu = document.createElement("div");
6975
+ menu.setAttribute("data-testid", "m-chart-type-menu");
6976
+ Object.assign(menu.style, {
6977
+ position: "fixed",
6978
+ zIndex: "2147483000",
6979
+ minWidth: "184px",
6980
+ maxHeight: "60vh",
6981
+ overflowY: "auto",
6982
+ padding: "4px",
6983
+ borderRadius: "8px",
6984
+ border: `1px solid ${t.axisBorder}`,
6985
+ background: t.background,
6986
+ boxShadow: "0 8px 28px rgba(0,0,0,0.35)",
6987
+ fontFamily: this.fontFamily,
6988
+ WebkitOverflowScrolling: "touch"
6989
+ });
6990
+ for (const opt of SERIES_OPTIONS) {
6991
+ const active = opt.value === this.currentSeries;
6992
+ const row = document.createElement("button");
6993
+ row.type = "button";
6994
+ row.setAttribute("data-testid", `m-chart-type-${opt.value}`);
6995
+ Object.assign(row.style, {
6996
+ display: "flex",
6997
+ alignItems: "center",
6998
+ gap: "10px",
6999
+ width: "100%",
7000
+ padding: "9px 10px",
7001
+ borderRadius: "6px",
7002
+ border: "none",
7003
+ cursor: "pointer",
7004
+ outline: "none",
7005
+ textAlign: "left",
7006
+ fontSize: "13px",
7007
+ fontFamily: this.fontFamily,
7008
+ background: active ? t.ui.accentBg : "transparent",
7009
+ color: active ? t.ui.accent : t.axisText
7010
+ });
7011
+ const icon = (ICON_SERIES[opt.value] ?? "").replace(/width="\d+" height="\d+"/, 'width="16" height="16"');
7012
+ const check = active ? ICON_CHECKMARK.replace(/width="\d+" height="\d+"/, 'width="16" height="16"') : "";
7013
+ row.innerHTML = `<span style="display:flex;flex-shrink:0;">${icon}</span><span style="flex:1;">${opt.label}</span><span style="display:flex;flex-shrink:0;width:16px;">${check}</span>`;
7014
+ row.addEventListener("mouseenter", () => {
7015
+ if (opt.value !== this.currentSeries) row.style.background = t.ui.accentBg;
7016
+ });
7017
+ row.addEventListener("mouseleave", () => {
7018
+ if (opt.value !== this.currentSeries) row.style.background = "transparent";
7019
+ });
7020
+ row.addEventListener("click", (e) => {
7021
+ e.stopPropagation();
7022
+ this.selectSeries(opt.value);
7023
+ });
7024
+ menu.appendChild(row);
7025
+ }
7026
+ return menu;
7027
+ }
7028
+ positionSeriesMenu() {
7029
+ if (!this.seriesMenu || !this.seriesBtn) return;
7030
+ const r = this.seriesBtn.getBoundingClientRect();
7031
+ const m = this.seriesMenu;
7032
+ m.style.top = `${r.bottom + 6}px`;
7033
+ m.style.left = `${r.left}px`;
7034
+ const mr = m.getBoundingClientRect();
7035
+ if (mr.right > window.innerWidth - 8) {
7036
+ m.style.left = `${Math.max(8, window.innerWidth - 8 - mr.width)}px`;
7037
+ }
7038
+ if (mr.bottom > window.innerHeight - 8) {
7039
+ m.style.top = `${Math.max(8, r.top - 6 - mr.height)}px`;
7040
+ }
7041
+ }
7042
+ selectSeries(series) {
7043
+ this.closeSeriesMenu();
7044
+ if (series === this.currentSeries) return;
7045
+ this.currentSeries = series;
7046
+ if (this.seriesBtn) this.seriesBtn.innerHTML = this.seriesIconHtml(series);
7047
+ this.onSeriesChange?.(series);
7048
+ }
7049
+ styleSeriesBtnActive(active) {
7050
+ if (!this.seriesBtn) return;
7051
+ this.seriesBtn.style.color = active ? this.theme.ui.accent : this.theme.axisText;
7052
+ this.seriesBtn.style.background = active ? this.theme.ui.accentBg : "transparent";
7053
+ }
6795
7054
  // ── Public surface (drop-in parity with CompactToolbar) ──────────────────────
6796
7055
  setTimeframe(tf) {
6797
7056
  this.currentTf = tf;
@@ -6809,10 +7068,12 @@ var MobileHeader = class {
6809
7068
  this.sheet?.setTheme(theme);
6810
7069
  }
6811
7070
  destroy() {
7071
+ this.closeSeriesMenu();
6812
7072
  this.sheet?.destroy();
6813
7073
  this.el.remove();
6814
7074
  this.tfBtns.clear();
6815
7075
  this.toolsBtn = null;
7076
+ this.seriesBtn = null;
6816
7077
  }
6817
7078
  // ── Forwarded to the "Draw & Indicators" sheet so its toggles stay in sync ───
6818
7079
  /**
@@ -6828,15 +7089,24 @@ var MobileHeader = class {
6828
7089
  this.sheet?.syncVolume(show);
6829
7090
  }
6830
7091
  // ── No-op stubs — controls this variant intentionally does not render ────────
6831
- setSeries(_series) {
7092
+ /** Engine → header sync: reflect an external series change (restored layout
7093
+ * state, keyboard shortcut, etc.) on the chart-type button. */
7094
+ setSeries(series) {
7095
+ this.currentSeries = series;
7096
+ if (this.seriesBtn) this.seriesBtn.innerHTML = this.seriesIconHtml(series);
7097
+ if (this.seriesMenuOpen) {
7098
+ this.closeSeriesMenu();
7099
+ this.openSeriesMenu();
7100
+ }
6832
7101
  }
6833
7102
  setIndicatorOptions(_options) {
6834
7103
  }
6835
7104
  closeDropdown() {
6836
7105
  this.sheet?.close();
7106
+ this.closeSeriesMenu();
6837
7107
  }
6838
7108
  get hasOpenDropdown() {
6839
- return this.sheet?.isOpen ?? false;
7109
+ return (this.sheet?.isOpen ?? false) || this.seriesMenuOpen;
6840
7110
  }
6841
7111
  setFullscreen(_active) {
6842
7112
  }
@@ -23726,7 +23996,9 @@ var _ChartEngine = class _ChartEngine {
23726
23996
  toolsController,
23727
23997
  config.onAskAiClick ?? null,
23728
23998
  this.settingsEnabled ? () => this.openChartSettings() : null,
23999
+ (s) => this.setSeries(s),
23729
24000
  this.timeframe,
24001
+ this.series,
23730
24002
  this.theme,
23731
24003
  this.uiConfig.topBar?.dropBtnFontFamily
23732
24004
  );