@luxalgo/vela 0.6.13 → 0.6.15

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.
Files changed (49) hide show
  1. package/NOTICE +28 -28
  2. package/README.md +1 -1
  3. package/dist/{DataProvider-DhzstpQb.d.ts → DataProvider-XLdJB86x.d.ts} +1 -1
  4. package/dist/{DataProvider-DlMtrwqM.d.cts → DataProvider-xH2VBcFT.d.cts} +1 -1
  5. package/dist/{chunk-F4M24ANM.js → chunk-32A7KHFM.js} +73 -3
  6. package/dist/{chunk-KG4YT3TI.js → chunk-6DPAYEGO.js} +8 -1
  7. package/dist/{chunk-G52XAKZY.js → chunk-7C7NWEXH.js} +345 -148
  8. package/dist/{chunk-JKGA36ZM.js → chunk-J5QIR2Z3.js} +165 -130
  9. package/dist/{chunk-MHY7MVXH.js → chunk-MWDNPGU3.js} +7 -1
  10. package/dist/{chunk-G77Y7LK2.js → chunk-MWS4CUJL.js} +2 -2
  11. package/dist/{contributions-37nni40G.d.ts → contributions-h5BzEiV2.d.ts} +13 -2
  12. package/dist/{contributions-lPojhTxI.d.cts → contributions-x7iamlnd.d.cts} +13 -2
  13. package/dist/index.cjs +176 -127
  14. package/dist/index.d.cts +20 -12
  15. package/dist/index.d.ts +20 -12
  16. package/dist/index.js +4 -4
  17. package/dist/{options-CYS5Wmlx.d.ts → options-bdSAtp7y.d.cts} +5 -0
  18. package/dist/{options-CYS5Wmlx.d.cts → options-bdSAtp7y.d.ts} +5 -0
  19. package/dist/{plugin-Cwikpz1m.d.cts → plugin-2sJcf5mk.d.cts} +11 -8
  20. package/dist/{plugin-DHyaoMjW.d.ts → plugin-BLaNPh55.d.ts} +11 -8
  21. package/dist/plugin.cjs +8 -0
  22. package/dist/plugin.d.cts +5 -5
  23. package/dist/plugin.d.ts +5 -5
  24. package/dist/plugin.js +2 -2
  25. package/dist/providers/binance.d.cts +2 -2
  26. package/dist/providers/binance.d.ts +2 -2
  27. package/dist/providers/coinbase.d.cts +2 -2
  28. package/dist/providers/coinbase.d.ts +2 -2
  29. package/dist/providers/hyperliquid.d.cts +2 -2
  30. package/dist/providers/hyperliquid.d.ts +2 -2
  31. package/dist/{side-panel-CT9ZwIGz.d.cts → side-panel-HF0IAzwf.d.cts} +17 -0
  32. package/dist/{side-panel-CT9ZwIGz.d.ts → side-panel-HF0IAzwf.d.ts} +17 -0
  33. package/dist/{statusline-model-D-q_OOx9.d.ts → statusline-model--tH0VWCy.d.cts} +6 -4
  34. package/dist/{statusline-model-CiJm-riV.d.cts → statusline-model-CLpaO3Dl.d.ts} +6 -4
  35. package/dist/ui.cjs +12 -0
  36. package/dist/ui.d.cts +1 -1
  37. package/dist/ui.d.ts +1 -1
  38. package/dist/ui.js +3 -3
  39. package/dist/vela.global.js +176 -127
  40. package/dist/vela.global.min.js +52 -46
  41. package/dist/widget.cjs +587 -272
  42. package/dist/widget.d.cts +15 -11
  43. package/dist/widget.d.ts +15 -11
  44. package/dist/widget.js +7 -7
  45. package/dist/workspace.cjs +587 -272
  46. package/dist/workspace.d.cts +29 -10
  47. package/dist/workspace.d.ts +29 -10
  48. package/dist/workspace.js +6 -6
  49. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -300,6 +300,7 @@ var SERIES_LINE = "#3b82f6";
300
300
  var CROSSHAIR = "#9aa0ad";
301
301
  var SLATE_DEEP = "#1e293b";
302
302
  var SLATE = "#475569";
303
+ var CHIP_PLATE = "#595959";
303
304
  var TRADE_LONG = ACCENT;
304
305
  var TRADE_SHORT = BEARISH;
305
306
  var TRADE_EXIT = "#d500f9";
@@ -527,6 +528,10 @@ registerIcon(
527
528
  "market-post",
528
529
  svg24('<path d="M12 10V2"/><path d="m4.93 10.93 1.41 1.41"/><path d="M2 18h2"/><path d="M20 18h2"/><path d="m19.07 10.93-1.41 1.41"/><path d="M22 22H2"/><path d="m16 14-4 4-4-4"/><path d="M16 6a4 4 0 0 0-8 0"/>')
529
530
  );
531
+ registerIcon(
532
+ "market-extended",
533
+ svg24('<path d="M22 22H2"/><path d="M12 3a5 5 0 0 0 7.5 7.5A7.5 7.5 0 1 1 12 3Z"/>')
534
+ );
530
535
  registerIcon("market-closed", svg24('<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>'));
