@luxalgo/vela 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{DataProvider-BrlxntPN.d.cts → DataProvider-COGDs9Xg.d.cts} +1 -1
- package/dist/{DataProvider-DwFIoV4r.d.ts → DataProvider-DpOWZD8F.d.ts} +1 -1
- package/dist/{chunk-LMBYEGUR.js → chunk-27UTYE7T.js} +25 -2
- package/dist/{chunk-EZ5FWVLA.js → chunk-DPAA3SRT.js} +94 -13
- package/dist/{chunk-BZQM2XO7.js → chunk-HKNO24GD.js} +13 -1
- package/dist/{chunk-NELQJCGK.js → chunk-NLDTVFOI.js} +41 -3
- package/dist/{chunk-DBDXKZUF.js → chunk-R2JMNIHY.js} +53 -13
- package/dist/{chunk-ATGTCWHJ.js → chunk-T3DZIR5Y.js} +171 -32
- package/dist/{contributions-tjNExo1o.d.ts → contributions-Cgm9RJYP.d.cts} +38 -11
- package/dist/{contributions-CtlptxR8.d.cts → contributions-bWgwyiVi.d.ts} +38 -11
- package/dist/index.cjs +239 -37
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +4 -4
- package/dist/{options-BnEPUuVV.d.ts → options-NAUHiQEC.d.cts} +3 -3
- package/dist/{options-BnEPUuVV.d.cts → options-NAUHiQEC.d.ts} +3 -3
- package/dist/{plugin-BWxJRKzS.d.cts → plugin-CjjzZX2F.d.cts} +4 -4
- package/dist/{plugin-e2WUEtiI.d.ts → plugin-CqxWoDKS.d.ts} +4 -4
- package/dist/plugin.cjs +20 -6
- package/dist/plugin.d.cts +5 -5
- package/dist/plugin.d.ts +5 -5
- package/dist/plugin.js +2 -2
- package/dist/providers/binance.d.cts +2 -2
- package/dist/providers/binance.d.ts +2 -2
- package/dist/providers/coinbase.d.cts +2 -2
- package/dist/providers/coinbase.d.ts +2 -2
- package/dist/providers/hyperliquid.d.cts +2 -2
- package/dist/providers/hyperliquid.d.ts +2 -2
- package/dist/{side-panel-HF0IAzwf.d.cts → side-panel-wMNfgyZb.d.cts} +13 -0
- package/dist/{side-panel-HF0IAzwf.d.ts → side-panel-wMNfgyZb.d.ts} +13 -0
- package/dist/{statusline-model-zKXtGIjj.d.ts → statusline-model-Dih6FGWP.d.ts} +3 -3
- package/dist/{statusline-model-DFY7tuHj.d.cts → statusline-model-Dpfpq54A.d.cts} +3 -3
- package/dist/ui.cjs +77 -2
- package/dist/ui.d.cts +28 -2
- package/dist/ui.d.ts +28 -2
- package/dist/ui.js +3 -3
- package/dist/vela.global.js +239 -37
- package/dist/vela.global.min.js +52 -52
- package/dist/widget.cjs +383 -50
- package/dist/widget.d.cts +20 -10
- package/dist/widget.d.ts +20 -10
- package/dist/widget.js +7 -7
- package/dist/workspace.cjs +383 -50
- package/dist/workspace.d.cts +5 -5
- package/dist/workspace.d.ts +5 -5
- package/dist/workspace.js +6 -6
- package/package.json +2 -2
package/dist/vela.global.js
CHANGED
|
@@ -214,7 +214,7 @@ var Vela = (function (exports) {
|
|
|
214
214
|
this.controller.applyProps(this.id, values);
|
|
215
215
|
}
|
|
216
216
|
updateCode(source) {
|
|
217
|
-
this.controller.updateCode(this.id, source);
|
|
217
|
+
return this.controller.updateCode(this.id, source);
|
|
218
218
|
}
|
|
219
219
|
setVisible(visible) {
|
|
220
220
|
this.controller.setVisible(this.id, visible);
|
|
@@ -617,6 +617,7 @@ var Vela = (function (exports) {
|
|
|
617
617
|
registerIcon("plus", S('<path d="M8 2.8v10.4M2.8 8h10.4"/>'));
|
|
618
618
|
registerIcon("minus", S('<path d="M2.8 8h10.4"/>'));
|
|
619
619
|
registerIcon("maximize", S('<path d="M2.5 6V3a.5.5 0 0 1 .5-.5h3M10 2.5h3a.5.5 0 0 1 .5.5v3M13.5 10v3a.5.5 0 0 1-.5.5h-3M6 13.5H3a.5.5 0 0 1-.5-.5v-3"/>'));
|
|
620
|
+
registerIcon("restore", S('<path d="M6 2.5v3a.5.5 0 0 1-.5.5h-3M13.5 6h-3a.5.5 0 0 1-.5-.5v-3M10 13.5v-3a.5.5 0 0 1 .5-.5h3M2.5 10h3a.5.5 0 0 1 .5.5v3"/>'));
|
|
620
621
|
registerIcon("restore", S('<path d="M6.2 2.5v3.7H2.5M9.8 13.5V9.8h3.7M13.5 6.2H9.8V2.5M2.5 9.8h3.7v3.7"/>'));
|
|
621
622
|
registerIcon("star", S('<path d="M8 2.2l1.75 3.55 3.9.55-2.8 2.75.65 3.9L8 11.1l-3.5 1.85.65-3.9-2.8-2.75 3.9-.55z"/>'));
|
|
622
623
|
registerIcon("star-filled", S('<path d="M8 2.2l1.75 3.55 3.9.55-2.8 2.75.65 3.9L8 11.1l-3.5 1.85.65-3.9-2.8-2.75 3.9-.55z"/>', 'fill="currentColor"'));
|
|
@@ -3275,6 +3276,10 @@ var Vela = (function (exports) {
|
|
|
3275
3276
|
|
|
3276
3277
|
// src/core/drawings/types/FibLevels.ts
|
|
3277
3278
|
var FibLevels = class extends FibRatios {
|
|
3279
|
+
/** Price of a level for the two anchor prices; subclasses override to change which anchor ratio 0 sits on. */
|
|
3280
|
+
levelPrice(ratio, p1, p2) {
|
|
3281
|
+
return p1 + ratio * (p2 - p1);
|
|
3282
|
+
}
|
|
3278
3283
|
/** Per-level pixel line + price for the ENABLED levels, spanning the anchors' time range. */
|
|
3279
3284
|
levelLines(proj) {
|
|
3280
3285
|
const a = this.anchors[0];
|
|
@@ -3284,11 +3289,10 @@ var Vela = (function (exports) {
|
|
|
3284
3289
|
const xb = proj.xOf(b.time);
|
|
3285
3290
|
const x1 = Math.min(xa, xb);
|
|
3286
3291
|
const x2 = Math.max(xa, xb);
|
|
3287
|
-
const delta = b.price - a.price;
|
|
3288
3292
|
const out = [];
|
|
3289
3293
|
for (const lv of this.levels) {
|
|
3290
3294
|
if (!lv.enabled) continue;
|
|
3291
|
-
const price =
|
|
3295
|
+
const price = this.levelPrice(lv.ratio, a.price, b.price);
|
|
3292
3296
|
const y = proj.yOf(price, this.paneId);
|
|
3293
3297
|
if (y == null) continue;
|
|
3294
3298
|
out.push({ ratio: lv.ratio, color: lv.color, label: lv.label, price, x1, x2, y });
|
|
@@ -3328,8 +3332,7 @@ var Vela = (function (exports) {
|
|
|
3328
3332
|
const a = this.anchors[0];
|
|
3329
3333
|
const b = this.anchors[1];
|
|
3330
3334
|
if (!a || !b) return null;
|
|
3331
|
-
const
|
|
3332
|
-
const prices = this.levels.filter((l) => l.enabled).map((l) => a.price + l.ratio * delta);
|
|
3335
|
+
const prices = this.levels.filter((l) => l.enabled).map((l) => this.levelPrice(l.ratio, a.price, b.price));
|
|
3333
3336
|
if (prices.length === 0) return null;
|
|
3334
3337
|
return { min: Math.min(...prices), max: Math.max(...prices) };
|
|
3335
3338
|
}
|
|
@@ -3415,13 +3418,24 @@ var Vela = (function (exports) {
|
|
|
3415
3418
|
// src/core/drawings/types/FibRetracement.ts
|
|
3416
3419
|
var LEVELS = fibLevels([0, 0.236, 0.382, 0.5, 0.618, 0.786, 1]);
|
|
3417
3420
|
var FibRetracement = class extends FibLevels {
|
|
3418
|
-
constructor() {
|
|
3419
|
-
super(
|
|
3421
|
+
constructor(init) {
|
|
3422
|
+
super(init);
|
|
3420
3423
|
this.type = "fibretracement";
|
|
3424
|
+
if (this.reverse === void 0) this.reverse = false;
|
|
3421
3425
|
}
|
|
3422
3426
|
defaultLevels() {
|
|
3423
3427
|
return LEVELS;
|
|
3424
3428
|
}
|
|
3429
|
+
levelPrice(ratio, p1, p2) {
|
|
3430
|
+
return this.reverse ? p1 + ratio * (p2 - p1) : p2 + ratio * (p1 - p2);
|
|
3431
|
+
}
|
|
3432
|
+
writeProps() {
|
|
3433
|
+
return { ...super.writeProps(), reverse: this.reverse };
|
|
3434
|
+
}
|
|
3435
|
+
readProps(props) {
|
|
3436
|
+
super.readProps(props);
|
|
3437
|
+
this.reverse = typeof props.reverse === "boolean" ? props.reverse : true;
|
|
3438
|
+
}
|
|
3425
3439
|
};
|
|
3426
3440
|
|
|
3427
3441
|
// src/core/drawings/types/FibExtension.ts
|
|
@@ -9234,20 +9248,26 @@ var Vela = (function (exports) {
|
|
|
9234
9248
|
/**
|
|
9235
9249
|
* IndicatorController: replace a SCRIPT indicator's source in place (see
|
|
9236
9250
|
* {@link IndicatorHandle.updateCode}). Prepare-first: the running session keeps
|
|
9237
|
-
* computing until the new source has compiled
|
|
9238
|
-
*
|
|
9251
|
+
* computing until the new source has compiled; then the new code runs on TRIAL until
|
|
9252
|
+
* its first model lands, and a failure before that puts the previous code back.
|
|
9253
|
+
* Natives have no script — warn and leave them alone.
|
|
9239
9254
|
*/
|
|
9240
9255
|
updateCode(id, source) {
|
|
9241
9256
|
const record = this.registry.get(id);
|
|
9242
9257
|
const handle = this.handles.get(id);
|
|
9243
|
-
if (!record || !handle) return;
|
|
9258
|
+
if (!record || !handle) return Promise.resolve({ ok: false, error: new Error(`[vela] updateCode("${id}") \u2014 the indicator is no longer on the chart.`) });
|
|
9244
9259
|
if (record.native) {
|
|
9245
9260
|
console.warn(`[vela] updateCode("${id}") \u2014 a native indicator has no script to update.`);
|
|
9246
|
-
return;
|
|
9261
|
+
return Promise.resolve({ ok: false, error: new Error(`[vela] updateCode("${id}") \u2014 a native indicator has no script to update.`) });
|
|
9247
9262
|
}
|
|
9248
|
-
|
|
9249
|
-
record.
|
|
9250
|
-
|
|
9263
|
+
const busy = record.pendingSource !== void 0 || record.codeTrial !== void 0;
|
|
9264
|
+
if (!busy && source === record.source) return Promise.resolve({ ok: true, error: null });
|
|
9265
|
+
return new Promise((resolve) => {
|
|
9266
|
+
(record.codeWaiters ?? (record.codeWaiters = [])).push(resolve);
|
|
9267
|
+
if (record.pendingSource === source || record.pendingSource === void 0 && record.codeTrial && record.source === source) return;
|
|
9268
|
+
record.pendingSource = source;
|
|
9269
|
+
void this.swapSource(id, source, handle);
|
|
9270
|
+
});
|
|
9251
9271
|
}
|
|
9252
9272
|
async swapSource(id, source, handle) {
|
|
9253
9273
|
const engine = this.registry.get(id)?.engine ?? this.engineFor(this.registry.get(id)?.options?.language);
|
|
@@ -9258,26 +9278,41 @@ var Vela = (function (exports) {
|
|
|
9258
9278
|
const record2 = this.registry.get(id);
|
|
9259
9279
|
if (record2?.pendingSource === source) {
|
|
9260
9280
|
record2.pendingSource = void 0;
|
|
9261
|
-
this.
|
|
9281
|
+
this.rejectCode(id, record2, handle, err);
|
|
9262
9282
|
}
|
|
9263
9283
|
return;
|
|
9264
9284
|
}
|
|
9265
9285
|
const record = this.registry.get(id);
|
|
9266
9286
|
if (!record || record.pendingSource !== source) return;
|
|
9267
9287
|
record.pendingSource = void 0;
|
|
9288
|
+
const previous = record.codeTrial?.previous ?? {
|
|
9289
|
+
source: record.source,
|
|
9290
|
+
engine: record.engine,
|
|
9291
|
+
prepared: record.prepared,
|
|
9292
|
+
inputValues: record.inputValues,
|
|
9293
|
+
propValues: record.propValues,
|
|
9294
|
+
inputs: [...handle.inputs],
|
|
9295
|
+
props: [...handle.props]
|
|
9296
|
+
};
|
|
9297
|
+
record.inputValues = valuesOnSchema(prepared.inputs, record.inputValues, record.prepared?.inputs);
|
|
9298
|
+
record.propValues = valuesOnSchema(prepared.props ?? [], record.propValues, record.prepared?.props);
|
|
9268
9299
|
record.source = source;
|
|
9269
9300
|
record.engine = engine;
|
|
9270
9301
|
record.prepared = prepared;
|
|
9271
9302
|
handle.setSource(source);
|
|
9272
|
-
record.inputValues = valuesOnSchema(prepared.inputs, record.inputValues);
|
|
9273
|
-
record.propValues = valuesOnSchema(prepared.props ?? [], record.propValues);
|
|
9274
9303
|
handle.setSchema(prepared.inputs);
|
|
9275
9304
|
handle.setPropsSchema(prepared.props ?? []);
|
|
9276
9305
|
record.session?.stop();
|
|
9277
9306
|
record.session = void 0;
|
|
9278
9307
|
record.pendingStructural = true;
|
|
9279
9308
|
record.pendingCause = "code";
|
|
9280
|
-
if (record.hidden)
|
|
9309
|
+
if (record.hidden) {
|
|
9310
|
+
record.codeTrial = void 0;
|
|
9311
|
+
if (record.renderHandle) this.renderer.setIndicatorInputs(record.renderHandle, record.inputValues, record.propValues);
|
|
9312
|
+
this.settleCode(record, { ok: true, error: null });
|
|
9313
|
+
return;
|
|
9314
|
+
}
|
|
9315
|
+
record.codeTrial = { previous };
|
|
9281
9316
|
if (record.renderHandle) {
|
|
9282
9317
|
this.renderer.setIndicatorInputs(record.renderHandle, record.inputValues, record.propValues);
|
|
9283
9318
|
this.setLoading(record, true);
|
|
@@ -9285,6 +9320,46 @@ var Vela = (function (exports) {
|
|
|
9285
9320
|
this.mountLoadingPlaceholder(id, record);
|
|
9286
9321
|
}
|
|
9287
9322
|
this.executeIndicator(id, handle);
|
|
9323
|
+
if (this.bars.length === 0 && record.codeTrial) {
|
|
9324
|
+
record.codeTrial = void 0;
|
|
9325
|
+
this.settleCode(record, { ok: true, error: null });
|
|
9326
|
+
}
|
|
9327
|
+
}
|
|
9328
|
+
/** Resolve every `updateCode` caller waiting on this record's chain of edits. */
|
|
9329
|
+
settleCode(record, result) {
|
|
9330
|
+
const waiters = record.codeWaiters;
|
|
9331
|
+
record.codeWaiters = void 0;
|
|
9332
|
+
if (waiters) for (const resolve of waiters) resolve(result);
|
|
9333
|
+
}
|
|
9334
|
+
/**
|
|
9335
|
+
* An update failed — at prepare, or on trial before its first model. A trial puts the
|
|
9336
|
+
* previous code back (source, engine, prepared script, values, schema) and restarts it;
|
|
9337
|
+
* its visuals were never dropped, so the chart keeps painting throughout. Then the
|
|
9338
|
+
* failure reports the usual way and every waiting caller learns it.
|
|
9339
|
+
*/
|
|
9340
|
+
rejectCode(id, record, handle, err) {
|
|
9341
|
+
const trial = record.codeTrial;
|
|
9342
|
+
record.codeTrial = void 0;
|
|
9343
|
+
this.fail(id, handle, err);
|
|
9344
|
+
if (trial) {
|
|
9345
|
+
const p = trial.previous;
|
|
9346
|
+
record.session?.stop();
|
|
9347
|
+
record.session = void 0;
|
|
9348
|
+
record.source = p.source;
|
|
9349
|
+
record.engine = p.engine;
|
|
9350
|
+
record.prepared = p.prepared;
|
|
9351
|
+
record.inputValues = p.inputValues;
|
|
9352
|
+
record.propValues = p.propValues;
|
|
9353
|
+
handle.setSource(p.source);
|
|
9354
|
+
handle.setSchema(p.inputs);
|
|
9355
|
+
handle.setPropsSchema(p.props);
|
|
9356
|
+
record.pendingStructural = true;
|
|
9357
|
+
record.pendingCause = void 0;
|
|
9358
|
+
if (record.renderHandle) this.renderer.setIndicatorInputs(record.renderHandle, record.inputValues, record.propValues);
|
|
9359
|
+
if (!record.hidden) this.executeIndicator(id, handle);
|
|
9360
|
+
}
|
|
9361
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
9362
|
+
this.settleCode(record, { ok: false, error });
|
|
9288
9363
|
}
|
|
9289
9364
|
/** IndicatorController: tear down an indicator and (if now empty) its pane. */
|
|
9290
9365
|
/** Live handles of every indicator on the chart (script + native), insertion order. */
|
|
@@ -9299,6 +9374,7 @@ var Vela = (function (exports) {
|
|
|
9299
9374
|
removeIndicator(id) {
|
|
9300
9375
|
const record = this.registry.remove(id);
|
|
9301
9376
|
if (record?.native?.type === "volume") this.volumeOptedOut = true;
|
|
9377
|
+
if (record) this.settleCode(record, { ok: false, error: new Error(`[vela] updateCode("${id}") \u2014 the indicator was removed.`) });
|
|
9302
9378
|
record?.session?.stop();
|
|
9303
9379
|
if (record?.native?.started) record.native.instance.stop();
|
|
9304
9380
|
this.handles.delete(id);
|
|
@@ -9326,6 +9402,10 @@ var Vela = (function (exports) {
|
|
|
9326
9402
|
if (!visible) {
|
|
9327
9403
|
record.session?.stop();
|
|
9328
9404
|
record.session = void 0;
|
|
9405
|
+
if (record.codeTrial) {
|
|
9406
|
+
record.codeTrial = void 0;
|
|
9407
|
+
this.settleCode(record, { ok: true, error: null });
|
|
9408
|
+
}
|
|
9329
9409
|
if (record.native?.started) record.native.instance.suspend();
|
|
9330
9410
|
if (record.renderHandle) this.renderer.setIndicatorVisible?.(record.renderHandle, false);
|
|
9331
9411
|
else if (record.native) this.mountHiddenNativeRow(id, record);
|
|
@@ -9413,6 +9493,7 @@ var Vela = (function (exports) {
|
|
|
9413
9493
|
this.viewportUnsub?.();
|
|
9414
9494
|
this.paneActionUnsub?.();
|
|
9415
9495
|
for (const record of this.registry.all()) {
|
|
9496
|
+
this.settleCode(record, { ok: false, error: new Error("[vela] updateCode \u2014 the chart was destroyed.") });
|
|
9416
9497
|
record.session?.stop();
|
|
9417
9498
|
if (record.native?.started) record.native.instance.stop();
|
|
9418
9499
|
}
|
|
@@ -9481,7 +9562,8 @@ var Vela = (function (exports) {
|
|
|
9481
9562
|
const record = this.registry.get(id);
|
|
9482
9563
|
if (!record || !record.engine || !record.prepared || record.hidden) return;
|
|
9483
9564
|
const mode = this.config.live && !record.prepared.reactsToViewport && record.engine.capabilities.streaming ? "live" : "static";
|
|
9484
|
-
|
|
9565
|
+
const prepared = record.prepared;
|
|
9566
|
+
const session = record.engine.execute(
|
|
9485
9567
|
{
|
|
9486
9568
|
prepared: record.prepared,
|
|
9487
9569
|
market: this.market(),
|
|
@@ -9502,6 +9584,10 @@ var Vela = (function (exports) {
|
|
|
9502
9584
|
const cause = record.pendingCause ?? "history";
|
|
9503
9585
|
if (!this.applyModel(id, model)) return;
|
|
9504
9586
|
record.pendingCause = void 0;
|
|
9587
|
+
if (record.codeTrial) {
|
|
9588
|
+
record.codeTrial = void 0;
|
|
9589
|
+
this.settleCode(record, { ok: true, error: null });
|
|
9590
|
+
}
|
|
9505
9591
|
this.emitContextChanged(id);
|
|
9506
9592
|
this.emitScriptRun(id, cause, first2);
|
|
9507
9593
|
},
|
|
@@ -9512,9 +9598,17 @@ var Vela = (function (exports) {
|
|
|
9512
9598
|
handle.emit("alert", { id: a.id, message: a.message, title: a.title, time: a.time });
|
|
9513
9599
|
},
|
|
9514
9600
|
onWarning: (w) => this.events.emit("warning", w),
|
|
9515
|
-
onError: (err) =>
|
|
9601
|
+
onError: (err) => {
|
|
9602
|
+
if (record.codeTrial) this.rejectCode(id, record, handle, err);
|
|
9603
|
+
else this.fail(id, handle, err);
|
|
9604
|
+
}
|
|
9516
9605
|
}
|
|
9517
9606
|
);
|
|
9607
|
+
if (record.prepared !== prepared) {
|
|
9608
|
+
session.stop();
|
|
9609
|
+
return;
|
|
9610
|
+
}
|
|
9611
|
+
record.session = session;
|
|
9518
9612
|
this.emitContextChanged(id);
|
|
9519
9613
|
}
|
|
9520
9614
|
/**
|
|
@@ -10015,7 +10109,7 @@ var Vela = (function (exports) {
|
|
|
10015
10109
|
}
|
|
10016
10110
|
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
10017
10111
|
}
|
|
10018
|
-
function valuesOnSchema(schema, previous) {
|
|
10112
|
+
function valuesOnSchema(schema, previous, oldSchema = []) {
|
|
10019
10113
|
const out = {};
|
|
10020
10114
|
const declared = /* @__PURE__ */ new Set();
|
|
10021
10115
|
for (const s of schema) {
|
|
@@ -10023,9 +10117,22 @@ var Vela = (function (exports) {
|
|
|
10023
10117
|
declared.add(s.key);
|
|
10024
10118
|
declared.add(s.title);
|
|
10025
10119
|
}
|
|
10026
|
-
|
|
10120
|
+
const oldDefaults = /* @__PURE__ */ new Map();
|
|
10121
|
+
for (const s of oldSchema) {
|
|
10122
|
+
oldDefaults.set(s.key, s.defval);
|
|
10123
|
+
if (!oldDefaults.has(s.title)) oldDefaults.set(s.title, s.defval);
|
|
10124
|
+
}
|
|
10125
|
+
for (const [k, v] of Object.entries(previous)) {
|
|
10126
|
+
if (!declared.has(k)) continue;
|
|
10127
|
+
if (oldDefaults.has(k) && sameInputValue(oldDefaults.get(k), v)) continue;
|
|
10128
|
+
out[k] = v;
|
|
10129
|
+
}
|
|
10027
10130
|
return out;
|
|
10028
10131
|
}
|
|
10132
|
+
function sameInputValue(a, b) {
|
|
10133
|
+
if (a === b) return true;
|
|
10134
|
+
return typeof a === "object" && a !== null && typeof b === "object" && b !== null && JSON.stringify(a) === JSON.stringify(b);
|
|
10135
|
+
}
|
|
10029
10136
|
function blankedModel(model) {
|
|
10030
10137
|
return {
|
|
10031
10138
|
...model,
|
|
@@ -13587,6 +13694,17 @@ ${STATIC_DECLS}
|
|
|
13587
13694
|
return span;
|
|
13588
13695
|
}
|
|
13589
13696
|
|
|
13697
|
+
// src/ui/surface-events.ts
|
|
13698
|
+
var SURFACE_OPEN_EVENT = "vela:surface-open";
|
|
13699
|
+
var SURFACE_CLOSE_EVENT = "vela:surface-close";
|
|
13700
|
+
function announceSurface(el, open2, kind, trigger = null) {
|
|
13701
|
+
const View = el.ownerDocument.defaultView;
|
|
13702
|
+
if (!View) return;
|
|
13703
|
+
el.dispatchEvent(
|
|
13704
|
+
new View.CustomEvent(open2 ? SURFACE_OPEN_EVENT : SURFACE_CLOSE_EVENT, { bubbles: true, composed: true, detail: { kind, trigger } })
|
|
13705
|
+
);
|
|
13706
|
+
}
|
|
13707
|
+
|
|
13590
13708
|
// node_modules/@zag-js/anatomy/dist/create-anatomy.mjs
|
|
13591
13709
|
var createAnatomy = (name, parts3 = []) => ({
|
|
13592
13710
|
parts: (...values) => {
|
|
@@ -18065,6 +18183,8 @@ ${STATIC_DECLS}
|
|
|
18065
18183
|
/** Trigger rect captured when this level opened — the list stays put if the
|
|
18066
18184
|
* trigger then moves (favorite chips shifting the caret). */
|
|
18067
18185
|
this.pinnedAnchor = null;
|
|
18186
|
+
/** The open state last announced — see {@link announce}. */
|
|
18187
|
+
this.shown = false;
|
|
18068
18188
|
this.doc = doc;
|
|
18069
18189
|
this.host = opts.host;
|
|
18070
18190
|
this.onSelect = opts.onSelect;
|
|
@@ -18078,6 +18198,7 @@ ${STATIC_DECLS}
|
|
|
18078
18198
|
this.positioner.appendChild(this.list);
|
|
18079
18199
|
this.host.appendChild(this.positioner);
|
|
18080
18200
|
const trigger = opts.trigger;
|
|
18201
|
+
this.opener = trigger ?? opts.opener ?? null;
|
|
18081
18202
|
this.ctrl = menuController({
|
|
18082
18203
|
items: [],
|
|
18083
18204
|
id: opts.id,
|
|
@@ -18099,15 +18220,21 @@ ${STATIC_DECLS}
|
|
|
18099
18220
|
if (opts.triggerId && trigger) trigger.id = opts.triggerId;
|
|
18100
18221
|
this.handle = runMachine(this.ctrl.machine, this.ctrl.props, (service) => {
|
|
18101
18222
|
const api = this.ctrl.connect(service);
|
|
18223
|
+
if (this.shown && !api.open) this.announce(false);
|
|
18102
18224
|
if (trigger) spreadProps(trigger, api.getTriggerProps(), this.mid);
|
|
18103
18225
|
spreadProps(this.positioner, api.getPositionerProps(), this.mid);
|
|
18104
18226
|
spreadProps(this.list, api.getContentProps(), this.mid);
|
|
18105
18227
|
this.project(api);
|
|
18228
|
+
if (api.open && !this.shown) this.announce(true);
|
|
18106
18229
|
});
|
|
18107
18230
|
}
|
|
18108
18231
|
get api() {
|
|
18109
18232
|
return this.ctrl.connect(this.handle.service);
|
|
18110
18233
|
}
|
|
18234
|
+
announce(open2) {
|
|
18235
|
+
this.shown = open2;
|
|
18236
|
+
announceSurface(this.list, open2, "menu", this.opener);
|
|
18237
|
+
}
|
|
18111
18238
|
setItems(items) {
|
|
18112
18239
|
this.items = items;
|
|
18113
18240
|
for (const sub2 of this.subs.values()) sub2.destroy();
|
|
@@ -18125,6 +18252,7 @@ ${STATIC_DECLS}
|
|
|
18125
18252
|
for (const sub2 of this.subs.values()) sub2.destroy();
|
|
18126
18253
|
this.subs.clear();
|
|
18127
18254
|
this.handle.stop();
|
|
18255
|
+
if (this.shown) this.announce(false);
|
|
18128
18256
|
this.positioner.remove();
|
|
18129
18257
|
}
|
|
18130
18258
|
byId(id) {
|
|
@@ -18218,6 +18346,7 @@ ${STATIC_DECLS}
|
|
|
18218
18346
|
const sub2 = new _Surface(doc, {
|
|
18219
18347
|
host: this.host,
|
|
18220
18348
|
placement: "right-start",
|
|
18349
|
+
opener: li,
|
|
18221
18350
|
onSelect: this.onSelect,
|
|
18222
18351
|
onFavorite: this.onFavorite,
|
|
18223
18352
|
checkmarks: this.checkmarks,
|
|
@@ -18437,16 +18566,21 @@ ${STATIC_DECLS}
|
|
|
18437
18566
|
this.hide();
|
|
18438
18567
|
};
|
|
18439
18568
|
const onReflow = () => this.place();
|
|
18440
|
-
setTimeout(() =>
|
|
18569
|
+
setTimeout(() => {
|
|
18570
|
+
if (this.onOutside === onOutside) document.addEventListener("pointerdown", onOutside, true);
|
|
18571
|
+
}, 0);
|
|
18441
18572
|
document.addEventListener("keydown", onKey, true);
|
|
18442
18573
|
window.addEventListener("resize", onReflow, true);
|
|
18443
18574
|
document.addEventListener("scroll", onReflow, true);
|
|
18444
18575
|
this.onOutside = onOutside;
|
|
18445
18576
|
this.onKey = onKey;
|
|
18446
18577
|
this.onReflow = onReflow;
|
|
18578
|
+
announceSurface(this.el, true, "popover", this.trigger);
|
|
18447
18579
|
}
|
|
18448
18580
|
hide() {
|
|
18449
18581
|
if (!this.shown) return;
|
|
18582
|
+
this.shown = false;
|
|
18583
|
+
announceSurface(this.el, false, "popover", this.trigger);
|
|
18450
18584
|
if (this.onOutside) document.removeEventListener("pointerdown", this.onOutside, true);
|
|
18451
18585
|
if (this.onKey) document.removeEventListener("keydown", this.onKey, true);
|
|
18452
18586
|
if (this.onReflow) {
|
|
@@ -18466,7 +18600,6 @@ ${STATIC_DECLS}
|
|
|
18466
18600
|
} else {
|
|
18467
18601
|
this.el.remove();
|
|
18468
18602
|
}
|
|
18469
|
-
this.shown = false;
|
|
18470
18603
|
if (open === this) open = null;
|
|
18471
18604
|
this.ctrl.onClose?.();
|
|
18472
18605
|
}
|
|
@@ -20356,6 +20489,8 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20356
20489
|
// src/ui/components/dialog/view.ts
|
|
20357
20490
|
var Dialog = class {
|
|
20358
20491
|
constructor(opts = {}) {
|
|
20492
|
+
this.opener = null;
|
|
20493
|
+
this.wasOpen = false;
|
|
20359
20494
|
const doc = (opts.host ?? document.body).ownerDocument;
|
|
20360
20495
|
injectStyles(DIALOG_STYLE_ID, DIALOG_CSS, doc);
|
|
20361
20496
|
const host = opts.host ?? doc.body;
|
|
@@ -20452,6 +20587,7 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20452
20587
|
const mid = String(this.ctrl.props.id);
|
|
20453
20588
|
this.handle = runMachine(this.ctrl.machine, this.ctrl.props, (service) => {
|
|
20454
20589
|
const api = this.ctrl.connect(service);
|
|
20590
|
+
if (this.wasOpen && !api.open) this.announce(false);
|
|
20455
20591
|
spreadProps(this.backdrop, api.getBackdropProps(), mid);
|
|
20456
20592
|
spreadProps(this.positioner, api.getPositionerProps(), mid);
|
|
20457
20593
|
spreadProps(this.panel, api.getContentProps(), mid);
|
|
@@ -20459,12 +20595,27 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20459
20595
|
spreadProps(close, api.getCloseTriggerProps(), mid);
|
|
20460
20596
|
this.backdrop.style.display = api.open ? "" : "none";
|
|
20461
20597
|
this.positioner.style.display = api.open ? "" : "none";
|
|
20598
|
+
if (api.open && !this.wasOpen) this.announce(true);
|
|
20599
|
+
if (this.wasOpen && !api.open) this.restoreOpener();
|
|
20600
|
+
this.wasOpen = api.open;
|
|
20462
20601
|
});
|
|
20463
20602
|
}
|
|
20603
|
+
/** Closing hands focus back to whatever opened it (Escape, the ✕, hide(), or a
|
|
20604
|
+
* teardown that outruns the machine's close notification). */
|
|
20605
|
+
restoreOpener() {
|
|
20606
|
+
const opener = this.opener;
|
|
20607
|
+
this.opener = null;
|
|
20608
|
+
if (opener?.isConnected) opener.focus({ preventScroll: true });
|
|
20609
|
+
}
|
|
20610
|
+
announce(open2) {
|
|
20611
|
+
const opener = this.opener === this.panel.ownerDocument.body ? null : this.opener;
|
|
20612
|
+
announceSurface(this.panel, open2, "dialog", opener);
|
|
20613
|
+
}
|
|
20464
20614
|
get open() {
|
|
20465
20615
|
return this.ctrl.connect(this.handle.service).open;
|
|
20466
20616
|
}
|
|
20467
20617
|
show() {
|
|
20618
|
+
this.opener = this.panel.ownerDocument.activeElement;
|
|
20468
20619
|
this.ctrl.connect(this.handle.service).setOpen(true);
|
|
20469
20620
|
}
|
|
20470
20621
|
hide() {
|
|
@@ -20479,6 +20630,11 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20479
20630
|
destroy() {
|
|
20480
20631
|
if (this.open) this.hide();
|
|
20481
20632
|
this.handle.stop();
|
|
20633
|
+
if (this.wasOpen) {
|
|
20634
|
+
this.wasOpen = false;
|
|
20635
|
+
this.announce(false);
|
|
20636
|
+
}
|
|
20637
|
+
this.restoreOpener();
|
|
20482
20638
|
this.backdrop.remove();
|
|
20483
20639
|
this.positioner.remove();
|
|
20484
20640
|
}
|
|
@@ -24648,15 +24804,23 @@ ${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
|
24648
24804
|
this.seg(x + w, y + h, x, y + h, lineWidth, c);
|
|
24649
24805
|
this.seg(x, y + h, x, y, lineWidth, c);
|
|
24650
24806
|
}
|
|
24651
|
-
/**
|
|
24807
|
+
/**
|
|
24808
|
+
* Filled circle (triangle fan), feathered like a line: the rim is padded by {@link AA_PAD} and
|
|
24809
|
+
* edgeDist runs from 0 at the center to the padded radius at the rim, with edgeHalf = r. The
|
|
24810
|
+
* distance grows linearly along each spoke, so the shader's line feather gives a round soft edge.
|
|
24811
|
+
*/
|
|
24652
24812
|
circle(cx, cy, r, c, segments = 16) {
|
|
24653
|
-
|
|
24813
|
+
const ext = r + AA_PAD;
|
|
24814
|
+
let px = cx + ext;
|
|
24654
24815
|
let py = cy;
|
|
24816
|
+
this.ensure(segments * 3);
|
|
24655
24817
|
for (let i = 1; i <= segments; i += 1) {
|
|
24656
24818
|
const a = i / segments * Math.PI * 2;
|
|
24657
|
-
const nx = cx + Math.cos(a) *
|
|
24658
|
-
const ny = cy + Math.sin(a) *
|
|
24659
|
-
this.
|
|
24819
|
+
const nx = cx + Math.cos(a) * ext;
|
|
24820
|
+
const ny = cy + Math.sin(a) * ext;
|
|
24821
|
+
this.v(cx, cy, c, 0, r);
|
|
24822
|
+
this.v(px, py, c, ext, r);
|
|
24823
|
+
this.v(nx, ny, c, ext, r);
|
|
24660
24824
|
px = nx;
|
|
24661
24825
|
py = ny;
|
|
24662
24826
|
}
|
|
@@ -24837,7 +25001,7 @@ void main() {
|
|
|
24837
25001
|
}
|
|
24838
25002
|
mount(canvas) {
|
|
24839
25003
|
this.canvas = canvas;
|
|
24840
|
-
this.gl = canvas.getContext("webgl2", { alpha: true, antialias:
|
|
25004
|
+
this.gl = canvas.getContext("webgl2", { alpha: true, antialias: false, depth: false, stencil: false, premultipliedAlpha: true });
|
|
24841
25005
|
if (!this.gl) return;
|
|
24842
25006
|
if (!this.initGL()) {
|
|
24843
25007
|
this.gl = null;
|
|
@@ -26289,7 +26453,7 @@ void main() {
|
|
|
26289
26453
|
this.deps.drawingsPointerUp?.(x, y, this.snapMode(e));
|
|
26290
26454
|
} else if (tapRelease && this.region === "data") {
|
|
26291
26455
|
this.deps.onClick(x, y);
|
|
26292
|
-
} else if (this.dragging && this.region === "data") {
|
|
26456
|
+
} else if (this.dragging && this.region === "data" && wasTouch) {
|
|
26293
26457
|
const stale = e.timeStamp - this.lastT > FLING_STALE_MS;
|
|
26294
26458
|
if (!stale && Math.abs(this.vx) > FLING_MIN_SPEED) {
|
|
26295
26459
|
const pitch = this.deps.getCoords().pxPerBar();
|
|
@@ -32745,6 +32909,12 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
32745
32909
|
activeDragId() {
|
|
32746
32910
|
return this.state.kind === "pressed" && this.state.moved ? this.state.id : null;
|
|
32747
32911
|
}
|
|
32912
|
+
/** The store drawings a live drag is moving — the pressed one and its riders — or none
|
|
32913
|
+
* before the drag passes the slop. A Ctrl-drag moves copies, so its sources stay put. */
|
|
32914
|
+
movingIds() {
|
|
32915
|
+
if (this.state.kind !== "pressed" || !this.state.moved || this.state.clones) return /* @__PURE__ */ new Set();
|
|
32916
|
+
return /* @__PURE__ */ new Set([this.state.id, ...this.state.riders.map((r) => r.id)]);
|
|
32917
|
+
}
|
|
32748
32918
|
/** The drawing under a press that has not been released yet (drag or click undecided), or null. */
|
|
32749
32919
|
pressedId() {
|
|
32750
32920
|
return this.state.kind === "pressed" ? this.state.id : null;
|
|
@@ -33403,6 +33573,17 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
33403
33573
|
}
|
|
33404
33574
|
}));
|
|
33405
33575
|
}
|
|
33576
|
+
if (drawing instanceof FibRetracement) {
|
|
33577
|
+
const fib = drawing;
|
|
33578
|
+
grid.appendChild(fieldRow({
|
|
33579
|
+
label: "Reverse",
|
|
33580
|
+
bool: true,
|
|
33581
|
+
toggle: {
|
|
33582
|
+
checked: fib.reverse,
|
|
33583
|
+
onChange: (v) => actions.patch({ reverse: v })
|
|
33584
|
+
}
|
|
33585
|
+
}));
|
|
33586
|
+
}
|
|
33406
33587
|
levels.forEach((lv, i) => {
|
|
33407
33588
|
const row = document.createElement("div");
|
|
33408
33589
|
row.className = "vela-field-span";
|
|
@@ -34770,6 +34951,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
34770
34951
|
);
|
|
34771
34952
|
}
|
|
34772
34953
|
}
|
|
34954
|
+
announceSurface(fly, true, "menu", cell);
|
|
34773
34955
|
}
|
|
34774
34956
|
openMagnetFlyout() {
|
|
34775
34957
|
const cell = this.magnetCell;
|
|
@@ -34793,6 +34975,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
34793
34975
|
})
|
|
34794
34976
|
);
|
|
34795
34977
|
}
|
|
34978
|
+
announceSurface(fly, true, "menu", cell);
|
|
34796
34979
|
}
|
|
34797
34980
|
flyoutHeader(text) {
|
|
34798
34981
|
const t = this.theme;
|
|
@@ -34861,9 +35044,11 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
34861
35044
|
}
|
|
34862
35045
|
closeFlyout() {
|
|
34863
35046
|
this.starEls.clear();
|
|
34864
|
-
|
|
34865
|
-
|
|
35047
|
+
const fly = this.flyout;
|
|
35048
|
+
if (fly) {
|
|
34866
35049
|
this.flyout = null;
|
|
35050
|
+
announceSurface(fly, false, "menu", this.flyoutCell);
|
|
35051
|
+
fly.remove();
|
|
34867
35052
|
this.flyoutCell?.classList.remove("vela-open");
|
|
34868
35053
|
this.flyoutCell = null;
|
|
34869
35054
|
this.flyoutOwnerId = null;
|
|
@@ -35188,6 +35373,8 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
35188
35373
|
this.drawings = [];
|
|
35189
35374
|
/** Ids painted on an interleave layer this frame — the top canvas paints only their handles. */
|
|
35190
35375
|
this.sliced = /* @__PURE__ */ new Set();
|
|
35376
|
+
/** Interleaved drawings mid-drag: painted on the top canvas, left out of their slice. */
|
|
35377
|
+
this.lifted = /* @__PURE__ */ new Set();
|
|
35191
35378
|
/** Cached slice canvases, keyed `paneId|beforeZ`, reused across frames to avoid churn. */
|
|
35192
35379
|
this.sliceCache = /* @__PURE__ */ new Map();
|
|
35193
35380
|
/** Series boundaries per pane as of the last `prepareSlices` — lets a repaint between data
|
|
@@ -35275,7 +35462,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
35275
35462
|
selectedIds: () => this.selectedIds,
|
|
35276
35463
|
emit: (i) => this.emit(i),
|
|
35277
35464
|
changed: () => {
|
|
35278
|
-
this.
|
|
35465
|
+
this.syncLift();
|
|
35279
35466
|
this.render();
|
|
35280
35467
|
},
|
|
35281
35468
|
openSettings: (id, x, y) => this.openSettingsById(id, x, y),
|
|
@@ -35901,6 +36088,20 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
35901
36088
|
/** A drawing that paints inside the series stack changed (content, not hover): its pixels
|
|
35902
36089
|
* live in the backend composite, so this layer alone can't show the change — ask for a
|
|
35903
36090
|
* data frame, which re-runs `prepareSlices` before the backend composites. */
|
|
36091
|
+
/** A drawing being dragged leaves its interleave slice for the top canvas, so each pointer
|
|
36092
|
+
* move repaints one 2D layer instead of re-rasterizing and re-uploading a plot-sized slice
|
|
36093
|
+
* texture through the data frame. The slices rebuild once as the drag starts and once as it
|
|
36094
|
+
* ends (release, cancel), when the lifted set changes. */
|
|
36095
|
+
syncLift() {
|
|
36096
|
+
const moving = this.interaction.movingIds();
|
|
36097
|
+
let same = moving.size === this.lifted.size;
|
|
36098
|
+
if (same) {
|
|
36099
|
+
for (const id of moving) if (!this.lifted.has(id)) same = false;
|
|
36100
|
+
}
|
|
36101
|
+
if (same) return;
|
|
36102
|
+
this.lifted = new Set(moving);
|
|
36103
|
+
this.invalidateSlices();
|
|
36104
|
+
}
|
|
35904
36105
|
invalidateSlices() {
|
|
35905
36106
|
if (this.sliced.size > 0 || this.drawings.some((d) => this.isInterleaved(d))) this.deps.requestDataPaint();
|
|
35906
36107
|
}
|
|
@@ -35919,7 +36120,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
35919
36120
|
const theme = this.deps.theme();
|
|
35920
36121
|
const buckets = /* @__PURE__ */ new Map();
|
|
35921
36122
|
for (const d of this.drawings) {
|
|
35922
|
-
if (!d.visible) continue;
|
|
36123
|
+
if (!d.visible || this.lifted.has(d.id)) continue;
|
|
35923
36124
|
const beforeZ = sliceKeyFor(d.zIndex, this.lastBounds.get(d.paneId) ?? []);
|
|
35924
36125
|
if (beforeZ === null) continue;
|
|
35925
36126
|
const key = `${d.paneId}|${beforeZ}`;
|
|
@@ -35971,8 +36172,9 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
35971
36172
|
mutedLabel: edited instanceof TextLabel ? edited.id : null
|
|
35972
36173
|
};
|
|
35973
36174
|
this.painter.seriesLook = this.deps.seriesLook();
|
|
35974
|
-
|
|
35975
|
-
this.painter.
|
|
36175
|
+
const onTop = (d) => !this.isInterleaved(d) || this.lifted.has(d.id);
|
|
36176
|
+
this.painter.paintAll(ctx, this.drawings.filter(onTop), proj, this.deps.theme(), targets);
|
|
36177
|
+
this.painter.paintHighlights(ctx, this.drawings.filter((d) => !onTop(d)), proj, handleIdsFor(targets));
|
|
35976
36178
|
const clones = this.interaction.dragClones();
|
|
35977
36179
|
if (clones) this.painter.paintAll(ctx, clones, proj, this.deps.theme(), { selected: new Set(clones.map((c) => c.id)) });
|
|
35978
36180
|
this.layoutTextEditor();
|