hyperprop-charting-library 0.1.139 → 0.1.141

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.js CHANGED
@@ -2623,6 +2623,88 @@ var compileScriptIndicator = (definition) => {
2623
2623
  return plugin;
2624
2624
  };
2625
2625
 
2626
+ // src/themes.ts
2627
+ var CHART_THEMES = {
2628
+ dark: {
2629
+ name: "dark",
2630
+ background: "#0f0f0f",
2631
+ upColor: "#089981",
2632
+ downColor: "#f23645",
2633
+ lineColor: "#2962ff",
2634
+ gridColor: "#3c3c3c",
2635
+ gridOpacity: 0.5,
2636
+ axisTextColor: "#dbdbdb",
2637
+ axisLineColor: "#424242",
2638
+ crosshairColor: "#9598a1",
2639
+ crosshairLabelBackground: "#3c3c3c",
2640
+ crosshairLabelText: "#dbdbdb",
2641
+ crosshairLabelBorder: "#5d5d5d",
2642
+ watermarkColor: "rgba(219,219,219,0.06)",
2643
+ indicatorTextColor: "#b2b5be",
2644
+ labelTextColor: "#ffffff",
2645
+ labelBackground: "#1a1a1a"
2646
+ },
2647
+ light: {
2648
+ name: "light",
2649
+ background: "#ffffff",
2650
+ upColor: "#089981",
2651
+ downColor: "#f23645",
2652
+ lineColor: "#2962ff",
2653
+ gridColor: "#d5d5d5",
2654
+ gridOpacity: 0.9,
2655
+ axisTextColor: "#0f0f0f",
2656
+ axisLineColor: "#c3c3c3",
2657
+ crosshairColor: "#787b86",
2658
+ crosshairLabelBackground: "#4b4b4b",
2659
+ crosshairLabelText: "#ffffff",
2660
+ crosshairLabelBorder: "#878787",
2661
+ watermarkColor: "rgba(15,15,15,0.06)",
2662
+ indicatorTextColor: "#4b4b4b",
2663
+ labelTextColor: "#ffffff",
2664
+ labelBackground: "#f0f3fa"
2665
+ },
2666
+ midnight: {
2667
+ name: "midnight",
2668
+ background: "#171717",
2669
+ upColor: "#22ab94",
2670
+ downColor: "#f23645",
2671
+ lineColor: "#2563eb",
2672
+ gridColor: "#2b2f38",
2673
+ gridOpacity: 0.38,
2674
+ axisTextColor: "#dbe4f0",
2675
+ axisLineColor: "#5f646d",
2676
+ crosshairColor: "#94a3b8",
2677
+ crosshairLabelBackground: "#6b6f76",
2678
+ crosshairLabelText: "#e2e8f0",
2679
+ crosshairLabelBorder: "#e2e8f0",
2680
+ watermarkColor: "rgba(226,232,240,0.05)",
2681
+ indicatorTextColor: "#cbd5e1",
2682
+ labelTextColor: "#dbeafe",
2683
+ labelBackground: "#0b1220"
2684
+ },
2685
+ "high-contrast": {
2686
+ name: "high-contrast",
2687
+ background: "#000000",
2688
+ upColor: "#00e5a0",
2689
+ downColor: "#ff4d5e",
2690
+ lineColor: "#4d9fff",
2691
+ gridColor: "#5a5a5a",
2692
+ gridOpacity: 0.7,
2693
+ axisTextColor: "#ffffff",
2694
+ axisLineColor: "#8a8a8a",
2695
+ crosshairColor: "#ffffff",
2696
+ crosshairLabelBackground: "#ffffff",
2697
+ crosshairLabelText: "#000000",
2698
+ crosshairLabelBorder: "#ffffff",
2699
+ watermarkColor: "rgba(255,255,255,0.08)",
2700
+ indicatorTextColor: "#ffffff",
2701
+ labelTextColor: "#000000",
2702
+ labelBackground: "#1a1a1a"
2703
+ }
2704
+ };
2705
+ var CHART_THEME_NAMES = Object.keys(CHART_THEMES);
2706
+ var resolveTheme = (theme) => typeof theme === "string" ? CHART_THEMES[theme] ?? CHART_THEMES.dark : theme;
2707
+
2626
2708
  // src/options.ts