531
536
  registerIcon(
532
537
  "market-holiday",
@@ -540,6 +545,8 @@ registerIcon("chevrons-right", S('<path d="m4 3.5 4.5 4.5L4 12.5"/><path d="m8.5
540
545
  registerIcon("chevrons-left", S('<path d="M12 3.5 7.5 8l4.5 4.5"/><path d="M7.5 3.5 3 8l4.5 4.5"/>'));
541
546
  registerIcon("check", S('<path d="m2.8 8.4 3.4 3.4 7-7.6"/>'));
542
547
  registerIcon("close", S('<path d="m3.8 3.8 8.4 8.4M12.2 3.8l-8.4 8.4"/>'));
548
+ registerIcon("pin", S('<path d="M5.6 2.5h4.8M6.4 2.5v3.6L4.4 8.4v.9h7.2v-.9L9.6 6.1V2.5M8 9.3v4.2"/>'));
549
+ registerIcon("pin-filled", S('<path d="M5.6 2.5h4.8M6.4 2.5v3.6L4.4 8.4v.9h7.2v-.9L9.6 6.1V2.5M8 9.3v4.2"/><path d="M6.4 2.5h3.2v3.6l2 2.3v.9H4.4v-.9l2-2.3z" fill="currentColor" stroke="none"/>'));
543
550
  registerIcon("eye", S('<path d="M1.5 8s2.5-5.4 6.5-5.4S14.5 8 14.5 8 12 13.4 8 13.4 1.5 8 1.5 8z"/><circle cx="8" cy="8" r="1.8"/>'));
544
551
  registerIcon("eye-off", S('<path d="M1.5 8s2.5-5.4 6.5-5.4S14.5 8 14.5 8 12 13.4 8 13.4 1.5 8 1.5 8z" opacity="0.45"/><path d="m3 13 10-10"/>'));
545
552
  registerIcon("lock", S('<rect x="3.2" y="7" width="9.6" height="6.6" rx="1.2"/><path d="M5.6 7V5.2a2.4 2.4 0 0 1 4.8 0V7"/>'));
@@ -7602,6 +7609,7 @@ var RUN_EMIT_THROTTLE_MS = 1e3;
7602
7609
  var PREVIEW_BARS = 300;
7603
7610
  var SINGLE_LOAD_BARS = 5e3;
7604
7611
  var CHUNK_BARS = 1e4;
7612
+ var FIRST_PAINT_BARS = 20;
7605
7613
  var GAP_FACTOR = 1.5;
7606
7614
  var HEAL_COOLDOWN_MS = 5e3;
7607
7615
  var EngineOrchestrator = class _EngineOrchestrator {
@@ -7877,6 +7885,7 @@ var EngineOrchestrator = class _EngineOrchestrator {
7877
7885
  let painted = false;
7878
7886
  const paint = (bars, final) => {
7879
7887
  if (this.generation !== gen || !final && bars.length === 0) return;
7888
+ if (!painted && !final && bars.length < Math.min(requested, FIRST_PAINT_BARS)) return;
7880
7889
  this.setBarSeries(bars, painted ? { preserveView: true } : void 0);
7881
7890
  if (!painted && bars.length > 0) {
7882
7891
  painted = true;
@@ -9294,6 +9303,15 @@ var RendererControl = class {
9294
9303
  console.warn(`[vela] renderer "${this.renderer.name}" does not support screenshot().`);
9295
9304
  return null;
9296
9305
  }
9306
+ /**
9307
+ * Raster of the current chart onto a canvas (same pixels as {@link screenshot}),
9308
+ * or null if the renderer has no canvas export. Silent — a host compositing
9309
+ * several charts skips a renderer that cannot contribute.
9310
+ */
9311
+ screenshotCanvas() {
9312
+ if (typeof this.renderer.screenshotCanvas === "function") return this.renderer.screenshotCanvas();
9313
+ return null;
9314
+ }
9297
9315
  /**
9298
9316
  * The active renderer's full cosmetic config as a serializable, versioned JSON
9299
9317
  * document — persist it (templates, saved settings) and feed it back to
@@ -10912,6 +10930,12 @@ ${STATIC_DECLS}
10912
10930
  .vela-ui *, .vela-ui-layer * { box-sizing: border-box; }
10913
10931
  /* Text ENTRY is the one exception: selection is part of editing. */
10914
10932
  .vela-ui :is(input, textarea), .vela-ui-layer :is(input, textarea) { user-select: text; -webkit-user-select: text; }
10933
+ /* iOS Safari zooms the page when a focused field is under 16px, and often
10934
+ keeps that zoom after the field blurs or a dialog closes. The shell's
10935
+ mobile size class is the honest gate \u2014 not a media query \u2014 so an embedded
10936
+ chart on a wide desktop still gets the rule when it is in the phone layout.
10937
+ Scoped to the kit root so a host page's own [data-layout] is never touched. */
10938
+ .vela-ui[data-layout='mobile'] :is(input, textarea, select) { font-size: 16px; }
10915
10939
  .vela-icon { display: inline-flex; align-items: center; flex: none; }
10916
10940
  .vela-icon svg { display: block; }
10917
10941
  `;
@@ -15343,6 +15367,66 @@ function candleGeometry(xCss, spacing, dpr, bodyScale = 1) {
15343
15367
  center: (wickLeftDev + wickDev / 2) / dpr
15344
15368
  };
15345
15369
  }
15370
+ function aggregateCandleColumns(bars, i0, i1, xOf, yOf) {
15371
+ const out = [];
15372
+ let col = NaN;
15373
+ let intervals = [];
15374
+ const flush = () => {
15375
+ if (intervals.length === 0) return;
15376
+ const merged = [intervals[0]];
15377
+ for (let k = 1; k < intervals.length; k += 1) {
15378
+ const prev2 = merged[merged.length - 1];
15379
+ const next = intervals[k];
15380
+ if (Math.abs(yOf(prev2.hi) - yOf(next.lo)) < 1) {
15381
+ prev2.hi = next.hi;
15382
+ if (next.headIdx < prev2.headIdx) {
15383
+ prev2.headIdx = next.headIdx;
15384
+ prev2.headTime = next.headTime;
15385
+ prev2.open = next.open;
15386
+ }
15387
+ if (next.lastIdx > prev2.lastIdx) {
15388
+ prev2.lastIdx = next.lastIdx;
15389
+ prev2.close = next.close;
15390
+ }
15391
+ } else {
15392
+ merged.push(next);
15393
+ }
15394
+ }
15395
+ for (const iv of merged) out.push({ x: col, hi: iv.hi, lo: iv.lo, headTime: iv.headTime, open: iv.open, close: iv.close });
15396
+ intervals = [];
15397
+ };
15398
+ for (let i = i0; i <= i1; i += 1) {
15399
+ const b = bars[i];
15400
+ if (!b || b.high <= b.low) continue;
15401
+ const x = Math.round(xOf(i));
15402
+ if (x !== col) {
15403
+ flush();
15404
+ col = x;
15405
+ }
15406
+ let lo = b.low;
15407
+ let hi = b.high;
15408
+ let headIdx = i;
15409
+ let headTime = b.time;
15410
+ let open2 = b.open;
15411
+ for (let k = intervals.length - 1; k >= 0; k -= 1) {
15412
+ const iv = intervals[k];
15413
+ if (iv.lo > hi || iv.hi < lo) continue;
15414
+ if (iv.lo < lo) lo = iv.lo;
15415
+ if (iv.hi > hi) hi = iv.hi;
15416
+ if (iv.headIdx < headIdx) {
15417
+ headIdx = iv.headIdx;
15418
+ headTime = iv.headTime;
15419
+ open2 = iv.open;
15420
+ }
15421
+ intervals.splice(k, 1);
15422
+ }
15423
+ let insertAt = 0;
15424
+ while (insertAt < intervals.length && intervals[insertAt].lo < lo) insertAt += 1;
15425
+ intervals.splice(insertAt, 0, { lo, hi, headIdx, headTime, open: open2, lastIdx: i, close: b.close });
15426
+ }
15427
+ flush();
15428
+ return out;
15429
+ }
15346
15430
 
15347
15431
  // src/renderers/native/core/chartConfig.ts
15348
15432
  var CHART_CONFIG_VERSION = 1;
@@ -15353,6 +15437,7 @@ var BASELINE_FILL_ALPHA_FAR = 0.05;
15353
15437
  var BASELINE_LEVEL_DEFAULT = 50;
15354
15438
  var PREMARKET_SHADE = withAlpha(WARNING, 0.08);
15355
15439
  var POSTMARKET_SHADE = withAlpha(ACCENT, 0.08);
15440
+ var EXTENDED_SHADE = POSTMARKET_SHADE;
15356
15441
  function defaultChartStyle() {
15357
15442
  return {
15358
15443
  chartTypes: {},
@@ -15361,7 +15446,7 @@ function defaultChartStyle() {
15361
15446
  gridHorz: { visible: true, color: null },
15362
15447
  borderColor: null,
15363
15448
  separatorColor: null,
15364
- crosshair: { color: CROSSHAIR, width: 1, style: "dashed", opacity: 0.4, labelBackground: SLATE },
15449
+ crosshair: { color: CROSSHAIR, width: 1, style: "dashed", opacity: 0.4, labelBackground: CHIP_PLATE },
15365
15450
  candle: {
15366
15451
  bodyVisible: true,
15367
15452
  borderVisible: false,
@@ -15384,7 +15469,7 @@ function defaultChartStyle() {
15384
15469
  width: 2,
15385
15470
  baselineLevel: BASELINE_LEVEL_DEFAULT
15386
15471
  },
15387
- sessions: { premarketColor: PREMARKET_SHADE, postmarketColor: POSTMARKET_SHADE }
15472
+ sessions: { premarketColor: PREMARKET_SHADE, postmarketColor: POSTMARKET_SHADE, extendedColor: EXTENDED_SHADE }
15388
15473
  };
15389
15474
  }
15390
15475
  var LINE_STYLES = ["solid", "dashed", "dotted"];
@@ -15613,7 +15698,8 @@ function mergeConfig(base, patch) {
15613
15698
  },
15614
15699
  sessions: {
15615
15700
  premarketColor: isColor(sessions.premarketColor) ? sessions.premarketColor : base.sessions.premarketColor,
15616
- postmarketColor: isColor(sessions.postmarketColor) ? sessions.postmarketColor : base.sessions.postmarketColor
15701
+ postmarketColor: isColor(sessions.postmarketColor) ? sessions.postmarketColor : base.sessions.postmarketColor,
15702
+ extendedColor: isColor(sessions.extendedColor) ? sessions.extendedColor : base.sessions.extendedColor
15617
15703
  },
15618
15704
  stacking: {
15619
15705
  candles: isNum(stacking.candles) ? stacking.candles : base.stacking.candles,
@@ -16598,44 +16684,19 @@ var WebGL2Backend = class {
16598
16684
  }
16599
16685
  }
16600
16686
  /**
16601
- * Sub-pixel LOD (mirrors Canvas2dBackend.drawCandlesAggregated): bucket bars
16602
- * sharing a rounded pixel column into one high-low stick draw cost bounded by
16603
- * screen width, not bar count. Bucket color follows first-open→last-close.
16687
+ * Sub-pixel LOD (mirrors Canvas2dBackend.drawCandlesAggregated): bars sharing a
16688
+ * rounded pixel column collapse into high-low sticks one per contiguous
16689
+ * coverage run (see {@link aggregateCandleColumns}), so a price gap inside the
16690
+ * column stays a void. Draw cost stays bounded by screen width, not bar count;
16691
+ * stick color follows its own first-open→last-close.
16604
16692
  */
16605
16693
  emitCandlesAggregated(b, bars, i0, i1, coords, pane, up, down, barColors) {
16606
- let px = NaN;
16607
- let lo = Infinity;
16608
- let hi = -Infinity;
16609
- let openV = 0;
16610
- let closeV = 0;
16611
- let headTime = 0;
16612
- let active = false;
16613
- const flush = () => {
16614
- if (!active) return;
16615
- const c = parseColor(barColors.get(headTime) ?? (closeV >= openV ? up : down));
16616
- const hY = coords.priceToY(hi, pane.scale, pane.bounds);
16617
- const lY = coords.priceToY(lo, pane.scale, pane.bounds);
16618
- b.rect(px - 0.5, hY, 1, lY - hY, c);
16619
- };
16620
- for (let i = i0; i <= i1; i += 1) {
16621
- const bar = bars[i];
16622
- if (!bar || bar.high <= bar.low) continue;
16623
- const x = Math.round(coords.logicalToX(i));
16624
- if (!active || x !== px) {
16625
- flush();
16626
- px = x;
16627
- lo = bar.low;
16628
- hi = bar.high;
16629
- openV = bar.open;
16630
- headTime = bar.time;
16631
- active = true;
16632
- } else {
16633
- if (bar.low < lo) lo = bar.low;
16634
- if (bar.high > hi) hi = bar.high;
16635
- }
16636
- closeV = bar.close;
16694
+ const yOf = (price) => coords.priceToY(price, pane.scale, pane.bounds);
16695
+ for (const s of aggregateCandleColumns(bars, i0, i1, (i) => coords.logicalToX(i), yOf)) {
16696
+ const c = parseColor(barColors.get(s.headTime) ?? (s.close >= s.open ? up : down));
16697
+ const hY = yOf(s.hi);
16698
+ b.rect(s.x - 0.5, hY, 1, yOf(s.lo) - hY, c);
16637
16699
  }
16638
- flush();
16639
16700
  }
16640
16701
  emitSeries(b, spec, pane, coords, i0, i1, theme, off = 0) {
16641
16702
  if (spec.kind === "candle" || spec.kind === "bar") {
@@ -17933,13 +17994,15 @@ var SceneGraph = class {
17933
17994
  if (!this.orderedCache) this.orderedCache = [...this.panes.values()].sort((a, b) => a.order - b.order);
17934
17995
  return this.orderedCache;
17935
17996
  }
17936
- /** The session zones resolved into colored bands (pre/post-market washes from the
17937
- * config's session colors) — consumed by the same painting path as {@link highlights}. */
17997
+ /** The session zones resolved into colored bands (pre/post-market or extended-hours
17998
+ * washes from the config's session colors) — consumed by the same painting path as
17999
+ * {@link highlights}. */
17938
18000
  sessionHighlightBands() {
17939
18001
  if (!this.sessionZones) return [];
17940
18002
  const out = [];
17941
18003
  for (const [from, to] of this.sessionZones.pre) out.push({ from, to, color: this.style.sessions.premarketColor });
17942
18004
  for (const [from, to] of this.sessionZones.post) out.push({ from, to, color: this.style.sessions.postmarketColor });
18005
+ for (const [from, to] of this.sessionZones.extended) out.push({ from, to, color: this.style.sessions.extendedColor });
17943
18006
  return out;
17944
18007
  }
17945
18008
  indicatorsForPane(paneId) {
@@ -18478,50 +18541,23 @@ var Canvas2dBackend = class {
18478
18541
  }
18479
18542
  }
18480
18543
  /**
18481
- * Sub-pixel LOD: bucket every bar sharing a rounded pixel column into ONE
18482
- * high-low stick, so draw cost is bounded by screen width (not bar count) when
18483
- * zoomed far out. The bucket's color follows its first-open→last-close
18484
- * direction (a barcolor() on the head bar still wins).
18544
+ * Sub-pixel LOD: bars sharing a rounded pixel column collapse into high-low
18545
+ * sticks (one per contiguous coverage run see {@link aggregateCandleColumns}),
18546
+ * so draw cost is bounded by screen width (not bar count) when zoomed far out
18547
+ * and a price gap inside the column stays a void. Each stick's color follows
18548
+ * its first-open→last-close direction (a barcolor() on the head bar still wins).
18485
18549
  */
18486
18550
  drawCandlesAggregated(ctx, bars, i0, i1, coords, pane, up, down, barColors) {
18487
- let px = NaN;
18488
- let lo = Infinity;
18489
- let hi = -Infinity;
18490
- let openV = 0;
18491
- let closeV = 0;
18492
- let headTime = 0;
18493
- let active = false;
18494
- const flush = () => {
18495
- if (!active) return;
18496
- const color = barColors.get(headTime) ?? (closeV >= openV ? up : down);
18497
- const hY = coords.priceToY(hi, pane.scale, pane.bounds);
18498
- const lY = coords.priceToY(lo, pane.scale, pane.bounds);
18499
- ctx.strokeStyle = color;
18500
- ctx.lineWidth = 1;
18551
+ const yOf = (price) => coords.priceToY(price, pane.scale, pane.bounds);
18552
+ ctx.lineWidth = 1;
18553
+ for (const s of aggregateCandleColumns(bars, i0, i1, (i) => coords.logicalToX(i), yOf)) {
18554
+ const x = s.x + 0.5;
18555
+ ctx.strokeStyle = barColors.get(s.headTime) ?? (s.close >= s.open ? up : down);
18501
18556
  ctx.beginPath();
18502
- ctx.moveTo(px, hY);
18503
- ctx.lineTo(px, lY);
18557
+ ctx.moveTo(x, yOf(s.hi));
18558
+ ctx.lineTo(x, yOf(s.lo));
18504
18559
  ctx.stroke();
18505
- };
18506
- for (let i = i0; i <= i1; i += 1) {
18507
- const b = bars[i];
18508
- if (!b || b.high <= b.low) continue;
18509
- const x = Math.round(coords.logicalToX(i)) + 0.5;
18510
- if (!active || x !== px) {
18511
- flush();
18512
- px = x;
18513
- lo = b.low;
18514
- hi = b.high;
18515
- openV = b.open;
18516
- headTime = b.time;
18517
- active = true;
18518
- } else {
18519
- if (b.low < lo) lo = b.low;
18520
- if (b.high > hi) hi = b.high;
18521
- }
18522
- closeV = b.close;
18523
18560
  }
18524
- flush();
18525
18561
  }
18526
18562
  drawSeries(ctx, spec, pane, coords, i0, i1, theme, off = 0) {
18527
18563
  if (spec.kind === "candle" || spec.kind === "bar") {
@@ -19545,6 +19581,32 @@ var DrawingSceneRenderer = class {
19545
19581
  }
19546
19582
  };
19547
19583
 
19584
+ // src/renderers/native/chrome/tz.ts
19585
+ function tzOffsetMs(ms, timeZone) {
19586
+ if (!timeZone || timeZone === "UTC") return 0;
19587
+ try {
19588
+ const dtf = new Intl.DateTimeFormat("en-US", {
19589
+ timeZone,
19590
+ hourCycle: "h23",
19591
+ year: "numeric",
19592
+ month: "2-digit",
19593
+ day: "2-digit",
19594
+ hour: "2-digit",
19595
+ minute: "2-digit",
19596
+ second: "2-digit"
19597
+ });
19598
+ const parts = dtf.formatToParts(new Date(ms));
19599
+ const get = (t) => Number(parts.find((p) => p.type === t)?.value);
19600
+ const asUTC = Date.UTC(get("year"), get("month") - 1, get("day"), get("hour") % 24, get("minute"), get("second"));
19601
+ return asUTC - ms;
19602
+ } catch {
19603
+ return 0;
19604
+ }
19605
+ }
19606
+ function zonedDate(ms, timeZone) {
19607
+ return new Date(ms + tzOffsetMs(ms, timeZone));
19608
+ }
19609
+
19548
19610
  // src/renderers/native/chrome/ticks.ts
19549
19611
  function priceTicks(min, max, target = 6) {
19550
19612
  if (!(max > min) || !Number.isFinite(min) || !Number.isFinite(max)) return [];
@@ -19692,7 +19754,14 @@ var STEP_LADDER = [
19692
19754
  YEAR
19693
19755
  ];
19694
19756
  var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
19757
+ var WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
19695
19758
  var pad2 = (n) => n < 10 ? `0${n}` : String(n);
19759
+ function formatTimeStamp(ms, timeZone, barIntervalMs) {
19760
+ const d = zonedDate(ms, timeZone);
19761
+ const date = `${WEEKDAYS[d.getUTCDay()]} ${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]} '${pad2(d.getUTCFullYear() % 100)}`;
19762
+ if (barIntervalMs >= DAY) return date;
19763
+ return `${date} ${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())}`;
19764
+ }
19696
19765
  function pickStep(targetMs) {
19697
19766
  for (const step of STEP_LADDER) if (step >= targetMs) return step;
19698
19767
  return STEP_LADDER[STEP_LADDER.length - 1];
@@ -19734,32 +19803,6 @@ function timeTicks(fromMs, toMs, target = 8, offsetMs = 0) {
19734
19803
  return out;
19735
19804
  }
19736
19805
 
19737
- // src/renderers/native/chrome/tz.ts
19738
- function tzOffsetMs(ms, timeZone) {
19739
- if (!timeZone || timeZone === "UTC") return 0;
19740
- try {
19741
- const dtf = new Intl.DateTimeFormat("en-US", {
19742
- timeZone,
19743
- hourCycle: "h23",
19744
- year: "numeric",
19745
- month: "2-digit",
19746
- day: "2-digit",
19747
- hour: "2-digit",
19748
- minute: "2-digit",
19749
- second: "2-digit"
19750
- });
19751
- const parts = dtf.formatToParts(new Date(ms));
19752
- const get = (t) => Number(parts.find((p) => p.type === t)?.value);
19753
- const asUTC = Date.UTC(get("year"), get("month") - 1, get("day"), get("hour") % 24, get("minute"), get("second"));
19754
- return asUTC - ms;
19755
- } catch {
19756
- return 0;
19757
- }
19758
- }
19759
- function zonedDate(ms, timeZone) {
19760
- return new Date(ms + tzOffsetMs(ms, timeZone));
19761
- }
19762
-
19763
19806
  // src/renderers/native/chrome/ChromeRenderer.ts
19764
19807
  var ChromeRenderer = class {
19765
19808
  constructor() {
@@ -20206,7 +20249,7 @@ var CrosshairRenderer = class {
20206
20249
  const price = coords.yToPrice(ch.y, pane.scale, pane.bounds);
20207
20250
  this.chip(ctx, dataW + 1, ch.y, formatAxisValue(pane.scale, pane.bounds.height, price, percentScaleFor(scene, pane), scene.priceMintick, pane.axisFormat), chipBg, "left", false, theme.background);
20208
20251
  }
20209
- this.chip(ctx, x, dataH + 1, formatStamp(coords.logicalToTime(logical), scene.timezone), chipBg, "center", true, theme.background);
20252
+ this.chip(ctx, x, dataH + 1, formatTimeStamp(coords.logicalToTime(logical), scene.timezone, coords.barInterval), chipBg, "center", true, theme.background);
20210
20253
  }
20211
20254
  destroy() {
20212
20255
  this.canvas = null;
@@ -20254,7 +20297,7 @@ var CrosshairRenderer = class {
20254
20297
  this.chip(ctx, dataW + 1, ext.y, formatAxisValue(pane.scale, pane.bounds.height, ext.price, percentScaleFor(scene, pane), scene.priceMintick, pane.axisFormat), chipBg, "left", false, theme.background);
20255
20298
  }
20256
20299
  }
20257
- this.chip(ctx, x, dataH + 1, formatStamp(ext.time, scene.timezone), chipBg, "center", true, theme.background);
20300
+ this.chip(ctx, x, dataH + 1, formatTimeStamp(ext.time, scene.timezone, coords.barInterval), chipBg, "center", true, theme.background);
20258
20301
  ctx.globalAlpha = 1;
20259
20302
  }
20260
20303
  /** A soft band + a brighter crisp center line over the hovered separator, so it reads as
@@ -20287,11 +20330,6 @@ function setDash3(ctx, style) {
20287
20330
  else if (style === "dotted") ctx.setLineDash([2, 3]);
20288
20331
  else ctx.setLineDash([]);
20289
20332
  }
20290
- function formatStamp(ms, timeZone) {
20291
- const d = zonedDate(ms, timeZone);
20292
- const pad = (n) => n < 10 ? `0${n}` : String(n);
20293
- return `${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`;
20294
- }
20295
20333
 
20296
20334
  // src/core/timezones.ts
20297
20335
  var TIMEZONES = [
@@ -26780,6 +26818,9 @@ function clipHighlightRect(x1, x2, left, right) {
26780
26818
  const end = Math.min(right, x2);
26781
26819
  return end > x ? { x, width: end - x } : null;
26782
26820
  }
26821
+ function bandEdgeSlot(logical) {
26822
+ return Math.ceil(logical) - 0.5;
26823
+ }
26783
26824
  var BackdropRenderer = class {
26784
26825
  constructor() {
26785
26826
  this.canvas = null;
@@ -26810,21 +26851,22 @@ var BackdropRenderer = class {
26810
26851
  this.drawGrid(ctx, scene, coords, theme, coords.width, gridAlpha);
26811
26852
  }
26812
26853
  /** Renderer-owned session highlight bands: full-height (all panes), behind the grid.
26813
- * Session-zone washes (pre/post-market) paint first, host highlights on top. */
26854
+ * Session-zone washes paint first (edges snapped to bar-slot boundaries so a band
26855
+ * never cuts a candle in two), host highlights on top (continuous time mapping —
26856
+ * hosts may paint sub-bar spans). */
26814
26857
  drawHighlights(ctx, scene, coords) {
26815
26858
  const sessions = scene.sessionHighlightBands();
26816
26859
  if (sessions.length > 0) {
26817
26860
  const left = Math.max(0, coords.logicalToX(-0.5));
26818
26861
  const right = Math.min(coords.width, coords.logicalToX(coords.barCount - 0.5));
26819
- this.drawHighlightSet(ctx, sessions, coords, left, right);
26862
+ this.drawHighlightSet(ctx, sessions, coords, left, right, true);
26820
26863
  }
26821
- this.drawHighlightSet(ctx, scene.highlights, coords, 0, coords.width);
26864
+ this.drawHighlightSet(ctx, scene.highlights, coords, 0, coords.width, false);
26822
26865
  }
26823
- drawHighlightSet(ctx, bands, coords, left, right) {
26866
+ drawHighlightSet(ctx, bands, coords, left, right, snapToSlots) {
26867
+ const edgeX = (ms) => snapToSlots ? coords.logicalToX(bandEdgeSlot(coords.timeToLogical(ms))) : coords.timeToX(ms);
26824
26868
  for (const band of bands) {
26825
- const x1 = coords.timeToX(band.from);
26826
- const x2 = coords.timeToX(band.to);
26827
- const rect = clipHighlightRect(x1, x2, left, right);
26869
+ const rect = clipHighlightRect(edgeX(band.from), edgeX(band.to), left, right);
26828
26870
  if (!rect) continue;
26829
26871
  ctx.fillStyle = band.color;
26830
26872
  ctx.fillRect(rect.x, 0, rect.width, coords.height);
@@ -27083,6 +27125,7 @@ function createCustomMark(doc, html, background) {
27083
27125
  });
27084
27126
  el.style.color = attributionMarkColor(background);
27085
27127
  el.innerHTML = html;
27128
+ el.dataset.velaScreenshot = "1";
27086
27129
  return el;
27087
27130
  }
27088
27131
  function createAttributionMark(doc, background) {
@@ -27101,6 +27144,7 @@ function createAttributionMark(doc, background) {
27101
27144
  cursor: "pointer"
27102
27145
  });
27103
27146
  applyAttributionMarkTheme(a, background);
27147
+ a.dataset.velaScreenshot = "1";
27104
27148
  const symbol = doc.createElement("span");
27105
27149
  symbol.className = "vela-attr-symbol";
27106
27150
  symbol.setAttribute("aria-hidden", "true");
@@ -28105,7 +28149,7 @@ var NativeRenderer = class {
28105
28149
  };
28106
28150
  })(),
28107
28151
  series: { style: this.scene.priceStyle, baseline: this.scene.baselineValue, spacing: this.coords.spacingScale },
28108
- sessions: { premarketColor: s.sessions.premarketColor, postmarketColor: s.sessions.postmarketColor }
28152
+ sessions: { premarketColor: s.sessions.premarketColor, postmarketColor: s.sessions.postmarketColor, extendedColor: s.sessions.extendedColor }
28109
28153
  };
28110
28154
  }
28111
28155
  /**
@@ -28187,7 +28231,7 @@ var NativeRenderer = class {
28187
28231
  width: next.baseline.width,
28188
28232
  baselineLevel: next.baseline.baselineLevel
28189
28233
  };
28190
- s.sessions = { premarketColor: next.sessions.premarketColor, postmarketColor: next.sessions.postmarketColor };
28234
+ s.sessions = { premarketColor: next.sessions.premarketColor, postmarketColor: next.sessions.postmarketColor, extendedColor: next.sessions.extendedColor };
28191
28235
  this.setPriceStyle(next.series.style);
28192
28236
  this.scene.candleOverride = candleOverrideFor(this.scene.priceStyle, s.chartTypes);
28193
28237
  this.scene.baselineValue = next.series.baseline;
@@ -28409,9 +28453,10 @@ var NativeRenderer = class {
28409
28453
  * opts in with a `data-vela-screenshot` attribute on the mount container's
28410
28454
  * subtree (the widget marks its status line, and its symbol watermark with
28411
28455
  * `"under"` — drawn beneath the canvases, where it sits on screen). Only the
28412
- * crosshair (L2) is intentionally excluded.
28456
+ * crosshair (L2) is intentionally excluded. {@link screenshot} is this canvas
28457
+ * as a PNG data URL.
28413
28458
  */
28414
- screenshot() {
28459
+ screenshotCanvas() {
28415
28460
  if (!this.dataCanvas) return null;
28416
28461
  this.computeScales();
28417
28462
  this.paintData();
@@ -28439,7 +28484,10 @@ var NativeRenderer = class {
28439
28484
  if (el.getAttribute("data-vela-screenshot") !== "under") rasterizeOverlay(ctx, el, frame);
28440
28485
  }
28441
28486
  }
28442
- return out.toDataURL("image/png");
28487
+ return out;
28488
+ }
28489
+ screenshot() {
28490
+ return this.screenshotCanvas()?.toDataURL("image/png") ?? null;
28443
28491
  }
28444
28492
  /**
28445
28493
  * The candles-first-appear reveal — animates the **candles themselves** (no extra
@@ -29834,7 +29882,7 @@ var NativeRenderer = class {
29834
29882
  const pricePane = this.dataWindowPricePane();
29835
29883
  const ohlc = this.dataWindowOHLC(bar, pricePane);
29836
29884
  const parts = [];
29837
- if (bar) parts.push(formatStamp2(bar.time, this.scene.timezone));
29885
+ if (bar) parts.push(formatStamp(bar.time, this.scene.timezone));
29838
29886
  if (ohlc) parts.push(`Open ${ohlc.o}, High ${ohlc.h}, Low ${ohlc.l}, Close ${ohlc.c}`);
29839
29887
  for (const group of this.dataWindowGroups(idx, pricePane)) {
29840
29888
  for (const row of group.rows) parts.push(`${row.label} ${row.value}`);
@@ -30721,7 +30769,7 @@ function formatStampParts(ms, timeZone) {
30721
30769
  time: `${p(d.getUTCHours())}:${p(d.getUTCMinutes())}`
30722
30770
  };
30723
30771
  }
30724
- function formatStamp2(ms, timeZone) {
30772
+ function formatStamp(ms, timeZone) {
30725
30773
  const { date, time } = formatStampParts(ms, timeZone);
30726
30774
  return `${date} ${time}`;
30727
30775
  }
@@ -30752,7 +30800,7 @@ function sanitizeSessionZones(value) {
30752
30800
  }
30753
30801
  return out.sort((a, b) => a[0] - b[0]);
30754
30802
  };
30755
- return { pre: windows(v.pre), post: windows(v.post) };
30803
+ return { pre: windows(v.pre), post: windows(v.post), extended: windows(v.extended) };
30756
30804
  }
30757
30805
  function clamp012(v) {
30758
30806
  return Math.max(0, Math.min(1, v));
@@ -31429,6 +31477,7 @@ exports.BEARISH = BEARISH;
31429
31477
  exports.BULLISH = BULLISH;
31430
31478
  exports.BarStore = BarStore;
31431
31479
  exports.CATEGORICAL = CATEGORICAL;
31480
+ exports.CHIP_PLATE = CHIP_PLATE;
31432
31481
  exports.CROSSHAIR = CROSSHAIR;
31433
31482
  exports.CachingDataFeed = CachingDataFeed;
31434
31483
  exports.DARK_THEME = DARK_THEME;
package/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
1
- import { D as DrawingsDocument, R as Resolved } from './contributions-lPojhTxI.cjs';
2
- export { B as BarsChangeReason, C as CellStateContext, b as ContextSelect, c as DataControl, d as DrawingsControl, e as EngineAlert, f as EngineCapabilities, g as EngineContextSnapshot, h as EngineFactory, i as EngineWarning, j as ExecutionHandlers, k as ExecutionMarket, l as ExecutionRequest, m as ExecutionSession, E as ExternalIndicatorEntry, F as FetchSeries, n as IndicatorEventMap, I as IndicatorHandle, o as IndicatorSummary, L as LegendActionDescriptor, p as LegendCalloutContent, q as LegendCalloutDescriptor, r as LegendCalloutItem, s as LegendCalloutSpec, t as LegendIndicatorInfo, N as NativeIndicator, u as NativeIndicatorContext, v as NativeIndicatorDescriptor, w as NativeIndicatorInfo, x as NativeIndicatorOutput, O as OVERRIDABLE_TOPBAR_IDS, P as ParsedSymbol, y as PreparedScript, z as RendererControl, A as RunIndicatorResult, G as SceneInspection, a as ScriptRun, H as ScriptRunCause, J as ScriptRunResult, S as ScriptingEngine, K as SidePanelButton, M as SidePanelDescriptor, Q as SidePanelHandle, T as SidePanelHeader, U as StatePersistenceHandler, X as StrategyFill, Y as StrategyState, Z as StrategyTrade, _ as SymbolRankingHook, $ as TypedEventBus, V as Vela, a0 as VelaDeps, a1 as VelaEventMap, a2 as VisibleBarRange, a3 as WidgetActionDescriptor, a4 as WidgetActionTarget, a5 as WidgetAttachment, W as WidgetContext, a6 as getNativeIndicator, a7 as legendActions, a8 as legendCallouts, a9 as nativeIndicatorDescriptors, aa as nativeIndicatorTypes, ab as registerDefaultEngine, ac as registerLegendAction, ad as registerLegendCallout, ae as registerNativeIndicator, af as registerSidePanel, ag as registerStatePersistence, ah as registerSymbolRanking, ai as registerWidgetAction, aj as registerWidgetAttachment, ak as resolveEngines, al as sidePanels, am as statePersistenceHandlers, an as symbolRanking, ao as topbarActionOverride, ap as unregisterDefaultEngine, aq as unregisterLegendAction, ar as unregisterLegendCallout, as as unregisterNativeIndicator, at as unregisterSidePanel, au as unregisterStatePersistence, av as unregisterWidgetAction, aw as unregisterWidgetAttachment, ax as widgetActions, ay as widgetAttachments } from './contributions-lPojhTxI.cjs';
3
- import { D as Drawing, S as SerializedDrawing, U as Unsubscribe, L as LineStyle, P as PriceStyle, e as IChartRenderer, R as RendererCapabilities, f as RendererDisplayOptions, g as IndicatorRenderHandle, h as IndicatorStatus, c as VelaTheme, O as OHLCV, i as Pane, j as PaneAction, k as MoveTarget, l as IndicatorModel, m as ScenePatch, I as InputValue, n as SymbolPickerFn, o as LegendActionView, p as LegendCalloutView, q as InputChangeEvent, T as ThemeName, C as CrosshairEvent, r as ClickEvent, A as AxisLongPressEvent, a as VisibleRange, s as DataWindowReadout, t as IDrawingsRendererPort, u as Millis, v as SnapMode, w as DrawingTypeKey, x as ToolbarDefinition, M as MarketConfig } from './options-CYS5Wmlx.cjs';
4
- export { y as AddIndicatorOptions, B as Background, z as BoxFontFamily, E as BoxHAlign, F as BoxTextSize, G as BoxVAlign, H as CandleBarColor, J as CandleSeries, K as CandleStyle, Q as DataWindowGroup, W as DataWindowOHLC, X as DataWindowRow, Y as DirtyRange, Z as DrawingBox, _ as DrawingExtend, $ as DrawingIntent, a0 as DrawingLabel, a1 as DrawingLine, a2 as DrawingLinefill, a3 as DrawingMode, a4 as DrawingPoint, a5 as DrawingPolyline, a6 as DrawingSeriesBar, a7 as DrawingSeriesGateway, a8 as DrawingSeriesState, a9 as DrawingStyle, aa as DrawingTable, ab as DrawingText, ac as DrawingXLoc, ad as DrawingsOption, ae as Fill, af as FillGradientStop, ag as IndicatorMeta, ah as InputCondition, ai as InputSchema, aj as InputType, ak as InputWhen, al as LabelStyle, am as LabelYLoc, an as LineLikeKind, ao as LineLikeSeries, ap as LineLikeStyle, aq as MarkerPoint, ar as MarkerSeries, as as MarketSnapshot, at as MarketSwitch, au as PaneAxis, av as PaneAxisBand, aw as PaneHint, ax as PaneKind, ay as PolylinePoint, az as PriceLine, aA as Projector, aB as ProviderName, aC as RendererConstructor, aD as Scene, aE as SchemaPatch, aF as SeriesKind, aG as SeriesPoint, aH as SeriesSpec, aI as SeriesValueDelta, aJ as SettingsField, aK as SettingsSchema, aL as SettingsVisibilityPolicy, aM as TableCell, aN as TableMerge, aO as TablePosition, aP as ToolbarGroupConfig, aQ as TradeExecution, aR as ValuePatch, b as VelaOptions, V as VisibleRangePreset, aS as buildToolbar, aT as defaultToolbar, aU as inputDeltas, aV as inputVisible } from './options-CYS5Wmlx.cjs';
5
- import { M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, S as SymbolInfo, b as ProviderCapabilities, B as BarRange } from './DataProvider-DlMtrwqM.cjs';
6
- export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CROSSHAIR, f as ChartTypeDefinition, g as ChartTypeSettingsInstance, h as ChartTypeSettingsSection, i as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, j as INVALID, k as IdentifiableKind, M as MARKER, N as NEUTRAL, l as NormalizedSettingsRow, R as RendererLayerArgs, m as RendererLayerDefinition, n as RendererLayerInstance, S as SERIES_LINE, o as SESSION_OFF, p as SESSION_POST, q as SESSION_PRE, r as SLATE, s as SLATE_DEEP, t as SeriesDataEngine, u as SeriesDataEngineHost, v as SettingsInlineControl, w as SettingsRowCondition, x as SettingsRowDescriptor, y as SettingsRowInlineNumber, z as SettingsRowSwatch, E as SettingsRowValueKey, F as SettingsRowWhen, G as SettingsRowWidth, J as SettingsSelectOption, K as SettingsValueRow, T as TRADE_EXIT, L as TRADE_LONG, O as TRADE_SHORT, V as VALID, W as WARNING, P as categoricalColor, Q as chartType, U as chartTypes, X as createDrawing, Y as deserializeDrawing, Z as drawingTypes, _ as getDrawingType, $ as normalizeSettingsRow, a0 as registerChartType, a1 as registerDrawingType, a2 as registerRendererDefaults, a3 as registerRendererLayer, a4 as rendererDefaults, a5 as rendererLayers, a6 as settingsRowValueKeys, a7 as stableSeriesId, a8 as tickerModifierIds, a9 as unregisterChartType, aa as unregisterRendererDefaults, ab as unregisterRendererLayer } from './plugin-Cwikpz1m.cjs';
7
- export { D as DEFAULT_PANEL_MAX_WIDTH, a as DEFAULT_PANEL_MIN_WIDTH, b as DEFAULT_PANEL_WIDTH, S as SidePanelOptions, c as clampPanelWidth } from './side-panel-CT9ZwIGz.cjs';
1
+ import { D as DrawingsDocument, R as Resolved } from './contributions-x7iamlnd.cjs';
2
+ export { B as BarsChangeReason, C as CellStateContext, b as ContextSelect, c as DataControl, d as DrawingsControl, e as EngineAlert, f as EngineCapabilities, g as EngineContextSnapshot, h as EngineFactory, i as EngineWarning, j as ExecutionHandlers, k as ExecutionMarket, l as ExecutionRequest, m as ExecutionSession, E as ExternalIndicatorEntry, F as FetchSeries, n as IndicatorEventMap, I as IndicatorHandle, o as IndicatorSummary, L as LegendActionDescriptor, p as LegendCalloutContent, q as LegendCalloutDescriptor, r as LegendCalloutItem, s as LegendCalloutSpec, t as LegendIndicatorInfo, N as NativeIndicator, u as NativeIndicatorContext, v as NativeIndicatorDescriptor, w as NativeIndicatorInfo, x as NativeIndicatorOutput, O as OVERRIDABLE_TOPBAR_IDS, P as ParsedSymbol, y as PreparedScript, z as RendererControl, A as RunIndicatorResult, G as SceneInspection, a as ScriptRun, H as ScriptRunCause, J as ScriptRunResult, S as ScriptingEngine, K as SidePanelButton, M as SidePanelDescriptor, Q as SidePanelHandle, T as SidePanelHeader, U as StatePersistenceHandler, X as StrategyFill, Y as StrategyState, Z as StrategyTrade, _ as SymbolRankingHook, $ as TypedEventBus, V as Vela, a0 as VelaDeps, a1 as VelaEventMap, a2 as VisibleBarRange, a3 as WidgetActionDescriptor, a4 as WidgetActionTarget, a5 as WidgetAttachment, W as WidgetContext, a6 as getNativeIndicator, a7 as legendActions, a8 as legendCallouts, a9 as nativeIndicatorDescriptors, aa as nativeIndicatorTypes, ab as registerDefaultEngine, ac as registerLegendAction, ad as registerLegendCallout, ae as registerNativeIndicator, af as registerSidePanel, ag as registerStatePersistence, ah as registerSymbolRanking, ai as registerWidgetAction, aj as registerWidgetAttachment, ak as resolveEngines, al as sidePanels, am as statePersistenceHandlers, an as symbolRanking, ao as topbarActionOverride, ap as unregisterDefaultEngine, aq as unregisterLegendAction, ar as unregisterLegendCallout, as as unregisterNativeIndicator, at as unregisterSidePanel, au as unregisterStatePersistence, av as unregisterWidgetAction, aw as unregisterWidgetAttachment, ax as widgetActions, ay as widgetAttachments } from './contributions-x7iamlnd.cjs';
3
+ import { D as Drawing, S as SerializedDrawing, U as Unsubscribe, L as LineStyle, P as PriceStyle, e as IChartRenderer, R as RendererCapabilities, f as RendererDisplayOptions, g as IndicatorRenderHandle, h as IndicatorStatus, c as VelaTheme, O as OHLCV, i as Pane, j as PaneAction, k as MoveTarget, l as IndicatorModel, m as ScenePatch, I as InputValue, n as SymbolPickerFn, o as LegendActionView, p as LegendCalloutView, q as InputChangeEvent, T as ThemeName, C as CrosshairEvent, r as ClickEvent, A as AxisLongPressEvent, a as VisibleRange, s as DataWindowReadout, t as IDrawingsRendererPort, u as Millis, v as SnapMode, w as DrawingTypeKey, x as ToolbarDefinition, M as MarketConfig } from './options-bdSAtp7y.cjs';
4
+ export { y as AddIndicatorOptions, B as Background, z as BoxFontFamily, E as BoxHAlign, F as BoxTextSize, G as BoxVAlign, H as CandleBarColor, J as CandleSeries, K as CandleStyle, Q as DataWindowGroup, W as DataWindowOHLC, X as DataWindowRow, Y as DirtyRange, Z as DrawingBox, _ as DrawingExtend, $ as DrawingIntent, a0 as DrawingLabel, a1 as DrawingLine, a2 as DrawingLinefill, a3 as DrawingMode, a4 as DrawingPoint, a5 as DrawingPolyline, a6 as DrawingSeriesBar, a7 as DrawingSeriesGateway, a8 as DrawingSeriesState, a9 as DrawingStyle, aa as DrawingTable, ab as DrawingText, ac as DrawingXLoc, ad as DrawingsOption, ae as Fill, af as FillGradientStop, ag as IndicatorMeta, ah as InputCondition, ai as InputSchema, aj as InputType, ak as InputWhen, al as LabelStyle, am as LabelYLoc, an as LineLikeKind, ao as LineLikeSeries, ap as LineLikeStyle, aq as MarkerPoint, ar as MarkerSeries, as as MarketSnapshot, at as MarketSwitch, au as PaneAxis, av as PaneAxisBand, aw as PaneHint, ax as PaneKind, ay as PolylinePoint, az as PriceLine, aA as Projector, aB as ProviderName, aC as RendererConstructor, aD as Scene, aE as SchemaPatch, aF as SeriesKind, aG as SeriesPoint, aH as SeriesSpec, aI as SeriesValueDelta, aJ as SettingsField, aK as SettingsSchema, aL as SettingsVisibilityPolicy, aM as TableCell, aN as TableMerge, aO as TablePosition, aP as ToolbarGroupConfig, aQ as TradeExecution, aR as ValuePatch, b as VelaOptions, V as VisibleRangePreset, aS as buildToolbar, aT as defaultToolbar, aU as inputDeltas, aV as inputVisible } from './options-bdSAtp7y.cjs';
5
+ import { M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, S as SymbolInfo, b as ProviderCapabilities, B as BarRange } from './DataProvider-xH2VBcFT.cjs';
6
+ export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CHIP_PLATE, f as CROSSHAIR, g as ChartTypeDefinition, h as ChartTypeSettingsInstance, i as ChartTypeSettingsSection, j as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, k as INVALID, l as IdentifiableKind, M as MARKER, N as NEUTRAL, m as NormalizedSettingsRow, R as RendererLayerArgs, n as RendererLayerDefinition, o as RendererLayerInstance, S as SERIES_LINE, p as SESSION_OFF, q as SESSION_POST, r as SESSION_PRE, s as SLATE, t as SLATE_DEEP, u as SeriesDataEngine, v as SeriesDataEngineHost, w as SettingsInlineControl, x as SettingsRowCondition, y as SettingsRowDescriptor, z as SettingsRowInlineNumber, E as SettingsRowSwatch, F as SettingsRowValueKey, G as SettingsRowWhen, J as SettingsRowWidth, K as SettingsSelectOption, L as SettingsValueRow, T as TRADE_EXIT, O as TRADE_LONG, P as TRADE_SHORT, V as VALID, W as WARNING, Q as categoricalColor, U as chartType, X as chartTypes, Y as createDrawing, Z as deserializeDrawing, _ as drawingTypes, $ as getDrawingType, a0 as normalizeSettingsRow, a1 as registerChartType, a2 as registerDrawingType, a3 as registerRendererDefaults, a4 as registerRendererLayer, a5 as rendererDefaults, a6 as rendererLayers, a7 as settingsRowValueKeys, a8 as stableSeriesId, a9 as tickerModifierIds, aa as unregisterChartType, ab as unregisterRendererDefaults, ac as unregisterRendererLayer } from './plugin-2sJcf5mk.cjs';
7
+ export { D as DEFAULT_PANEL_MAX_WIDTH, a as DEFAULT_PANEL_MIN_WIDTH, b as DEFAULT_PANEL_WIDTH, S as SidePanelOptions, c as clampPanelWidth } from './side-panel-HF0IAzwf.cjs';
8
8
  export { i as iconMarkup, r as registerIcon } from './icons-BZYbJXSV.cjs';
9
9
  export { a as KeyBindingDescriptor, R as ResolvedBinding } from './keymap-CGOz5F5f.cjs';
10
10
 
@@ -129,11 +129,14 @@ interface BaselineSeriesStyle {
129
129
  /** Baseline position as a percent of the visible pane price range (0 = low, 100 = high). */
130
130
  baselineLevel: number;
131
131
  }
132
- /** Session-zone shading (the `sessionZones` feature): the wash painted over
133
- * pre-market and post-market time bands. Alpha belongs in the color itself. */
132
+ /** Session-zone shading (the `sessionZones` feature): the washes painted over
133
+ * pre-market and post-market time bands on day-split tapes, and the single
134
+ * extended-hours band on overnight roll tapes. Alpha belongs in the
135
+ * color itself. */
134
136
  interface SessionShadeStyle {
135
137
  premarketColor: string;
136
138
  postmarketColor: string;
139
+ extendedColor: string;
137
140
  }
138
141
  interface ChartStyle {
139
142
  /** Per-chart-type settings (plugin SDK sections), keyed by type id then row key. */
@@ -256,11 +259,14 @@ interface ChartConfig {
256
259
  * center-to-center pitch (and the crosshair step) without changing body width. 1 = default. */
257
260
  spacing: number;
258
261
  };
259
- /** Session-zone shading — the washes painted over the pre/post-market bands a host
260
- * pushes through the `sessionZones` feature (no bands the colors are dormant). */
262
+ /** Session-zone shading — the washes painted over the session bands a host pushes
263
+ * through the `sessionZones` feature: pre/post-market on day-split tapes, the
264
+ * single extended-hours phase on overnight roll tapes (no bands ⇒ the colors are
265
+ * dormant). */
261
266
  sessions: {
262
267
  premarketColor: string;
263
268
  postmarketColor: string;
269
+ extendedColor: string;
264
270
  };
265
271
  /** Draw-order keys — what paints in front of what. The candles' own key plus one per
266
272
  * indicator id; user drawings persist their keys in the drawings document, in the same
@@ -575,8 +581,10 @@ declare class NativeRenderer implements IChartRenderer {
575
581
  * opts in with a `data-vela-screenshot` attribute on the mount container's
576
582
  * subtree (the widget marks its status line, and its symbol watermark with
577
583
  * `"under"` — drawn beneath the canvases, where it sits on screen). Only the
578
- * crosshair (L2) is intentionally excluded.
584
+ * crosshair (L2) is intentionally excluded. {@link screenshot} is this canvas
585
+ * as a PNG data URL.
579
586
  */
587
+ screenshotCanvas(): HTMLCanvasElement | null;
580
588
  screenshot(): string | null;
581
589
  /**
582
590
  * The candles-first-appear reveal — animates the **candles themselves** (no extra