@diagrammo/dgmo 0.53.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.d.ts +36 -0
- package/dist/advanced.js +159 -154
- package/dist/auto.js +142 -128
- package/dist/auto.mjs +775 -466
- package/dist/block.js +62 -60
- package/dist/chart-meta.js +50 -47
- package/dist/{charts-d3-DH2XA45I.js → charts-d3-25E4VWXO.js} +9 -8
- package/dist/chunk-2CW5ZTNH.js +58 -0
- package/dist/{chunk-PKNNHU7H.js → chunk-2NYXI35Z.js} +17 -10
- package/dist/{chunk-W5KMNC5U.js → chunk-2NZOHEP4.js} +9 -10
- package/dist/{chunk-6DCOIN4W.js → chunk-3FRO35WW.js} +768 -2
- package/dist/{chunk-6AUZPPAV.js → chunk-3KHJJP3J.js} +2 -2
- package/dist/{chunk-X3RXGSCZ.js → chunk-3SBHODJ4.js} +11 -11
- package/dist/{chunk-KUSAVOWZ.js → chunk-3SEEP2JM.js} +3 -3
- package/dist/{chunk-QWIBT6DS.js → chunk-47JNEKJA.js} +10 -10
- package/dist/{chunk-LHILKFDP.js → chunk-4T6OCSJ2.js} +9 -9
- package/dist/{chunk-XQ4KN6JQ.js → chunk-4ZIKWVSQ.js} +16 -15
- package/dist/{chunk-GMAH572Z.js → chunk-5VXU6MND.js} +2 -2
- package/dist/{chunk-HORZ5H2L.js → chunk-5XSNLXU5.js} +17 -17
- package/dist/{chunk-BFDVEO5R.js → chunk-62Y27T4C.js} +2 -2
- package/dist/{chunk-R5NH5BZG.js → chunk-6KL7TFLS.js} +6 -6
- package/dist/{chunk-UVDCHR4E.js → chunk-6OYDOQ2Q.js} +2 -2
- package/dist/{chunk-QI3BOLQB.js → chunk-7K6NDSXH.js} +4 -4
- package/dist/{chunk-27STWBOK.js → chunk-7SP4C6EV.js} +6 -8
- package/dist/{chunk-I46X5VUA.js → chunk-7TF3QOOD.js} +25 -1
- package/dist/{chunk-FGDSTT3F.js → chunk-7U4OR7CD.js} +2 -2
- package/dist/{chunk-VKNCC2GX.js → chunk-7UPFTBOW.js} +13 -13
- package/dist/{chunk-FT7TPPZ5.js → chunk-A3BDLDYG.js} +12 -12
- package/dist/{chunk-AZNXGWDC.js → chunk-ADCHLNWT.js} +7 -7
- package/dist/{chunk-CMVZWP32.js → chunk-AHTTKERF.js} +2 -2
- package/dist/{chunk-GAWKIIPO.js → chunk-AJFHNS67.js} +7 -7
- package/dist/{chunk-Q7AH665U.js → chunk-AQEYUVGJ.js} +111 -35
- package/dist/{chunk-BR7AYN76.js → chunk-B7N5KYXQ.js} +12 -12
- package/dist/chunk-BEOAKGNA.js +484 -0
- package/dist/{chunk-GABSL6TH.js → chunk-BM7MG6HT.js} +3 -3
- package/dist/{chunk-UKP5HWB5.js → chunk-BWYFIVZF.js} +4 -4
- package/dist/{chunk-7GUF6SDR.js → chunk-BZJIITYM.js} +9 -9
- package/dist/{chunk-RW5PEJ7D.js → chunk-C2UORMIA.js} +3 -3
- package/dist/{chunk-FXCB7H5O.js → chunk-CCGWX6AO.js} +2 -2
- package/dist/{chunk-AHXIMHDQ.js → chunk-COJW2NEY.js} +9 -9
- package/dist/{chunk-XY3UDKKH.js → chunk-COVYNAKJ.js} +4 -4
- package/dist/{chunk-GQ644SPD.js → chunk-CSHFU6LT.js} +14 -14
- package/dist/{chunk-JTMSWEIW.js → chunk-DLU643TF.js} +4 -4
- package/dist/{chunk-QAALSCKI.js → chunk-DPGQ5UMO.js} +12 -12
- package/dist/{chunk-I64ECJX3.js → chunk-EAI6XJ7D.js} +3 -3
- package/dist/{chunk-DWUMPMV2.js → chunk-EPRF3ZRV.js} +2 -2
- package/dist/{chunk-AIMLCDAO.js → chunk-EQOMY4PY.js} +2 -2
- package/dist/{chunk-XEAQDIMF.js → chunk-F7XM366V.js} +6 -6
- package/dist/{chunk-SG4PRYO3.js → chunk-FFVFZLRT.js} +49 -18
- package/dist/{chunk-LC3FFD43.js → chunk-FR6UFVSV.js} +12 -12
- package/dist/{chunk-6HTRCTAS.js → chunk-FVMKCZHF.js} +6 -4
- package/dist/{chunk-FUKNRLIJ.js → chunk-GK32ZFZY.js} +6 -6
- package/dist/{chunk-6KY7OCZC.js → chunk-GKYHWJXI.js} +3 -3
- package/dist/{chunk-NNYFQOTK.js → chunk-GQ5ECRP4.js} +10 -8
- package/dist/{chunk-PT4SW76W.js → chunk-HAA25PLC.js} +9 -9
- package/dist/{chunk-J7HI6G3G.js → chunk-HFEOOQ46.js} +6 -6
- package/dist/{chunk-KKHCNSKK.js → chunk-I47VHSPS.js} +5 -5
- package/dist/{chunk-YG2BEIQU.js → chunk-ICKXIMBA.js} +11 -11
- package/dist/{chunk-A44USUV7.js → chunk-ICZ7M6IZ.js} +23 -17
- package/dist/{chunk-HE5J53SZ.js → chunk-IOIMQHQ6.js} +3 -3
- package/dist/{chunk-3BEKKRH5.js → chunk-IYNKLCAZ.js} +8 -8
- package/dist/{chunk-774C2FF3.js → chunk-J7HQPVYH.js} +2 -2
- package/dist/{chunk-UFQJMOVZ.js → chunk-KBVOVDYP.js} +6 -6
- package/dist/{chunk-JHOAH4TI.js → chunk-KDK5EKUR.js} +2 -2
- package/dist/{chunk-VIRANCNY.js → chunk-KINOX74I.js} +14 -14
- package/dist/{chunk-VJHBSPGF.js → chunk-KQ3FNRGR.js} +3 -3
- package/dist/{chunk-U7NKYLX2.js → chunk-KQYQECWQ.js} +13 -13
- package/dist/{chunk-GMIJ35PW.js → chunk-KS5ZSM5T.js} +13 -13
- package/dist/{chunk-FLDC7ZAK.js → chunk-KV4HLIJE.js} +2 -2
- package/dist/{chunk-PYO4TJJ3.js → chunk-LPJ6H5X4.js} +11 -11
- package/dist/{chunk-LQHVDZYC.js → chunk-LRSW4JLE.js} +4 -4
- package/dist/{chunk-VRRDUYOK.js → chunk-M24VXUFG.js} +3 -3
- package/dist/{chunk-22OQWBWD.js → chunk-M3H7ZE6C.js} +10 -10
- package/dist/{chunk-MA3HJZHB.js → chunk-MTZOXISJ.js} +7 -7
- package/dist/{chunk-GWQJKTFS.js → chunk-N7BSBAVP.js} +94 -94
- package/dist/{chunk-65V6IRFN.js → chunk-NUTWTV6G.js} +10 -10
- package/dist/{chunk-HNBY6CNV.js → chunk-O576GYAP.js} +2 -2
- package/dist/{chunk-3CZLWOCI.js → chunk-OJ435DQZ.js} +3 -3
- package/dist/{chunk-BD3WGY4T.js → chunk-OR3R27CU.js} +2 -2
- package/dist/{chunk-2QC4HXCY.js → chunk-OSXQKC3S.js} +8 -10
- package/dist/{chunk-4RGZFA7H.js → chunk-Q5IHQ4NW.js} +11 -1
- package/dist/{chunk-ALYZ3MAA.js → chunk-QBYP2FBZ.js} +8 -476
- package/dist/{chunk-4ASVFYB2.js → chunk-R5BGGBFF.js} +5 -5
- package/dist/{chunk-YR43LJT5.js → chunk-RIEAN4D5.js} +15 -12
- package/dist/{chunk-P3H7QVDH.js → chunk-RRGKMJYL.js} +6 -6
- package/dist/{chunk-XG4NWFPY.js → chunk-S7FOIURR.js} +13 -13
- package/dist/{chunk-NNUMX6WX.js → chunk-S7YFT3PO.js} +40 -15
- package/dist/{chunk-SQCBSFT5.js → chunk-SBOAZ7YK.js} +51 -263
- package/dist/{chunk-VGNIDAPQ.js → chunk-SSHS42QG.js} +4 -4
- package/dist/{chunk-SGPFVDUL.js → chunk-T3FAJAJT.js} +6 -6
- package/dist/{chunk-AN2DQB3G.js → chunk-T7Y554OK.js} +12 -12
- package/dist/chunk-TGOMHUOV.js +218 -0
- package/dist/{chunk-W2DINCHL.js → chunk-TJN2OIVG.js} +31 -16
- package/dist/{chunk-CK2GMDXD.js → chunk-TLNVYWPA.js} +2 -2
- package/dist/{chunk-CQFNIIQN.js → chunk-U4IN6AHE.js} +2 -2
- package/dist/{chunk-HOXKNRON.js → chunk-UEU6IYKY.js} +2 -2
- package/dist/{chunk-UK6DKJLD.js → chunk-UIT7E6UF.js} +4 -4
- package/dist/{chunk-IQJCVREL.js → chunk-VMSBMIHW.js} +6 -6
- package/dist/{chunk-FFXCKZOU.js → chunk-VQFDBNYF.js} +3 -3
- package/dist/{chunk-PV2QO7QL.js → chunk-W6PCFRPL.js} +2 -2
- package/dist/{chunk-UQRIKAMH.js → chunk-WKNAJ4BR.js} +13 -13
- package/dist/{chunk-4WGMGKCZ.js → chunk-WW4BQ744.js} +11 -11
- package/dist/{chunk-ZXUAPTCK.js → chunk-WWHECSYZ.js} +2 -2
- package/dist/{chunk-4K42RUGC.js → chunk-XWODFBHJ.js} +43 -12
- package/dist/{chunk-VAO6ANGC.js → chunk-YENNFS5F.js} +9 -9
- package/dist/cli.cjs +160 -146
- package/dist/completion-registry.d.ts +129 -0
- package/dist/completion-registry.js +1270 -0
- package/dist/{compute-G55RG53N.js → compute-JAP5E2E4.js} +2 -2
- package/dist/dgmo-router-TGZWFIZO.js +88 -0
- package/dist/{dimensions-K6PGYYGT.js → dimensions-L6BXQXXL.js} +8 -8
- package/dist/editor.js +18 -0
- package/dist/element.js +142 -128
- package/dist/element.mjs +775 -466
- package/dist/{flowchart-parser-LALR6J6F.js → flowchart-parser-UKYOW3VM.js} +5 -5
- package/dist/{flowchart-renderer-DXYB5YRF.js → flowchart-renderer-DCFKUDDR.js} +9 -9
- package/dist/highlight.js +18 -0
- package/dist/index.js +65 -62
- package/dist/{layout-WCAIKGZG.js → layout-25Y3VDYF.js} +5 -5
- package/dist/layout-4SPLI4HG.js +15 -0
- package/dist/{layout-E6HR6PXH.js → layout-A6OIGZN2.js} +3 -3
- package/dist/{layout-3BVDMKXI.js → layout-CH4HFFRD.js} +4 -4
- package/dist/{layout-ZE5DRJWX.js → layout-G2ABQJQZ.js} +4 -4
- package/dist/{layout-3V2A4MUE.js → layout-ITLPDG6M.js} +6 -5
- package/dist/{layout-WSMPBQ4Q.js → layout-NF4EWFLT.js} +3 -3
- package/dist/layout-NY7MHJCL.js +15 -0
- package/dist/{layout-4IHCMWZN.js → layout-QBNAMEOA.js} +4 -4
- package/dist/{layout-OL2XFJXA.js → layout-SP7HJWKA.js} +3 -3
- package/dist/{layout-search-34DPZD43.js → layout-search-LUI475P3.js} +9 -4
- package/dist/{legend-constants-P5EQWRQQ.js → legend-constants-B77VKB3R.js} +7 -2
- package/dist/{parser-5QPFOB5F.js → parser-2UWWNTFL.js} +4 -4
- package/dist/{parser-CKA3QMAG.js → parser-3RXYQSA7.js} +5 -5
- package/dist/{parser-GKP2MHHL.js → parser-5C3PEZK3.js} +3 -3
- package/dist/{parser-275KP7JO.js → parser-66RYGJRB.js} +5 -6
- package/dist/{parser-7JHWEWXM.js → parser-6GN5YJBJ.js} +4 -4
- package/dist/{parser-XVPTRWZ4.js → parser-6MQM7WT3.js} +4 -4
- package/dist/{parser-7JVIDLLR.js → parser-7UI6UQ7B.js} +4 -4
- package/dist/{parser-5HQXCNOS.js → parser-B2A7XOAK.js} +3 -3
- package/dist/{parser-UWRX52PC.js → parser-CCNJKDDA.js} +4 -4
- package/dist/{parser-CRKLXGW7.js → parser-ESHNUFME.js} +4 -4
- package/dist/{parser-EXNBDNGY.js → parser-F4FEU57T.js} +3 -3
- package/dist/{parser-IVGHXLZP.js → parser-FHRMFUNX.js} +4 -3
- package/dist/{parser-XNKJCMMA.js → parser-FPCWDYQV.js} +4 -4
- package/dist/{parser-ZQDQTB4X.js → parser-FY3YFFBS.js} +5 -5
- package/dist/{parser-VOERD6XR.js → parser-GML6V2KZ.js} +4 -4
- package/dist/{parser-3CODK6RG.js → parser-HA3PF5FL.js} +4 -4
- package/dist/{parser-GN2MM5CC.js → parser-KTYF6WO5.js} +3 -3
- package/dist/{parser-ZGNXYFPS.js → parser-LTA2BOZO.js} +3 -3
- package/dist/{parser-FOOFEJQU.js → parser-LU7UAKNB.js} +4 -4
- package/dist/{parser-NNIL3HXU.js → parser-MHKYQPC2.js} +3 -3
- package/dist/{parser-IKWK2ZU3.js → parser-MVSYFK63.js} +4 -5
- package/dist/{parser-3VSWEKBF.js → parser-O7YQYFEN.js} +4 -4
- package/dist/{parser-YSLNDFLV.js → parser-OPIXXUY4.js} +4 -5
- package/dist/{parser-RNLTBIJ6.js → parser-S4EJPNVN.js} +4 -4
- package/dist/{parser-G26MTBFS.js → parser-T3D7BV6O.js} +3 -3
- package/dist/{parser-3KIGEEJM.js → parser-VVE4THG3.js} +4 -4
- package/dist/{parser-5FGJSQNS.js → parser-WPPJGB4R.js} +4 -4
- package/dist/{parser-27Z76SN3.js → parser-X5XLFY4Z.js} +4 -4
- package/dist/{parser-6B6SSZT7.js → parser-XCPMEB2Z.js} +3 -3
- package/dist/{parser-6PPHAXXH.js → parser-XRDUX2AR.js} +5 -5
- package/dist/{parser-FF4BMRSB.js → parser-YPWYT46P.js} +4 -4
- package/dist/{parser-4E4I3GNT.js → parser-YULS5MLD.js} +4 -4
- package/dist/{renderer-ZBTEX2JK.js → renderer-2DME63VZ.js} +4 -4
- package/dist/{renderer-RLMOTXZ6.js → renderer-3VY3VXJE.js} +13 -13
- package/dist/{renderer-6WRYVM5R.js → renderer-4A32DX5L.js} +8 -8
- package/dist/{renderer-UPF7NRTI.js → renderer-4K5YYX5R.js} +11 -11
- package/dist/{renderer-HIFQVEJA.js → renderer-6CFML5G3.js} +9 -9
- package/dist/{renderer-7NQSTQMQ.js → renderer-7HMZ5OCJ.js} +4 -4
- package/dist/{renderer-NE5W7CQP.js → renderer-B7Y6I7JX.js} +6 -5
- package/dist/{renderer-LVZAHRP6.js → renderer-C3RI4OPJ.js} +11 -12
- package/dist/{renderer-COLQFSFV.js → renderer-CJ56SUMF.js} +9 -9
- package/dist/{renderer-WFSUBKUL.js → renderer-COJZZ4F6.js} +8 -8
- package/dist/{renderer-SQ54MDSA.js → renderer-FXMGCSRP.js} +9 -9
- package/dist/{renderer-TYHGXAVT.js → renderer-G4UOW3RH.js} +4 -4
- package/dist/{renderer-YUXGXGSW.js → renderer-HQ4JFZOV.js} +9 -9
- package/dist/{renderer-JTCX6PCG.js → renderer-LHVCKEWF.js} +9 -9
- package/dist/{renderer-WNFXYYGL.js → renderer-OZX5KGQM.js} +8 -8
- package/dist/{renderer-CWEFGEIC.js → renderer-P3YQES7B.js} +13 -13
- package/dist/{renderer-UKXW2QPE.js → renderer-PLVIARM7.js} +9 -8
- package/dist/{renderer-5MPN7CXZ.js → renderer-RA4PTAMF.js} +5 -5
- package/dist/{renderer-JCZG6AYU.js → renderer-RMAM2SOJ.js} +10 -10
- package/dist/{renderer-JWGQSTMR.js → renderer-SES7QZYL.js} +14 -14
- package/dist/{renderer-KARQF3F3.js → renderer-TQ5QDZOE.js} +8 -8
- package/dist/{renderer-6EN5XXJZ.js → renderer-V5SNTPAM.js} +10 -10
- package/dist/{renderer-QD2SJF2I.js → renderer-WVD6G2TS.js} +9 -9
- package/dist/{renderer-AK2WO4EI.js → renderer-X2LYSMLU.js} +4 -4
- package/dist/{renderer-VMH6L6CP.js → renderer-Y3NXZINM.js} +8 -8
- package/dist/{renderer-XTXSOK3L.js → renderer-YEFOOULC.js} +10 -10
- package/dist/{renderer-YUKPS27O.js → renderer-YP3P6UVT.js} +8 -8
- package/dist/{renderer-D3BRNOMV.js → renderer-YVMETH6V.js} +11 -11
- package/dist/{renderer-2C6DJRYN.js → renderer-Z4GNKNXO.js} +8 -8
- package/dist/{renderer-radial-WF6VOUOD.js → renderer-radial-VYBZAXXE.js} +9 -9
- package/dist/{state-parser-L7DHZIQO.js → state-parser-VIW2WNA5.js} +5 -5
- package/dist/{state-renderer-TFEUOP4H.js → state-renderer-H22AQD3U.js} +12 -12
- package/package.json +5 -1
- package/dist/chunk-YJVA3QUU.js +0 -734
- package/dist/dgmo-router-B4S23EBH.js +0 -86
- package/dist/layout-3M5UYJHY.js +0 -14
- package/dist/layout-KPQWJNAG.js +0 -14
package/dist/auto.mjs
CHANGED
|
@@ -429,6 +429,408 @@ var init_colors = __esm({
|
|
|
429
429
|
}
|
|
430
430
|
});
|
|
431
431
|
|
|
432
|
+
// src/directives-registry.ts
|
|
433
|
+
function tokensWhere(pred) {
|
|
434
|
+
const out = /* @__PURE__ */ new Set();
|
|
435
|
+
for (const e of DIRECTIVES_REGISTRY) if (pred(e)) out.add(e.token);
|
|
436
|
+
return out;
|
|
437
|
+
}
|
|
438
|
+
var DIRECTIVES_REGISTRY, ALL_REGISTRY_TOKENS, INFRA_TOP_LEVEL_OPTION_SET, INFRA_BEHAVIOR_KEY_SET, INFRA_EDGE_ONLY_KEY_SET, GANTT_OPTION_SET, GANTT_BOOLEAN_SET, MAP_DIRECTIVE_KEY_SET, REGISTRY_DIRECTIVE_TOKENS, REGISTRY_CONTROL_TOKENS, REGISTRY_STATUS_TOKENS, REGISTRY_MODIFIER_TOKENS, REGISTRY_COLON_KEY_TOKENS, REGISTRY_NON_HIGHLIGHT_TOKENS;
|
|
439
|
+
var init_directives_registry = __esm({
|
|
440
|
+
"src/directives-registry.ts"() {
|
|
441
|
+
"use strict";
|
|
442
|
+
DIRECTIVES_REGISTRY = [
|
|
443
|
+
// ── Universal date handling (§ BL-121) ───────────────────
|
|
444
|
+
// Accepted in every date-bearing chart (gantt, pert, countdown, timeline,
|
|
445
|
+
// event-line). Handled inline by each parser's prescan — no parser-Set
|
|
446
|
+
// membership here — so they only contribute highlighting (DIRECTIVE_KEYWORDS).
|
|
447
|
+
{ token: "year", category: "directive" },
|
|
448
|
+
{ token: "date-order", category: "directive" },
|
|
449
|
+
{ token: "no-current-year", category: "directive" },
|
|
450
|
+
// ── Infra ────────────────────────────────────────────────
|
|
451
|
+
// Top-level SLO options that are ALSO accepted as node colon-properties
|
|
452
|
+
// (dual membership). Highlight bare (kept in DIRECTIVE_KEYWORDS) — their
|
|
453
|
+
// rarer colon form stays keyword, an accepted minor false-positive.
|
|
454
|
+
{
|
|
455
|
+
token: "slo-availability",
|
|
456
|
+
category: "directive",
|
|
457
|
+
infra: ["top-level", "behavior"]
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
token: "slo-p90-latency-ms",
|
|
461
|
+
category: "directive",
|
|
462
|
+
infra: ["top-level", "behavior"]
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
token: "slo-warning-margin",
|
|
466
|
+
category: "directive",
|
|
467
|
+
infra: ["top-level", "behavior"]
|
|
468
|
+
},
|
|
469
|
+
// Top-level-only options (space-separated, bare).
|
|
470
|
+
{ token: "default-latency-ms", category: "directive", infra: ["top-level"] },
|
|
471
|
+
{ token: "default-uptime", category: "directive", infra: ["top-level"] },
|
|
472
|
+
{ token: "default-rps", category: "directive", infra: ["top-level"] },
|
|
473
|
+
// `active-tag` is shared with gantt + map (see below).
|
|
474
|
+
// Node behavior colon-keys — highlight as propertyName.
|
|
475
|
+
{ token: "latency-ms", colonKey: true, infra: ["behavior"] },
|
|
476
|
+
{ token: "uptime", colonKey: true, infra: ["behavior"] },
|
|
477
|
+
{ token: "instances", colonKey: true, infra: ["behavior"] },
|
|
478
|
+
{ token: "max-rps", colonKey: true, infra: ["behavior"] },
|
|
479
|
+
{ token: "cache-hit", colonKey: true, infra: ["behavior"] },
|
|
480
|
+
{ token: "firewall-block", colonKey: true, infra: ["behavior"] },
|
|
481
|
+
{ token: "ratelimit-rps", colonKey: true, infra: ["behavior"] },
|
|
482
|
+
{ token: "buffer", colonKey: true, infra: ["behavior"] },
|
|
483
|
+
{ token: "drain-rate", colonKey: true, infra: ["behavior"] },
|
|
484
|
+
{ token: "retention-hours", colonKey: true, infra: ["behavior"] },
|
|
485
|
+
{ token: "partitions", colonKey: true, infra: ["behavior"] },
|
|
486
|
+
{ token: "concurrency", colonKey: true, infra: ["behavior"] },
|
|
487
|
+
{ token: "duration-ms", colonKey: true, infra: ["behavior"] },
|
|
488
|
+
{ token: "cold-start-ms", colonKey: true, infra: ["behavior"] },
|
|
489
|
+
{ token: "cb-error-threshold", colonKey: true, infra: ["behavior"] },
|
|
490
|
+
{ token: "cb-latency-threshold-ms", colonKey: true, infra: ["behavior"] },
|
|
491
|
+
// Edge-only colon-key.
|
|
492
|
+
{ token: "rps", colonKey: true, infra: ["edge"] },
|
|
493
|
+
// ── Gantt ────────────────────────────────────────────────
|
|
494
|
+
{ token: "start", category: "directive", gantt: ["option"] },
|
|
495
|
+
{
|
|
496
|
+
token: "today-marker",
|
|
497
|
+
category: "directive",
|
|
498
|
+
gantt: ["option", "boolean"]
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
token: "critical-path",
|
|
502
|
+
category: "directive",
|
|
503
|
+
gantt: ["option", "boolean"]
|
|
504
|
+
},
|
|
505
|
+
{ token: "sprint-length", category: "directive", gantt: ["option"] },
|
|
506
|
+
{ token: "sprint-number", category: "directive", gantt: ["option"] },
|
|
507
|
+
{ token: "sprint-start", category: "directive", gantt: ["option"] },
|
|
508
|
+
{ token: "fill-tint", category: "directive", gantt: ["boolean"] },
|
|
509
|
+
{ token: "fill-solid", category: "directive", gantt: ["boolean"] },
|
|
510
|
+
{ token: "fill-outline", category: "directive", gantt: ["boolean"] },
|
|
511
|
+
// `chart` is a wireframe element keyword (CONTROL); gantt also accepts it as
|
|
512
|
+
// an option. Highlight family is control.
|
|
513
|
+
{ token: "chart", category: "control", gantt: ["option"] },
|
|
514
|
+
// `dependencies` is ON by default → almost never written bare (authors write
|
|
515
|
+
// `no-dependencies`, which DOES highlight). Bare word collides with prose and
|
|
516
|
+
// the specializer is context-free, so it stays plain. Present for parser
|
|
517
|
+
// Set derivation only.
|
|
518
|
+
{ token: "dependencies", noHighlight: true, gantt: ["option", "boolean"] },
|
|
519
|
+
// ── Map ──────────────────────────────────────────────────
|
|
520
|
+
// Per-element value→channel ramps (decision #20): the directive names the
|
|
521
|
+
// visual channel — `region-heat` (colour), `poi-size` (marker area),
|
|
522
|
+
// `flow-width` (stroke). The per-element key mirrors it (`heat:`/`size:`/`width:`).
|
|
523
|
+
{ token: "region-heat", category: "directive", map: true },
|
|
524
|
+
{ token: "poi-size", category: "directive", map: true },
|
|
525
|
+
{ token: "flow-width", category: "directive", map: true },
|
|
526
|
+
{ token: "locale", category: "directive", map: true },
|
|
527
|
+
{ token: "caption", category: "directive", map: true },
|
|
528
|
+
{ token: "no-coastline", category: "directive", map: true },
|
|
529
|
+
{ token: "no-relief", category: "directive", map: true },
|
|
530
|
+
{ token: "no-context-labels", category: "directive", map: true },
|
|
531
|
+
{ token: "no-region-labels", category: "directive", map: true },
|
|
532
|
+
{ token: "no-region-heat-value", category: "directive", map: true },
|
|
533
|
+
{ token: "no-poi-labels", category: "directive", map: true },
|
|
534
|
+
{ token: "no-colorize", category: "directive", map: true },
|
|
535
|
+
{ token: "no-cities", category: "directive", map: true },
|
|
536
|
+
{ token: "no-cluster-pois", category: "directive", map: true },
|
|
537
|
+
// ── Clock channel (BL-122): live local-time cards on POIs flagged `clock` ──
|
|
538
|
+
// Activation is the per-POI `clock` flag (peeled in the map parser, not a
|
|
539
|
+
// directive). `hours 9-17` / `days mon-fri` are the global availability
|
|
540
|
+
// window (reused verbatim from the clock chart type).
|
|
541
|
+
{ token: "hours", category: "directive", map: true },
|
|
542
|
+
{ token: "days", category: "directive", map: true },
|
|
543
|
+
// ── Shared across types ──────────────────────────────────
|
|
544
|
+
// `active-tag`: infra top-level option + gantt option + map directive.
|
|
545
|
+
// Treemap also accepts it (§24C.6, decision #48) — validated inline in its
|
|
546
|
+
// parser, so no chart-scoped Set is derived for it; highlighting comes from
|
|
547
|
+
// the global directive category here.
|
|
548
|
+
{
|
|
549
|
+
token: "active-tag",
|
|
550
|
+
category: "directive",
|
|
551
|
+
infra: ["top-level"],
|
|
552
|
+
gantt: ["option"],
|
|
553
|
+
map: true
|
|
554
|
+
},
|
|
555
|
+
// `title`: gantt option. (The data-chart `title` directive was removed in
|
|
556
|
+
// decision #48 — it now raises E_TITLE_DIRECTIVE; the token stays here for
|
|
557
|
+
// gantt.)
|
|
558
|
+
{ token: "title", category: "directive", gantt: ["option"] },
|
|
559
|
+
// `sort`: gantt option (also general, hand-listed).
|
|
560
|
+
{ token: "sort", category: "directive", gantt: ["option"] },
|
|
561
|
+
// `lane-by <group>`: swimlane axis (view-state). NB not `swimlane` — that's a
|
|
562
|
+
// chart type. Kanban reads it via its own KNOWN_OPTIONS; gantt via the switch.
|
|
563
|
+
{ token: "lane-by", category: "directive", gantt: ["option"] },
|
|
564
|
+
// `no-title`: gantt boolean + map directive (also general, hand-listed).
|
|
565
|
+
{ token: "no-title", category: "directive", gantt: ["boolean"], map: true },
|
|
566
|
+
// `no-legend`: universal (decision #48) — every chart that renders a legend
|
|
567
|
+
// accepts it, and charts without one take it as a harmless no-op. Parsed for
|
|
568
|
+
// most types via GLOBAL_BOOLEANS in utils/parsing; gantt derives its boolean
|
|
569
|
+
// Set from here, and map from `map: true`.
|
|
570
|
+
{ token: "no-legend", category: "directive", gantt: ["boolean"], map: true },
|
|
571
|
+
// ══════════════════════════════════════════════════════════
|
|
572
|
+
// Highlight-only vocab (no extractable parser Set).
|
|
573
|
+
// ══════════════════════════════════════════════════════════
|
|
574
|
+
// These chart types validate their directives with inline checks rather than
|
|
575
|
+
// a literal Set, so there is no parser literal to delete — the registry is
|
|
576
|
+
// simply their single declaration site for highlighting. Grouped by chart
|
|
577
|
+
// type. Categories route to the specializer-read sets in keywords.ts.
|
|
578
|
+
// ── Gantt (extras beyond the option/boolean Sets) ────────
|
|
579
|
+
{ token: "era", category: "directive" },
|
|
580
|
+
{ token: "marker", category: "directive" },
|
|
581
|
+
{ token: "holiday", category: "directive" },
|
|
582
|
+
// `workweek` is also the canonical weekday-window directive on clock and map
|
|
583
|
+
// clock-cards (decision #48; `days` stays as the legacy alias).
|
|
584
|
+
{ token: "workweek", category: "directive", map: true },
|
|
585
|
+
{ token: "no-dependencies", category: "directive" },
|
|
586
|
+
// ── Tech-radar ───────────────────────────────────────────
|
|
587
|
+
{ token: "rings", category: "directive" },
|
|
588
|
+
// Blip listing is default-on everywhere (decision #48): `no-blip-legend`
|
|
589
|
+
// suppresses it; `show-blip-legend` stays as the parse-accepted legacy no-op.
|
|
590
|
+
{ token: "no-blip-legend", category: "directive" },
|
|
591
|
+
{ token: "show-blip-legend", category: "directive" },
|
|
592
|
+
{ token: "trend", category: "directive" },
|
|
593
|
+
// ── Tags / shared directives ─────────────────────────────
|
|
594
|
+
{ token: "tags", category: "directive" },
|
|
595
|
+
{ token: "import", category: "directive" },
|
|
596
|
+
{ token: "hide", category: "directive" },
|
|
597
|
+
{ token: "direction", category: "directive" },
|
|
598
|
+
// ── Clock ────────────────────────────────────────────────
|
|
599
|
+
// The board's flat directives — highlight-only (the parser validates them
|
|
600
|
+
// inline, no extractable Set). `no-title` + `direction` are already listed
|
|
601
|
+
// above (shared). Values (analog is a bare flag; color-by's
|
|
602
|
+
// place|work|daylight|time|none) highlight as plain tokens.
|
|
603
|
+
{ token: "analog", category: "directive" },
|
|
604
|
+
{ token: "hours", category: "directive" },
|
|
605
|
+
{ token: "days", category: "directive" },
|
|
606
|
+
{ token: "no-sun", category: "directive" },
|
|
607
|
+
{ token: "time-24", category: "directive" },
|
|
608
|
+
{ token: "color-by", category: "directive" },
|
|
609
|
+
// ── Boxes-and-lines ──────────────────────────────────────
|
|
610
|
+
// `heat <Label> [low] [high]` is the value→colour ramp directive, but `heat`
|
|
611
|
+
// is NOT registered as a directive keyword: it is dual-use with the `heat:`
|
|
612
|
+
// metadata key (decision #20), and a token in DIRECTIVE_KEYWORDS would block the
|
|
613
|
+
// ATTRIBUTE_KEYS colon-gate from reclassifying `heat:` as a propertyName. So
|
|
614
|
+
// `heat` lives only in the reserved-key registry + ATTRIBUTE_KEYS and highlights
|
|
615
|
+
// as a property in both positions — exactly the treemap `heat` precedent.
|
|
616
|
+
// Box values render by default since decision #48; `show-values` stays as
|
|
617
|
+
// the parse-accepted legacy no-op (suppress with the shared `no-value`).
|
|
618
|
+
{ token: "show-values", category: "directive" },
|
|
619
|
+
// Treemap's legacy plural spelling of the same suppression (decision #48
|
|
620
|
+
// made the shared singular `no-value` canonical). Registered so a legacy
|
|
621
|
+
// document still highlights it as a directive rather than plain text.
|
|
622
|
+
{ token: "no-values", category: "directive" },
|
|
623
|
+
// ── Swimlane ─────────────────────────────────────────────
|
|
624
|
+
{ token: "lane", category: "directive" },
|
|
625
|
+
// ── ER ───────────────────────────────────────────────────
|
|
626
|
+
{ token: "notation", category: "directive" },
|
|
627
|
+
// ── Class ────────────────────────────────────────────────
|
|
628
|
+
{ token: "extends", category: "directive" },
|
|
629
|
+
{ token: "implements", category: "directive" },
|
|
630
|
+
{ token: "abstract", category: "directive" },
|
|
631
|
+
{ token: "interface", category: "directive" },
|
|
632
|
+
{ token: "enum", category: "directive" },
|
|
633
|
+
// ── C4 ───────────────────────────────────────────────────
|
|
634
|
+
{ token: "containers", category: "directive" },
|
|
635
|
+
{ token: "components", category: "directive" },
|
|
636
|
+
{ token: "deployment", category: "directive" },
|
|
637
|
+
{ token: "technology", category: "directive" },
|
|
638
|
+
// ── Infra (directives beyond the option/behavior Sets) ───
|
|
639
|
+
{ token: "sub-node-label", category: "directive" },
|
|
640
|
+
{ token: "show-sub-node-count", category: "directive" },
|
|
641
|
+
{ token: "animate", category: "directive" },
|
|
642
|
+
// ── Sequence ─────────────────────────────────────────────
|
|
643
|
+
{ token: "activations", category: "directive" },
|
|
644
|
+
{ token: "no-activations", category: "directive" },
|
|
645
|
+
// ── Map element leaders (not in DIRECTIVE_SET) ───────────
|
|
646
|
+
{ token: "poi", category: "directive" },
|
|
647
|
+
{ token: "route", category: "directive" },
|
|
648
|
+
// ── Data charts ──────────────────────────────────────────
|
|
649
|
+
{ token: "stacked", category: "directive" },
|
|
650
|
+
{ token: "no-name", category: "directive" },
|
|
651
|
+
{ token: "no-value", category: "directive" },
|
|
652
|
+
{ token: "no-percent", category: "directive" },
|
|
653
|
+
{ token: "series", category: "directive" },
|
|
654
|
+
{ token: "orientation", category: "directive" },
|
|
655
|
+
{ token: "x-label", category: "directive" },
|
|
656
|
+
{ token: "y-label", category: "directive" },
|
|
657
|
+
{ token: "size-label", category: "directive" },
|
|
658
|
+
{ token: "columns", category: "directive" },
|
|
659
|
+
{ token: "rows", category: "directive" },
|
|
660
|
+
{ token: "labels", category: "directive" },
|
|
661
|
+
{ token: "rotate", category: "directive" },
|
|
662
|
+
{ token: "scale", category: "directive" },
|
|
663
|
+
{ token: "values", category: "directive" },
|
|
664
|
+
{ token: "orientation-horizontal", category: "directive" },
|
|
665
|
+
// ── Slope ────────────────────────────────────────────────
|
|
666
|
+
{ token: "period", category: "directive" },
|
|
667
|
+
// ── Quadrant ─────────────────────────────────────────────
|
|
668
|
+
{ token: "x-axis", category: "directive" },
|
|
669
|
+
{ token: "y-axis", category: "directive" },
|
|
670
|
+
{ token: "top-right", category: "directive" },
|
|
671
|
+
{ token: "top-left", category: "directive" },
|
|
672
|
+
{ token: "bottom-right", category: "directive" },
|
|
673
|
+
{ token: "bottom-left", category: "directive" },
|
|
674
|
+
// ── Layout (cross-chart) ─────────────────────────────────
|
|
675
|
+
{ token: "direction-tb", category: "directive" },
|
|
676
|
+
{ token: "direction-lr", category: "directive" },
|
|
677
|
+
{ token: "orientation-vertical", category: "directive" },
|
|
678
|
+
// ── Pyramid ──────────────────────────────────────────────
|
|
679
|
+
{ token: "inverted", category: "directive" },
|
|
680
|
+
// ── Color / notes (cross-chart) ──────────────────────────
|
|
681
|
+
{ token: "color", category: "directive" },
|
|
682
|
+
{ token: "no-notes", category: "directive" },
|
|
683
|
+
// ── Emphasis family (§1.11, decision #49) ────────────────
|
|
684
|
+
// `highlight <Name>…` / `dim <Name>…` — the figure/ground axis, orthogonal
|
|
685
|
+
// to color (§1.5) and to the chart-wide `fill-*` family (§1.9). Both are
|
|
686
|
+
// chart-level directives taking a name list, validated inline by each
|
|
687
|
+
// adopting parser (no extractable Set), so the registry is their single
|
|
688
|
+
// declaration site for highlighting.
|
|
689
|
+
//
|
|
690
|
+
// `highlight` shipped on `family` long before this entry existed and was
|
|
691
|
+
// never registered — it had completions but highlighted as plain text. Both
|
|
692
|
+
// tokens are registered together so the whole family lights up at once.
|
|
693
|
+
//
|
|
694
|
+
// Supported on `sankey` and `family` today; every further chart type is a
|
|
695
|
+
// separate decision. Registering them globally is correct regardless: the
|
|
696
|
+
// Lezer specializer is context-free (it cannot know the chart type), and the
|
|
697
|
+
// same is already true of every other chart-scoped token here.
|
|
698
|
+
{ token: "highlight", category: "directive" },
|
|
699
|
+
{ token: "dim", category: "directive" },
|
|
700
|
+
// ── RACI ─────────────────────────────────────────────────
|
|
701
|
+
{ token: "roles", category: "directive" },
|
|
702
|
+
// ── Cycle ────────────────────────────────────────────────
|
|
703
|
+
{ token: "direction-counterclockwise", category: "directive" },
|
|
704
|
+
{ token: "circle-nodes", category: "directive" },
|
|
705
|
+
// ── Journey-map ──────────────────────────────────────────
|
|
706
|
+
{ token: "persona", category: "directive" },
|
|
707
|
+
// ── Function ─────────────────────────────────────────────
|
|
708
|
+
{ token: "x", category: "directive" },
|
|
709
|
+
{ token: "shade", category: "directive" },
|
|
710
|
+
// ── Wordcloud ────────────────────────────────────────────
|
|
711
|
+
{ token: "max", category: "directive" },
|
|
712
|
+
{ token: "size", category: "directive" },
|
|
713
|
+
// ── Arc ──────────────────────────────────────────────────
|
|
714
|
+
{ token: "order", category: "directive" },
|
|
715
|
+
// ── PERT ─────────────────────────────────────────────────
|
|
716
|
+
{ token: "time-unit", category: "directive" },
|
|
717
|
+
{ token: "default-confidence", category: "directive" },
|
|
718
|
+
{ token: "node-detail", category: "directive" },
|
|
719
|
+
{ token: "trials", category: "directive" },
|
|
720
|
+
{ token: "seed", category: "directive" },
|
|
721
|
+
{ token: "scrubber-trials", category: "directive" },
|
|
722
|
+
// `start-date` is also gantt's canonical project-start option (decision #48;
|
|
723
|
+
// bare `start` above stays as the legacy alias).
|
|
724
|
+
{ token: "start-date", category: "directive", gantt: ["option"] },
|
|
725
|
+
{ token: "end-date", category: "directive" },
|
|
726
|
+
// ── Goal ─────────────────────────────────────────────────
|
|
727
|
+
// Mode flags, value-key leaders, and opt-outs. `now`/`target` collide with
|
|
728
|
+
// label prose ("start now", "on target"), but the arrow-label demotion pass
|
|
729
|
+
// (see highlight-api LABEL_WORD_NODES) treats any keyword-bearing label as
|
|
730
|
+
// text and demotes them, so they highlight only as line leaders.
|
|
731
|
+
{ token: "thermometer", category: "directive" },
|
|
732
|
+
{ token: "gauge", category: "directive" },
|
|
733
|
+
{ token: "now", category: "directive" },
|
|
734
|
+
{ token: "target", category: "directive" },
|
|
735
|
+
{ token: "no-note", category: "directive" },
|
|
736
|
+
{ token: "no-auto-color", category: "directive" },
|
|
737
|
+
// ── Control-flow + wireframe element keywords (CONTROL) ──
|
|
738
|
+
{ token: "if", category: "control" },
|
|
739
|
+
{ token: "else", category: "control" },
|
|
740
|
+
{ token: "loop", category: "control" },
|
|
741
|
+
{ token: "parallel", category: "control" },
|
|
742
|
+
{ token: "note", category: "control" },
|
|
743
|
+
{ token: "nav", category: "control" },
|
|
744
|
+
{ token: "tabs", category: "control" },
|
|
745
|
+
{ token: "table", category: "control" },
|
|
746
|
+
{ token: "image", category: "control" },
|
|
747
|
+
{ token: "modal", category: "control" },
|
|
748
|
+
{ token: "skeleton", category: "control" },
|
|
749
|
+
{ token: "alert", category: "control" },
|
|
750
|
+
{ token: "progress", category: "control" },
|
|
751
|
+
{ token: "mobile", category: "control" },
|
|
752
|
+
// ── Kanban status keywords (STATUS) ──────────────────────
|
|
753
|
+
{ token: "na", category: "status" },
|
|
754
|
+
{ token: "todo", category: "status" },
|
|
755
|
+
{ token: "wip", category: "status" },
|
|
756
|
+
{ token: "done", category: "status" },
|
|
757
|
+
{ token: "blocked", category: "status" },
|
|
758
|
+
{ token: "in-progress", category: "status" },
|
|
759
|
+
{ token: "backlog", category: "status" },
|
|
760
|
+
{ token: "ready", category: "status" },
|
|
761
|
+
// ── Modifiers + ER column types/modifiers (MODIFIER) ─────
|
|
762
|
+
// `collapsed` is the bare trailing group-line flag made canonical by
|
|
763
|
+
// decision #48 (`[Fulfillment] collapsed`). It is deliberately a bare
|
|
764
|
+
// MODIFIER rather than a colon key: the legacy `collapsed: true` form still
|
|
765
|
+
// parses and still highlights (as `modifier` instead of `propertyName`),
|
|
766
|
+
// whereas leaving it colon-only left the canonical bare form as plain text.
|
|
767
|
+
{ token: "collapsed", category: "modifier" },
|
|
768
|
+
{ token: "as", category: "modifier" },
|
|
769
|
+
{ token: "alias", category: "modifier" },
|
|
770
|
+
{ token: "aka", category: "modifier" },
|
|
771
|
+
{ token: "position", category: "modifier" },
|
|
772
|
+
{ token: "default", category: "modifier" },
|
|
773
|
+
{ token: "pk", category: "modifier" },
|
|
774
|
+
{ token: "fk", category: "modifier" },
|
|
775
|
+
{ token: "nullable", category: "modifier" },
|
|
776
|
+
{ token: "unique", category: "modifier" },
|
|
777
|
+
{ token: "int", category: "modifier" },
|
|
778
|
+
{ token: "varchar", category: "modifier" },
|
|
779
|
+
{ token: "text", category: "modifier" },
|
|
780
|
+
{ token: "boolean", category: "modifier" },
|
|
781
|
+
{ token: "date", category: "modifier" },
|
|
782
|
+
{ token: "timestamp", category: "modifier" },
|
|
783
|
+
{ token: "float", category: "modifier" },
|
|
784
|
+
{ token: "decimal", category: "modifier" },
|
|
785
|
+
// ── Bracket ──────────────────────────────────────────────
|
|
786
|
+
// `beats` / `vs` are the infix match keywords; the rest are line directives.
|
|
787
|
+
// (`seed` and `no-legend` already appear above — shared, not re-listed.)
|
|
788
|
+
{ token: "beats", category: "control" },
|
|
789
|
+
{ token: "vs", category: "control" },
|
|
790
|
+
{ token: "rounds", category: "directive" },
|
|
791
|
+
{ token: "accent", category: "directive" },
|
|
792
|
+
{ token: "no-round", category: "modifier" },
|
|
793
|
+
{ token: "no-rounds", category: "modifier" },
|
|
794
|
+
{ token: "single-elim", category: "modifier" },
|
|
795
|
+
{ token: "double-elim", category: "modifier" },
|
|
796
|
+
{ token: "seeded", category: "modifier" }
|
|
797
|
+
];
|
|
798
|
+
ALL_REGISTRY_TOKENS = tokensWhere(() => true);
|
|
799
|
+
INFRA_TOP_LEVEL_OPTION_SET = tokensWhere(
|
|
800
|
+
(e) => !!e.infra?.includes("top-level")
|
|
801
|
+
);
|
|
802
|
+
INFRA_BEHAVIOR_KEY_SET = tokensWhere(
|
|
803
|
+
(e) => !!e.infra?.includes("behavior")
|
|
804
|
+
);
|
|
805
|
+
INFRA_EDGE_ONLY_KEY_SET = tokensWhere(
|
|
806
|
+
(e) => !!e.infra?.includes("edge")
|
|
807
|
+
);
|
|
808
|
+
GANTT_OPTION_SET = tokensWhere(
|
|
809
|
+
(e) => !!e.gantt?.includes("option")
|
|
810
|
+
);
|
|
811
|
+
GANTT_BOOLEAN_SET = tokensWhere(
|
|
812
|
+
(e) => !!e.gantt?.includes("boolean")
|
|
813
|
+
);
|
|
814
|
+
MAP_DIRECTIVE_KEY_SET = tokensWhere((e) => e.map === true);
|
|
815
|
+
REGISTRY_DIRECTIVE_TOKENS = tokensWhere(
|
|
816
|
+
(e) => e.category === "directive" && !e.colonKey && !e.noHighlight
|
|
817
|
+
);
|
|
818
|
+
REGISTRY_CONTROL_TOKENS = tokensWhere(
|
|
819
|
+
(e) => e.category === "control" && !e.colonKey && !e.noHighlight
|
|
820
|
+
);
|
|
821
|
+
REGISTRY_STATUS_TOKENS = tokensWhere(
|
|
822
|
+
(e) => e.category === "status" && !e.colonKey && !e.noHighlight
|
|
823
|
+
);
|
|
824
|
+
REGISTRY_MODIFIER_TOKENS = tokensWhere(
|
|
825
|
+
(e) => e.category === "modifier" && !e.colonKey && !e.noHighlight
|
|
826
|
+
);
|
|
827
|
+
REGISTRY_COLON_KEY_TOKENS = tokensWhere((e) => !!e.colonKey);
|
|
828
|
+
REGISTRY_NON_HIGHLIGHT_TOKENS = tokensWhere(
|
|
829
|
+
(e) => !!e.noHighlight
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
|
|
432
834
|
// src/utils/reserved-key-registry.ts
|
|
433
835
|
function staticRegistry(keys) {
|
|
434
836
|
return { keys: new Set(keys), tagAliases: /* @__PURE__ */ new Set() };
|
|
@@ -683,6 +1085,19 @@ function parseFirstLine(line11) {
|
|
|
683
1085
|
title: trimmed.substring(spaceIdx + 1).trim() || void 0
|
|
684
1086
|
};
|
|
685
1087
|
}
|
|
1088
|
+
function detectBadChartTypeDeclaration(line11, knownOptionKeys) {
|
|
1089
|
+
const trimmed = line11.trim();
|
|
1090
|
+
if (!trimmed || trimmed.includes(":")) return null;
|
|
1091
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
1092
|
+
const token = spaceIdx === -1 ? trimmed : trimmed.substring(0, spaceIdx);
|
|
1093
|
+
if (!CHART_TYPE_TOKEN_RE.test(token)) return null;
|
|
1094
|
+
const lower = token.toLowerCase();
|
|
1095
|
+
if (knownOptionKeys.has(lower) || ALL_REGISTRY_TOKENS.has(lower)) return null;
|
|
1096
|
+
if (spaceIdx === -1) return /\d/.test(token) ? null : token;
|
|
1097
|
+
const rest = trimmed.substring(spaceIdx + 1).trim();
|
|
1098
|
+
if (!rest || !TITLE_LIKE_RE.test(rest)) return null;
|
|
1099
|
+
return token;
|
|
1100
|
+
}
|
|
686
1101
|
function normalizeNumericToken(token) {
|
|
687
1102
|
if (!token.includes(",") && !token.includes("_")) return null;
|
|
688
1103
|
if (token.includes(",") && token.includes("_")) return null;
|
|
@@ -1028,12 +1443,13 @@ function warnUnknownMetaKeys(meta, registry, warn2, nameToScan) {
|
|
|
1028
1443
|
}
|
|
1029
1444
|
}
|
|
1030
1445
|
}
|
|
1031
|
-
var RECOGNIZED_COLOR_SET, ALL_CHART_TYPES, OPTION_NOCOLON_RE, GLOBAL_BOOLEANS, FILL_FAMILY_TOKENS, RESERVED_KEY_RE, AS_ALIAS_RE, POTENTIAL_META_RE;
|
|
1446
|
+
var RECOGNIZED_COLOR_SET, ALL_CHART_TYPES, OPTION_NOCOLON_RE, GLOBAL_BOOLEANS, FILL_FAMILY_TOKENS, CHART_TYPE_TOKEN_RE, TITLE_LIKE_RE, RESERVED_KEY_RE, AS_ALIAS_RE, POTENTIAL_META_RE;
|
|
1032
1447
|
var init_parsing = __esm({
|
|
1033
1448
|
"src/utils/parsing.ts"() {
|
|
1034
1449
|
"use strict";
|
|
1035
1450
|
init_colors();
|
|
1036
1451
|
init_diagnostics();
|
|
1452
|
+
init_directives_registry();
|
|
1037
1453
|
init_reserved_key_registry();
|
|
1038
1454
|
RECOGNIZED_COLOR_SET = new Set(
|
|
1039
1455
|
RECOGNIZED_COLOR_NAMES
|
|
@@ -1107,6 +1523,8 @@ var init_parsing = __esm({
|
|
|
1107
1523
|
"fill-solid",
|
|
1108
1524
|
"fill-outline"
|
|
1109
1525
|
]);
|
|
1526
|
+
CHART_TYPE_TOKEN_RE = /^[A-Za-z][A-Za-z0-9-]*$/;
|
|
1527
|
+
TITLE_LIKE_RE = /^[A-Za-z][A-Za-z\s'&,.\-—–]*$/;
|
|
1110
1528
|
RESERVED_KEY_RE = /^[A-Za-z][A-Za-z0-9_-]*$/;
|
|
1111
1529
|
AS_ALIAS_RE = /\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})$/;
|
|
1112
1530
|
POTENTIAL_META_RE = /\b([\w-]+)\s*:/;
|
|
@@ -4943,13 +5361,21 @@ __export(legend_constants_exports, {
|
|
|
4943
5361
|
LEGEND_PILL_PAD: () => LEGEND_PILL_PAD,
|
|
4944
5362
|
LEGEND_TOGGLE_DOT_R: () => LEGEND_TOGGLE_DOT_R,
|
|
4945
5363
|
LEGEND_TOGGLE_OFF_OPACITY: () => LEGEND_TOGGLE_OFF_OPACITY,
|
|
5364
|
+
legendChromeColors: () => legendChromeColors,
|
|
4946
5365
|
measureLegendText: () => measureLegendText,
|
|
4947
5366
|
truncateLegendText: () => truncateLegendText
|
|
4948
5367
|
});
|
|
5368
|
+
function legendChromeColors(palette, isDark) {
|
|
5369
|
+
return {
|
|
5370
|
+
groupBg: isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.textMuted, 98),
|
|
5371
|
+
pillBorder: mix(palette.textMuted, palette.bg, 50)
|
|
5372
|
+
};
|
|
5373
|
+
}
|
|
4949
5374
|
var LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_SIZE, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP, LEGEND_EYE_SIZE, LEGEND_EYE_GAP, LEGEND_ICON_W, LEGEND_MAX_ENTRY_ROWS, measureLegendText, truncateLegendText, EYE_OPEN_PATH, EYE_CLOSED_PATH, CONTROLS_ICON_PATH, LEGEND_TOGGLE_DOT_R, LEGEND_TOGGLE_OFF_OPACITY, LEGEND_GEAR_PILL_W;
|
|
4950
5375
|
var init_legend_constants = __esm({
|
|
4951
5376
|
"src/utils/legend-constants.ts"() {
|
|
4952
5377
|
"use strict";
|
|
5378
|
+
init_color_utils();
|
|
4953
5379
|
init_text_measure();
|
|
4954
5380
|
LEGEND_HEIGHT = 28;
|
|
4955
5381
|
LEGEND_PILL_PAD = 16;
|
|
@@ -5528,8 +5954,7 @@ function renderLegendD3(container, config, state, palette, isDark, callbacks, co
|
|
|
5528
5954
|
} else {
|
|
5529
5955
|
legendG.attr("data-legend-active", null);
|
|
5530
5956
|
}
|
|
5531
|
-
const groupBg
|
|
5532
|
-
const pillBorder = mix(palette.textMuted, palette.bg, 50);
|
|
5957
|
+
const { groupBg, pillBorder } = legendChromeColors(palette, isDark);
|
|
5533
5958
|
if (currentLayout.activeCapsule) {
|
|
5534
5959
|
renderCapsule(
|
|
5535
5960
|
legendG,
|
|
@@ -6032,7 +6457,7 @@ function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette,
|
|
|
6032
6457
|
const PAD_X = 10;
|
|
6033
6458
|
const FONT_SIZE = 11;
|
|
6034
6459
|
const GAP = 8;
|
|
6035
|
-
const pillBg =
|
|
6460
|
+
const pillBg = legendChromeColors(palette, isDark).groupBg;
|
|
6036
6461
|
let legendX = 0;
|
|
6037
6462
|
for (const grp of groups) {
|
|
6038
6463
|
const color = groupColorMap.get(grp.name) ?? textColor;
|
|
@@ -8967,6 +9392,30 @@ A
|
|
|
8967
9392
|
|
|
8968
9393
|
Orphan
|
|
8969
9394
|
latency-ms: 20
|
|
9395
|
+
`
|
|
9396
|
+
},
|
|
9397
|
+
INFRA_SPLIT_SUM: {
|
|
9398
|
+
// src/infra/parser.ts — makeDgmoError(..., 'warning', 'W_INFRA_SPLIT_SUM')
|
|
9399
|
+
code: "W_INFRA_SPLIT_SUM",
|
|
9400
|
+
severity: "warning",
|
|
9401
|
+
chartType: "infra",
|
|
9402
|
+
title: "Infra splits do not sum to 100%",
|
|
9403
|
+
message: (p) => `Sync splits from '${String(p.label ?? "")}' sum to ${String(
|
|
9404
|
+
p.sum ?? ""
|
|
9405
|
+
)}%, not 100% \u2014 the traffic leaving a node must add up to the traffic entering it, so the computed downstream RPS will be wrong. Async ('~>') edges are derived streams and are excluded from this sum.`,
|
|
9406
|
+
hint: "Adjust the split percentages so the sync edges from this node total 100%, or drop them and let dgmo split evenly.",
|
|
9407
|
+
example: `infra
|
|
9408
|
+
|
|
9409
|
+
edge
|
|
9410
|
+
rps: 1000
|
|
9411
|
+
-> LB
|
|
9412
|
+
|
|
9413
|
+
LB
|
|
9414
|
+
-> A split: 50%
|
|
9415
|
+
-> B split: 30%
|
|
9416
|
+
|
|
9417
|
+
A
|
|
9418
|
+
B
|
|
8970
9419
|
`
|
|
8971
9420
|
},
|
|
8972
9421
|
FLOWCHART_NODE_SUFFIX: {
|
|
@@ -14247,9 +14696,13 @@ function parseChart(content, palette) {
|
|
|
14247
14696
|
return fail(lineNumber, msg2);
|
|
14248
14697
|
}
|
|
14249
14698
|
}
|
|
14250
|
-
|
|
14251
|
-
|
|
14252
|
-
|
|
14699
|
+
const badType = detectBadChartTypeDeclaration(
|
|
14700
|
+
trimmed,
|
|
14701
|
+
KNOWN_FIRST_TOKENS
|
|
14702
|
+
);
|
|
14703
|
+
if (badType) {
|
|
14704
|
+
let msg2 = `Unsupported chart type: ${badType}. Supported types: ${[...VALID_TYPES].join(", ")}.`;
|
|
14705
|
+
const hint2 = suggest(badType.toLowerCase(), [...VALID_TYPES]);
|
|
14253
14706
|
if (hint2) msg2 += ` ${hint2}`;
|
|
14254
14707
|
return fail(lineNumber, msg2);
|
|
14255
14708
|
}
|
|
@@ -14435,6 +14888,14 @@ function parseChart(content, palette) {
|
|
|
14435
14888
|
...multiValue && { expectedValues: seriesCount }
|
|
14436
14889
|
});
|
|
14437
14890
|
if (dataValues) {
|
|
14891
|
+
if (multiValue) {
|
|
14892
|
+
const surplus = surplusValueDiagnostic(
|
|
14893
|
+
dataValues,
|
|
14894
|
+
seriesCount,
|
|
14895
|
+
lineNumber
|
|
14896
|
+
);
|
|
14897
|
+
if (surplus) result.diagnostics.push(surplus);
|
|
14898
|
+
}
|
|
14438
14899
|
const { label: rawLabel, color: pointColor } = extractColor(
|
|
14439
14900
|
dataValues.label,
|
|
14440
14901
|
palette,
|
|
@@ -14526,34 +14987,74 @@ function parseChart(content, palette) {
|
|
|
14526
14987
|
return result;
|
|
14527
14988
|
}
|
|
14528
14989
|
function parseDataRowValues(line11, options) {
|
|
14990
|
+
const quoted = line11.match(/^(["'])(.*?)\1\s+(\S.*)$/);
|
|
14991
|
+
if (quoted) {
|
|
14992
|
+
const label2 = quoted[2].trim();
|
|
14993
|
+
if (!label2) return null;
|
|
14994
|
+
const valueTokens = quoted[3].trim().split(/\s+/);
|
|
14995
|
+
const numeric2 = trailingNumerics(valueTokens, 0);
|
|
14996
|
+
if (numeric2.length !== valueTokens.length) return null;
|
|
14997
|
+
const limit = options?.multiValue ? options.expectedValues ?? Infinity : 1;
|
|
14998
|
+
return {
|
|
14999
|
+
label: label2,
|
|
15000
|
+
values: numeric2.slice(0, limit),
|
|
15001
|
+
bareLabel: label2,
|
|
15002
|
+
trailingNumericCount: numeric2.length,
|
|
15003
|
+
quotedLabel: true
|
|
15004
|
+
};
|
|
15005
|
+
}
|
|
14529
15006
|
const tokens = line11.split(/\s+/);
|
|
14530
15007
|
if (tokens.length < 2) return null;
|
|
15008
|
+
const numeric = trailingNumerics(tokens, 1);
|
|
15009
|
+
if (numeric.length === 0) return null;
|
|
15010
|
+
const bareLabel = tokens.slice(0, tokens.length - numeric.length).join(" ");
|
|
14531
15011
|
if (options?.multiValue) {
|
|
14532
15012
|
const limit = options.expectedValues ?? Infinity;
|
|
14533
|
-
const
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
const tok = tokens[idx];
|
|
14537
|
-
const normTok = normalizeNumericToken(tok) ?? tok;
|
|
14538
|
-
const num2 = parseFloat(normTok);
|
|
14539
|
-
if (isNaN(num2) || !isFinite(Number(normTok))) break;
|
|
14540
|
-
values.unshift(num2);
|
|
14541
|
-
idx--;
|
|
14542
|
-
}
|
|
14543
|
-
if (values.length === 0) return null;
|
|
14544
|
-
const label2 = tokens.slice(0, idx + 1).join(" ");
|
|
15013
|
+
const take = Math.min(numeric.length, limit);
|
|
15014
|
+
const values = numeric.slice(numeric.length - take);
|
|
15015
|
+
const label2 = tokens.slice(0, tokens.length - take).join(" ");
|
|
14545
15016
|
if (!label2) return null;
|
|
14546
|
-
return {
|
|
15017
|
+
return {
|
|
15018
|
+
label: label2,
|
|
15019
|
+
values,
|
|
15020
|
+
bareLabel,
|
|
15021
|
+
trailingNumericCount: numeric.length,
|
|
15022
|
+
quotedLabel: false
|
|
15023
|
+
};
|
|
14547
15024
|
}
|
|
14548
|
-
const lastToken = tokens[tokens.length - 1];
|
|
14549
|
-
const normalizedLast = normalizeNumericToken(lastToken) ?? lastToken;
|
|
14550
|
-
const num = parseFloat(normalizedLast);
|
|
14551
|
-
if (isNaN(num) || !isFinite(Number(normalizedLast))) return null;
|
|
14552
15025
|
const label = tokens.slice(0, -1).join(" ");
|
|
14553
15026
|
if (!label) return null;
|
|
14554
|
-
return {
|
|
15027
|
+
return {
|
|
15028
|
+
label,
|
|
15029
|
+
// numeric.length >= 1 by the guard above.
|
|
15030
|
+
values: [numeric[numeric.length - 1]],
|
|
15031
|
+
bareLabel,
|
|
15032
|
+
trailingNumericCount: numeric.length,
|
|
15033
|
+
quotedLabel: false
|
|
15034
|
+
};
|
|
14555
15035
|
}
|
|
14556
|
-
|
|
15036
|
+
function surplusValueDiagnostic(row, expectedValues, lineNumber) {
|
|
15037
|
+
if (row.quotedLabel || row.trailingNumericCount <= expectedValues)
|
|
15038
|
+
return null;
|
|
15039
|
+
const expectation = expectedValues === 1 ? "but only 1 value is expected" : `but ${expectedValues} series defined`;
|
|
15040
|
+
return makeDgmoError(
|
|
15041
|
+
lineNumber,
|
|
15042
|
+
`Data point "${row.bareLabel}" has ${row.trailingNumericCount} value(s), ${expectation}. If the label ends in a number, quote it: "${row.label}" ${row.values.join(" ")}`,
|
|
15043
|
+
"warning"
|
|
15044
|
+
);
|
|
15045
|
+
}
|
|
15046
|
+
function trailingNumerics(tokens, minIndex) {
|
|
15047
|
+
const values = [];
|
|
15048
|
+
for (let idx = tokens.length - 1; idx >= minIndex; idx--) {
|
|
15049
|
+
const tok = tokens[idx];
|
|
15050
|
+
const normTok = normalizeNumericToken(tok) ?? tok;
|
|
15051
|
+
const num = parseFloat(normTok);
|
|
15052
|
+
if (isNaN(num) || !isFinite(Number(normTok))) break;
|
|
15053
|
+
values.unshift(num);
|
|
15054
|
+
}
|
|
15055
|
+
return values;
|
|
15056
|
+
}
|
|
15057
|
+
var VALID_TYPES, KNOWN_OPTIONS3, DEFAULT_HOLE, KNOWN_BOOLEANS2, KNOWN_FIRST_TOKENS;
|
|
14557
15058
|
var init_chart = __esm({
|
|
14558
15059
|
"src/chart.ts"() {
|
|
14559
15060
|
"use strict";
|
|
@@ -14595,6 +15096,67 @@ var init_chart = __esm({
|
|
|
14595
15096
|
"fill",
|
|
14596
15097
|
"hole"
|
|
14597
15098
|
]);
|
|
15099
|
+
KNOWN_FIRST_TOKENS = /* @__PURE__ */ new Set([
|
|
15100
|
+
...KNOWN_OPTIONS3,
|
|
15101
|
+
...KNOWN_BOOLEANS2,
|
|
15102
|
+
...GLOBAL_BOOLEANS
|
|
15103
|
+
]);
|
|
15104
|
+
}
|
|
15105
|
+
});
|
|
15106
|
+
|
|
15107
|
+
// src/utils/emphasis.ts
|
|
15108
|
+
function isEmphasisToken(token) {
|
|
15109
|
+
return EMPHASIS_TOKENS.includes(token.toLowerCase());
|
|
15110
|
+
}
|
|
15111
|
+
function parseEmphasisDirective(line11, lineNumber) {
|
|
15112
|
+
const m = line11.trim().match(/^(highlight|dim)\s+(.+)$/i);
|
|
15113
|
+
if (!m) return null;
|
|
15114
|
+
const kind = m[1].toLowerCase();
|
|
15115
|
+
const raw = m[2].trim();
|
|
15116
|
+
if (!raw) return null;
|
|
15117
|
+
const hasComma = raw.includes(",");
|
|
15118
|
+
const names = (hasComma ? raw.split(",") : [raw]).map((n) => n.trim()).filter(Boolean);
|
|
15119
|
+
if (names.length === 0) return null;
|
|
15120
|
+
return { kind, names, ambiguous: !hasComma, raw, lineNumber };
|
|
15121
|
+
}
|
|
15122
|
+
function resolveEmphasis(directive, elementNames, expandHighlight) {
|
|
15123
|
+
if (!directive) return EMPTY;
|
|
15124
|
+
const norm = (s) => s.trim().toLowerCase().replace(/\s+/g, " ");
|
|
15125
|
+
const byNorm = /* @__PURE__ */ new Map();
|
|
15126
|
+
for (const name of elementNames) byNorm.set(norm(name), name);
|
|
15127
|
+
const match = (listed) => {
|
|
15128
|
+
const hit2 = /* @__PURE__ */ new Set();
|
|
15129
|
+
const unknown2 = [];
|
|
15130
|
+
for (const name of listed) {
|
|
15131
|
+
const found = byNorm.get(norm(name));
|
|
15132
|
+
if (found === void 0) unknown2.push(name);
|
|
15133
|
+
else hit2.add(found);
|
|
15134
|
+
}
|
|
15135
|
+
return { hit: hit2, unknown: unknown2 };
|
|
15136
|
+
};
|
|
15137
|
+
let { hit, unknown } = match(directive.names);
|
|
15138
|
+
if (directive.ambiguous && hit.size === 0) {
|
|
15139
|
+
const tokens = directive.raw.split(/\s+/).filter(Boolean);
|
|
15140
|
+
if (tokens.length > 1) {
|
|
15141
|
+
const retry = match(tokens);
|
|
15142
|
+
if (retry.hit.size > 0) ({ hit, unknown } = retry);
|
|
15143
|
+
}
|
|
15144
|
+
}
|
|
15145
|
+
if (hit.size === 0) return { dimmed: /* @__PURE__ */ new Set(), unknown };
|
|
15146
|
+
if (directive.kind === "dim") return { dimmed: hit, unknown };
|
|
15147
|
+
const lit = expandHighlight ? new Set(expandHighlight(hit)) : hit;
|
|
15148
|
+
const dimmed = /* @__PURE__ */ new Set();
|
|
15149
|
+
for (const name of byNorm.values()) if (!lit.has(name)) dimmed.add(name);
|
|
15150
|
+
return { dimmed, unknown };
|
|
15151
|
+
}
|
|
15152
|
+
var EMPHASIS_DIM_OPACITY, EMPHASIS_DIM_TEXT_OPACITY, EMPHASIS_TOKENS, EMPTY;
|
|
15153
|
+
var init_emphasis = __esm({
|
|
15154
|
+
"src/utils/emphasis.ts"() {
|
|
15155
|
+
"use strict";
|
|
15156
|
+
EMPHASIS_DIM_OPACITY = 0.28;
|
|
15157
|
+
EMPHASIS_DIM_TEXT_OPACITY = 0.5;
|
|
15158
|
+
EMPHASIS_TOKENS = Object.freeze(["highlight", "dim"]);
|
|
15159
|
+
EMPTY = { dimmed: /* @__PURE__ */ new Set(), unknown: [] };
|
|
14598
15160
|
}
|
|
14599
15161
|
});
|
|
14600
15162
|
|
|
@@ -14713,10 +15275,14 @@ function parseExtendedChartFull(content, palette) {
|
|
|
14713
15275
|
return result;
|
|
14714
15276
|
}
|
|
14715
15277
|
}
|
|
14716
|
-
|
|
15278
|
+
const badType = detectBadChartTypeDeclaration(
|
|
15279
|
+
trimmed,
|
|
15280
|
+
KNOWN_EXTENDED_FIRST_TOKENS
|
|
15281
|
+
);
|
|
15282
|
+
if (badType) {
|
|
14717
15283
|
const validTypes = [...VALID_EXTENDED_TYPES];
|
|
14718
|
-
let msg = `Unsupported chart type: ${
|
|
14719
|
-
const hint = suggest(
|
|
15284
|
+
let msg = `Unsupported chart type: ${badType}. Supported types: ${validTypes.join(", ")}.`;
|
|
15285
|
+
const hint = suggest(badType.toLowerCase(), validTypes);
|
|
14720
15286
|
if (hint) msg += ` ${hint}`;
|
|
14721
15287
|
const diag = makeDgmoError(lineNumber, msg);
|
|
14722
15288
|
result.diagnostics.push(diag);
|
|
@@ -14744,7 +15310,7 @@ function parseExtendedChartFull(content, palette) {
|
|
|
14744
15310
|
continue;
|
|
14745
15311
|
}
|
|
14746
15312
|
const arrowMatch = trimmed.match(
|
|
14747
|
-
/^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\
|
|
15313
|
+
/^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d,_]+(?:\.[\d]+)?)(?:\s+([A-Za-z][A-Za-z0-9_-]*))?\s*$/
|
|
14748
15314
|
);
|
|
14749
15315
|
if (arrowMatch) {
|
|
14750
15316
|
const [, rawSource, arrow, rawTarget, rawVal, rawLinkColor] = arrowMatch;
|
|
@@ -14793,12 +15359,9 @@ function parseExtendedChartFull(content, palette) {
|
|
|
14793
15359
|
}
|
|
14794
15360
|
if (sankeyStack.length > 0) {
|
|
14795
15361
|
const valColorMatch = trimmed.match(
|
|
14796
|
-
/(-?[\
|
|
15362
|
+
/(-?[\d,_]+(?:\.[\d]+)?)\s+([A-Za-z][A-Za-z0-9_-]*)\s*$/
|
|
14797
15363
|
);
|
|
14798
|
-
const strippedLine = valColorMatch ? trimmed.replace(
|
|
14799
|
-
/\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/,
|
|
14800
|
-
""
|
|
14801
|
-
) : trimmed;
|
|
15364
|
+
const strippedLine = valColorMatch ? trimmed.replace(/\s+[A-Za-z][A-Za-z0-9_-]*\s*$/, "") : trimmed;
|
|
14802
15365
|
const dataRow2 = parseDataRowValues(strippedLine);
|
|
14803
15366
|
if (dataRow2?.values.length === 1) {
|
|
14804
15367
|
const source = sankeyStack.at(-1).name;
|
|
@@ -14839,8 +15402,9 @@ function parseExtendedChartFull(content, palette) {
|
|
|
14839
15402
|
const isBareKeywordOption = spaceIdx2 < 0 && /^(fill-tint|fill-solid|fill-outline|no-name|no-value|no-percent|shade|no-title)$/i.test(
|
|
14840
15403
|
trimmed
|
|
14841
15404
|
);
|
|
14842
|
-
const
|
|
14843
|
-
|
|
15405
|
+
const leadToken = spaceIdx2 >= 0 ? trimmed.substring(0, spaceIdx2).toLowerCase() : "";
|
|
15406
|
+
const isValuedDirective = spaceIdx2 >= 0 && (leadToken === "layout" || isEmphasisToken(leadToken));
|
|
15407
|
+
if (!hasNumericSuffix && !isBareKeywordOption && !isValuedDirective) {
|
|
14844
15408
|
while (sankeyStack.length && sankeyStack.at(-1).indent >= indent) {
|
|
14845
15409
|
sankeyStack.pop();
|
|
14846
15410
|
}
|
|
@@ -14879,6 +15443,11 @@ function parseExtendedChartFull(content, palette) {
|
|
|
14879
15443
|
}
|
|
14880
15444
|
continue;
|
|
14881
15445
|
}
|
|
15446
|
+
if (isEmphasisToken(firstToken)) {
|
|
15447
|
+
const directive = parseEmphasisDirective(trimmed, lineNumber);
|
|
15448
|
+
if (directive) result.emphasis = directive;
|
|
15449
|
+
continue;
|
|
15450
|
+
}
|
|
14882
15451
|
if (firstToken === "title") {
|
|
14883
15452
|
result.diagnostics.push(emit(TITLE_DIRECTIVE_DX, lineNumber));
|
|
14884
15453
|
continue;
|
|
@@ -15176,7 +15745,7 @@ function getExtendedChartLegendGroups(parsed, colors) {
|
|
|
15176
15745
|
}
|
|
15177
15746
|
return [];
|
|
15178
15747
|
}
|
|
15179
|
-
var VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, EXTENDED_CHART_DOORS;
|
|
15748
|
+
var VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, KNOWN_EXTENDED_FIRST_TOKENS, EXTENDED_CHART_DOORS;
|
|
15180
15749
|
var init_data_chart_parser = __esm({
|
|
15181
15750
|
"src/data-chart-parser.ts"() {
|
|
15182
15751
|
"use strict";
|
|
@@ -15184,6 +15753,7 @@ var init_data_chart_parser = __esm({
|
|
|
15184
15753
|
init_colors();
|
|
15185
15754
|
init_parsing();
|
|
15186
15755
|
init_chart();
|
|
15756
|
+
init_emphasis();
|
|
15187
15757
|
VALID_EXTENDED_TYPES = /* @__PURE__ */ new Set([
|
|
15188
15758
|
"sankey",
|
|
15189
15759
|
"chord",
|
|
@@ -15205,7 +15775,13 @@ var init_data_chart_parser = __esm({
|
|
|
15205
15775
|
"no-percent",
|
|
15206
15776
|
"columns",
|
|
15207
15777
|
"rows",
|
|
15208
|
-
"x"
|
|
15778
|
+
"x",
|
|
15779
|
+
"highlight",
|
|
15780
|
+
"dim"
|
|
15781
|
+
]);
|
|
15782
|
+
KNOWN_EXTENDED_FIRST_TOKENS = /* @__PURE__ */ new Set([
|
|
15783
|
+
...KNOWN_EXTENDED_OPTIONS,
|
|
15784
|
+
...GLOBAL_BOOLEANS
|
|
15209
15785
|
]);
|
|
15210
15786
|
EXTENDED_CHART_DOORS = /* @__PURE__ */ new Set([
|
|
15211
15787
|
parseSankey,
|
|
@@ -16865,6 +17441,13 @@ function parseC4(content, palette) {
|
|
|
16865
17441
|
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
16866
17442
|
if (optMatch) {
|
|
16867
17443
|
const key = optMatch[1].trim().toLowerCase();
|
|
17444
|
+
if (key === "layout") {
|
|
17445
|
+
pushError(
|
|
17446
|
+
lineNumber,
|
|
17447
|
+
`'layout' is not a valid C4 option \u2014 C4 diagrams have a single layered layout with no algorithm to select. Use the 'direction-tb' (default) or 'direction-lr' booleans to change orientation (\xA77.7).`
|
|
17448
|
+
);
|
|
17449
|
+
continue;
|
|
17450
|
+
}
|
|
16868
17451
|
if (KNOWN_C4_OPTIONS.has(key)) {
|
|
16869
17452
|
options[key] = optMatch[2].trim();
|
|
16870
17453
|
continue;
|
|
@@ -17463,7 +18046,7 @@ var init_parser16 = __esm({
|
|
|
17463
18046
|
"cloud",
|
|
17464
18047
|
"external"
|
|
17465
18048
|
]);
|
|
17466
|
-
KNOWN_C4_OPTIONS = /* @__PURE__ */ new Set(["
|
|
18049
|
+
KNOWN_C4_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
|
|
17467
18050
|
KNOWN_C4_BOOLEANS = /* @__PURE__ */ new Set([
|
|
17468
18051
|
"direction-tb",
|
|
17469
18052
|
"direction-lr",
|
|
@@ -17494,390 +18077,6 @@ var init_parser16 = __esm({
|
|
|
17494
18077
|
}
|
|
17495
18078
|
});
|
|
17496
18079
|
|
|
17497
|
-
// src/directives-registry.ts
|
|
17498
|
-
function tokensWhere(pred) {
|
|
17499
|
-
const out = /* @__PURE__ */ new Set();
|
|
17500
|
-
for (const e of DIRECTIVES_REGISTRY) if (pred(e)) out.add(e.token);
|
|
17501
|
-
return out;
|
|
17502
|
-
}
|
|
17503
|
-
var DIRECTIVES_REGISTRY, INFRA_TOP_LEVEL_OPTION_SET, INFRA_BEHAVIOR_KEY_SET, INFRA_EDGE_ONLY_KEY_SET, GANTT_OPTION_SET, GANTT_BOOLEAN_SET, MAP_DIRECTIVE_KEY_SET, REGISTRY_DIRECTIVE_TOKENS, REGISTRY_CONTROL_TOKENS, REGISTRY_STATUS_TOKENS, REGISTRY_MODIFIER_TOKENS, REGISTRY_COLON_KEY_TOKENS, REGISTRY_NON_HIGHLIGHT_TOKENS;
|
|
17504
|
-
var init_directives_registry = __esm({
|
|
17505
|
-
"src/directives-registry.ts"() {
|
|
17506
|
-
"use strict";
|
|
17507
|
-
DIRECTIVES_REGISTRY = [
|
|
17508
|
-
// ── Universal date handling (§ BL-121) ───────────────────
|
|
17509
|
-
// Accepted in every date-bearing chart (gantt, pert, countdown, timeline,
|
|
17510
|
-
// event-line). Handled inline by each parser's prescan — no parser-Set
|
|
17511
|
-
// membership here — so they only contribute highlighting (DIRECTIVE_KEYWORDS).
|
|
17512
|
-
{ token: "year", category: "directive" },
|
|
17513
|
-
{ token: "date-order", category: "directive" },
|
|
17514
|
-
{ token: "no-current-year", category: "directive" },
|
|
17515
|
-
// ── Infra ────────────────────────────────────────────────
|
|
17516
|
-
// Top-level SLO options that are ALSO accepted as node colon-properties
|
|
17517
|
-
// (dual membership). Highlight bare (kept in DIRECTIVE_KEYWORDS) — their
|
|
17518
|
-
// rarer colon form stays keyword, an accepted minor false-positive.
|
|
17519
|
-
{
|
|
17520
|
-
token: "slo-availability",
|
|
17521
|
-
category: "directive",
|
|
17522
|
-
infra: ["top-level", "behavior"]
|
|
17523
|
-
},
|
|
17524
|
-
{
|
|
17525
|
-
token: "slo-p90-latency-ms",
|
|
17526
|
-
category: "directive",
|
|
17527
|
-
infra: ["top-level", "behavior"]
|
|
17528
|
-
},
|
|
17529
|
-
{
|
|
17530
|
-
token: "slo-warning-margin",
|
|
17531
|
-
category: "directive",
|
|
17532
|
-
infra: ["top-level", "behavior"]
|
|
17533
|
-
},
|
|
17534
|
-
// Top-level-only options (space-separated, bare).
|
|
17535
|
-
{ token: "default-latency-ms", category: "directive", infra: ["top-level"] },
|
|
17536
|
-
{ token: "default-uptime", category: "directive", infra: ["top-level"] },
|
|
17537
|
-
{ token: "default-rps", category: "directive", infra: ["top-level"] },
|
|
17538
|
-
// `active-tag` is shared with gantt + map (see below).
|
|
17539
|
-
// Node behavior colon-keys — highlight as propertyName.
|
|
17540
|
-
{ token: "latency-ms", colonKey: true, infra: ["behavior"] },
|
|
17541
|
-
{ token: "uptime", colonKey: true, infra: ["behavior"] },
|
|
17542
|
-
{ token: "instances", colonKey: true, infra: ["behavior"] },
|
|
17543
|
-
{ token: "max-rps", colonKey: true, infra: ["behavior"] },
|
|
17544
|
-
{ token: "cache-hit", colonKey: true, infra: ["behavior"] },
|
|
17545
|
-
{ token: "firewall-block", colonKey: true, infra: ["behavior"] },
|
|
17546
|
-
{ token: "ratelimit-rps", colonKey: true, infra: ["behavior"] },
|
|
17547
|
-
{ token: "buffer", colonKey: true, infra: ["behavior"] },
|
|
17548
|
-
{ token: "drain-rate", colonKey: true, infra: ["behavior"] },
|
|
17549
|
-
{ token: "retention-hours", colonKey: true, infra: ["behavior"] },
|
|
17550
|
-
{ token: "partitions", colonKey: true, infra: ["behavior"] },
|
|
17551
|
-
{ token: "concurrency", colonKey: true, infra: ["behavior"] },
|
|
17552
|
-
{ token: "duration-ms", colonKey: true, infra: ["behavior"] },
|
|
17553
|
-
{ token: "cold-start-ms", colonKey: true, infra: ["behavior"] },
|
|
17554
|
-
{ token: "cb-error-threshold", colonKey: true, infra: ["behavior"] },
|
|
17555
|
-
{ token: "cb-latency-threshold-ms", colonKey: true, infra: ["behavior"] },
|
|
17556
|
-
// Edge-only colon-key.
|
|
17557
|
-
{ token: "rps", colonKey: true, infra: ["edge"] },
|
|
17558
|
-
// ── Gantt ────────────────────────────────────────────────
|
|
17559
|
-
{ token: "start", category: "directive", gantt: ["option"] },
|
|
17560
|
-
{
|
|
17561
|
-
token: "today-marker",
|
|
17562
|
-
category: "directive",
|
|
17563
|
-
gantt: ["option", "boolean"]
|
|
17564
|
-
},
|
|
17565
|
-
{
|
|
17566
|
-
token: "critical-path",
|
|
17567
|
-
category: "directive",
|
|
17568
|
-
gantt: ["option", "boolean"]
|
|
17569
|
-
},
|
|
17570
|
-
{ token: "sprint-length", category: "directive", gantt: ["option"] },
|
|
17571
|
-
{ token: "sprint-number", category: "directive", gantt: ["option"] },
|
|
17572
|
-
{ token: "sprint-start", category: "directive", gantt: ["option"] },
|
|
17573
|
-
{ token: "fill-tint", category: "directive", gantt: ["boolean"] },
|
|
17574
|
-
{ token: "fill-solid", category: "directive", gantt: ["boolean"] },
|
|
17575
|
-
{ token: "fill-outline", category: "directive", gantt: ["boolean"] },
|
|
17576
|
-
// `chart` is a wireframe element keyword (CONTROL); gantt also accepts it as
|
|
17577
|
-
// an option. Highlight family is control.
|
|
17578
|
-
{ token: "chart", category: "control", gantt: ["option"] },
|
|
17579
|
-
// `dependencies` is ON by default → almost never written bare (authors write
|
|
17580
|
-
// `no-dependencies`, which DOES highlight). Bare word collides with prose and
|
|
17581
|
-
// the specializer is context-free, so it stays plain. Present for parser
|
|
17582
|
-
// Set derivation only.
|
|
17583
|
-
{ token: "dependencies", noHighlight: true, gantt: ["option", "boolean"] },
|
|
17584
|
-
// ── Map ──────────────────────────────────────────────────
|
|
17585
|
-
// Per-element value→channel ramps (decision #20): the directive names the
|
|
17586
|
-
// visual channel — `region-heat` (colour), `poi-size` (marker area),
|
|
17587
|
-
// `flow-width` (stroke). The per-element key mirrors it (`heat:`/`size:`/`width:`).
|
|
17588
|
-
{ token: "region-heat", category: "directive", map: true },
|
|
17589
|
-
{ token: "poi-size", category: "directive", map: true },
|
|
17590
|
-
{ token: "flow-width", category: "directive", map: true },
|
|
17591
|
-
{ token: "locale", category: "directive", map: true },
|
|
17592
|
-
{ token: "caption", category: "directive", map: true },
|
|
17593
|
-
{ token: "no-coastline", category: "directive", map: true },
|
|
17594
|
-
{ token: "no-relief", category: "directive", map: true },
|
|
17595
|
-
{ token: "no-context-labels", category: "directive", map: true },
|
|
17596
|
-
{ token: "no-region-labels", category: "directive", map: true },
|
|
17597
|
-
{ token: "no-region-heat-value", category: "directive", map: true },
|
|
17598
|
-
{ token: "no-poi-labels", category: "directive", map: true },
|
|
17599
|
-
{ token: "no-colorize", category: "directive", map: true },
|
|
17600
|
-
{ token: "no-cities", category: "directive", map: true },
|
|
17601
|
-
{ token: "no-cluster-pois", category: "directive", map: true },
|
|
17602
|
-
// ── Clock channel (BL-122): live local-time cards on POIs flagged `clock` ──
|
|
17603
|
-
// Activation is the per-POI `clock` flag (peeled in the map parser, not a
|
|
17604
|
-
// directive). `hours 9-17` / `days mon-fri` are the global availability
|
|
17605
|
-
// window (reused verbatim from the clock chart type).
|
|
17606
|
-
{ token: "hours", category: "directive", map: true },
|
|
17607
|
-
{ token: "days", category: "directive", map: true },
|
|
17608
|
-
// ── Shared across types ──────────────────────────────────
|
|
17609
|
-
// `active-tag`: infra top-level option + gantt option + map directive.
|
|
17610
|
-
// Treemap also accepts it (§24C.6, decision #48) — validated inline in its
|
|
17611
|
-
// parser, so no chart-scoped Set is derived for it; highlighting comes from
|
|
17612
|
-
// the global directive category here.
|
|
17613
|
-
{
|
|
17614
|
-
token: "active-tag",
|
|
17615
|
-
category: "directive",
|
|
17616
|
-
infra: ["top-level"],
|
|
17617
|
-
gantt: ["option"],
|
|
17618
|
-
map: true
|
|
17619
|
-
},
|
|
17620
|
-
// `title`: gantt option. (The data-chart `title` directive was removed in
|
|
17621
|
-
// decision #48 — it now raises E_TITLE_DIRECTIVE; the token stays here for
|
|
17622
|
-
// gantt.)
|
|
17623
|
-
{ token: "title", category: "directive", gantt: ["option"] },
|
|
17624
|
-
// `sort`: gantt option (also general, hand-listed).
|
|
17625
|
-
{ token: "sort", category: "directive", gantt: ["option"] },
|
|
17626
|
-
// `lane-by <group>`: swimlane axis (view-state). NB not `swimlane` — that's a
|
|
17627
|
-
// chart type. Kanban reads it via its own KNOWN_OPTIONS; gantt via the switch.
|
|
17628
|
-
{ token: "lane-by", category: "directive", gantt: ["option"] },
|
|
17629
|
-
// `no-title`: gantt boolean + map directive (also general, hand-listed).
|
|
17630
|
-
{ token: "no-title", category: "directive", gantt: ["boolean"], map: true },
|
|
17631
|
-
// `no-legend`: universal (decision #48) — every chart that renders a legend
|
|
17632
|
-
// accepts it, and charts without one take it as a harmless no-op. Parsed for
|
|
17633
|
-
// most types via GLOBAL_BOOLEANS in utils/parsing; gantt derives its boolean
|
|
17634
|
-
// Set from here, and map from `map: true`.
|
|
17635
|
-
{ token: "no-legend", category: "directive", gantt: ["boolean"], map: true },
|
|
17636
|
-
// ══════════════════════════════════════════════════════════
|
|
17637
|
-
// Highlight-only vocab (no extractable parser Set).
|
|
17638
|
-
// ══════════════════════════════════════════════════════════
|
|
17639
|
-
// These chart types validate their directives with inline checks rather than
|
|
17640
|
-
// a literal Set, so there is no parser literal to delete — the registry is
|
|
17641
|
-
// simply their single declaration site for highlighting. Grouped by chart
|
|
17642
|
-
// type. Categories route to the specializer-read sets in keywords.ts.
|
|
17643
|
-
// ── Gantt (extras beyond the option/boolean Sets) ────────
|
|
17644
|
-
{ token: "era", category: "directive" },
|
|
17645
|
-
{ token: "marker", category: "directive" },
|
|
17646
|
-
{ token: "holiday", category: "directive" },
|
|
17647
|
-
// `workweek` is also the canonical weekday-window directive on clock and map
|
|
17648
|
-
// clock-cards (decision #48; `days` stays as the legacy alias).
|
|
17649
|
-
{ token: "workweek", category: "directive", map: true },
|
|
17650
|
-
{ token: "no-dependencies", category: "directive" },
|
|
17651
|
-
// ── Tech-radar ───────────────────────────────────────────
|
|
17652
|
-
{ token: "rings", category: "directive" },
|
|
17653
|
-
// Blip listing is default-on everywhere (decision #48): `no-blip-legend`
|
|
17654
|
-
// suppresses it; `show-blip-legend` stays as the parse-accepted legacy no-op.
|
|
17655
|
-
{ token: "no-blip-legend", category: "directive" },
|
|
17656
|
-
{ token: "show-blip-legend", category: "directive" },
|
|
17657
|
-
{ token: "trend", category: "directive" },
|
|
17658
|
-
// ── Tags / shared directives ─────────────────────────────
|
|
17659
|
-
{ token: "tags", category: "directive" },
|
|
17660
|
-
{ token: "import", category: "directive" },
|
|
17661
|
-
{ token: "hide", category: "directive" },
|
|
17662
|
-
{ token: "direction", category: "directive" },
|
|
17663
|
-
// ── Clock ────────────────────────────────────────────────
|
|
17664
|
-
// The board's flat directives — highlight-only (the parser validates them
|
|
17665
|
-
// inline, no extractable Set). `no-title` + `direction` are already listed
|
|
17666
|
-
// above (shared). Values (analog is a bare flag; color-by's
|
|
17667
|
-
// place|work|daylight|time|none) highlight as plain tokens.
|
|
17668
|
-
{ token: "analog", category: "directive" },
|
|
17669
|
-
{ token: "hours", category: "directive" },
|
|
17670
|
-
{ token: "days", category: "directive" },
|
|
17671
|
-
{ token: "no-sun", category: "directive" },
|
|
17672
|
-
{ token: "time-24", category: "directive" },
|
|
17673
|
-
{ token: "color-by", category: "directive" },
|
|
17674
|
-
// ── Boxes-and-lines ──────────────────────────────────────
|
|
17675
|
-
// `heat <Label> [low] [high]` is the value→colour ramp directive, but `heat`
|
|
17676
|
-
// is NOT registered as a directive keyword: it is dual-use with the `heat:`
|
|
17677
|
-
// metadata key (decision #20), and a token in DIRECTIVE_KEYWORDS would block the
|
|
17678
|
-
// ATTRIBUTE_KEYS colon-gate from reclassifying `heat:` as a propertyName. So
|
|
17679
|
-
// `heat` lives only in the reserved-key registry + ATTRIBUTE_KEYS and highlights
|
|
17680
|
-
// as a property in both positions — exactly the treemap `heat` precedent.
|
|
17681
|
-
// Box values render by default since decision #48; `show-values` stays as
|
|
17682
|
-
// the parse-accepted legacy no-op (suppress with the shared `no-value`).
|
|
17683
|
-
{ token: "show-values", category: "directive" },
|
|
17684
|
-
// Treemap's legacy plural spelling of the same suppression (decision #48
|
|
17685
|
-
// made the shared singular `no-value` canonical). Registered so a legacy
|
|
17686
|
-
// document still highlights it as a directive rather than plain text.
|
|
17687
|
-
{ token: "no-values", category: "directive" },
|
|
17688
|
-
// ── Swimlane ─────────────────────────────────────────────
|
|
17689
|
-
{ token: "lane", category: "directive" },
|
|
17690
|
-
// ── ER ───────────────────────────────────────────────────
|
|
17691
|
-
{ token: "notation", category: "directive" },
|
|
17692
|
-
// ── Class ────────────────────────────────────────────────
|
|
17693
|
-
{ token: "extends", category: "directive" },
|
|
17694
|
-
{ token: "implements", category: "directive" },
|
|
17695
|
-
{ token: "abstract", category: "directive" },
|
|
17696
|
-
{ token: "interface", category: "directive" },
|
|
17697
|
-
{ token: "enum", category: "directive" },
|
|
17698
|
-
// ── C4 ───────────────────────────────────────────────────
|
|
17699
|
-
{ token: "containers", category: "directive" },
|
|
17700
|
-
{ token: "components", category: "directive" },
|
|
17701
|
-
{ token: "deployment", category: "directive" },
|
|
17702
|
-
{ token: "technology", category: "directive" },
|
|
17703
|
-
// ── Infra (directives beyond the option/behavior Sets) ───
|
|
17704
|
-
{ token: "sub-node-label", category: "directive" },
|
|
17705
|
-
{ token: "show-sub-node-count", category: "directive" },
|
|
17706
|
-
{ token: "animate", category: "directive" },
|
|
17707
|
-
// ── Sequence ─────────────────────────────────────────────
|
|
17708
|
-
{ token: "activations", category: "directive" },
|
|
17709
|
-
{ token: "no-activations", category: "directive" },
|
|
17710
|
-
// ── Map element leaders (not in DIRECTIVE_SET) ───────────
|
|
17711
|
-
{ token: "poi", category: "directive" },
|
|
17712
|
-
{ token: "route", category: "directive" },
|
|
17713
|
-
// ── Data charts ──────────────────────────────────────────
|
|
17714
|
-
{ token: "stacked", category: "directive" },
|
|
17715
|
-
{ token: "no-name", category: "directive" },
|
|
17716
|
-
{ token: "no-value", category: "directive" },
|
|
17717
|
-
{ token: "no-percent", category: "directive" },
|
|
17718
|
-
{ token: "series", category: "directive" },
|
|
17719
|
-
{ token: "orientation", category: "directive" },
|
|
17720
|
-
{ token: "x-label", category: "directive" },
|
|
17721
|
-
{ token: "y-label", category: "directive" },
|
|
17722
|
-
{ token: "size-label", category: "directive" },
|
|
17723
|
-
{ token: "columns", category: "directive" },
|
|
17724
|
-
{ token: "rows", category: "directive" },
|
|
17725
|
-
{ token: "labels", category: "directive" },
|
|
17726
|
-
{ token: "rotate", category: "directive" },
|
|
17727
|
-
{ token: "scale", category: "directive" },
|
|
17728
|
-
{ token: "values", category: "directive" },
|
|
17729
|
-
{ token: "orientation-horizontal", category: "directive" },
|
|
17730
|
-
// ── Slope ────────────────────────────────────────────────
|
|
17731
|
-
{ token: "period", category: "directive" },
|
|
17732
|
-
// ── Quadrant ─────────────────────────────────────────────
|
|
17733
|
-
{ token: "x-axis", category: "directive" },
|
|
17734
|
-
{ token: "y-axis", category: "directive" },
|
|
17735
|
-
{ token: "top-right", category: "directive" },
|
|
17736
|
-
{ token: "top-left", category: "directive" },
|
|
17737
|
-
{ token: "bottom-right", category: "directive" },
|
|
17738
|
-
{ token: "bottom-left", category: "directive" },
|
|
17739
|
-
// ── Layout (cross-chart) ─────────────────────────────────
|
|
17740
|
-
{ token: "direction-tb", category: "directive" },
|
|
17741
|
-
{ token: "direction-lr", category: "directive" },
|
|
17742
|
-
{ token: "orientation-vertical", category: "directive" },
|
|
17743
|
-
// ── Pyramid ──────────────────────────────────────────────
|
|
17744
|
-
{ token: "inverted", category: "directive" },
|
|
17745
|
-
// ── Color / notes (cross-chart) ──────────────────────────
|
|
17746
|
-
{ token: "color", category: "directive" },
|
|
17747
|
-
{ token: "no-notes", category: "directive" },
|
|
17748
|
-
// ── RACI ─────────────────────────────────────────────────
|
|
17749
|
-
{ token: "roles", category: "directive" },
|
|
17750
|
-
// ── Cycle ────────────────────────────────────────────────
|
|
17751
|
-
{ token: "direction-counterclockwise", category: "directive" },
|
|
17752
|
-
{ token: "circle-nodes", category: "directive" },
|
|
17753
|
-
// ── Journey-map ──────────────────────────────────────────
|
|
17754
|
-
{ token: "persona", category: "directive" },
|
|
17755
|
-
// ── Function ─────────────────────────────────────────────
|
|
17756
|
-
{ token: "x", category: "directive" },
|
|
17757
|
-
{ token: "shade", category: "directive" },
|
|
17758
|
-
// ── Wordcloud ────────────────────────────────────────────
|
|
17759
|
-
{ token: "max", category: "directive" },
|
|
17760
|
-
{ token: "size", category: "directive" },
|
|
17761
|
-
// ── Arc ──────────────────────────────────────────────────
|
|
17762
|
-
{ token: "order", category: "directive" },
|
|
17763
|
-
// ── PERT ─────────────────────────────────────────────────
|
|
17764
|
-
{ token: "time-unit", category: "directive" },
|
|
17765
|
-
{ token: "default-confidence", category: "directive" },
|
|
17766
|
-
{ token: "node-detail", category: "directive" },
|
|
17767
|
-
{ token: "trials", category: "directive" },
|
|
17768
|
-
{ token: "seed", category: "directive" },
|
|
17769
|
-
{ token: "scrubber-trials", category: "directive" },
|
|
17770
|
-
// `start-date` is also gantt's canonical project-start option (decision #48;
|
|
17771
|
-
// bare `start` above stays as the legacy alias).
|
|
17772
|
-
{ token: "start-date", category: "directive", gantt: ["option"] },
|
|
17773
|
-
{ token: "end-date", category: "directive" },
|
|
17774
|
-
// ── Goal ─────────────────────────────────────────────────
|
|
17775
|
-
// Mode flags, value-key leaders, and opt-outs. `now`/`target` collide with
|
|
17776
|
-
// label prose ("start now", "on target"), but the arrow-label demotion pass
|
|
17777
|
-
// (see highlight-api LABEL_WORD_NODES) treats any keyword-bearing label as
|
|
17778
|
-
// text and demotes them, so they highlight only as line leaders.
|
|
17779
|
-
{ token: "thermometer", category: "directive" },
|
|
17780
|
-
{ token: "gauge", category: "directive" },
|
|
17781
|
-
{ token: "now", category: "directive" },
|
|
17782
|
-
{ token: "target", category: "directive" },
|
|
17783
|
-
{ token: "no-note", category: "directive" },
|
|
17784
|
-
{ token: "no-auto-color", category: "directive" },
|
|
17785
|
-
// ── Control-flow + wireframe element keywords (CONTROL) ──
|
|
17786
|
-
{ token: "if", category: "control" },
|
|
17787
|
-
{ token: "else", category: "control" },
|
|
17788
|
-
{ token: "loop", category: "control" },
|
|
17789
|
-
{ token: "parallel", category: "control" },
|
|
17790
|
-
{ token: "note", category: "control" },
|
|
17791
|
-
{ token: "nav", category: "control" },
|
|
17792
|
-
{ token: "tabs", category: "control" },
|
|
17793
|
-
{ token: "table", category: "control" },
|
|
17794
|
-
{ token: "image", category: "control" },
|
|
17795
|
-
{ token: "modal", category: "control" },
|
|
17796
|
-
{ token: "skeleton", category: "control" },
|
|
17797
|
-
{ token: "alert", category: "control" },
|
|
17798
|
-
{ token: "progress", category: "control" },
|
|
17799
|
-
{ token: "mobile", category: "control" },
|
|
17800
|
-
// ── Kanban status keywords (STATUS) ──────────────────────
|
|
17801
|
-
{ token: "na", category: "status" },
|
|
17802
|
-
{ token: "todo", category: "status" },
|
|
17803
|
-
{ token: "wip", category: "status" },
|
|
17804
|
-
{ token: "done", category: "status" },
|
|
17805
|
-
{ token: "blocked", category: "status" },
|
|
17806
|
-
{ token: "in-progress", category: "status" },
|
|
17807
|
-
{ token: "backlog", category: "status" },
|
|
17808
|
-
{ token: "ready", category: "status" },
|
|
17809
|
-
// ── Modifiers + ER column types/modifiers (MODIFIER) ─────
|
|
17810
|
-
// `collapsed` is the bare trailing group-line flag made canonical by
|
|
17811
|
-
// decision #48 (`[Fulfillment] collapsed`). It is deliberately a bare
|
|
17812
|
-
// MODIFIER rather than a colon key: the legacy `collapsed: true` form still
|
|
17813
|
-
// parses and still highlights (as `modifier` instead of `propertyName`),
|
|
17814
|
-
// whereas leaving it colon-only left the canonical bare form as plain text.
|
|
17815
|
-
{ token: "collapsed", category: "modifier" },
|
|
17816
|
-
{ token: "as", category: "modifier" },
|
|
17817
|
-
{ token: "alias", category: "modifier" },
|
|
17818
|
-
{ token: "aka", category: "modifier" },
|
|
17819
|
-
{ token: "position", category: "modifier" },
|
|
17820
|
-
{ token: "default", category: "modifier" },
|
|
17821
|
-
{ token: "pk", category: "modifier" },
|
|
17822
|
-
{ token: "fk", category: "modifier" },
|
|
17823
|
-
{ token: "nullable", category: "modifier" },
|
|
17824
|
-
{ token: "unique", category: "modifier" },
|
|
17825
|
-
{ token: "int", category: "modifier" },
|
|
17826
|
-
{ token: "varchar", category: "modifier" },
|
|
17827
|
-
{ token: "text", category: "modifier" },
|
|
17828
|
-
{ token: "boolean", category: "modifier" },
|
|
17829
|
-
{ token: "date", category: "modifier" },
|
|
17830
|
-
{ token: "timestamp", category: "modifier" },
|
|
17831
|
-
{ token: "float", category: "modifier" },
|
|
17832
|
-
{ token: "decimal", category: "modifier" },
|
|
17833
|
-
// ── Bracket ──────────────────────────────────────────────
|
|
17834
|
-
// `beats` / `vs` are the infix match keywords; the rest are line directives.
|
|
17835
|
-
// (`seed` and `no-legend` already appear above — shared, not re-listed.)
|
|
17836
|
-
{ token: "beats", category: "control" },
|
|
17837
|
-
{ token: "vs", category: "control" },
|
|
17838
|
-
{ token: "rounds", category: "directive" },
|
|
17839
|
-
{ token: "accent", category: "directive" },
|
|
17840
|
-
{ token: "no-round", category: "modifier" },
|
|
17841
|
-
{ token: "no-rounds", category: "modifier" },
|
|
17842
|
-
{ token: "single-elim", category: "modifier" },
|
|
17843
|
-
{ token: "double-elim", category: "modifier" },
|
|
17844
|
-
{ token: "seeded", category: "modifier" }
|
|
17845
|
-
];
|
|
17846
|
-
INFRA_TOP_LEVEL_OPTION_SET = tokensWhere(
|
|
17847
|
-
(e) => !!e.infra?.includes("top-level")
|
|
17848
|
-
);
|
|
17849
|
-
INFRA_BEHAVIOR_KEY_SET = tokensWhere(
|
|
17850
|
-
(e) => !!e.infra?.includes("behavior")
|
|
17851
|
-
);
|
|
17852
|
-
INFRA_EDGE_ONLY_KEY_SET = tokensWhere(
|
|
17853
|
-
(e) => !!e.infra?.includes("edge")
|
|
17854
|
-
);
|
|
17855
|
-
GANTT_OPTION_SET = tokensWhere(
|
|
17856
|
-
(e) => !!e.gantt?.includes("option")
|
|
17857
|
-
);
|
|
17858
|
-
GANTT_BOOLEAN_SET = tokensWhere(
|
|
17859
|
-
(e) => !!e.gantt?.includes("boolean")
|
|
17860
|
-
);
|
|
17861
|
-
MAP_DIRECTIVE_KEY_SET = tokensWhere((e) => e.map === true);
|
|
17862
|
-
REGISTRY_DIRECTIVE_TOKENS = tokensWhere(
|
|
17863
|
-
(e) => e.category === "directive" && !e.colonKey && !e.noHighlight
|
|
17864
|
-
);
|
|
17865
|
-
REGISTRY_CONTROL_TOKENS = tokensWhere(
|
|
17866
|
-
(e) => e.category === "control" && !e.colonKey && !e.noHighlight
|
|
17867
|
-
);
|
|
17868
|
-
REGISTRY_STATUS_TOKENS = tokensWhere(
|
|
17869
|
-
(e) => e.category === "status" && !e.colonKey && !e.noHighlight
|
|
17870
|
-
);
|
|
17871
|
-
REGISTRY_MODIFIER_TOKENS = tokensWhere(
|
|
17872
|
-
(e) => e.category === "modifier" && !e.colonKey && !e.noHighlight
|
|
17873
|
-
);
|
|
17874
|
-
REGISTRY_COLON_KEY_TOKENS = tokensWhere((e) => !!e.colonKey);
|
|
17875
|
-
REGISTRY_NON_HIGHLIGHT_TOKENS = tokensWhere(
|
|
17876
|
-
(e) => !!e.noHighlight
|
|
17877
|
-
);
|
|
17878
|
-
}
|
|
17879
|
-
});
|
|
17880
|
-
|
|
17881
18080
|
// src/infra/types.ts
|
|
17882
18081
|
var INFRA_BEHAVIOR_KEYS, EDGE_ONLY_KEYS;
|
|
17883
18082
|
var init_types2 = __esm({
|
|
@@ -18632,8 +18831,35 @@ function parseInfra(content) {
|
|
|
18632
18831
|
}
|
|
18633
18832
|
validateTagGroupNames(result.tagGroups, warn2, setError);
|
|
18634
18833
|
checkReachability(result);
|
|
18834
|
+
checkSplitSums(result);
|
|
18635
18835
|
return result;
|
|
18636
18836
|
}
|
|
18837
|
+
function checkSplitSums(result) {
|
|
18838
|
+
const outbound = /* @__PURE__ */ new Map();
|
|
18839
|
+
for (const edge of result.edges) {
|
|
18840
|
+
if (edge.async) continue;
|
|
18841
|
+
const list = outbound.get(edge.sourceId) ?? [];
|
|
18842
|
+
list.push(edge);
|
|
18843
|
+
outbound.set(edge.sourceId, list);
|
|
18844
|
+
}
|
|
18845
|
+
for (const [sourceId, edges] of outbound) {
|
|
18846
|
+
if (edges.length <= 1) continue;
|
|
18847
|
+
const declared = edges.filter((e) => e.split !== null);
|
|
18848
|
+
if (declared.length === 0) continue;
|
|
18849
|
+
const sum = declared.reduce((s, e) => s + (e.split ?? 0), 0);
|
|
18850
|
+
const allDeclared = declared.length === edges.length;
|
|
18851
|
+
if (allDeclared ? Math.abs(sum - 100) > 0.01 : sum > 100) {
|
|
18852
|
+
const label = result.nodes.find((n) => n.id === sourceId)?.label ?? sourceId;
|
|
18853
|
+
result.diagnostics.push(
|
|
18854
|
+
// In-bounds: declared.length > 0 here.
|
|
18855
|
+
emit(GRAPH_DX.INFRA_SPLIT_SUM, declared[0].lineNumber, {
|
|
18856
|
+
label,
|
|
18857
|
+
sum: String(Number(sum.toFixed(2)))
|
|
18858
|
+
})
|
|
18859
|
+
);
|
|
18860
|
+
}
|
|
18861
|
+
}
|
|
18862
|
+
}
|
|
18637
18863
|
function checkReachability(result) {
|
|
18638
18864
|
if (result.nodes.length === 0) return;
|
|
18639
18865
|
const entries = result.nodes.filter((n) => n.isEdge);
|
|
@@ -25926,6 +26152,21 @@ var init_diagnostics9 = __esm({
|
|
|
25926
26152
|
hint: "Add a trailing number (e.g. `Lonely 40`) so the leaf gets a size.",
|
|
25927
26153
|
example: "treemap T\nA\n Lonely"
|
|
25928
26154
|
},
|
|
26155
|
+
LEAF_VALUE_UNPARSEABLE: {
|
|
26156
|
+
code: "W_TREEMAP_LEAF_VALUE_UNPARSEABLE",
|
|
26157
|
+
severity: "warning",
|
|
26158
|
+
chartType: "treemap",
|
|
26159
|
+
title: "Leaf value could not be read as a number",
|
|
26160
|
+
message: (p) => {
|
|
26161
|
+
const token = p.token ?? "1,24,000";
|
|
26162
|
+
return `Leaf "${p.label ?? "Cluster"}" \u2014 could not read "${token}" as a number, so it renders with zero size. Remove the grouping separators: ${token.replace(
|
|
26163
|
+
/[,_]/g,
|
|
26164
|
+
""
|
|
26165
|
+
)}`;
|
|
26166
|
+
},
|
|
26167
|
+
hint: "Grouping separators must split the digits into even groups \u2014 `1,240,000` or `1_240_000`. Anything else must be written plainly, e.g. `1240000`.",
|
|
26168
|
+
example: "treemap T\nA\n Cluster 1,24,000"
|
|
26169
|
+
},
|
|
25929
26170
|
BRANCH_VALUE_IGNORED: {
|
|
25930
26171
|
code: "W_TREEMAP_BRANCH_VALUE_IGNORED",
|
|
25931
26172
|
severity: "warning",
|
|
@@ -25985,6 +26226,7 @@ function parseTreemap(content, palette) {
|
|
|
25985
26226
|
const lines = content.split("\n");
|
|
25986
26227
|
let contentStarted = false;
|
|
25987
26228
|
let nodeCounter = 0;
|
|
26229
|
+
const badValueTokens = /* @__PURE__ */ new Map();
|
|
25988
26230
|
let currentTagGroup = null;
|
|
25989
26231
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
25990
26232
|
const indentStack = [];
|
|
@@ -26079,7 +26321,8 @@ function parseTreemap(content, palette) {
|
|
|
26079
26321
|
lineNumber,
|
|
26080
26322
|
++nodeCounter,
|
|
26081
26323
|
aliasMap,
|
|
26082
|
-
result.diagnostics
|
|
26324
|
+
result.diagnostics,
|
|
26325
|
+
badValueTokens
|
|
26083
26326
|
);
|
|
26084
26327
|
if (node.heat !== void 0) result.hasHeat = true;
|
|
26085
26328
|
attachNode4(node, indent, indentStack, result);
|
|
@@ -26106,8 +26349,12 @@ function parseTreemap(content, palette) {
|
|
|
26106
26349
|
delete node.value;
|
|
26107
26350
|
}
|
|
26108
26351
|
} else if (node.value === void 0) {
|
|
26352
|
+
const bad = badValueTokens.get(n);
|
|
26109
26353
|
result.diagnostics.push(
|
|
26110
|
-
emit(TREEMAP_DX.
|
|
26354
|
+
bad !== void 0 ? emit(TREEMAP_DX.LEAF_VALUE_UNPARSEABLE, node.lineNumber, {
|
|
26355
|
+
label: node.label,
|
|
26356
|
+
token: bad
|
|
26357
|
+
}) : emit(TREEMAP_DX.LEAF_NO_VALUE, node.lineNumber, {
|
|
26111
26358
|
label: node.label
|
|
26112
26359
|
})
|
|
26113
26360
|
);
|
|
@@ -26214,7 +26461,7 @@ function resolveDefaultColorMode(result, pushWarning) {
|
|
|
26214
26461
|
if (result.tagGroups.length > 0) return "tag";
|
|
26215
26462
|
return "branch";
|
|
26216
26463
|
}
|
|
26217
|
-
function parseNodeLine3(trimmed, lineNumber, counter, aliasMap, diagnostics) {
|
|
26464
|
+
function parseNodeLine3(trimmed, lineNumber, counter, aliasMap, diagnostics, badValueTokens) {
|
|
26218
26465
|
const registry = withTagAliases(TREEMAP_REGISTRY, new Set(aliasMap.keys()));
|
|
26219
26466
|
const split = splitNameAndMeta(
|
|
26220
26467
|
trimmed,
|
|
@@ -26233,13 +26480,15 @@ function parseNodeLine3(trimmed, lineNumber, counter, aliasMap, diagnostics) {
|
|
|
26233
26480
|
const metadata = { ...split.meta };
|
|
26234
26481
|
let heat;
|
|
26235
26482
|
if ("heat" in metadata) {
|
|
26236
|
-
const
|
|
26483
|
+
const rawHeat = metadata["heat"];
|
|
26484
|
+
const h = parseFloat(normalizeNumericToken(rawHeat) ?? rawHeat);
|
|
26237
26485
|
if (Number.isFinite(h)) heat = h;
|
|
26238
26486
|
delete metadata["heat"];
|
|
26239
26487
|
}
|
|
26240
26488
|
const rawName = split.name;
|
|
26241
26489
|
let label;
|
|
26242
26490
|
let value;
|
|
26491
|
+
let badValueToken;
|
|
26243
26492
|
if (isFullyQuoted(rawName)) {
|
|
26244
26493
|
label = stripQuotes(rawName);
|
|
26245
26494
|
} else {
|
|
@@ -26247,11 +26496,16 @@ function parseNodeLine3(trimmed, lineNumber, counter, aliasMap, diagnostics) {
|
|
|
26247
26496
|
if (vm) {
|
|
26248
26497
|
const labelPart = vm[1].trim();
|
|
26249
26498
|
const token = vm[2];
|
|
26250
|
-
const
|
|
26251
|
-
const
|
|
26499
|
+
const normalized = normalizeNumericToken(token);
|
|
26500
|
+
const hasSeparators = /[,_]/.test(token);
|
|
26501
|
+
const parsed = hasSeparators && normalized === null ? NaN : parseFloat(normalized ?? token);
|
|
26502
|
+
const peeled = isFullyQuoted(labelPart) ? stripQuotes(labelPart) : labelPart;
|
|
26252
26503
|
if (Number.isFinite(parsed)) {
|
|
26253
26504
|
value = parsed;
|
|
26254
|
-
label =
|
|
26505
|
+
label = peeled;
|
|
26506
|
+
} else if (hasSeparators) {
|
|
26507
|
+
label = peeled;
|
|
26508
|
+
badValueToken = token;
|
|
26255
26509
|
} else {
|
|
26256
26510
|
label = rawName;
|
|
26257
26511
|
}
|
|
@@ -26259,7 +26513,7 @@ function parseNodeLine3(trimmed, lineNumber, counter, aliasMap, diagnostics) {
|
|
|
26259
26513
|
label = rawName;
|
|
26260
26514
|
}
|
|
26261
26515
|
}
|
|
26262
|
-
|
|
26516
|
+
const node = {
|
|
26263
26517
|
id: `treemap-node-${counter}`,
|
|
26264
26518
|
label,
|
|
26265
26519
|
...value !== void 0 && { value },
|
|
@@ -26268,6 +26522,8 @@ function parseNodeLine3(trimmed, lineNumber, counter, aliasMap, diagnostics) {
|
|
|
26268
26522
|
children: [],
|
|
26269
26523
|
lineNumber
|
|
26270
26524
|
};
|
|
26525
|
+
if (badValueToken !== void 0) badValueTokens.set(node, badValueToken);
|
|
26526
|
+
return node;
|
|
26271
26527
|
}
|
|
26272
26528
|
function attachNode4(node, indent, indentStack, result) {
|
|
26273
26529
|
while (indentStack.length > 0) {
|
|
@@ -26292,7 +26548,7 @@ var init_parser31 = __esm({
|
|
|
26292
26548
|
init_tag_groups();
|
|
26293
26549
|
init_parsing();
|
|
26294
26550
|
init_reserved_key_registry();
|
|
26295
|
-
VALUE_TOKEN_RE = /^(.+?)\s+(-?\d[\d_
|
|
26551
|
+
VALUE_TOKEN_RE = /^(.+?)\s+(-?\d[\d_,.]*)$/;
|
|
26296
26552
|
}
|
|
26297
26553
|
});
|
|
26298
26554
|
|
|
@@ -26637,8 +26893,9 @@ __export(parser_exports27, {
|
|
|
26637
26893
|
parseGoal: () => parseGoal
|
|
26638
26894
|
});
|
|
26639
26895
|
function parseGoalNumber(token) {
|
|
26640
|
-
|
|
26641
|
-
|
|
26896
|
+
const normalized = normalizeNumericToken(token);
|
|
26897
|
+
if (normalized === null && /[,_]/.test(token)) return null;
|
|
26898
|
+
const n = parseFloat(normalized ?? token);
|
|
26642
26899
|
return Number.isFinite(n) ? n : null;
|
|
26643
26900
|
}
|
|
26644
26901
|
function parseGoal(content, palette) {
|
|
@@ -33243,8 +33500,7 @@ function renderLegendSvg(groups, options) {
|
|
|
33243
33500
|
if (!layout.activeCapsule && layout.pills.length === 0) {
|
|
33244
33501
|
return { svg: "", height: 0, width: 0 };
|
|
33245
33502
|
}
|
|
33246
|
-
const groupBg
|
|
33247
|
-
const pillBorder = mix(palette.textMuted, palette.bg, 50);
|
|
33503
|
+
const { groupBg, pillBorder } = legendChromeColors(palette, isDark);
|
|
33248
33504
|
const parts = [];
|
|
33249
33505
|
let bottom = 0;
|
|
33250
33506
|
let left = Infinity;
|
|
@@ -33278,7 +33534,6 @@ var init_legend_svg = __esm({
|
|
|
33278
33534
|
init_tag_groups();
|
|
33279
33535
|
init_legend_constants();
|
|
33280
33536
|
init_legend_layout();
|
|
33281
|
-
init_color_utils();
|
|
33282
33537
|
init_fonts();
|
|
33283
33538
|
}
|
|
33284
33539
|
});
|
|
@@ -34403,6 +34658,25 @@ function renderSankey(svg, chart, width, height, colors, bgColor, textColor, top
|
|
|
34403
34658
|
if (links.length === 0) return;
|
|
34404
34659
|
const solid = chart.fillMode === "solid";
|
|
34405
34660
|
const names = Array.from(new Set(links.flatMap((l) => [l.source, l.target])));
|
|
34661
|
+
const walk = (seeds, up) => {
|
|
34662
|
+
const seen = new Set(seeds);
|
|
34663
|
+
for (let pass = 0; pass < names.length; pass++) {
|
|
34664
|
+
let grew = false;
|
|
34665
|
+
for (const l of links) {
|
|
34666
|
+
const from = up ? l.target : l.source;
|
|
34667
|
+
const to = up ? l.source : l.target;
|
|
34668
|
+
if (seen.has(from) && !seen.has(to)) {
|
|
34669
|
+
seen.add(to);
|
|
34670
|
+
grew = true;
|
|
34671
|
+
}
|
|
34672
|
+
}
|
|
34673
|
+
if (!grew) break;
|
|
34674
|
+
}
|
|
34675
|
+
return seen;
|
|
34676
|
+
};
|
|
34677
|
+
const flowClosure = (seeds) => /* @__PURE__ */ new Set([...walk(seeds, true), ...walk(seeds, false)]);
|
|
34678
|
+
const { dimmed } = resolveEmphasis(chart.emphasis, names, flowClosure);
|
|
34679
|
+
const linkDimmed = (l) => dimmed.has(l.source) || dimmed.has(l.target);
|
|
34406
34680
|
const node = /* @__PURE__ */ new Map();
|
|
34407
34681
|
names.forEach(
|
|
34408
34682
|
(name, i) => node.set(name, {
|
|
@@ -34500,7 +34774,10 @@ function renderSankey(svg, chart, width, height, colors, bgColor, textColor, top
|
|
|
34500
34774
|
const ribbon = svg.append("path").attr(
|
|
34501
34775
|
"d",
|
|
34502
34776
|
`M${sx},${sy} C${cx0},${sy} ${cx0},${ty} ${tx},${ty} L${tx},${ty + th} C${cx0},${ty + th} ${cx0},${sy + th} ${sx},${sy + th} Z`
|
|
34503
|
-
).attr("fill", color).attr(
|
|
34777
|
+
).attr("fill", color).attr(
|
|
34778
|
+
"fill-opacity",
|
|
34779
|
+
linkDimmed(l) ? RIBBON_FILL_OPACITY * EMPHASIS_DIM_OPACITY : RIBBON_FILL_OPACITY
|
|
34780
|
+
);
|
|
34504
34781
|
tagDatum(ribbon, {
|
|
34505
34782
|
line: l.lineNumber,
|
|
34506
34783
|
// U+241F (symbol-for-unit-separator) — collision-proof AND XML-legal;
|
|
@@ -34515,7 +34792,9 @@ function renderSankey(svg, chart, width, height, colors, bgColor, textColor, top
|
|
|
34515
34792
|
const nodeLine = links.find(
|
|
34516
34793
|
(l) => l.source === n.name || l.target === n.name
|
|
34517
34794
|
)?.lineNumber;
|
|
34795
|
+
const nodeDim = dimmed.has(n.name);
|
|
34518
34796
|
const nr = svg.append("rect").attr("x", n.x).attr("y", n.y).attr("width", NODE_W).attr("height", Math.max(1, n.h)).attr("fill", solid ? n.raw : mix(n.raw, bgColor, 75)).attr("stroke", n.raw).attr("stroke-width", 1);
|
|
34797
|
+
if (nodeDim) nr.attr("opacity", EMPHASIS_DIM_OPACITY);
|
|
34519
34798
|
tagDatum(nr, {
|
|
34520
34799
|
...nodeLine !== void 0 && { line: nodeLine },
|
|
34521
34800
|
key: `node:${n.name}`,
|
|
@@ -34524,10 +34803,11 @@ function renderSankey(svg, chart, width, height, colors, bgColor, textColor, top
|
|
|
34524
34803
|
color: n.raw
|
|
34525
34804
|
});
|
|
34526
34805
|
const lastLayer = n.rank === maxRank;
|
|
34527
|
-
svg.append("text").attr("x", lastLayer ? n.x - 6 : n.x + NODE_W + 6).attr("y", n.y + n.h / 2 + 4).attr("text-anchor", lastLayer ? "end" : "start").attr("fill", textColor).attr("font-size", 13).attr("font-family", FONT_FAMILY).text(n.name);
|
|
34806
|
+
const label = svg.append("text").attr("x", lastLayer ? n.x - 6 : n.x + NODE_W + 6).attr("y", n.y + n.h / 2 + 4).attr("text-anchor", lastLayer ? "end" : "start").attr("fill", textColor).attr("font-size", 13).attr("font-family", FONT_FAMILY).text(n.name);
|
|
34807
|
+
if (nodeDim) label.attr("opacity", EMPHASIS_DIM_TEXT_OPACITY);
|
|
34528
34808
|
}
|
|
34529
34809
|
}
|
|
34530
|
-
var NODE_W, NODE_GAP;
|
|
34810
|
+
var NODE_W, NODE_GAP, RIBBON_FILL_OPACITY;
|
|
34531
34811
|
var init_sankey = __esm({
|
|
34532
34812
|
"src/charts-d3/sankey.ts"() {
|
|
34533
34813
|
"use strict";
|
|
@@ -34535,8 +34815,10 @@ var init_sankey = __esm({
|
|
|
34535
34815
|
init_color_utils();
|
|
34536
34816
|
init_text_measure();
|
|
34537
34817
|
init_shared();
|
|
34818
|
+
init_emphasis();
|
|
34538
34819
|
NODE_W = 20;
|
|
34539
34820
|
NODE_GAP = 14;
|
|
34821
|
+
RIBBON_FILL_OPACITY = 0.6;
|
|
34540
34822
|
}
|
|
34541
34823
|
});
|
|
34542
34824
|
|
|
@@ -34694,7 +34976,7 @@ function renderFunction(svg, chart, width, height, colors, textColor, mutedColor
|
|
|
34694
34976
|
}
|
|
34695
34977
|
const gen = d3line2().defined((p) => isFinite(p[1]) && p[1] >= yLo - 1 && p[1] <= yHi + 1).x((p) => x(p[0])).y((p) => y(p[1]));
|
|
34696
34978
|
for (const c of curves) {
|
|
34697
|
-
const path = svg.append("path").attr("d", gen(c.pts) ?? "").attr("fill", "none").attr("stroke", c.color).attr("stroke-width",
|
|
34979
|
+
const path = svg.append("path").attr("d", gen(c.pts) ?? "").attr("fill", "none").attr("stroke", c.color).attr("stroke-width", 1.75).attr("stroke-linejoin", "round").attr("data-series-name", c.name);
|
|
34698
34980
|
tagDatum(path, { line: c.line, key: c.name, name: c.name, color: c.color });
|
|
34699
34981
|
}
|
|
34700
34982
|
drawXAxisTitle(
|
|
@@ -35521,8 +35803,21 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
35521
35803
|
"fill",
|
|
35522
35804
|
parsed.options.fillMode ? p.color : mix(p.color, themeBaseBg(palette, isDark), SHELF_TINT)
|
|
35523
35805
|
);
|
|
35524
|
-
|
|
35525
|
-
|
|
35806
|
+
if (SHELF_EDGE_STYLE !== "none" && !parsed.options.fillMode) {
|
|
35807
|
+
const lip = SHELF_EDGE_STYLE === "left" ? {
|
|
35808
|
+
// vertical lip on the spine-relative leading edge
|
|
35809
|
+
x: 0,
|
|
35810
|
+
y: shelfTop,
|
|
35811
|
+
width: SHELF_LIP,
|
|
35812
|
+
height: shelfH
|
|
35813
|
+
} : {
|
|
35814
|
+
x: 0,
|
|
35815
|
+
y: titleNearTop ? shelfTop : shelfTop + shelfH - SHELF_LIP,
|
|
35816
|
+
width: CARD_W,
|
|
35817
|
+
height: SHELF_LIP
|
|
35818
|
+
};
|
|
35819
|
+
cardG.append("rect").attr("x", lip.x).attr("y", lip.y).attr("width", lip.width).attr("height", lip.height).attr("clip-path", `url(#${clipId})`).attr("fill", p.color).attr("fill-opacity", p.future ? 0.4 : 1);
|
|
35820
|
+
}
|
|
35526
35821
|
const shelfText = parsed.options.fillMode ? contrastText(p.color, palette.textOnFillLight, palette.textOnFillDark) : p.color;
|
|
35527
35822
|
const titleMid = headBandTop + p.headerH / 2;
|
|
35528
35823
|
const titleTop = titleMid - (p.titleLines.length - 1) * TITLE_LINE_H / 2;
|
|
@@ -35959,7 +36254,7 @@ function renderBody(cardG, lines, bodyColor, palette, startBaseline = CARD_BODY_
|
|
|
35959
36254
|
y += DESC_LINE_H;
|
|
35960
36255
|
}
|
|
35961
36256
|
}
|
|
35962
|
-
var CARD_W, H_MARGIN, TITLE_AREA, LEGEND_BAND, LEADER_ABOVE, LEADER_BELOW, DESC_FONT, DESC_LINE_H, CARD_PAD, CARD_BODY_TOP, TITLE_LINE_H, TITLE_MAX_W, DOT_R, MIN_SPACING, LANE_GAP, NEUTRAL_TAG, CARD_INSET, FAN_GAP, DATE_SUBTITLE_H, DATE_SUBTITLE_FONT, SHELF_TINT, SHELF_EDGE, ERA_BLOCK, ERA_BRACKET_CAP, ERA_BRACKET_PAD, ERA_SEAM_GAP, BREAK_HALF_H, BREAK_AMP, BREAK_GAP, ERA_LEG, ERA_LABEL_FONT, HL, DIM, ERA_HL, COLLAPSED, OFF, HIDDEN_ATTR, HOVER_CSS, DIMMABLE_SEL, PIN_ATTR;
|
|
36257
|
+
var CARD_W, H_MARGIN, TITLE_AREA, LEGEND_BAND, LEADER_ABOVE, LEADER_BELOW, DESC_FONT, DESC_LINE_H, CARD_PAD, CARD_BODY_TOP, TITLE_LINE_H, TITLE_MAX_W, DOT_R, MIN_SPACING, LANE_GAP, NEUTRAL_TAG, CARD_INSET, FAN_GAP, DATE_SUBTITLE_H, DATE_SUBTITLE_FONT, SHELF_TINT, SHELF_EDGE, SHELF_EDGE_STYLE, SHELF_LIP, ERA_BLOCK, ERA_BRACKET_CAP, ERA_BRACKET_PAD, ERA_SEAM_GAP, BREAK_HALF_H, BREAK_AMP, BREAK_GAP, ERA_LEG, ERA_LABEL_FONT, HL, DIM, ERA_HL, COLLAPSED, OFF, HIDDEN_ATTR, HOVER_CSS, DIMMABLE_SEL, PIN_ATTR;
|
|
35963
36258
|
var init_renderer2 = __esm({
|
|
35964
36259
|
"src/event-line/renderer.ts"() {
|
|
35965
36260
|
"use strict";
|
|
@@ -35997,6 +36292,8 @@ var init_renderer2 = __esm({
|
|
|
35997
36292
|
DATE_SUBTITLE_FONT = 10;
|
|
35998
36293
|
SHELF_TINT = 13;
|
|
35999
36294
|
SHELF_EDGE = 4;
|
|
36295
|
+
SHELF_EDGE_STYLE = "spine";
|
|
36296
|
+
SHELF_LIP = 2;
|
|
36000
36297
|
ERA_BLOCK = 30;
|
|
36001
36298
|
ERA_BRACKET_CAP = 8;
|
|
36002
36299
|
ERA_BRACKET_PAD = 14;
|
|
@@ -36103,7 +36400,7 @@ function renderFigureBody(fig, view, parts, partColor, emphKey, form, palette, i
|
|
|
36103
36400
|
out += `<path${dataLine} d="${d}" fill="${color}" fill-opacity="0.5" stroke="${color}" stroke-width="1.5"/>`;
|
|
36104
36401
|
}
|
|
36105
36402
|
} else {
|
|
36106
|
-
const lightFill = mix(color, palette
|
|
36403
|
+
const lightFill = mix(color, themeBaseBg(palette, isDark), 25);
|
|
36107
36404
|
for (const d of paths) {
|
|
36108
36405
|
out += `<path${dataLine} d="${d}" fill="${lightFill}" stroke="${color}" stroke-width="1.5"/>`;
|
|
36109
36406
|
}
|
|
@@ -45818,6 +46115,8 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
45818
46115
|
const YIELD_EVERY_MS = 30;
|
|
45819
46116
|
const searchStart = performance.now();
|
|
45820
46117
|
let lastYield = searchStart;
|
|
46118
|
+
const budgetMs = opts?.budgetMs ?? DEFAULT_SEARCH_BUDGET_MS;
|
|
46119
|
+
const overBudget = () => budgetMs > 0 && performance.now() - searchStart > budgetMs;
|
|
45821
46120
|
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
45822
46121
|
if (collapseInfo) {
|
|
45823
46122
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -46116,6 +46415,7 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
46116
46415
|
} catch {
|
|
46117
46416
|
}
|
|
46118
46417
|
await step("Optimizing layout");
|
|
46418
|
+
if (pool.length && overBudget()) break;
|
|
46119
46419
|
}
|
|
46120
46420
|
if (!pool.length)
|
|
46121
46421
|
return place({ ranker: "network-simplex", nodesep: 50, ranksep: 60 });
|
|
@@ -46170,6 +46470,7 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
46170
46470
|
cfgOf.set(lay, cfg);
|
|
46171
46471
|
} catch {
|
|
46172
46472
|
}
|
|
46473
|
+
if (overBudget()) break;
|
|
46173
46474
|
}
|
|
46174
46475
|
const extraKey = /* @__PURE__ */ new Map();
|
|
46175
46476
|
for (const lay of extra)
|
|
@@ -46206,7 +46507,7 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
46206
46507
|
opts?.onTopConfigs?.(topConfigs);
|
|
46207
46508
|
return best;
|
|
46208
46509
|
}
|
|
46209
|
-
var DEFAULT_LAMBDA, ESCALATE_THRESHOLD, ESCALATE_MAX_N, ESCALATE_SEEDS, ESCALATE_REFINE, splineGen, PATH_TOKEN_RE, FLAT_CACHE, GROUP_LABEL_ZONE3;
|
|
46510
|
+
var DEFAULT_LAMBDA, ESCALATE_THRESHOLD, ESCALATE_MAX_N, ESCALATE_SEEDS, ESCALATE_REFINE, DEFAULT_SEARCH_BUDGET_MS, splineGen, PATH_TOKEN_RE, FLAT_CACHE, GROUP_LABEL_ZONE3;
|
|
46210
46511
|
var init_layout_search = __esm({
|
|
46211
46512
|
"src/boxes-and-lines/layout-search.ts"() {
|
|
46212
46513
|
"use strict";
|
|
@@ -46219,6 +46520,7 @@ var init_layout_search = __esm({
|
|
|
46219
46520
|
ESCALATE_MAX_N = 45;
|
|
46220
46521
|
ESCALATE_SEEDS = 18;
|
|
46221
46522
|
ESCALATE_REFINE = 10;
|
|
46523
|
+
DEFAULT_SEARCH_BUDGET_MS = 5e3;
|
|
46222
46524
|
splineGen = d3line3().x((d) => d.x).y((d) => d.y).curve(curveBasis5);
|
|
46223
46525
|
PATH_TOKEN_RE = /[MLQC]|-?\d*\.?\d+(?:e-?\d+)?/gi;
|
|
46224
46526
|
FLAT_CACHE = /* @__PURE__ */ new WeakMap();
|
|
@@ -48053,12 +48355,13 @@ var init_renderer13 = __esm({
|
|
|
48053
48355
|
init_legend_constants();
|
|
48054
48356
|
init_text_measure();
|
|
48055
48357
|
init_visual_conventions();
|
|
48358
|
+
init_emphasis();
|
|
48056
48359
|
init_card_model();
|
|
48057
48360
|
KEY_X2 = 10;
|
|
48058
48361
|
KEY_VALUE_GAP2 = 6;
|
|
48059
48362
|
BAR_DOT_R = 3.5;
|
|
48060
48363
|
TITLE_RESERVE = 40;
|
|
48061
|
-
DIM_OPACITY =
|
|
48364
|
+
DIM_OPACITY = EMPHASIS_DIM_OPACITY;
|
|
48062
48365
|
ROMAN = [
|
|
48063
48366
|
[10, "X"],
|
|
48064
48367
|
[9, "IX"],
|
|
@@ -53899,6 +54202,19 @@ function collapseGroups(parsed, collapsedIds, defaultLatencyMs = 0, defaultUptim
|
|
|
53899
54202
|
}
|
|
53900
54203
|
function resolveSplits(outbound, diagnostics) {
|
|
53901
54204
|
if (outbound.length === 0) return [];
|
|
54205
|
+
const async = outbound.filter((e) => e.async);
|
|
54206
|
+
if (async.length > 0) {
|
|
54207
|
+
const sync = outbound.filter((e) => !e.async);
|
|
54208
|
+
const asyncResolved = async.map((e) => ({
|
|
54209
|
+
edge: e,
|
|
54210
|
+
split: e.split ?? 100
|
|
54211
|
+
}));
|
|
54212
|
+
const syncResolved = resolveSplits(sync, diagnostics);
|
|
54213
|
+
const byEdge = /* @__PURE__ */ new Map();
|
|
54214
|
+
for (const r of [...asyncResolved, ...syncResolved])
|
|
54215
|
+
byEdge.set(r.edge, r.split);
|
|
54216
|
+
return outbound.filter((e) => byEdge.has(e)).map((e) => ({ edge: e, split: byEdge.get(e) }));
|
|
54217
|
+
}
|
|
53902
54218
|
if (outbound.length === 1) {
|
|
53903
54219
|
return [{ edge: outbound[0], split: 100 }];
|
|
53904
54220
|
}
|
|
@@ -54006,8 +54322,9 @@ function computeInfra(parsed, params = {}) {
|
|
|
54006
54322
|
const computedLatency = /* @__PURE__ */ new Map();
|
|
54007
54323
|
const computedUptime = /* @__PURE__ */ new Map();
|
|
54008
54324
|
const localAvailability = /* @__PURE__ */ new Map();
|
|
54325
|
+
const defaultRps = parseFloat(parsed.options["default-rps"] ?? "") || 0;
|
|
54009
54326
|
const edgeNode = effectiveParsed.nodes.find((n) => n.isEdge);
|
|
54010
|
-
const baseRps = params.rps ?? (edgeNode ? getNumProp(edgeNode, "rps",
|
|
54327
|
+
const baseRps = params.rps ?? (edgeNode ? getNumProp(edgeNode, "rps", defaultRps) : 0);
|
|
54011
54328
|
if (edgeNode) {
|
|
54012
54329
|
computedRps.set(edgeNode.id, baseRps);
|
|
54013
54330
|
computedLatency.set(edgeNode.id, 0);
|
|
@@ -54052,13 +54369,14 @@ function computeInfra(parsed, params = {}) {
|
|
|
54052
54369
|
} else {
|
|
54053
54370
|
targetIds = [edge.targetId];
|
|
54054
54371
|
}
|
|
54372
|
+
const edgeDownstreamLatency = edge.async ? 0 : downstreamLatency;
|
|
54055
54373
|
for (const targetId of targetIds) {
|
|
54056
54374
|
const perTarget = fanoutedRps / targetIds.length;
|
|
54057
54375
|
const existing = computedRps.get(targetId) ?? 0;
|
|
54058
54376
|
computedRps.set(targetId, existing + perTarget);
|
|
54059
54377
|
const prevLatency = computedLatency.get(targetId) ?? 0;
|
|
54060
|
-
if (
|
|
54061
|
-
computedLatency.set(targetId,
|
|
54378
|
+
if (edgeDownstreamLatency > prevLatency) {
|
|
54379
|
+
computedLatency.set(targetId, edgeDownstreamLatency);
|
|
54062
54380
|
}
|
|
54063
54381
|
const prevUptime = computedUptime.get(targetId) ?? 1;
|
|
54064
54382
|
if (cumulativeUptime < prevUptime) {
|
|
@@ -54142,7 +54460,8 @@ function computeInfra(parsed, params = {}) {
|
|
|
54142
54460
|
const coldStartMs = isServerless(node) ? getNumProp(node, "cold-start-ms", 0) : 0;
|
|
54143
54461
|
const coldLatency = nodeLatency + coldStartMs;
|
|
54144
54462
|
const outbound = outboundMap.get(nodeId3) ?? [];
|
|
54145
|
-
|
|
54463
|
+
const syncOutbound = outbound.filter((e) => !e.async);
|
|
54464
|
+
if (syncOutbound.length === 0) {
|
|
54146
54465
|
const rps = computedRps.get(nodeId3) ?? 0;
|
|
54147
54466
|
let result;
|
|
54148
54467
|
if (rps <= 0) {
|
|
@@ -54175,7 +54494,7 @@ function computeInfra(parsed, params = {}) {
|
|
|
54175
54494
|
nodeLeafCache.set(nodeId3, result);
|
|
54176
54495
|
return result;
|
|
54177
54496
|
}
|
|
54178
|
-
const resolved = resolveSplits(outbound, []);
|
|
54497
|
+
const resolved = resolveSplits(outbound, []).filter((r) => !r.edge.async);
|
|
54179
54498
|
const paths = [];
|
|
54180
54499
|
for (const { edge, split } of resolved) {
|
|
54181
54500
|
const fanout = edge.fanout != null && edge.fanout >= 1 ? edge.fanout : 1;
|
|
@@ -54391,17 +54710,7 @@ function computeInfra(parsed, params = {}) {
|
|
|
54391
54710
|
const edgeKey = `${edge.sourceId}->${edge.targetId}`;
|
|
54392
54711
|
const rps = computedEdgeRps.get(edgeKey) ?? 0;
|
|
54393
54712
|
const outbound = outboundMap.get(edge.sourceId) ?? [];
|
|
54394
|
-
|
|
54395
|
-
if (outbound.length > 1 && edge.split === null) {
|
|
54396
|
-
const declared = outbound.filter((e) => e.split !== null);
|
|
54397
|
-
if (declared.length === 0) {
|
|
54398
|
-
resolvedSplit = 100 / outbound.length;
|
|
54399
|
-
} else {
|
|
54400
|
-
const declaredSum = declared.reduce((s, e) => s + (e.split ?? 0), 0);
|
|
54401
|
-
const undeclared = outbound.filter((e) => e.split === null);
|
|
54402
|
-
resolvedSplit = undeclared.length > 0 ? (100 - declaredSum) / undeclared.length : 0;
|
|
54403
|
-
}
|
|
54404
|
-
}
|
|
54713
|
+
const resolvedSplit = resolveSplits(outbound, []).find((r) => r.edge === edge)?.split ?? edge.split ?? 100;
|
|
54405
54714
|
return {
|
|
54406
54715
|
sourceId: edge.sourceId,
|
|
54407
54716
|
targetId: edge.targetId,
|
|
@@ -66782,7 +67091,7 @@ var init_renderer22 = __esm({
|
|
|
66782
67091
|
init_text_measure();
|
|
66783
67092
|
NODE_FONT_SIZE8 = 13;
|
|
66784
67093
|
DESC_FONT_SIZE7 = 11;
|
|
66785
|
-
EDGE_LABEL_FONT_SIZE14 =
|
|
67094
|
+
EDGE_LABEL_FONT_SIZE14 = 13;
|
|
66786
67095
|
DESC_LINE_HEIGHT8 = 15;
|
|
66787
67096
|
TITLE_AREA_HEIGHT = 50;
|
|
66788
67097
|
}
|
|
@@ -85096,7 +85405,7 @@ var CSS = AUTO_BASE_CSS + "\n" + BLOCK_CSS + "\n" + darkScopedBlockCss(BLOCK_CSS
|
|
|
85096
85405
|
|
|
85097
85406
|
// src/auto/shared.ts
|
|
85098
85407
|
init_safe_href();
|
|
85099
|
-
var VERSION = "0.
|
|
85408
|
+
var VERSION = "0.54.0";
|
|
85100
85409
|
var ARIA_LABEL_MAX = 200;
|
|
85101
85410
|
var COPIED_INTERACTION_MS = 1500;
|
|
85102
85411
|
var LOG_PREFIX = "[dgmo]";
|