2627
2709
  var DEFAULT_GRID_OPTIONS = {
2628
2710
  color: "#2b2f38",
@@ -2822,6 +2904,8 @@ var DEFAULT_OPTIONS = {
2822
2904
  keyboard: { enabled: true, panBars: 1, deleteSelectedDrawing: true },
2823
2905
  accessibility: { label: "Price chart", description: "", focusable: true },
2824
2906
  downsampling: { enabled: true, thresholdPx: 1.5 },
2907
+ touch: { hitToleranceScale: 2.2, longPressTooltip: true, longPressMs: 400 },
2908
+ datafeedOptions: { prefetchThresholdBars: 150, cooldownMs: 1200, chunkBars: 1500 },
2825
2909
  crosshair: DEFAULT_CROSSHAIR_OPTIONS,
2826
2910
  grid: DEFAULT_GRID_OPTIONS,
2827
2911
  watermark: DEFAULT_WATERMARK_OPTIONS,
@@ -2876,6 +2960,14 @@ var mergeChartOptions = (baseOptions, options = {}) => ({
2876
2960
  ...baseOptions.downsampling,
2877
2961
  ...options.downsampling ?? {}
2878
2962
  },
2963
+ touch: {
2964
+ ...baseOptions.touch,
2965
+ ...options.touch ?? {}
2966
+ },
2967
+ datafeedOptions: {
2968
+ ...baseOptions.datafeedOptions,
2969
+ ...options.datafeedOptions ?? {}
2970
+ },
2879
2971
  crosshair: {
2880
2972
  ...baseOptions.crosshair,
2881
2973
  ...options.crosshair ?? {}
@@ -3050,10 +3142,12 @@ function createChart(element, options = {}) {
3050
3142
  let drawingDoubleClickHandler = null;
3051
3143
  let drawingEditTextHandler = null;
3052
3144
  let selectionChangeHandler = null;
3145
+ let longPressHandler = null;
3053
3146
  let contextMenuHandler = null;
3054
3147
  let keyboardShortcutHandler = null;
3055
3148
  let lastSelectionSignature = null;
3056
3149
  let magnetMode = "none";
3150
+ let activeThemeName = null;
3057
3151
  let priceScaleMode = "linear";
3058
3152
  let priceScaleInverted = false;
3059
3153
  const PRICE_SCALE_LOG_FLOOR = 1e-9;
@@ -3809,6 +3903,92 @@ function createChart(element, options = {}) {
3809
3903
  scheduleDraw({ updateAutoScale: true });
3810
3904
  };
3811
3905
  const getCompareSeries = () => compareSeriesStates.map((state) => state.options);
3906
+ let datafeed = null;
3907
+ let datafeedUnsubscribe = null;
3908
+ let datafeedLoading = false;
3909
+ let datafeedExhausted = false;
3910
+ let datafeedLastRequestAt = 0;
3911
+ const estimateBarStepMs = () => {
3912
+ if (mergedOptions.timeStepMs > 0) return mergedOptions.timeStepMs;
3913
+ if (data.length < 2) return 6e4;
3914
+ const span = data[data.length - 1].time.getTime() - data[0].time.getTime();
3915
+ return Math.max(1e3, span / (data.length - 1));
3916
+ };
3917
+ const requestDatafeedBars = async (request) => {
3918
+ if (!datafeed) return [];
3919
+ try {
3920
+ return await datafeed.getBars(request) ?? [];
3921
+ } catch (error) {
3922
+ datafeed.onError?.(error, request);
3923
+ return [];
3924
+ }
3925
+ };
3926
+ const maybeLoadOlderHistory = () => {
3927
+ if (!datafeed || datafeedLoading || datafeedExhausted || data.length === 0) return;
3928
+ const options2 = mergedOptions.datafeedOptions ?? DEFAULT_OPTIONS.datafeedOptions;
3929
+ const threshold = options2?.prefetchThresholdBars ?? 150;
3930
+ const cooldown = options2?.cooldownMs ?? 1200;
3931
+ if (Date.now() - datafeedLastRequestAt < cooldown) return;
3932
+ if (xCenter - xSpan / 2 > threshold) return;
3933
+ const stepMs = estimateBarStepMs();
3934
+ const chunk = Math.max(10, options2?.chunkBars ?? 1500);
3935
+ const toMs = data[0].time.getTime();
3936
+ datafeedLoading = true;
3937
+ datafeedLastRequestAt = Date.now();
3938
+ void requestDatafeedBars({
3939
+ fromMs: toMs - chunk * stepMs,
3940
+ toMs,
3941
+ countBack: chunk,
3942
+ firstRequest: false
3943
+ }).then((bars) => {
3944
+ const older = bars.filter((bar) => new Date(bar.t).getTime() < toMs);
3945
+ if (older.length === 0) {
3946
+ datafeedExhausted = true;
3947
+ return;
3948
+ }
3949
+ const merged = [...older, ...data.map((bar) => ({
3950
+ t: bar.time.toISOString(),
3951
+ o: bar.o,
3952
+ h: bar.h,
3953
+ l: bar.l,
3954
+ c: bar.c,
3955
+ ...bar.v === void 0 ? {} : { v: bar.v }
3956
+ }))];
3957
+ setData(merged);
3958
+ }).finally(() => {
3959
+ datafeedLoading = false;
3960
+ });
3961
+ };
3962
+ const setDatafeed = async (nextDatafeed) => {
3963
+ datafeedUnsubscribe?.();
3964
+ datafeedUnsubscribe = null;
3965
+ datafeed = nextDatafeed;
3966
+ datafeedExhausted = false;
3967
+ datafeedLoading = false;
3968
+ datafeedLastRequestAt = 0;
3969
+ if (!nextDatafeed) return;
3970
+ await nextDatafeed.onReady?.();
3971
+ if (datafeed !== nextDatafeed) return;
3972
+ const stepMs = estimateBarStepMs();
3973
+ const countBack = Math.max(50, Math.round(mergedOptions.initialVisibleBars * 3));
3974
+ const toMs = Date.now();
3975
+ datafeedLoading = true;
3976
+ const bars = await requestDatafeedBars({
3977
+ fromMs: toMs - countBack * stepMs,
3978
+ toMs,
3979
+ countBack,
3980
+ firstRequest: true
3981
+ });
3982
+ datafeedLoading = false;
3983
+ if (datafeed !== nextDatafeed) return;
3984
+ if (bars.length > 0) {
3985
+ setData(bars);
3986
+ }
3987
+ const unsubscribe = nextDatafeed.subscribeBars?.((bar) => {
3988
+ if (datafeed === nextDatafeed) upsertBar(bar);
3989
+ });
3990
+ datafeedUnsubscribe = typeof unsubscribe === "function" ? unsubscribe : null;
3991
+ };
3812
3992
  const formatHoverTimeLabel = (time, mode) => {
3813
3993
  if (mode === "time") {
3814
3994
  return time.toLocaleTimeString(void 0, {
@@ -6803,6 +6983,7 @@ function createChart(element, options = {}) {
6803
6983
  };
6804
6984
  paintCrosshairOverlay();
6805
6985
  emitSelectionChangeIfMoved();
6986
+ maybeLoadOlderHistory();
6806
6987
  };
6807
6988
  const paintCrosshairOverlay = () => {
6808
6989
  crosshairPriceActionRegion = null;
@@ -6995,6 +7176,67 @@ function createChart(element, options = {}) {
6995
7176
  drawText(timeText, timeX + labelPaddingX, timeY + timeHeight / 2, "left", "middle", labelTextColor);
6996
7177
  }
6997
7178
  }
7179
+ if (longPressState && (mergedOptions.touch?.longPressTooltip ?? true)) {
7180
+ const index = indexFromCanvasX(cx);
7181
+ const bar = index === null ? void 0 : data[index];
7182
+ if (bar) {
7183
+ const barTime = getTimeForIndex(index);
7184
+ const changeAbs = bar.c - bar.o;
7185
+ const changePct = bar.o !== 0 ? changeAbs / bar.o * 100 : 0;
7186
+ const rows = [
7187
+ ["O", formatPrice(bar.o), null],
7188
+ ["H", formatPrice(bar.h), null],
7189
+ ["L", formatPrice(bar.l), null],
7190
+ ["C", formatPrice(bar.c), null],
7191
+ [
7192
+ "Chg",
7193
+ `${changeAbs >= 0 ? "+" : ""}${formatPrice(changeAbs)} (${changeAbs >= 0 ? "+" : ""}${changePct.toFixed(2)}%)`,
7194
+ changeAbs >= 0 ? mergedOptions.upColor : mergedOptions.downColor
7195
+ ]
7196
+ ];
7197
+ if (bar.v !== void 0) {
7198
+ rows.push([
7199
+ "Vol",
7200
+ bar.v >= 1e6 ? `${(bar.v / 1e6).toFixed(2)}M` : bar.v >= 1e3 ? `${(bar.v / 1e3).toFixed(1)}K` : String(Math.round(bar.v)),
7201
+ null
7202
+ ]);
7203
+ }
7204
+ const prevFont = ctx.font;
7205
+ const fontSize = 11;
7206
+ ctx.font = `${fontSize}px ${mergedOptions.fontFamily}`;
7207
+ const headerText = barTime ? formatHoverTimeLabel(barTime, "auto") : "";
7208
+ const rowGap = 3;
7209
+ const padding = 8;
7210
+ const labelColumn = 26;
7211
+ const contentWidth = Math.max(
7212
+ measureTextWidth(headerText),
7213
+ ...rows.map(([, value]) => labelColumn + measureTextWidth(value))
7214
+ );
7215
+ const boxWidth = Math.ceil(contentWidth) + padding * 2;
7216
+ const boxHeight = padding * 2 + (fontSize + rowGap) * (rows.length + (headerText ? 1 : 0)) - rowGap;
7217
+ const fingerGap = 26;
7218
+ const boxX = cx + fingerGap + boxWidth <= chartRight ? cx + fingerGap : Math.max(chartLeft + 4, cx - fingerGap - boxWidth);
7219
+ const boxY = clamp(cy - boxHeight - fingerGap, chartTop + 4, chartBottom - boxHeight - 4);
7220
+ ctx.save();
7221
+ ctx.fillStyle = "rgba(16,17,20,0.94)";
7222
+ fillRoundedRect(Math.round(boxX), Math.round(boxY), boxWidth, boxHeight, 6);
7223
+ ctx.strokeStyle = "rgba(255,255,255,0.14)";
7224
+ ctx.lineWidth = 1;
7225
+ ctx.strokeRect(Math.round(boxX) + 0.5, Math.round(boxY) + 0.5, boxWidth - 1, boxHeight - 1);
7226
+ let textY = boxY + padding + fontSize / 2;
7227
+ if (headerText) {
7228
+ drawText(headerText, boxX + padding, textY, "left", "middle", "rgba(255,255,255,0.55)");
7229
+ textY += fontSize + rowGap;
7230
+ }
7231
+ for (const [label, value, valueColor] of rows) {
7232
+ drawText(label, boxX + padding, textY, "left", "middle", "rgba(255,255,255,0.5)");
7233
+ drawText(value, boxX + padding + labelColumn, textY, "left", "middle", valueColor ?? "#e6e8ee");
7234
+ textY += fontSize + rowGap;
7235
+ }
7236
+ ctx.restore();
7237
+ ctx.font = prevFont;
7238
+ }
7239
+ }
6998
7240
  };
6999
7241
  const drawOverlayOnly = () => {
7000
7242
  if (!baseCtx || !overlayLayout || baseCanvas.width !== canvas.width || baseCanvas.height !== canvas.height || baseCanvas.width === 0) {
@@ -7504,6 +7746,7 @@ function createChart(element, options = {}) {
7504
7746
  return Math.hypot(x - (x1 + t * dx), y - (y1 + t * dy));
7505
7747
  };
7506
7748
  const getDrawingHit = (x, y) => {
7749
+ const hitTolerance = touchInputActive ? Math.max(1, mergedOptions.touch?.hitToleranceScale ?? 2.2) : 1;
7507
7750
  for (let index = drawings.length - 1; index >= 0; index -= 1) {
7508
7751
  const drawing = drawings[index];
7509
7752
  if (!drawing?.visible) continue;
@@ -7512,10 +7755,10 @@ function createChart(element, options = {}) {
7512
7755
  if (!point) continue;
7513
7756
  const lineY = canvasYFromDrawingPrice(point.price);
7514
7757
  const handleX = drawState ? drawState.chartRight - 64 : 0;
7515
- if (Math.hypot(x - handleX, y - lineY) <= 8) {
7758
+ if (Math.hypot(x - handleX, y - lineY) <= 8 * hitTolerance) {
7516
7759
  return { drawing, target: "handle", pointIndex: 0 };
7517
7760
  }
7518
- if (Math.abs(y - lineY) <= 7) {
7761
+ if (Math.abs(y - lineY) <= 7 * hitTolerance) {
7519
7762
  return { drawing, target: "line" };
7520
7763
  }
7521
7764
  } else if (drawing.type === "vertical-line") {
@@ -7523,10 +7766,10 @@ function createChart(element, options = {}) {
7523
7766
  if (!point) continue;
7524
7767
  const lineX = canvasXFromDrawingPoint(point);
7525
7768
  const handleY = drawState ? (drawState.chartTop + drawState.chartBottom) / 2 : 0;
7526
- if (Math.hypot(x - lineX, y - handleY) <= 8) {
7769
+ if (Math.hypot(x - lineX, y - handleY) <= 8 * hitTolerance) {
7527
7770
  return { drawing, target: "handle", pointIndex: 0 };
7528
7771
  }
7529
- if (Math.abs(x - lineX) <= 7) {
7772
+ if (Math.abs(x - lineX) <= 7 * hitTolerance) {
7530
7773
  return { drawing, target: "line" };
7531
7774
  }
7532
7775
  } else if (drawing.type === "trendline") {
@@ -7537,13 +7780,13 @@ function createChart(element, options = {}) {
7537
7780
  const y1 = canvasYFromDrawingPrice(first.price);
7538
7781
  const x2 = canvasXFromDrawingPoint(second);
7539
7782
  const y2 = canvasYFromDrawingPrice(second.price);
7540
- if (Math.hypot(x - x1, y - y1) <= 8) {
7783
+ if (Math.hypot(x - x1, y - y1) <= 8 * hitTolerance) {
7541
7784
  return { drawing, target: "handle", pointIndex: 0 };
7542
7785
  }
7543
- if (Math.hypot(x - x2, y - y2) <= 8) {
7786
+ if (Math.hypot(x - x2, y - y2) <= 8 * hitTolerance) {
7544
7787
  return { drawing, target: "handle", pointIndex: 1 };
7545
7788
  }
7546
- if (distanceToSegment(x, y, x1, y1, x2, y2) <= 6) {
7789
+ if (distanceToSegment(x, y, x1, y1, x2, y2) <= 6 * hitTolerance) {
7547
7790
  return { drawing, target: "line" };
7548
7791
  }
7549
7792
  } else if (drawing.type === "ray") {
@@ -7554,10 +7797,10 @@ function createChart(element, options = {}) {
7554
7797
  const y1 = canvasYFromDrawingPrice(first.price);
7555
7798
  const x2 = canvasXFromDrawingPoint(second);
7556
7799
  const y2 = canvasYFromDrawingPrice(second.price);
7557
- if (Math.hypot(x - x1, y - y1) <= 8) {
7800
+ if (Math.hypot(x - x1, y - y1) <= 8 * hitTolerance) {
7558
7801
  return { drawing, target: "handle", pointIndex: 0 };
7559
7802
  }
7560
- if (Math.hypot(x - x2, y - y2) <= 8) {
7803
+ if (Math.hypot(x - x2, y - y2) <= 8 * hitTolerance) {
7561
7804
  return { drawing, target: "handle", pointIndex: 1 };
7562
7805
  }
7563
7806
  const dx = x2 - x1;
@@ -7567,7 +7810,7 @@ function createChart(element, options = {}) {
7567
7810
  const t = Math.max(0, ((x - x1) * dx + (y - y1) * dy) / lengthSq);
7568
7811
  const projX = x1 + t * dx;
7569
7812
  const projY = y1 + t * dy;
7570
- if (Math.hypot(x - projX, y - projY) <= 6) {
7813
+ if (Math.hypot(x - projX, y - projY) <= 6 * hitTolerance) {
7571
7814
  return { drawing, target: "line" };
7572
7815
  }
7573
7816
  }
@@ -7579,17 +7822,17 @@ function createChart(element, options = {}) {
7579
7822
  const y1 = canvasYFromDrawingPrice(first.price);
7580
7823
  const x2 = canvasXFromDrawingPoint(second);
7581
7824
  const y2 = canvasYFromDrawingPrice(second.price);
7582
- if (Math.hypot(x - x1, y - y1) <= 9) {
7825
+ if (Math.hypot(x - x1, y - y1) <= 9 * hitTolerance) {
7583
7826
  return { drawing, target: "handle", pointIndex: 0 };
7584
7827
  }
7585
- if (Math.hypot(x - x2, y - y2) <= 9) {
7828
+ if (Math.hypot(x - x2, y - y2) <= 9 * hitTolerance) {
7586
7829
  return { drawing, target: "handle", pointIndex: 1 };
7587
7830
  }
7588
7831
  const fibRatios = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
7589
7832
  for (const ratio of fibRatios) {
7590
7833
  const price = first.price + (second.price - first.price) * (1 - ratio);
7591
7834
  const lineY = canvasYFromDrawingPrice(price);
7592
- if (Math.abs(y - lineY) <= 5) {
7835
+ if (Math.abs(y - lineY) <= 5 * hitTolerance) {
7593
7836
  return { drawing, target: "line" };
7594
7837
  }
7595
7838
  }
@@ -7602,30 +7845,30 @@ function createChart(element, options = {}) {
7602
7845
  const y0 = canvasYFromDrawingPrice(p0.price);
7603
7846
  const x1 = canvasXFromDrawingPoint(p1);
7604
7847
  const y1 = canvasYFromDrawingPrice(p1.price);
7605
- if (Math.hypot(x - x0, y - y0) <= 8) {
7848
+ if (Math.hypot(x - x0, y - y0) <= 8 * hitTolerance) {
7606
7849
  return { drawing, target: "handle", pointIndex: 0 };
7607
7850
  }
7608
- if (Math.hypot(x - x1, y - y1) <= 8) {
7851
+ if (Math.hypot(x - x1, y - y1) <= 8 * hitTolerance) {
7609
7852
  return { drawing, target: "handle", pointIndex: 1 };
7610
7853
  }
7611
7854
  if (p2) {
7612
7855
  const x2 = canvasXFromDrawingPoint(p2);
7613
7856
  const y2 = canvasYFromDrawingPrice(p2.price);
7614
- if (Math.hypot(x - x2, y - y2) <= 8) {
7857
+ if (Math.hypot(x - x2, y - y2) <= 8 * hitTolerance) {
7615
7858
  return { drawing, target: "handle", pointIndex: 2 };
7616
7859
  }
7617
7860
  const move = p1.price - p0.price;
7618
7861
  const fibExtRatios = [0, 0.382, 0.5, 0.618, 1, 1.272, 1.618, 2.618];
7619
7862
  for (const ratio of fibExtRatios) {
7620
7863
  const lineY = canvasYFromDrawingPrice(p2.price + move * ratio);
7621
- if (Math.abs(y - lineY) <= 5) {
7864
+ if (Math.abs(y - lineY) <= 5 * hitTolerance) {
7622
7865
  return { drawing, target: "line" };
7623
7866
  }
7624
7867
  }
7625
- if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 || distanceToSegment(x, y, x1, y1, x2, y2) <= 6) {
7868
+ if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance || distanceToSegment(x, y, x1, y1, x2, y2) <= 6 * hitTolerance) {
7626
7869
  return { drawing, target: "line" };
7627
7870
  }
7628
- } else if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6) {
7871
+ } else if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance) {
7629
7872
  return { drawing, target: "line" };
7630
7873
  }
7631
7874
  } else if (drawing.type === "long-position" || drawing.type === "short-position") {
@@ -7639,10 +7882,10 @@ function createChart(element, options = {}) {
7639
7882
  const entryY = canvasYFromDrawingPrice(entry.price);
7640
7883
  const targetY = canvasYFromDrawingPrice(target.price);
7641
7884
  const stopY = canvasYFromDrawingPrice(stop.price);
7642
- if (Math.hypot(x - leftX, y - targetY) <= 9) return { drawing, target: "handle", pointIndex: 1 };
7643
- if (Math.hypot(x - leftX, y - entryY) <= 9) return { drawing, target: "handle", pointIndex: 0 };
7644
- if (Math.hypot(x - leftX, y - stopY) <= 9) return { drawing, target: "handle", pointIndex: 2 };
7645
- if (Math.hypot(x - rightX, y - entryY) <= 9) return { drawing, target: "handle", pointIndex: 3 };
7885
+ if (Math.hypot(x - leftX, y - targetY) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 1 };
7886
+ if (Math.hypot(x - leftX, y - entryY) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 0 };
7887
+ if (Math.hypot(x - leftX, y - stopY) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 2 };
7888
+ if (Math.hypot(x - rightX, y - entryY) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 3 };
7646
7889
  const x0 = Math.min(leftX, rightX);
7647
7890
  const x1 = Math.max(leftX, rightX);
7648
7891
  const yTop = Math.min(targetY, stopY, entryY);
@@ -7658,10 +7901,10 @@ function createChart(element, options = {}) {
7658
7901
  const px1 = canvasXFromDrawingPoint(p1);
7659
7902
  const y0 = canvasYFromDrawingPrice(p0.price);
7660
7903
  const y1 = canvasYFromDrawingPrice(p1.price);
7661
- if (Math.hypot(x - px0, y - y0) <= 9) return { drawing, target: "handle", pointIndex: 0 };
7662
- if (Math.hypot(x - px1, y - y1) <= 9) return { drawing, target: "handle", pointIndex: 1 };
7663
- if (Math.hypot(x - px0, y - y1) <= 9) return { drawing, target: "handle", pointIndex: 2 };
7664
- if (Math.hypot(x - px1, y - y0) <= 9) return { drawing, target: "handle", pointIndex: 3 };
7904
+ if (Math.hypot(x - px0, y - y0) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 0 };
7905
+ if (Math.hypot(x - px1, y - y1) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 1 };
7906
+ if (Math.hypot(x - px0, y - y1) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 2 };
7907
+ if (Math.hypot(x - px1, y - y0) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 3 };
7665
7908
  if (x >= Math.min(px0, px1) && x <= Math.max(px0, px1) && y >= Math.min(y0, y1) && y <= Math.max(y0, y1)) {
7666
7909
  return { drawing, target: "line" };
7667
7910
  }
@@ -7673,16 +7916,16 @@ function createChart(element, options = {}) {
7673
7916
  const px1 = canvasXFromDrawingPoint(p1);
7674
7917
  const y0 = canvasYFromDrawingPrice(p0.price);
7675
7918
  const y1 = canvasYFromDrawingPrice(p1.price);
7676
- if (Math.hypot(x - px0, y - y0) <= 9) return { drawing, target: "handle", pointIndex: 0 };
7677
- if (Math.hypot(x - px1, y - y1) <= 9) return { drawing, target: "handle", pointIndex: 1 };
7678
- if (Math.hypot(x - px0, y - y1) <= 9) return { drawing, target: "handle", pointIndex: 2 };
7679
- if (Math.hypot(x - px1, y - y0) <= 9) return { drawing, target: "handle", pointIndex: 3 };
7919
+ if (Math.hypot(x - px0, y - y0) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 0 };
7920
+ if (Math.hypot(x - px1, y - y1) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 1 };
7921
+ if (Math.hypot(x - px0, y - y1) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 2 };
7922
+ if (Math.hypot(x - px1, y - y0) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 3 };
7680
7923
  const cx = (px0 + px1) / 2;
7681
7924
  const cy = (y0 + y1) / 2;
7682
7925
  const rx = Math.max(1, Math.abs(px1 - px0) / 2);
7683
7926
  const ry = Math.max(1, Math.abs(y1 - y0) / 2);
7684
7927
  const norm = ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2;
7685
- if (norm <= 1) {
7928
+ if (norm <= 1 * hitTolerance) {
7686
7929
  return { drawing, target: "line" };
7687
7930
  }
7688
7931
  } else if (drawing.type === "parallel-channel") {
@@ -7694,18 +7937,18 @@ function createChart(element, options = {}) {
7694
7937
  const y0 = canvasYFromDrawingPrice(p0.price);
7695
7938
  const x1 = canvasXFromDrawingPoint(p1);
7696
7939
  const y1 = canvasYFromDrawingPrice(p1.price);
7697
- if (Math.hypot(x - x0, y - y0) <= 8) return { drawing, target: "handle", pointIndex: 0 };
7698
- if (Math.hypot(x - x1, y - y1) <= 8) return { drawing, target: "handle", pointIndex: 1 };
7940
+ if (Math.hypot(x - x0, y - y0) <= 8 * hitTolerance) return { drawing, target: "handle", pointIndex: 0 };
7941
+ if (Math.hypot(x - x1, y - y1) <= 8 * hitTolerance) return { drawing, target: "handle", pointIndex: 1 };
7699
7942
  if (p2) {
7700
7943
  const x2 = canvasXFromDrawingPoint(p2);
7701
7944
  const y2 = canvasYFromDrawingPrice(p2.price);
7702
- if (Math.hypot(x - x2, y - y2) <= 8) return { drawing, target: "handle", pointIndex: 2 };
7945
+ if (Math.hypot(x - x2, y - y2) <= 8 * hitTolerance) return { drawing, target: "handle", pointIndex: 2 };
7703
7946
  const indexSpan = p1.index - p0.index;
7704
7947
  const slope = indexSpan !== 0 ? (p1.price - p0.price) / indexSpan : 0;
7705
7948
  const offset = p2.price - (p0.price + slope * (p2.index - p0.index));
7706
7949
  const q0y = canvasYFromDrawingPrice(p0.price + offset);
7707
7950
  const q1y = canvasYFromDrawingPrice(p1.price + offset);
7708
- if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 || distanceToSegment(x, y, x0, q0y, x1, q1y) <= 6) {
7951
+ if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance || distanceToSegment(x, y, x0, q0y, x1, q1y) <= 6 * hitTolerance) {
7709
7952
  return { drawing, target: "line" };
7710
7953
  }
7711
7954
  const minX = Math.min(x0, x1);
@@ -7718,7 +7961,7 @@ function createChart(element, options = {}) {
7718
7961
  return { drawing, target: "line" };
7719
7962
  }
7720
7963
  }
7721
- } else if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6) {
7964
+ } else if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance) {
7722
7965
  return { drawing, target: "line" };
7723
7966
  }
7724
7967
  } else if (drawing.type === "arrow") {
@@ -7729,13 +7972,13 @@ function createChart(element, options = {}) {
7729
7972
  const y1 = canvasYFromDrawingPrice(first.price);
7730
7973
  const x2 = canvasXFromDrawingPoint(second);
7731
7974
  const y2 = canvasYFromDrawingPrice(second.price);
7732
- if (Math.hypot(x - x1, y - y1) <= 8) {
7975
+ if (Math.hypot(x - x1, y - y1) <= 8 * hitTolerance) {
7733
7976
  return { drawing, target: "handle", pointIndex: 0 };
7734
7977
  }
7735
- if (Math.hypot(x - x2, y - y2) <= 8) {
7978
+ if (Math.hypot(x - x2, y - y2) <= 8 * hitTolerance) {
7736
7979
  return { drawing, target: "handle", pointIndex: 1 };
7737
7980
  }
7738
- if (distanceToSegment(x, y, x1, y1, x2, y2) <= 6) {
7981
+ if (distanceToSegment(x, y, x1, y1, x2, y2) <= 6 * hitTolerance) {
7739
7982
  return { drawing, target: "line" };
7740
7983
  }
7741
7984
  } else if (drawing.type === "brush") {
@@ -7747,7 +7990,7 @@ function createChart(element, options = {}) {
7747
7990
  for (let i = 1; i < pts.length; i += 1) {
7748
7991
  const nextX = canvasXFromDrawingPoint(pts[i]);
7749
7992
  const nextY = canvasYFromDrawingPrice(pts[i].price);
7750
- if (distanceToSegment(x, y, prevX, prevY, nextX, nextY) <= 7) {
7993
+ if (distanceToSegment(x, y, prevX, prevY, nextX, nextY) <= 7 * hitTolerance) {
7751
7994
  hitBody = true;
7752
7995
  break;
7753
7996
  }
@@ -7765,8 +8008,8 @@ function createChart(element, options = {}) {
7765
8008
  const ay = canvasYFromDrawingPrice(anchor.price);
7766
8009
  const bx = canvasXFromDrawingPoint(boxPoint);
7767
8010
  const by = canvasYFromDrawingPrice(boxPoint.price);
7768
- if (Math.hypot(x - ax, y - ay) <= 9) return { drawing, target: "handle", pointIndex: 0 };
7769
- if (Math.hypot(x - bx, y - by) <= 9) return { drawing, target: "handle", pointIndex: 1 };
8011
+ if (Math.hypot(x - ax, y - ay) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 0 };
8012
+ if (Math.hypot(x - bx, y - by) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 1 };
7770
8013
  const fontSize = Math.max(6, drawing.fontSize);
7771
8014
  const prevFont = ctx.font;
7772
8015
  ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
@@ -7782,7 +8025,7 @@ function createChart(element, options = {}) {
7782
8025
  if (x >= bx && x <= bx + blockW && y >= by && y <= by + blockH) {
7783
8026
  return { drawing, target: "line" };
7784
8027
  }
7785
- if (distanceToSegment(x, y, bx + blockW / 2, by + blockH / 2, ax, ay) <= 5) {
8028
+ if (distanceToSegment(x, y, bx + blockW / 2, by + blockH / 2, ax, ay) <= 5 * hitTolerance) {
7786
8029
  return { drawing, target: "line" };
7787
8030
  }
7788
8031
  } else if (drawing.type === "price-range") {
@@ -7793,8 +8036,8 @@ function createChart(element, options = {}) {
7793
8036
  const px1 = canvasXFromDrawingPoint(p1);
7794
8037
  const y0 = canvasYFromDrawingPrice(p0.price);
7795
8038
  const y1 = canvasYFromDrawingPrice(p1.price);
7796
- if (Math.hypot(x - px0, y - y0) <= 9) return { drawing, target: "handle", pointIndex: 0 };
7797
- if (Math.hypot(x - px1, y - y1) <= 9) return { drawing, target: "handle", pointIndex: 1 };
8039
+ if (Math.hypot(x - px0, y - y0) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 0 };
8040
+ if (Math.hypot(x - px1, y - y1) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 1 };
7798
8041
  if (x >= Math.min(px0, px1) && x <= Math.max(px0, px1) && y >= Math.min(y0, y1) && y <= Math.max(y0, y1)) {
7799
8042
  return { drawing, target: "line" };
7800
8043
  }
@@ -7803,7 +8046,7 @@ function createChart(element, options = {}) {
7803
8046
  if (!anchor) continue;
7804
8047
  const ax = canvasXFromDrawingPoint(anchor);
7805
8048
  const ay = canvasYFromDrawingPrice(anchor.price);
7806
- if (Math.hypot(x - ax, y - ay) <= 9) return { drawing, target: "handle", pointIndex: 0 };
8049
+ if (Math.hypot(x - ax, y - ay) <= 9 * hitTolerance) return { drawing, target: "handle", pointIndex: 0 };
7807
8050
  const fontSize = Math.max(6, drawing.fontSize);
7808
8051
  const prevFont = ctx.font;
7809
8052
  ctx.font = `500 ${fontSize}px ${mergedOptions.fontFamily}`;
@@ -7898,8 +8141,9 @@ function createChart(element, options = {}) {
7898
8141
  if (!drawState || x < drawState.chartLeft || x > drawState.chartRight) {
7899
8142
  return null;
7900
8143
  }
8144
+ const dividerTolerance = touchInputActive ? 4 * Math.max(1, mergedOptions.touch?.hitToleranceScale ?? 2.2) : 4;
7901
8145
  for (const pane of paneLayoutInfos) {
7902
- if (pane.visible && Math.abs(y - pane.top) <= 4) {
8146
+ if (pane.visible && Math.abs(y - pane.top) <= dividerTolerance) {
7903
8147
  return { id: pane.id, heightPx: pane.bottom - pane.top };
7904
8148
  }
7905
8149
  }
@@ -8392,7 +8636,43 @@ function createChart(element, options = {}) {
8392
8636
  let lastPointerX = 0;
8393
8637
  let lastPointerY = 0;
8394
8638
  let activePointerId = null;
8639
+ let touchInputActive = false;
8395
8640
  const touchPointers = /* @__PURE__ */ new Map();
8641
+ let longPressTimerId = null;
8642
+ let longPressState = null;
8643
+ const cancelLongPressTimer = () => {
8644
+ if (longPressTimerId !== null) {
8645
+ clearTimeout(longPressTimerId);
8646
+ longPressTimerId = null;
8647
+ }
8648
+ };
8649
+ const emitLongPress = (x, y, scrubbing) => {
8650
+ if (!longPressHandler) return;
8651
+ const rect = canvas.getBoundingClientRect();
8652
+ const index = indexFromCanvasX(x);
8653
+ const barTime = index === null ? null : getTimeForIndex(index);
8654
+ const bar = index === null ? void 0 : data[index];
8655
+ longPressHandler({
8656
+ x,
8657
+ y,
8658
+ clientX: rect.left + x,
8659
+ clientY: rect.top + y,
8660
+ scrubbing,
8661
+ ...getHitRegion(x, y) === "plot" ? { price: roundToPricePrecision(priceFromCanvasY(y)) } : {},
8662
+ ...index === null ? {} : { index },
8663
+ ...barTime ? { time: barTime.toISOString() } : {},
8664
+ ...bar ? {
8665
+ point: {
8666
+ t: bar.time.toISOString(),
8667
+ o: bar.o,
8668
+ h: bar.h,
8669
+ l: bar.l,
8670
+ c: bar.c,
8671
+ ...bar.v === void 0 ? {} : { v: bar.v }
8672
+ }
8673
+ } : {}
8674
+ });
8675
+ };
8396
8676
  let pinchZoomState = null;
8397
8677
  const getTouchPair = () => {
8398
8678
  const points = Array.from(touchPointers.values());
@@ -8458,7 +8738,8 @@ function createChart(element, options = {}) {
8458
8738
  }
8459
8739
  };
8460
8740
  const onPointerDown = (event) => {
8461
- if (event.pointerType === "touch" || event.pointerType === "pen") {
8741
+ touchInputActive = event.pointerType === "touch" || event.pointerType === "pen";
8742
+ if (touchInputActive) {
8462
8743
  event.preventDefault();
8463
8744
  }
8464
8745
  if (mergedOptions.accessibility?.focusable !== false && document.activeElement !== canvas) {
@@ -8475,9 +8756,25 @@ function createChart(element, options = {}) {
8475
8756
  capturePointer(event.pointerId);
8476
8757
  const touchPair = getTouchPair();
8477
8758
  if (touchPair) {
8759
+ cancelLongPressTimer();
8760
+ longPressState = null;
8478
8761
  beginPinchZoom(touchPair[0], touchPair[1]);
8479
8762
  return;
8480
8763
  }
8764
+ cancelLongPressTimer();
8765
+ longPressState = null;
8766
+ const touchOptions = mergedOptions.touch ?? {};
8767
+ const wantsTooltip = touchOptions.longPressTooltip !== false || longPressHandler !== null;
8768
+ if (wantsTooltip && !activeDrawingTool && !draftDrawing && getHitRegion(point.x, point.y) === "plot") {
8769
+ const pointerId = event.pointerId;
8770
+ longPressTimerId = window.setTimeout(() => {
8771
+ longPressTimerId = null;
8772
+ longPressState = { pointerId, x: point.x, y: point.y };
8773
+ setCrosshairPoint(point);
8774
+ scheduleDraw({ overlayOnly: true });
8775
+ emitLongPress(point.x, point.y, false);
8776
+ }, Math.max(120, touchOptions.longPressMs ?? 400));
8777
+ }
8481
8778
  }
8482
8779
  if (measureState) {
8483
8780
  if (measureState.dragging) {
@@ -8643,7 +8940,10 @@ function createChart(element, options = {}) {
8643
8940
  };
8644
8941
  const onPointerMove = (event) => {
8645
8942
  if (event.pointerType === "touch" || event.pointerType === "pen") {
8943
+ touchInputActive = true;
8646
8944
  event.preventDefault();
8945
+ } else if (event.pointerType === "mouse") {
8946
+ touchInputActive = false;
8647
8947
  }
8648
8948
  magnetModifierActive = event.metaKey || event.ctrlKey;
8649
8949
  shiftKeyActive = event.shiftKey;
@@ -8652,6 +8952,8 @@ function createChart(element, options = {}) {
8652
8952
  touchPointers.set(event.pointerId, point);
8653
8953
  const touchPair = getTouchPair();
8654
8954
  if (touchPair) {
8955
+ cancelLongPressTimer();
8956
+ longPressState = null;
8655
8957
  if (!pinchZoomState) {
8656
8958
  beginPinchZoom(touchPair[0], touchPair[1]);
8657
8959
  }
@@ -8661,6 +8963,21 @@ function createChart(element, options = {}) {
8661
8963
  if (pinchZoomState) {
8662
8964
  return;
8663
8965
  }
8966
+ if (longPressState && longPressState.pointerId === event.pointerId) {
8967
+ longPressState = { ...longPressState, x: point.x, y: point.y };
8968
+ setCrosshairPoint(point);
8969
+ emitCrosshairMove(point.x, point.y, getHitRegion(point.x, point.y) === "plot" ? "plot" : "plot");
8970
+ scheduleDraw({ overlayOnly: true });
8971
+ emitLongPress(point.x, point.y, true);
8972
+ return;
8973
+ }
8974
+ if (longPressTimerId !== null) {
8975
+ const dx = point.x - (pointerDownInfo?.x ?? point.x);
8976
+ const dy = point.y - (pointerDownInfo?.y ?? point.y);
8977
+ if (dx * dx + dy * dy > 36) {
8978
+ cancelLongPressTimer();
8979
+ }
8980
+ }
8664
8981
  }
8665
8982
  if (pointerDownInfo && pointerDownInfo.pointerId === event.pointerId && !pointerDownInfo.moved) {
8666
8983
  const dx = point.x - pointerDownInfo.x;
@@ -8924,6 +9241,18 @@ function createChart(element, options = {}) {
8924
9241
  lastPointerY = point.y;
8925
9242
  };
8926
9243
  const endPointerDrag = (event) => {
9244
+ cancelLongPressTimer();
9245
+ if (longPressState && (!event || event.pointerId === longPressState.pointerId)) {
9246
+ longPressState = null;
9247
+ touchPointers.delete(event?.pointerId ?? -1);
9248
+ setCrosshairPoint(null);
9249
+ isDragging = false;
9250
+ dragMode = null;
9251
+ activePointerId = null;
9252
+ pointerDownInfo = null;
9253
+ scheduleDraw({ overlayOnly: true });
9254
+ return;
9255
+ }
8927
9256
  if (event?.pointerType === "touch") {
8928
9257
  touchPointers.delete(event.pointerId);
8929
9258
  if (pinchZoomState) {
@@ -9331,6 +9660,23 @@ function createChart(element, options = {}) {
9331
9660
  window.addEventListener("blur", onWindowBlurMagnet);
9332
9661
  }
9333
9662
  const updateOptions = (nextOptions) => {
9663
+ const THEMED_OPTION_KEYS = [
9664
+ "backgroundColor",
9665
+ "upColor",
9666
+ "downColor",
9667
+ "lineColor",
9668
+ "gridColor",
9669
+ "axisColor",
9670
+ "grid",
9671
+ "axis",
9672
+ "xAxis",
9673
+ "yAxis",
9674
+ "crosshair",
9675
+ "watermark"
9676
+ ];
9677
+ if (THEMED_OPTION_KEYS.some((key) => nextOptions[key] !== void 0) || nextOptions.labels?.indicatorTextColor !== void 0) {
9678
+ activeThemeName = null;
9679
+ }
9334
9680
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
9335
9681
  const previousWidth = width;
9336
9682
  const previousHeight = height;
@@ -9359,6 +9705,30 @@ function createChart(element, options = {}) {
9359
9705
  }
9360
9706
  scheduleDraw();
9361
9707
  };
9708
+ const setTheme = (theme) => {
9709
+ const resolved = resolveTheme(theme);
9710
+ updateOptions({
9711
+ backgroundColor: resolved.background,
9712
+ upColor: resolved.upColor,
9713
+ downColor: resolved.downColor,
9714
+ lineColor: resolved.lineColor,
9715
+ gridColor: resolved.gridColor,
9716
+ grid: { color: resolved.gridColor, opacity: resolved.gridOpacity },
9717
+ axis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9718
+ xAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9719
+ yAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9720
+ crosshair: {
9721
+ color: resolved.crosshairColor,
9722
+ labelBackgroundColor: resolved.crosshairLabelBackground,
9723
+ labelTextColor: resolved.crosshairLabelText,
9724
+ labelBorderColor: resolved.crosshairLabelBorder
9725
+ },
9726
+ watermark: { color: resolved.watermarkColor },
9727
+ labels: { indicatorTextColor: resolved.indicatorTextColor }
9728
+ });
9729
+ activeThemeName = resolved.name;
9730
+ };
9731
+ const getTheme = () => activeThemeName;
9362
9732
  const setChartType = (type) => {
9363
9733
  if (mergedOptions.chartType === type) {
9364
9734
  return;
@@ -9740,6 +10110,9 @@ function createChart(element, options = {}) {
9740
10110
  const onKeyboardShortcut = (handler) => {
9741
10111
  keyboardShortcutHandler = handler;
9742
10112
  };
10113
+ const onLongPress = (handler) => {
10114
+ longPressHandler = handler;
10115
+ };
9743
10116
  const focus = () => {
9744
10117
  canvas.focus({ preventScroll: true });
9745
10118
  };
@@ -9793,6 +10166,10 @@ function createChart(element, options = {}) {
9793
10166
  return canvas.toDataURL(options2.type ?? "image/png", options2.quality);
9794
10167
  };
9795
10168
  const destroy = () => {
10169
+ cancelLongPressTimer();
10170
+ datafeedUnsubscribe?.();
10171
+ datafeedUnsubscribe = null;
10172
+ datafeed = null;
9796
10173
  cancelKineticPan();
9797
10174
  if (smoothingRafId !== null) {
9798
10175
  cancelAnimationFrame(smoothingRafId);
@@ -9880,10 +10257,14 @@ function createChart(element, options = {}) {
9880
10257
  getMagnetMode,
9881
10258
  setPriceScale,
9882
10259
  getPriceScale,
10260
+ setTheme,
10261
+ getTheme,
9883
10262
  setCompareSeries,
9884
10263
  addCompareSeries,
9885
10264
  removeCompareSeries,
9886
10265
  getCompareSeries,
10266
+ setDatafeed,
10267
+ onLongPress,
9887
10268
  cancelDrawing,
9888
10269
  setTradeMarkers,
9889
10270
  setSelectedDrawing,
@@ -9907,6 +10288,8 @@ function createChart(element, options = {}) {
9907
10288
  };
9908
10289
  }
9909
10290
  export {
10291
+ CHART_THEMES,
10292
+ CHART_THEME_NAMES,
9910
10293
  FIB_DEFAULT_PALETTE,
9911
10294
  POSITION_DEFAULT_COLORS,
9912
10295
  SCRIPT_SOURCE_INPUT_VALUES,