@luxalgo/vela 0.6.14 → 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-64TF7JAJ.js → chunk-7C7NWEXH.js} +345 -148
  8. package/dist/{chunk-N2Q5EEFH.js → chunk-J5QIR2Z3.js} +163 -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 +174 -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 +174 -127
  40. package/dist/vela.global.min.js +52 -46
  41. package/dist/widget.cjs +585 -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 +585 -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"/>'));
@@ -9296,6 +9303,15 @@ var RendererControl = class {
9296
9303
  console.warn(`[vela] renderer "${this.renderer.name}" does not support screenshot().`);
9297
9304
  return null;
9298
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
+ }
9299
9315
  /**
9300
9316
  * The active renderer's full cosmetic config as a serializable, versioned JSON
9301
9317
  * document — persist it (templates, saved settings) and feed it back to
@@ -10914,6 +10930,12 @@ ${STATIC_DECLS}
10914
10930
  .vela-ui *, .vela-ui-layer * { box-sizing: border-box; }
10915
10931
  /* Text ENTRY is the one exception: selection is part of editing. */
10916
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; }
10917
10939
  .vela-icon { display: inline-flex; align-items: center; flex: none; }
10918
10940
  .vela-icon svg { display: block; }
10919
10941
  `;
@@ -15345,6 +15367,66 @@ function candleGeometry(xCss, spacing, dpr, bodyScale = 1) {
15345
15367
  center: (wickLeftDev + wickDev / 2) / dpr
15346
15368
  };
15347
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
+ }
15348
15430
 
15349
15431
  // src/renderers/native/core/chartConfig.ts
15350
15432
  var CHART_CONFIG_VERSION = 1;
@@ -15355,6 +15437,7 @@ var BASELINE_FILL_ALPHA_FAR = 0.05;
15355
15437
  var BASELINE_LEVEL_DEFAULT = 50;
15356
15438
  var PREMARKET_SHADE = withAlpha(WARNING, 0.08);
15357
15439
  var POSTMARKET_SHADE = withAlpha(ACCENT, 0.08);
15440
+ var EXTENDED_SHADE = POSTMARKET_SHADE;
15358
15441
  function defaultChartStyle() {
15359
15442
  return {
15360
15443
  chartTypes: {},
@@ -15363,7 +15446,7 @@ function defaultChartStyle() {
15363
15446
  gridHorz: { visible: true, color: null },
15364
15447
  borderColor: null,
15365
15448
  separatorColor: null,
15366
- 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 },
15367
15450
  candle: {
15368
15451
  bodyVisible: true,
15369
15452
  borderVisible: false,
@@ -15386,7 +15469,7 @@ function defaultChartStyle() {
15386
15469
  width: 2,
15387
15470
  baselineLevel: BASELINE_LEVEL_DEFAULT
15388
15471
  },
15389
- sessions: { premarketColor: PREMARKET_SHADE, postmarketColor: POSTMARKET_SHADE }
15472
+ sessions: { premarketColor: PREMARKET_SHADE, postmarketColor: POSTMARKET_SHADE, extendedColor: EXTENDED_SHADE }
15390
15473
  };
15391
15474
  }
15392
15475
  var LINE_STYLES = ["solid", "dashed", "dotted"];
@@ -15615,7 +15698,8 @@ function mergeConfig(base, patch) {
15615
15698
  },
15616
15699
  sessions: {
15617
15700
  premarketColor: isColor(sessions.premarketColor) ? sessions.premarketColor : base.sessions.premarketColor,
15618
- 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
15619
15703
  },
15620
15704
  stacking: {
15621
15705
  candles: isNum(stacking.candles) ? stacking.candles : base.stacking.candles,
@@ -16600,44 +16684,19 @@ var WebGL2Backend = class {
16600
16684
  }
16601
16685
  }
16602
16686
  /**
16603
- * Sub-pixel LOD (mirrors Canvas2dBackend.drawCandlesAggregated): bucket bars
16604
- * sharing a rounded pixel column into one high-low stick draw cost bounded by
16605
- * 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.
16606
16692
  */
16607
16693
  emitCandlesAggregated(b, bars, i0, i1, coords, pane, up, down, barColors) {
16608
- let px = NaN;
16609
- let lo = Infinity;
16610
- let hi = -Infinity;
16611
- let openV = 0;
16612
- let closeV = 0;
16613
- let headTime = 0;
16614
- let active = false;
16615
- const flush = () => {
16616
- if (!active) return;
16617
- const c = parseColor(barColors.get(headTime) ?? (closeV >= openV ? up : down));
16618
- const hY = coords.priceToY(hi, pane.scale, pane.bounds);
16619
- const lY = coords.priceToY(lo, pane.scale, pane.bounds);
16620
- b.rect(px - 0.5, hY, 1, lY - hY, c);
16621
- };
16622
- for (let i = i0; i <= i1; i += 1) {
16623
- const bar = bars[i];
16624
- if (!bar || bar.high <= bar.low) continue;
16625
- const x = Math.round(coords.logicalToX(i));
16626
- if (!active || x !== px) {
16627
- flush();
16628
- px = x;
16629
- lo = bar.low;
16630
- hi = bar.high;
16631
- openV = bar.open;
16632
- headTime = bar.time;
16633
- active = true;
16634
- } else {
16635
- if (bar.low < lo) lo = bar.low;
16636
- if (bar.high > hi) hi = bar.high;
16637
- }
16638
- 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);
16639
16699
  }
16640
- flush();
16641
16700
  }
16642
16701
  emitSeries(b, spec, pane, coords, i0, i1, theme, off = 0) {
16643
16702
  if (spec.kind === "candle" || spec.kind === "bar") {
@@ -17935,13 +17994,15 @@ var SceneGraph = class {
17935
17994
  if (!this.orderedCache) this.orderedCache = [...this.panes.values()].sort((a, b) => a.order - b.order);
17936
17995
  return this.orderedCache;
17937
17996
  }
17938
- /** The session zones resolved into colored bands (pre/post-market washes from the
17939
- * 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}. */
17940
18000
  sessionHighlightBands() {
17941
18001
  if (!this.sessionZones) return [];
17942
18002
  const out = [];
17943
18003
  for (const [from, to] of this.sessionZones.pre) out.push({ from, to, color: this.style.sessions.premarketColor });
17944
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 });
17945
18006
  return out;
17946
18007
  }
17947
18008
  indicatorsForPane(paneId) {
@@ -18480,50 +18541,23 @@ var Canvas2dBackend = class {
18480
18541
  }
18481
18542
  }
18482
18543
  /**
18483
- * Sub-pixel LOD: bucket every bar sharing a rounded pixel column into ONE
18484
- * high-low stick, so draw cost is bounded by screen width (not bar count) when
18485
- * zoomed far out. The bucket's color follows its first-open→last-close
18486
- * 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).
18487
18549
  */
18488
18550
  drawCandlesAggregated(ctx, bars, i0, i1, coords, pane, up, down, barColors) {
18489
- let px = NaN;
18490
- let lo = Infinity;
18491
- let hi = -Infinity;
18492
- let openV = 0;
18493
- let closeV = 0;
18494
- let headTime = 0;
18495
- let active = false;
18496
- const flush = () => {
18497
- if (!active) return;
18498
- const color = barColors.get(headTime) ?? (closeV >= openV ? up : down);
18499
- const hY = coords.priceToY(hi, pane.scale, pane.bounds);
18500
- const lY = coords.priceToY(lo, pane.scale, pane.bounds);
18501
- ctx.strokeStyle = color;
18502
- 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);
18503
18556
  ctx.beginPath();
18504
- ctx.moveTo(px, hY);
18505
- ctx.lineTo(px, lY);
18557
+ ctx.moveTo(x, yOf(s.hi));
18558
+ ctx.lineTo(x, yOf(s.lo));
18506
18559
  ctx.stroke();
18507
- };
18508
- for (let i = i0; i <= i1; i += 1) {
18509
- const b = bars[i];
18510
- if (!b || b.high <= b.low) continue;
18511
- const x = Math.round(coords.logicalToX(i)) + 0.5;
18512
- if (!active || x !== px) {
18513
- flush();
18514
- px = x;
18515
- lo = b.low;
18516
- hi = b.high;
18517
- openV = b.open;
18518
- headTime = b.time;
18519
- active = true;
18520
- } else {
18521
- if (b.low < lo) lo = b.low;
18522
- if (b.high > hi) hi = b.high;
18523
- }
18524
- closeV = b.close;
18525
18560
  }
18526
- flush();
18527
18561
  }
18528
18562
  drawSeries(ctx, spec, pane, coords, i0, i1, theme, off = 0) {
18529
18563
  if (spec.kind === "candle" || spec.kind === "bar") {
@@ -19547,6 +19581,32 @@ var DrawingSceneRenderer = class {
19547
19581
  }
19548
19582
  };
19549
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
+
19550
19610
  // src/renderers/native/chrome/ticks.ts
19551
19611
  function priceTicks(min, max, target = 6) {
19552
19612
  if (!(max > min) || !Number.isFinite(min) || !Number.isFinite(max)) return [];
@@ -19694,7 +19754,14 @@ var STEP_LADDER = [
19694
19754
  YEAR
19695
19755
  ];
19696
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"];
19697
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
+ }
19698
19765
  function pickStep(targetMs) {
19699
19766
  for (const step of STEP_LADDER) if (step >= targetMs) return step;
19700
19767
  return STEP_LADDER[STEP_LADDER.length - 1];
@@ -19736,32 +19803,6 @@ function timeTicks(fromMs, toMs, target = 8, offsetMs = 0) {
19736
19803
  return out;
19737
19804
  }
19738
19805
 
19739
- // src/renderers/native/chrome/tz.ts
19740
- function tzOffsetMs(ms, timeZone) {
19741
- if (!timeZone || timeZone === "UTC") return 0;
19742
- try {
19743
- const dtf = new Intl.DateTimeFormat("en-US", {
19744
- timeZone,
19745
- hourCycle: "h23",
19746
- year: "numeric",
19747
- month: "2-digit",
19748
- day: "2-digit",
19749
- hour: "2-digit",
19750
- minute: "2-digit",
19751
- second: "2-digit"
19752
- });
19753
- const parts = dtf.formatToParts(new Date(ms));
19754
- const get = (t) => Number(parts.find((p) => p.type === t)?.value);
19755
- const asUTC = Date.UTC(get("year"), get("month") - 1, get("day"), get("hour") % 24, get("minute"), get("second"));
19756
- return asUTC - ms;
19757
- } catch {
19758
- return 0;
19759
- }
19760
- }
19761
- function zonedDate(ms, timeZone) {
19762
- return new Date(ms + tzOffsetMs(ms, timeZone));
19763
- }
19764
-
19765
19806
  // src/renderers/native/chrome/ChromeRenderer.ts
19766
19807
  var ChromeRenderer = class {
19767
19808
  constructor() {
@@ -20208,7 +20249,7 @@ var CrosshairRenderer = class {
20208
20249
  const price = coords.yToPrice(ch.y, pane.scale, pane.bounds);
20209
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);
20210
20251
  }
20211
- 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);
20212
20253
  }
20213
20254
  destroy() {
20214
20255
  this.canvas = null;
@@ -20256,7 +20297,7 @@ var CrosshairRenderer = class {
20256
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);
20257
20298
  }
20258
20299
  }
20259
- 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);
20260
20301
  ctx.globalAlpha = 1;
20261
20302
  }
20262
20303
  /** A soft band + a brighter crisp center line over the hovered separator, so it reads as
@@ -20289,11 +20330,6 @@ function setDash3(ctx, style) {
20289
20330
  else if (style === "dotted") ctx.setLineDash([2, 3]);
20290
20331
  else ctx.setLineDash([]);
20291
20332
  }
20292
- function formatStamp(ms, timeZone) {
20293
- const d = zonedDate(ms, timeZone);
20294
- const pad = (n) => n < 10 ? `0${n}` : String(n);
20295
- return `${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`;
20296
- }
20297
20333
 
20298
20334
  // src/core/timezones.ts
20299
20335
  var TIMEZONES = [
@@ -26782,6 +26818,9 @@ function clipHighlightRect(x1, x2, left, right) {
26782
26818
  const end = Math.min(right, x2);
26783
26819
  return end > x ? { x, width: end - x } : null;
26784
26820
  }
26821
+ function bandEdgeSlot(logical) {
26822
+ return Math.ceil(logical) - 0.5;
26823
+ }
26785
26824
  var BackdropRenderer = class {
26786
26825
  constructor() {
26787
26826
  this.canvas = null;
@@ -26812,21 +26851,22 @@ var BackdropRenderer = class {
26812
26851
  this.drawGrid(ctx, scene, coords, theme, coords.width, gridAlpha);
26813
26852
  }
26814
26853
  /** Renderer-owned session highlight bands: full-height (all panes), behind the grid.
26815
- * 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). */
26816
26857
  drawHighlights(ctx, scene, coords) {
26817
26858
  const sessions = scene.sessionHighlightBands();
26818
26859
  if (sessions.length > 0) {
26819
26860
  const left = Math.max(0, coords.logicalToX(-0.5));
26820
26861
  const right = Math.min(coords.width, coords.logicalToX(coords.barCount - 0.5));
26821
- this.drawHighlightSet(ctx, sessions, coords, left, right);
26862
+ this.drawHighlightSet(ctx, sessions, coords, left, right, true);
26822
26863
  }
26823
- this.drawHighlightSet(ctx, scene.highlights, coords, 0, coords.width);
26864
+ this.drawHighlightSet(ctx, scene.highlights, coords, 0, coords.width, false);
26824
26865
  }
26825
- 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);
26826
26868
  for (const band of bands) {
26827
- const x1 = coords.timeToX(band.from);
26828
- const x2 = coords.timeToX(band.to);
26829
- const rect = clipHighlightRect(x1, x2, left, right);
26869
+ const rect = clipHighlightRect(edgeX(band.from), edgeX(band.to), left, right);
26830
26870
  if (!rect) continue;
26831
26871
  ctx.fillStyle = band.color;
26832
26872
  ctx.fillRect(rect.x, 0, rect.width, coords.height);
@@ -27085,6 +27125,7 @@ function createCustomMark(doc, html, background) {
27085
27125
  });
27086
27126
  el.style.color = attributionMarkColor(background);
27087
27127
  el.innerHTML = html;
27128
+ el.dataset.velaScreenshot = "1";
27088
27129
  return el;
27089
27130
  }
27090
27131
  function createAttributionMark(doc, background) {
@@ -27103,6 +27144,7 @@ function createAttributionMark(doc, background) {
27103
27144
  cursor: "pointer"
27104
27145
  });
27105
27146
  applyAttributionMarkTheme(a, background);
27147
+ a.dataset.velaScreenshot = "1";
27106
27148
  const symbol = doc.createElement("span");
27107
27149
  symbol.className = "vela-attr-symbol";
27108
27150
  symbol.setAttribute("aria-hidden", "true");
@@ -28107,7 +28149,7 @@ var NativeRenderer = class {
28107
28149
  };
28108
28150
  })(),
28109
28151
  series: { style: this.scene.priceStyle, baseline: this.scene.baselineValue, spacing: this.coords.spacingScale },
28110
- sessions: { premarketColor: s.sessions.premarketColor, postmarketColor: s.sessions.postmarketColor }
28152
+ sessions: { premarketColor: s.sessions.premarketColor, postmarketColor: s.sessions.postmarketColor, extendedColor: s.sessions.extendedColor }
28111
28153
  };
28112
28154
  }
28113
28155
  /**
@@ -28189,7 +28231,7 @@ var NativeRenderer = class {
28189
28231
  width: next.baseline.width,
28190
28232
  baselineLevel: next.baseline.baselineLevel
28191
28233
  };
28192
- 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 };
28193
28235
  this.setPriceStyle(next.series.style);
28194
28236
  this.scene.candleOverride = candleOverrideFor(this.scene.priceStyle, s.chartTypes);
28195
28237
  this.scene.baselineValue = next.series.baseline;
@@ -28411,9 +28453,10 @@ var NativeRenderer = class {
28411
28453
  * opts in with a `data-vela-screenshot` attribute on the mount container's
28412
28454
  * subtree (the widget marks its status line, and its symbol watermark with
28413
28455
  * `"under"` — drawn beneath the canvases, where it sits on screen). Only the
28414
- * crosshair (L2) is intentionally excluded.
28456
+ * crosshair (L2) is intentionally excluded. {@link screenshot} is this canvas
28457
+ * as a PNG data URL.
28415
28458
  */
28416
- screenshot() {
28459
+ screenshotCanvas() {
28417
28460
  if (!this.dataCanvas) return null;
28418
28461
  this.computeScales();
28419
28462
  this.paintData();
@@ -28441,7 +28484,10 @@ var NativeRenderer = class {
28441
28484
  if (el.getAttribute("data-vela-screenshot") !== "under") rasterizeOverlay(ctx, el, frame);
28442
28485
  }
28443
28486
  }
28444
- return out.toDataURL("image/png");
28487
+ return out;
28488
+ }
28489
+ screenshot() {
28490
+ return this.screenshotCanvas()?.toDataURL("image/png") ?? null;
28445
28491
  }
28446
28492
  /**
28447
28493
  * The candles-first-appear reveal — animates the **candles themselves** (no extra
@@ -29836,7 +29882,7 @@ var NativeRenderer = class {
29836
29882
  const pricePane = this.dataWindowPricePane();
29837
29883
  const ohlc = this.dataWindowOHLC(bar, pricePane);
29838
29884
  const parts = [];
29839
- if (bar) parts.push(formatStamp2(bar.time, this.scene.timezone));
29885
+ if (bar) parts.push(formatStamp(bar.time, this.scene.timezone));
29840
29886
  if (ohlc) parts.push(`Open ${ohlc.o}, High ${ohlc.h}, Low ${ohlc.l}, Close ${ohlc.c}`);
29841
29887
  for (const group of this.dataWindowGroups(idx, pricePane)) {
29842
29888
  for (const row of group.rows) parts.push(`${row.label} ${row.value}`);
@@ -30723,7 +30769,7 @@ function formatStampParts(ms, timeZone) {
30723
30769
  time: `${p(d.getUTCHours())}:${p(d.getUTCMinutes())}`
30724
30770
  };
30725
30771
  }
30726
- function formatStamp2(ms, timeZone) {
30772
+ function formatStamp(ms, timeZone) {
30727
30773
  const { date, time } = formatStampParts(ms, timeZone);
30728
30774
  return `${date} ${time}`;
30729
30775
  }
@@ -30754,7 +30800,7 @@ function sanitizeSessionZones(value) {
30754
30800
  }
30755
30801
  return out.sort((a, b) => a[0] - b[0]);
30756
30802
  };
30757
- return { pre: windows(v.pre), post: windows(v.post) };
30803
+ return { pre: windows(v.pre), post: windows(v.post), extended: windows(v.extended) };
30758
30804
  }
30759
30805
  function clamp012(v) {
30760
30806
  return Math.max(0, Math.min(1, v));
@@ -31431,6 +31477,7 @@ exports.BEARISH = BEARISH;
31431
31477
  exports.BULLISH = BULLISH;
31432
31478
  exports.BarStore = BarStore;
31433
31479
  exports.CATEGORICAL = CATEGORICAL;
31480
+ exports.CHIP_PLATE = CHIP_PLATE;
31434
31481
  exports.CROSSHAIR = CROSSHAIR;
31435
31482
  exports.CachingDataFeed = CachingDataFeed;
31436
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