schematex 0.8.2 → 0.9.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/ai/ai-sdk.cjs +6 -6
- package/dist/ai/ai-sdk.d.cts +2 -2
- package/dist/ai/ai-sdk.d.ts +2 -2
- package/dist/ai/ai-sdk.js +1 -1
- package/dist/ai/index.cjs +52 -13
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +37 -2
- package/dist/ai/index.d.ts +37 -2
- package/dist/ai/index.js +44 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/{chunk-HWNVSNDJ.cjs → chunk-HKOPXQYU.cjs} +1165 -340
- package/dist/chunk-HKOPXQYU.cjs.map +1 -0
- package/dist/{chunk-FLDHD4RM.js → chunk-PR6IAGVP.js} +1165 -340
- package/dist/chunk-PR6IAGVP.js.map +1 -0
- package/dist/{tools-CbBjmZVr.d.ts → tools-BbTuTWs_.d.ts} +18 -1
- package/dist/{tools-CVgUmiGP.d.cts → tools-D5dkAqNy.d.cts} +18 -1
- package/package.json +1 -1
- package/dist/chunk-FLDHD4RM.js.map +0 -1
- package/dist/chunk-HWNVSNDJ.cjs.map +0 -1
|
@@ -349,7 +349,18 @@ var DIAGRAM_REGISTRY = [
|
|
|
349
349
|
useWhen: "Use to propagate the consequences of an initiating event through a chain of barriers/safety functions and quantify each outcome's frequency \u2014 the inductive complement to a fault tree and the right wing of a bowtie. Header `eventtree`/`eta`; declare the initiating event with a frequency, the ordered functions with success/failure branch probabilities, and outcome rows with `s`/`f`/`*` patterns. The engine computes path frequency = f_initiating \xD7 \u03A0 branch-probabilities and flags the dominant sequence.",
|
|
350
350
|
cluster: "risk-reliability",
|
|
351
351
|
standard: "IEC 62502:2010 \xB7 NUREG/CR-2300 (PRA) \xB7 ISO 31010 Annex B; see 39-EVENT-TREE-STANDARD.md",
|
|
352
|
-
syntaxKey: "eventtree"
|
|
352
|
+
syntaxKey: "eventtree",
|
|
353
|
+
aliases: ["Event Tree Analysis", "ETA diagram", "event tree", "\u4E8B\u4EF6\u6811\u5206\u6790"],
|
|
354
|
+
keywords: [
|
|
355
|
+
"probabilistic risk assessment",
|
|
356
|
+
"PRA",
|
|
357
|
+
"safety function",
|
|
358
|
+
"accident sequence",
|
|
359
|
+
"barrier analysis",
|
|
360
|
+
"consequence analysis",
|
|
361
|
+
"nuclear safety",
|
|
362
|
+
"IEC 62502"
|
|
363
|
+
]
|
|
353
364
|
},
|
|
354
365
|
{
|
|
355
366
|
type: "fmea",
|
|
@@ -358,7 +369,25 @@ var DIAGRAM_REGISTRY = [
|
|
|
358
369
|
useWhen: "Use to score and prioritise how each component/process step can fail \u2014 severity, occurrence, detection \u2014 and decide what to fix first. Header `fmea`; declare item/function \u2192 failure mode \u2192 effect (with `sev`) \u2192 cause (with `occ`) \u2192 controls (with `det`). The engine computes RPN = S\xD7O\xD7D and the AIAG-VDA Action Priority (High/Medium/Low), sorts the sheet, and colour-fills the RPN/AP cells by risk. Schematex's first table-shaped diagram.",
|
|
359
370
|
cluster: "risk-reliability",
|
|
360
371
|
standard: "AIAG-VDA FMEA Handbook (2019) \xB7 IEC 60812:2018 \xB7 SAE J1739 \xB7 MIL-STD-1629A; see 40-FMEA-STANDARD.md",
|
|
361
|
-
syntaxKey: "fmea"
|
|
372
|
+
syntaxKey: "fmea",
|
|
373
|
+
aliases: [
|
|
374
|
+
"FMEA",
|
|
375
|
+
"Failure Mode and Effects Analysis",
|
|
376
|
+
"FMECA",
|
|
377
|
+
"failure mode analysis",
|
|
378
|
+
"\u6545\u969C\u6A21\u5F0F\u4E0E\u5F71\u54CD\u5206\u6790"
|
|
379
|
+
],
|
|
380
|
+
keywords: [
|
|
381
|
+
"RPN",
|
|
382
|
+
"risk priority number",
|
|
383
|
+
"Action Priority",
|
|
384
|
+
"AIAG-VDA",
|
|
385
|
+
"DFMEA",
|
|
386
|
+
"PFMEA",
|
|
387
|
+
"severity occurrence detection",
|
|
388
|
+
"reliability engineering",
|
|
389
|
+
"IEC 60812"
|
|
390
|
+
]
|
|
362
391
|
},
|
|
363
392
|
// ── Systems thinking / stochastic ────────────────────────────
|
|
364
393
|
{
|
|
@@ -368,7 +397,23 @@ var DIAGRAM_REGISTRY = [
|
|
|
368
397
|
useWhen: 'Use for systems thinking / system dynamics: variables connected by `+`/`\u2212` causal links, where the engine detects feedback loops and labels each R (even number of negative links) or B (odd). Header `causalloop`/`cld`; write `A -> B : +` links and optional `loop R1 "name"` annotations and `delay` marks. Distinct from `sociogram` (social ties, no polarity) and `flowchart` (process steps).',
|
|
369
398
|
cluster: "causality-analysis",
|
|
370
399
|
standard: "Sterman, Business Dynamics (2000) \xB7 Meadows, Thinking in Systems; see 41-CAUSAL-LOOP-STANDARD.md",
|
|
371
|
-
syntaxKey: "causalloop"
|
|
400
|
+
syntaxKey: "causalloop",
|
|
401
|
+
aliases: [
|
|
402
|
+
"Causal Loop Diagram",
|
|
403
|
+
"CLD",
|
|
404
|
+
"feedback loop diagram",
|
|
405
|
+
"systems thinking diagram",
|
|
406
|
+
"\u56E0\u679C\u56DE\u8DEF\u56FE"
|
|
407
|
+
],
|
|
408
|
+
keywords: [
|
|
409
|
+
"system dynamics",
|
|
410
|
+
"reinforcing loop",
|
|
411
|
+
"balancing loop",
|
|
412
|
+
"feedback loop",
|
|
413
|
+
"stock and flow",
|
|
414
|
+
"Sterman",
|
|
415
|
+
"Meadows"
|
|
416
|
+
]
|
|
372
417
|
},
|
|
373
418
|
{
|
|
374
419
|
type: "markov",
|
|
@@ -377,7 +422,22 @@ var DIAGRAM_REGISTRY = [
|
|
|
377
422
|
useWhen: "Use to model a probabilistic state process (reliability/availability, queueing, regime models) where you want the long-run distribution or absorption answer, not just the picture. Header `markov`/`markovchain`; write `S1 -> S2 : 0.3` transitions (each state's out-edges sum to 1). The engine computes the stationary distribution, classifies states, and for absorbing chains the fundamental matrix. Sibling of `state` and `petri`.",
|
|
378
423
|
cluster: "behavior-modeling",
|
|
379
424
|
standard: "Norris, Markov Chains (1997) \xB7 Kemeny & Snell, Finite Markov Chains; see 42-MARKOV-CHAIN-STANDARD.md",
|
|
380
|
-
syntaxKey: "markov"
|
|
425
|
+
syntaxKey: "markov",
|
|
426
|
+
aliases: [
|
|
427
|
+
"Markov chain",
|
|
428
|
+
"Markov chain diagram",
|
|
429
|
+
"stochastic state transition diagram",
|
|
430
|
+
"\u9A6C\u5C14\u53EF\u592B\u94FE"
|
|
431
|
+
],
|
|
432
|
+
keywords: [
|
|
433
|
+
"stationary distribution",
|
|
434
|
+
"stochastic process",
|
|
435
|
+
"transition matrix",
|
|
436
|
+
"transition probability",
|
|
437
|
+
"absorbing state",
|
|
438
|
+
"steady state",
|
|
439
|
+
"discrete-time"
|
|
440
|
+
]
|
|
381
441
|
},
|
|
382
442
|
// ── Software / process engineering ───────────────────────────
|
|
383
443
|
{
|
|
@@ -387,7 +447,23 @@ var DIAGRAM_REGISTRY = [
|
|
|
387
447
|
useWhen: 'Use to visualise a git branching/merging history. Header `gitGraph`; ordered `commit`, `branch <name>`, `checkout <name>`, `merge <name>`, `cherry-pick id: "\u2026"`, with `commit id:/tag:/type: HIGHLIGHT|REVERSE`. Mermaid `gitGraph` syntax parity so LLM output is drop-in compatible. Commits sit on per-branch lanes ordered chronologically; merges join lanes.',
|
|
388
448
|
cluster: "software-uml",
|
|
389
449
|
standard: "Mermaid gitGraph syntax \xB7 git DAG model; see 43-GIT-GRAPH-STANDARD.md",
|
|
390
|
-
syntaxKey: "gitgraph"
|
|
450
|
+
syntaxKey: "gitgraph",
|
|
451
|
+
aliases: [
|
|
452
|
+
"Git commit graph",
|
|
453
|
+
"git graph",
|
|
454
|
+
"git branch diagram",
|
|
455
|
+
"branching diagram",
|
|
456
|
+
"Git \u63D0\u4EA4\u56FE"
|
|
457
|
+
],
|
|
458
|
+
keywords: [
|
|
459
|
+
"branching strategy",
|
|
460
|
+
"git history",
|
|
461
|
+
"merge",
|
|
462
|
+
"cherry-pick",
|
|
463
|
+
"GitFlow",
|
|
464
|
+
"Mermaid gitGraph",
|
|
465
|
+
"commit history"
|
|
466
|
+
]
|
|
391
467
|
},
|
|
392
468
|
{
|
|
393
469
|
type: "epc",
|
|
@@ -396,7 +472,22 @@ var DIAGRAM_REGISTRY = [
|
|
|
396
472
|
useWhen: "Use for ARIS-style business process modelling (SAP / enterprise BPM). Header `epc`; declare `event`, `function`, connectors `and`/`or`/`xor`, and the control flow between them. The engine validates strict event\u2194function alternation and connector legality (an event cannot be the source of an OR/XOR split). Distinct from `bpmn` and `flowchart` \u2014 a separate published standard with stricter rules.",
|
|
397
473
|
cluster: "corporate-legal",
|
|
398
474
|
standard: "ARIS / Keller, N\xFCttgens & Scheer (1992); see 44-EPC-STANDARD.md",
|
|
399
|
-
syntaxKey: "epc"
|
|
475
|
+
syntaxKey: "epc",
|
|
476
|
+
aliases: [
|
|
477
|
+
"Event-driven Process Chain",
|
|
478
|
+
"EPC diagram",
|
|
479
|
+
"ARIS EPC",
|
|
480
|
+
"\u4E8B\u4EF6\u9A71\u52A8\u8FC7\u7A0B\u94FE"
|
|
481
|
+
],
|
|
482
|
+
keywords: [
|
|
483
|
+
"ARIS",
|
|
484
|
+
"business process modeling",
|
|
485
|
+
"SAP",
|
|
486
|
+
"BPM",
|
|
487
|
+
"process chain",
|
|
488
|
+
"enterprise architecture",
|
|
489
|
+
"Scheer"
|
|
490
|
+
]
|
|
400
491
|
},
|
|
401
492
|
{
|
|
402
493
|
type: "idef0",
|
|
@@ -405,7 +496,23 @@ var DIAGRAM_REGISTRY = [
|
|
|
405
496
|
useWhen: "Use to model what a system/process does and its inputs/controls/outputs/mechanisms \u2014 systems engineering, defence/government process docs, enterprise architecture. Header `idef0`; declare `function` boxes and ICOM arrows (`input`/`control`/`output`/`mechanism`) plus box\u2192box flows that name the target ICOM side. The engine enforces ICOM placement and assigns node numbers, in a diagonal box staircase.",
|
|
406
497
|
cluster: "project-management",
|
|
407
498
|
standard: "FIPS PUB 183 (1993) \xB7 SADT (Ross); see 45-IDEF0-STANDARD.md",
|
|
408
|
-
syntaxKey: "idef0"
|
|
499
|
+
syntaxKey: "idef0",
|
|
500
|
+
aliases: [
|
|
501
|
+
"IDEF0",
|
|
502
|
+
"IDEF0 function model",
|
|
503
|
+
"SADT diagram",
|
|
504
|
+
"function model",
|
|
505
|
+
"ICOM diagram"
|
|
506
|
+
],
|
|
507
|
+
keywords: [
|
|
508
|
+
"functional modeling",
|
|
509
|
+
"FIPS 183",
|
|
510
|
+
"systems engineering",
|
|
511
|
+
"activity model",
|
|
512
|
+
"ICOM",
|
|
513
|
+
"process model",
|
|
514
|
+
"enterprise architecture"
|
|
515
|
+
]
|
|
409
516
|
},
|
|
410
517
|
{
|
|
411
518
|
type: "threatmodel",
|
|
@@ -414,7 +521,25 @@ var DIAGRAM_REGISTRY = [
|
|
|
414
521
|
useWhen: "Use for security threat modelling (Microsoft SDL / OWASP Threat Dragon workflow): DFD shapes (external entity, process, data store), labelled data flows, and `boundary` trust zones. Header `threatmodel`/`stride`. The engine maps each element type to its STRIDE categories (external = S,R; process = all six; store = T,I,D + conditional R for logs; flow = T,I,D) and accents flows crossing a trust boundary. Includes the DFD base notation (no separate `dfd` engine).",
|
|
415
522
|
cluster: "network-infrastructure",
|
|
416
523
|
standard: "Shostack, Threat Modeling (2014) STRIDE-per-element \xB7 Microsoft SDL \xB7 base DFD DeMarco/Yourdon; see 46-THREAT-MODEL-STRIDE-STANDARD.md + 31-DFD-STANDARD.md",
|
|
417
|
-
syntaxKey: "threatmodel"
|
|
524
|
+
syntaxKey: "threatmodel",
|
|
525
|
+
aliases: [
|
|
526
|
+
"Threat model",
|
|
527
|
+
"STRIDE diagram",
|
|
528
|
+
"DFD threat model",
|
|
529
|
+
"data flow diagram",
|
|
530
|
+
"DFD",
|
|
531
|
+
"\u5A01\u80C1\u5EFA\u6A21"
|
|
532
|
+
],
|
|
533
|
+
keywords: [
|
|
534
|
+
"STRIDE",
|
|
535
|
+
"security threat modeling",
|
|
536
|
+
"Microsoft SDL",
|
|
537
|
+
"OWASP Threat Dragon",
|
|
538
|
+
"trust boundary",
|
|
539
|
+
"attack surface",
|
|
540
|
+
"application security",
|
|
541
|
+
"Shostack"
|
|
542
|
+
]
|
|
418
543
|
},
|
|
419
544
|
{
|
|
420
545
|
type: "welding",
|
|
@@ -423,7 +548,24 @@ var DIAGRAM_REGISTRY = [
|
|
|
423
548
|
useWhen: 'Use to annotate a welded joint on an engineering drawing: a horizontal reference line, a leader arrow to the joint, and a weld-symbol glyph above (other side) / below (arrow side) with size, length-pitch, groove angle, root opening, contour + finish. Header `welding [standard: aws|iso-a|iso-b]`; one `joint "label" { arrow: \u2026 other: \u2026 around field tail: \u2026 }` block per joint. Full glyph catalog (fillet, all groove types, plug/slot, spot/seam, back/backing, surfacing, edge) + weld-all-around, field flag, and tail process note. Validates illegal type/side/dimension combinations.',
|
|
424
549
|
cluster: "electrical-industrial",
|
|
425
550
|
standard: "AWS A2.4:2020 \xB7 ISO 2553:2019; see 47-WELDING-SYMBOL-STANDARD.md",
|
|
426
|
-
syntaxKey: "welding"
|
|
551
|
+
syntaxKey: "welding",
|
|
552
|
+
aliases: [
|
|
553
|
+
"Welding symbols",
|
|
554
|
+
"weld symbol",
|
|
555
|
+
"welding callout",
|
|
556
|
+
"weld joint symbol",
|
|
557
|
+
"\u710A\u63A5\u7B26\u53F7"
|
|
558
|
+
],
|
|
559
|
+
keywords: [
|
|
560
|
+
"AWS A2.4",
|
|
561
|
+
"ISO 2553",
|
|
562
|
+
"fillet weld",
|
|
563
|
+
"groove weld",
|
|
564
|
+
"weld notation",
|
|
565
|
+
"engineering drawing",
|
|
566
|
+
"fabrication",
|
|
567
|
+
"weld dimensions"
|
|
568
|
+
]
|
|
427
569
|
}
|
|
428
570
|
];
|
|
429
571
|
var DIAGRAM_SINCE = {
|
|
@@ -546,7 +688,7 @@ var EXAMPLES = [
|
|
|
546
688
|
"signal-flow"
|
|
547
689
|
],
|
|
548
690
|
"complexity": 2,
|
|
549
|
-
"featured":
|
|
691
|
+
"featured": true,
|
|
550
692
|
"dsl": 'blockdiagram "PID control loop"\nC = block("PID C(s)") [role: controller]\nG = block("Plant G(s)") [role: plant]\nerr = sum(+r, -y)\nr = signal("r (setpoint)")\ny = signal("y (output)")\nin -> r\nr -> err\nerr -> C\nC -> G\nG -> y\nG -> err',
|
|
551
693
|
"notes": '## Scenario\n\nThe standard closed-loop PID block diagram appears in every control systems textbook (Ogata, Franklin, \xC5str\xF6m) and every control system design spec sheet. Schematex renders it from a signal-flow description \u2014 not a generic flowchart \u2014 using proper summing junction symbols and automatic feedback routing.\n\n## Annotation key\n\n- `block("label") [role: ...]` \u2014 transfer function block; `role: controller` and `role: plant` affect visual styling\n- `sum(+r, -y)` \u2014 summing junction: adds the `+r` (reference) signal and subtracts the `-y` (output feedback)\n- `signal("label")` \u2014 named signal node\n- `G -> err` \u2014 the feedback path: plant output `y` routes back to the summing junction\n\n## How to read\n\nThe setpoint `r` enters the summing junction `err`, which subtracts the plant output `y` to compute the error signal. The PID controller `C(s)` processes the error and drives the plant `G(s)`. The plant output `y` is both the system output and the feedback signal. The loop is closed when `G -> err` feeds `y` back to the summing junction.'
|
|
552
694
|
},
|
|
@@ -782,7 +924,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
782
924
|
"balancing"
|
|
783
925
|
],
|
|
784
926
|
"complexity": 3,
|
|
785
|
-
"featured":
|
|
927
|
+
"featured": true,
|
|
786
928
|
"dsl": 'causalloop "Startup growth engine"\n "Active users" -> "Word of mouth" : +\n "Word of mouth" -> "New signups" : +\n "New signups" -> "Active users" : +\n "Active users" -> "Server load" : +\n "Server load" -> "App performance" : -\n "App performance" -> "Active users" : + delay\n "Active users" -> Revenue : +\n Revenue -> "Infra investment" : +\n "Infra investment" -> "App performance" : + delay\n loop R1 "Viral flywheel"\n loop B1 "Scaling strain"',
|
|
787
929
|
"notes": '## What this shows\n\nThe two-sided story of every viral product. One reinforcing loop drives growth: more active users produce more word of mouth, which drives signups, which adds users \u2014 an amplifying cycle. A second, balancing loop pushes back: more users raise server load, which degrades app performance, which (after a delay) loses users. The `delay` markers put the system-dynamics hash mark on the slow legs, where the lag between cause and effect is what makes the system overshoot.\n\nThe engine finds and labels the loops for you, which a drawing tool cannot. It enumerates every elementary cycle in the signed graph with Johnson\'s algorithm, then applies Sterman\'s rule \u2014 count the negative links, even means reinforcing (R), odd means balancing (B) \u2014 and numbers them R1, B1\u2026 The growth cycle comes back R (zero negatives), the load cycle B (one negative). The named `loop` declarations attach the human phrasing \u2014 "Viral flywheel", "Scaling strain" \u2014 onto the loops the engine detects.'
|
|
788
930
|
},
|
|
@@ -819,7 +961,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
819
961
|
"netlist"
|
|
820
962
|
],
|
|
821
963
|
"complexity": 2,
|
|
822
|
-
"featured":
|
|
964
|
+
"featured": true,
|
|
823
965
|
"dsl": 'circuit "Bridge Rectifier Supply" netlist\nV1 ac1 ac2 12Vac\nD1 ac1 vout 1N4007\nD2 ac2 vout 1N4007\nD3 0 ac1 1N4007\nD4 0 ac2 1N4007\nC1 vout 0 470u\nRload vout 0 1k',
|
|
824
966
|
"notes": "## Scenario\n\nA technician needs a quick schematic for the textbook AC-to-DC rectifier: a transformer secondary, four rectifier diodes, a reservoir capacitor, and a load. The netlist form keeps the topology precise while the renderer chooses the schematic placement.\n\n## Annotation key\n\n- `D1` to `D4` are ordinary diode components inferred from the `D` prefix.\n- `0` is the canonical ground net.\n- `C1` smooths the rectified output across `vout` and ground.\n\n## How to read\n\nDuring each half-cycle, two diodes conduct and steer current into `vout` with the same polarity. The capacitor charges near the peak and supplies the load between peaks, reducing ripple at `Rload`."
|
|
825
967
|
},
|
|
@@ -1109,7 +1251,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1109
1251
|
"control-flow"
|
|
1110
1252
|
],
|
|
1111
1253
|
"complexity": 3,
|
|
1112
|
-
"featured":
|
|
1254
|
+
"featured": true,
|
|
1113
1255
|
"dsl": 'epc "Purchase requisition"\n layout: tb\n event E1 "Material need identified"\n function F1 "Create requisition"\n function F2 "Determine source of supply"\n xor X1\n event E2 "Stock supplier exists"\n event E3 "New supplier needed"\n function F3 "Issue purchase order"\n function F4 "Run tender process"\n and A1\n event E4 "Order dispatched"\n event E5 "Supplier qualified"\n E1 -> F1 -> F2 -> X1\n X1 -> E2\n X1 -> E3\n E2 -> F3 -> A1\n E3 -> F4 -> A1\n A1 -> E4\n A1 -> E5',
|
|
1114
1256
|
"notes": '## What this shows\n\nA SAP-style procurement process modelled as an ARIS event-driven process chain (EPC), the notation that strictly alternates passive **events** ("Material need identified") and active **functions** ("Create requisition"). After sourcing, an **XOR** connector splits the flow on a real decision \u2014 an existing stock supplier versus a new supplier needing a tender \u2014 and the two paths re-converge on an **AND** connector that fans back out to the dispatched order and the qualified-supplier outcome.\n\nEPC\'s value here is structural validation, not a computed number. The engine checks the well-formedness rules and flags violations rather than silently drawing a broken model: event/function alternation along every path, single-in/single-out multiplicity carried by the connectors, reachability from start to end, and the **event-cannot-decide signature rule** \u2014 a passive event may not be the source of an XOR/OR split. That\'s why the decision routes *through* function `F2` before reaching the XOR, which is the correct ARIS form.'
|
|
1115
1257
|
},
|
|
@@ -1221,7 +1363,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1221
1363
|
"core-damage"
|
|
1222
1364
|
],
|
|
1223
1365
|
"complexity": 3,
|
|
1224
|
-
"featured":
|
|
1366
|
+
"featured": true,
|
|
1225
1367
|
"dsl": 'eventtree "Large LOCA"\n initiating LOCA "Large-break LOCA" freq: 1e-4\n function RT "Reactor trips" p: 0.001\n function ECCS "ECCS injection" p: 0.01\n function CHR "Containment heat removal" p: 0.02\n function CI "Containment integrity" p: 0.005\n outcome s s s s -> "OK"\n outcome s s s f -> "Late release"\n outcome s s f * -> "Late release"\n outcome s f * * -> "Early release"\n outcome f * * * -> "Core damage"',
|
|
1226
1368
|
"notes": '## What this shows\n\nThe textbook nuclear probabilistic-risk-assessment (PRA) tree. One initiating event \u2014 a large pipe break draining the coolant at a frequency of `1e-4` per year \u2014 is asked, left to right, whether each safety function holds: reactor trip, emergency core cooling (ECCS), containment heat removal, then containment integrity. Each `*` prunes a path that has already terminated, so the tree stays compact instead of ballooning to a full 2\u2074 ladder.\n\nThe engine does the arithmetic an event tree exists to give. It multiplies the initiating frequency by the success leg (`1 \u2212 p`) or failure leg (`p`) at each branch to get every sequence frequency, sums the two `"Late release"` leaves into one rolled-up outcome, and paints the largest-frequency path \u2014 the dominant accident sequence \u2014 in red. That computed answer, not the forking picture, is the deliverable a drawing tool can\'t produce.'
|
|
1227
1369
|
},
|
|
@@ -1465,7 +1607,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1465
1607
|
"automotive"
|
|
1466
1608
|
],
|
|
1467
1609
|
"complexity": 3,
|
|
1468
|
-
"featured":
|
|
1610
|
+
"featured": true,
|
|
1469
1611
|
"dsl": 'fmea "EV battery pack DFMEA"\n type: design\n rank: ap\n flag: ap >= High\n number: DFMEA-2026-014\n item "Cell module" fn "Store and deliver energy"\n mode "Thermal runaway"\n effect "Pack fire / occupant injury" sev: 10\n cause "Internal short from dendrite growth" occ: 3\n controls prevention: "Cell qualification", detection: "In-line CT scan" det: 4\n cause "Overcharge past cutoff" occ: 2\n controls prevention: "BMS voltage clamp", detection: "Redundant voltage sense" det: 3\n mode "Capacity fade"\n effect "Reduced range" sev: 6\n cause "Electrolyte depletion" occ: 5\n controls detection: "Periodic SOH estimate" det: 6\n item "Busbar joint" fn "Conduct current between modules"\n mode "High-resistance connection"\n effect "Local overheating" sev: 8\n cause "Loose torque on weld" occ: 4\n controls detection: "End-of-line resistance test" det: 4',
|
|
1470
1612
|
"notes": "## What this shows\n\nA design FMEA (DFMEA) on the highest-stakes subsystem in an electric vehicle. The nested chain reads item \u2192 mode \u2192 effect/cause/controls: a cell module that can suffer thermal runaway or capacity fade, and a busbar joint that can go high-resistance. Each effect carries a Severity, each cause an Occurrence, each control the Detection it earns \u2014 the three AIAG-VDA 1\u201310 scales.\n\nThe engine computes the priority rather than just tabling it. It flattens to one worksheet row per (item, mode, cause), multiplies RPN = S \xD7 O \xD7 D, and \u2014 the part that matters \u2014 derives the AIAG-VDA Action Priority, which is severity-primary. The thermal-runaway row sits at S10\xB7O3\xB7D4 with an RPN of 120; a naive RPN sort would rank it below a noisier low-severity defect, but Action Priority keeps every safety failure (S = 9\u201310) at **High** regardless. The `flag: ap >= High` directive highlights exactly those rows so the safety-critical work rises to the top."
|
|
1471
1613
|
},
|
|
@@ -1592,7 +1734,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1592
1734
|
"hotfix"
|
|
1593
1735
|
],
|
|
1594
1736
|
"complexity": 3,
|
|
1595
|
-
"featured":
|
|
1737
|
+
"featured": true,
|
|
1596
1738
|
"dsl": 'gitGraph\n commit id: "init"\n commit id: "scaffold"\n branch develop\n checkout develop\n commit id: "feature scaffold"\n branch feature/login\n checkout feature/login\n commit id: "login UI"\n commit id: "login API"\n checkout develop\n merge feature/login\n commit id: "polish"\n checkout main\n merge develop tag: "v1.0"\n branch hotfix\n checkout hotfix\n commit id: "patch CVE" type: HIGHLIGHT\n checkout main\n merge hotfix tag: "v1.0.1"\n checkout develop\n merge main',
|
|
1597
1739
|
"notes": "## What this shows\n\nA full Git Flow release cycle, the branching strategy teams adopt to keep a clean trunk. Work forks off `main` into a long-lived `develop`, then into a short-lived `feature/login` branch; the feature merges back to develop, develop merges to `main` as the tagged `v1.0` release. Then a security `hotfix` branches straight off `main`, lands a HIGHLIGHT commit, ships as `v1.0.1`, and is merged back down into develop so the fix isn't lost \u2014 the discipline that keeps the two lines from diverging.\n\nThe DSL is the Mermaid `gitGraph` dialect verbatim, so existing Mermaid sources port directly. The engine replays the operation list in order to assign each commit to a lane, routes the merge connectors from each branch tip without crossings, renders the patch commit emphasised as a HIGHLIGHT, and draws the version tags as flags \u2014 all from a KB-scale, dependency-free bundle."
|
|
1598
1740
|
},
|
|
@@ -1611,7 +1753,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1611
1753
|
"structured-analysis"
|
|
1612
1754
|
],
|
|
1613
1755
|
"complexity": 3,
|
|
1614
|
-
"featured":
|
|
1756
|
+
"featured": true,
|
|
1615
1757
|
"dsl": 'idef0 "Fulfil customer order"\nnode A0\nfunction A1 "Validate order"\nfunction A2 "Pick and pack"\nfunction A3 "Ship and invoice"\ninput A1 "Customer order"\ncontrol A1 "Credit policy"\nmechanism A1 "Order management system"\nA1 -> A2 "Validated order"\ninput A2 "Inventory"\ncontrol A2 "Picking rules"\nmechanism A2 "Warehouse staff"\nA2 -> A3 "Packed shipment"\ncontrol A3 "Carrier contract"\nmechanism A3 "Shipping carrier"\noutput A3 "Delivered order"\noutput A3 "Invoice"',
|
|
1616
1758
|
"notes": '## What this shows\n\nAn IDEF0 A0 diagram \u2014 the top-level functional decomposition of an order-fulfilment system \u2014 showing all four ICOM arrow roles. Reading the box edges by convention: **I**nputs enter on the left (the customer order, inventory), **C**ontrols govern from the top (credit policy, picking rules, carrier contract), **M**echanisms supply resources from the bottom (the order system, warehouse staff, carrier), and **O**utputs leave on the right (delivered order, invoice). The box-to-box flows (`A1 -> A2 "Validated order"`) chain the three activities.\n\nThe differentiator is that the model is correct by construction, not just drawn. Because the arrow keyword *is* the box edge it attaches to, the engine enforces ICOM placement \u2014 you cannot accidentally draw a control as an input. It resolves every box reference, assigns decomposition numbers (A0 \u2192 A1..A3), codes the boundary arrows down each edge (I1/C1/O1/M1\u2026), and applies the FIPS 3-to-6-box guideline. A flow that tried to *enter* a box via its `.output` edge would be rejected, because an output leaves a box \u2014 the standard is enforced, not suggested.'
|
|
1617
1759
|
},
|
|
@@ -1740,7 +1882,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1740
1882
|
"steady-state"
|
|
1741
1883
|
],
|
|
1742
1884
|
"complexity": 2,
|
|
1743
|
-
"featured":
|
|
1885
|
+
"featured": true,
|
|
1744
1886
|
"dsl": 'markov "Customer lifecycle"\n analysis: classify, stationary\n Trial -> Trial : 0.4\n Trial -> Active : 0.5\n Trial -> Churned : 0.1\n Active -> Active : 0.8\n Active -> Trial : 0.05\n Active -> Churned : 0.15\n Churned -> Churned : 0.7\n Churned -> Trial : 0.3',
|
|
1745
1887
|
"notes": "## What this shows\n\nA SaaS customer modelled as a memoryless hop between three states \u2014 Trial, Active, Churned \u2014 each month. Every row of probabilities leaving a state sums to 1 (the row-stochastic rule), and because churned customers can re-enter via Trial (`Churned -> Trial : 0.3`), no state is a dead end: the chain is **ergodic**, every state reachable from every other.\n\nThe engine does the linear algebra. It validates the matrix, runs SCC analysis to confirm a single recurrent class with no absorbing sink, then computes the **stationary distribution \u03C0** \u2014 the long-run share of your customer base sitting in each state once the system settles, independent of where it started. That steady-state answer (and the per-state classification) is carried in `data-*`, and it is the number a churn model exists to produce, not the circles-and-arrows."
|
|
1746
1888
|
},
|
|
@@ -2496,7 +2638,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
2496
2638
|
"color-coding"
|
|
2497
2639
|
],
|
|
2498
2640
|
"complexity": 3,
|
|
2499
|
-
"featured":
|
|
2641
|
+
"featured": true,
|
|
2500
2642
|
"dsl": 'phylo "Bacterial Diversity"\n newick: "((((Ecoli:0.1,Salmonella:0.12):0.05[&&NHX:B=98],Vibrio:0.2):0.08[&&NHX:B=85],((Bacillus:0.15,Staph:0.18):0.06[&&NHX:B=92],Listeria:0.22):0.1):0.15,((Myco_tb:0.3,Myco_leprae:0.28):0.12[&&NHX:B=100],(Strepto:0.25,Lactobacillus:0.2):0.08[&&NHX:B=78]):0.2);"\n clade Gamma = (Ecoli, Salmonella, Vibrio) [color: "#1E88E5", label: "\u03B3-Proteobacteria"]\n clade Firmi = (Bacillus, Staph, Listeria, Strepto, Lactobacillus) [color: "#E53935", label: "Firmicutes"]\n clade Actino = (Myco_tb, Myco_leprae) [color: "#43A047", label: "Actinobacteria"]\n scale "substitutions/site"',
|
|
2501
2643
|
"notes": '## Scenario\n\nA microbiologist or bioinformatician pastes a Newick tree string exported from RAxML, IQ-TREE, or MEGA and immediately gets a publication-ready SVG with clade highlights and a branch-length scale bar \u2014 no manual layout required.\n\n## Annotation key\n\n- `newick: "..."` \u2014 standard Newick format tree string; branch lengths follow `:` after each taxon name\n- `[&&NHX:B=98]` \u2014 NHX annotation; `B=` is the bootstrap support value (0\u2013100), rendered on internal nodes\n- `clade id = (taxon, ...)` \u2014 defines a named clade by listing its leaf members\n- `[color: "#hex", label: "..."]` \u2014 colors the clade\'s subtree and adds a labeled arc\n- `scale "..."` \u2014 draws a calibrated scale bar with the given unit label\n\n## How to read\n\nThe tree shows three major bacterial clades. Blue (\u03B3-Proteobacteria): *E. coli*, *Salmonella*, and *Vibrio* cluster with 98% bootstrap support. Red (Firmicutes): *Bacillus*, *Staph*, *Listeria*, *Streptococcus*, and *Lactobacillus*. Green (Actinobacteria): the two *Mycobacterium* species form a highly supported clade (bootstrap 100). Branch lengths represent substitutions per site \u2014 longer branches indicate faster evolutionary rates.'
|
|
2502
2644
|
},
|
|
@@ -3101,7 +3243,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
3101
3243
|
"data-flow"
|
|
3102
3244
|
],
|
|
3103
3245
|
"complexity": 3,
|
|
3104
|
-
"featured":
|
|
3246
|
+
"featured": true,
|
|
3105
3247
|
"dsl": 'threatmodel "E-commerce checkout"\nexternal: Customer\nexternal: Payment Gateway\nprocess 1.0: Web App\nprocess 2.0: Order Service\ndatastore D1: Orders DB\ndatastore D2: Audit Log\nCustomer -> 1.0 : "HTTPS Checkout"\n1.0 -> 2.0 : "Place order"\n2.0 -> D1 : "Write order"\n2.0 -> Payment Gateway : "Charge card"\n2.0 -> D2 : "Order event"\nboundary "Internet" { Customer, Payment_Gateway }\nboundary "DMZ" { 1.0 }\nboundary "Internal" { 2.0, D1, D2 }',
|
|
3106
3248
|
"notes": "## What this shows\n\nA STRIDE threat model of an e-commerce checkout drawn as a data-flow diagram (DFD): two external entities (the customer and a third-party payment gateway), two processes (the web app in the DMZ, the order service internally), and two data stores (the orders database and an audit log). Three trust boundaries partition the system \u2014 Internet, DMZ, Internal \u2014 and the labelled flows carry the data crossing between them.\n\nThe engine does the STRIDE-per-element analysis, not just the boxes. It applies the canonical mapping \u2014 externals get Spoofing/Repudiation, processes get the full S-T-R-I-D-E, stores get Tampering/Information-disclosure/DoS, and the **audit log additionally gets Repudiation** because it matches the log/journal pattern. Most usefully, it **flags every flow that crosses a trust boundary** \u2014 the customer\u2192web-app HTTPS request (Internet\u2192DMZ), the order-service\u2192payment-gateway charge (Internal\u2192Internet) \u2014 because boundary crossings are where spoofing, tampering, and information disclosure concentrate. Each element and flow carries its applicable STRIDE categories in `data-*`."
|
|
3107
3249
|
},
|
|
@@ -3174,7 +3316,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
3174
3316
|
"bus-read"
|
|
3175
3317
|
],
|
|
3176
3318
|
"complexity": 1,
|
|
3177
|
-
"featured":
|
|
3319
|
+
"featured": true,
|
|
3178
3320
|
"dsl": 'timing "Synchronous Bus Read"\nCLK: clock 8\nRST: rle 1*2 0*6\nEN: rle 0*2 1*4 0*2\nDATA: zz====zz data: ["D0","D1","D2","D3"]',
|
|
3179
3321
|
"notes": "## Scenario\n\nA digital designer documents an 8-cycle synchronous read. Rather than typing\n`pppppppp` for the clock and counting `0`/`1` runs by hand for reset and enable \u2014\nthe most common source of misaligned waveforms \u2014 the diagram uses the two\nlength-explicit shorthands.\n\n## Annotation key\n\n- **`clock N`** \u2014 a clock generator with `N` periods. `CLK: clock 8` expands to\n `pppppppp`; add `neg` for a negedge clock. No character-counting.\n- **`rle <state>*<count> \u2026`** \u2014 run-length segments. `RST: rle 1*2 0*6` expands to\n `11000000`; `EN: rle 0*2 1*4 0*2` expands to `00111100`. Every signal's total\n cell count is explicit, so the waves line up.\n- **raw wave string** \u2014 `DATA: zz====zz` keeps per-cell control where it matters;\n `data: [...]` labels the four `=` bus segments.\n\n## How to read\n\nThe clock runs 8 cycles. Reset is asserted for the first 2 cycles, then drops.\nEnable rises for the middle 4 cycles. The data bus is high-impedance until enable,\nthen presents four stable bytes `D0\u2026D3`, returning to high-Z after. Because\n`clock` and `rle` make each signal exactly 8 cells, the edges align without manual\ncounting."
|
|
3180
3322
|
},
|
|
@@ -3402,7 +3544,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
3402
3544
|
"fabrication"
|
|
3403
3545
|
],
|
|
3404
3546
|
"complexity": 3,
|
|
3405
|
-
"featured":
|
|
3547
|
+
"featured": true,
|
|
3406
3548
|
"dsl": 'welding "Bracket assembly"\njoint "gusset to column" {\n arrow: fillet size=8 len=50 pitch=150\n other: fillet size=6\n around\n field\n tail: "GMAW"\n}\njoint "splice plate (butt)" {\n arrow: vgroove angle=60 root=3 throat=12 contour=flush finish=G\n other: backing\n tail: "SMAW; E7018"\n}',
|
|
3407
3549
|
"notes": "## What this shows\n\nA **welding symbol** is the standard way a drawing tells a fabricator how to weld a joint \u2014 codified by **AWS A2.4** (US) and **ISO 2553** (international). It is a *reference-line skeleton*: a horizontal line, a leader arrow to the joint, and a weld glyph snapped above (other side) or below (arrow side) the line, with dimensions in fixed slots.\n\nThe first joint is an **intermittent double fillet** \u2014 a `size=8` arrow-side fillet welded `50` long on a `150` pitch, a `size=6` fillet on the other side \u2014 carried **all around** the gusset (the open circle at the leader junction) as a **field weld** (the flag), with the **GMAW** process noted in the tail. The second joint is a full-penetration **V-groove butt weld**: a `60\xB0` included angle with a `3 mm` root opening and a `12 mm` effective throat, a **backing** weld on the far side, ground **flush**, welded **SMAW** with **E7018** electrode. Each callout is placed correct-by-construction \u2014 the engine owns the skeleton, you describe the weld."
|
|
3408
3550
|
}
|
|
@@ -3630,280 +3772,696 @@ var PROFILES = {
|
|
|
3630
3772
|
genogram: {
|
|
3631
3773
|
type: "genogram",
|
|
3632
3774
|
header: 'genogram "Title"',
|
|
3633
|
-
mode: "
|
|
3775
|
+
mode: "individual declarations + couple lines + indented children",
|
|
3776
|
+
keywords: 'sex: male female unknown other \xB7 status: deceased stillborn miscarriage abortion \xB7 couple ops: -- (married) ~/~ (cohabiting-ended) ~x~ (divorced) -/- (separated) -o- (engaged) == (consanguineous) ~ (cohabiting) \xB7 child props: adopted foster guardian twin-identical twin-fraternal \xB7 individual attrs: age:N dob:"\u2026" dod:"\u2026" death:YYYY note:"\u2026" birth:out-of-wedlock|adopted|legitimate label:"\u2026" sibling-of:ID index \xB7 conditions: name(fill[,#color]) + \u2026 \xB7 fills: full half-left half-right half-top half-bottom quad-tl quad-tr quad-bl quad-br quarter striped dotted \xB7 emotional ops: -TYPE- or -TYPE-> where TYPE \u2208 harmony close love hostile conflict cutoff fused distant nevermet abuse neglect controlling jealous focused distrust',
|
|
3634
3777
|
forms: [
|
|
3635
|
-
"
|
|
3636
|
-
|
|
3637
|
-
"
|
|
3778
|
+
'genogram "Smith Family"',
|
|
3779
|
+
" john [male, 1975]",
|
|
3780
|
+
" mary [female, 1977]",
|
|
3781
|
+
' john -- mary "m. 2002"',
|
|
3782
|
+
" alice [female, 2005, index]",
|
|
3783
|
+
" john -conflict- mary"
|
|
3784
|
+
],
|
|
3785
|
+
prefer: [
|
|
3786
|
+
"Declare every individual (`id [sex, year, attrs]`) before any couple or emotional line that references them.",
|
|
3787
|
+
"Use couple operators `--` (married), `~/~` (cohabiting-ended), `~x~` (divorced), `-/-` (separated), `==` (consanguineous), `~` (cohabiting) on their own line; indent children beneath.",
|
|
3788
|
+
"Annotate conditions as `conditions: name(fill, #color) + name2(fill2)`, e.g. `conditions: diabetes(half-left, #ff9800) + cancer(quad-tr, #9c27b0)`.",
|
|
3789
|
+
"Mark the identified patient with the `index` attribute so the concentric double-border is drawn."
|
|
3638
3790
|
],
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3791
|
+
avoid: [
|
|
3792
|
+
"Don't use pedigree genetic-status tokens (`affected`, `carrier`, `proband`) in a genogram \u2014 use `conditions:` fill patterns instead.",
|
|
3793
|
+
'Don\'t attach emotional-operator labels with `[label:]`; place the optional quoted label after the right-hand id: `john -conflict- mary "ongoing"`.',
|
|
3794
|
+
"Don't invent fill patterns \u2014 use only `full`, `half-left/right/top/bottom`, `quad-tl/tr/bl/br`, `quarter`, `striped`, `dotted`."
|
|
3795
|
+
],
|
|
3796
|
+
repair: [
|
|
3797
|
+
"'Unknown individual' -> declare `id [sex]` before any couple or emotional line that references that id.",
|
|
3798
|
+
"'Invalid fill pattern' -> use one of: full, half-left, half-right, half-top, half-bottom, quad-tl, quad-tr, quad-bl, quad-br, quarter, striped, dotted.",
|
|
3799
|
+
"'Conflicting sex for' -> an individual was declared with two different sexes \u2014 keep sex in the first declaration only.",
|
|
3800
|
+
"'Invalid birth status' -> `birth:` accepts only `legitimate`, `out-of-wedlock`, or `adopted`."
|
|
3801
|
+
]
|
|
3642
3802
|
},
|
|
3643
3803
|
ecomap: {
|
|
3644
3804
|
type: "ecomap",
|
|
3645
3805
|
header: 'ecomap "Title"',
|
|
3646
|
-
mode: "center + external systems",
|
|
3806
|
+
mode: "center declaration + external systems + connection operators",
|
|
3807
|
+
keywords: 'center: ID [label:"\u2026"] \xB7 system: ID [label:"\u2026" category:family|friends|work|education|health|mental-health|religion|recreation|legal|community|substance|financial|cultural|technology|pet size:large|medium|small importance:major|moderate|minor] \xB7 connection ops (strength): === (strong) == (moderate) --- (normal) "- -" (weak) ~~~ (stressful) ~x~ (conflictual) -/- (broken) \xB7 directional variants: ===> <=== ==> <== --> <-- <-> <=> \xB7 [label:"\u2026"] on a connection',
|
|
3647
3808
|
forms: [
|
|
3648
|
-
'
|
|
3649
|
-
'
|
|
3650
|
-
'
|
|
3809
|
+
'ecomap "Marcus, age 15"',
|
|
3810
|
+
' center: client [label: "Marcus"]',
|
|
3811
|
+
' mom [label: "Mother", category: family]',
|
|
3812
|
+
' school [label: "East High School", category: education]',
|
|
3813
|
+
' therapist [label: "Ms. Chen", category: mental-health]',
|
|
3814
|
+
' mom === client [label: "primary caregiver"]',
|
|
3815
|
+
" school === client",
|
|
3816
|
+
' therapist <-> client [label: "weekly"]'
|
|
3817
|
+
],
|
|
3818
|
+
prefer: [
|
|
3819
|
+
"Declare exactly one `center: ID [props]` first; this is the central individual or family unit.",
|
|
3820
|
+
'Declare all external systems (`ID [label: "\u2026", category: \u2026]`) before their connection lines.',
|
|
3821
|
+
"Choose connection strength from `===` (strong), `==` (moderate), `---` (normal), `~~~` (stressful), `-/-` (broken); add a directional arrow variant (`-->`, `<->`, `==>`) when energy-flow direction matters."
|
|
3822
|
+
],
|
|
3823
|
+
avoid: [
|
|
3824
|
+
"Don't use genogram couple operators (`--`, `~/~`) inside an ecomap \u2014 they are not connection operators here.",
|
|
3825
|
+
"Don't omit the `center:` line; a diagram with no center is structurally invalid even if it renders.",
|
|
3826
|
+
"Don't nest family members under `center:` like a genogram; the ecomap center is a single node (use `sociogram` for network structure)."
|
|
3651
3827
|
],
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3828
|
+
repair: [
|
|
3829
|
+
"'Unexpected:' -> the line is not a center declaration, a system declaration, or a valid connection \u2014 check operator spelling (`~x~` has the letter x).",
|
|
3830
|
+
"'Expected ecomap header' -> the first non-blank line must start with `ecomap`; add or fix the header.",
|
|
3831
|
+
'A connection to an undeclared id silently creates a stray node \u2014 declare `systemId [label: "\u2026"]` before the connection line.'
|
|
3832
|
+
]
|
|
3655
3833
|
},
|
|
3656
3834
|
pedigree: {
|
|
3657
3835
|
type: "pedigree",
|
|
3658
3836
|
header: 'pedigree "Title"',
|
|
3659
|
-
mode: "
|
|
3837
|
+
mode: "individual declarations + couple lines + indented offspring (NSGC notation)",
|
|
3838
|
+
keywords: 'sex: male female unknown amab afab uaab \xB7 genetic status: affected carrier carrier-x obligate-carrier presymptomatic unaffected \xB7 life status: deceased stillborn pregnancy sab tab ectopic \xB7 markers: proband consultand evaluated \xB7 couple ops: -- (mated) -/- (separated) == (consanguineous) ~ (cohabiting, no offspring) \xB7 multi-trait legend: id = "Label" (fill: quad-tl|quad-tr|quad-bl|quad-br) + affected:trait1+trait2 \xB7 header mode suffix: pedigree:autosomal-dominant|autosomal-recessive|x-linked',
|
|
3660
3839
|
forms: [
|
|
3661
|
-
"
|
|
3662
|
-
"
|
|
3663
|
-
"
|
|
3840
|
+
'pedigree "Hemophilia A"',
|
|
3841
|
+
" I-1 [male, unaffected]",
|
|
3842
|
+
" I-2 [female, carrier-x]",
|
|
3843
|
+
" I-1 -- I-2",
|
|
3844
|
+
" II-1 [male, affected]",
|
|
3845
|
+
" II-2 [female, carrier-x]",
|
|
3846
|
+
" II-3 [male, unaffected]"
|
|
3847
|
+
],
|
|
3848
|
+
prefer: [
|
|
3849
|
+
"Use Roman-numeral generation labels (`I-1`, `II-3`) for individual ids \u2014 the NSGC clinical convention.",
|
|
3850
|
+
"Declare genetic status on each individual: `affected`, `carrier`, `carrier-x` (X-linked dot), `obligate-carrier`, `presymptomatic`, or `unaffected`.",
|
|
3851
|
+
"Mark the index case with `proband`; mark a family member seeking advice with `consultand`."
|
|
3664
3852
|
],
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3853
|
+
avoid: [
|
|
3854
|
+
"Don't use genogram emotional-relationship operators (`-conflict-`, `-abuse->`) in a pedigree \u2014 only couple and parent-child lines are valid.",
|
|
3855
|
+
"Don't mix pedigree status with genogram `conditions:` fill syntax; pedigree uses `affected`/`carrier` tokens, not `conditions:name(fill)`.",
|
|
3856
|
+
"Don't invent sex tokens; valid values are `male`, `female`, `unknown`, `amab`, `afab`, `uaab`."
|
|
3857
|
+
],
|
|
3858
|
+
repair: [
|
|
3859
|
+
"'Unknown individual' -> declare `id [sex, geneticStatus]` before any couple line that references that id.",
|
|
3860
|
+
"'Expected pedigree header' -> the first non-blank line must start with `pedigree`; the optional `:mode` suffix and title follow.",
|
|
3861
|
+
"'Conflicting' -> keep one canonical declaration per individual; redeclarations should add only the missing couple reference."
|
|
3862
|
+
]
|
|
3668
3863
|
},
|
|
3669
3864
|
phylo: {
|
|
3670
3865
|
type: "phylo",
|
|
3671
3866
|
header: 'phylo "Title"',
|
|
3672
|
-
mode: "
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3867
|
+
mode: "Newick string (newick:) or indented-tree DSL, with optional clade highlights",
|
|
3868
|
+
keywords: 'newick: "\u2026" (NHX supported) \xB7 indent tree: root: then indented Name:branchLength \xB7 header opts [layout: rectangular|slanted|circular|unrooted, mode: phylogram|cladogram|chronogram|dendrogram, mrsd:"YYYY", branch-width:N] \xB7 clade ID = (leaf1, leaf2) [color: "#hex", label: "\u2026", highlight: branch|background|both] \xB7 outgroup: ID \xB7 scale "unit label" \xB7 cut N (dendrogram threshold)',
|
|
3869
|
+
forms: [
|
|
3870
|
+
'phylo "Bacterial Diversity"',
|
|
3871
|
+
' newick: "((Ecoli:0.1,Salmonella:0.12):0.05,Vibrio:0.2);"',
|
|
3872
|
+
' clade Gamma = (Ecoli, Salmonella, Vibrio) [color: "#1E88E5", label: "Gammaproteobacteria"]',
|
|
3873
|
+
' scale "substitutions/site"'
|
|
3874
|
+
],
|
|
3875
|
+
prefer: [
|
|
3876
|
+
'Use `newick: "\u2026"` for first-shot generation \u2014 a Newick string with branch lengths (`Name:length`); NHX annotations `[&&NHX:B=98]` carry bootstrap values.',
|
|
3877
|
+
'Add `clade ID = (leaf1, leaf2, \u2026) [color: "#hex", label: "\u2026"]` after the newick line to highlight named clades.',
|
|
3878
|
+
'Use `[mode: chronogram, mrsd: "YYYY"]` for time-calibrated trees and `[mode: cladogram]` when branch lengths are absent.'
|
|
3879
|
+
],
|
|
3880
|
+
avoid: [
|
|
3881
|
+
"Don't use the indent-tree mode (`root:` + indented names) for first-shot generation \u2014 Newick is more compact.",
|
|
3882
|
+
"Don't omit branch lengths in phylogram mode; without them the layout collapses (use `[mode: cladogram]` explicitly instead).",
|
|
3883
|
+
"Don't reference clade member names that don't match the Newick leaf labels exactly \u2014 highlighting silently does nothing on a mismatch."
|
|
3884
|
+
],
|
|
3885
|
+
repair: [
|
|
3886
|
+
"'No tree definition found (newick: or indent tree)' -> add a `newick: \"\u2026;\"` line or an indent tree starting with `root:` after the header.",
|
|
3887
|
+
"'Empty indent tree definition' -> the `root:` block has no indented content \u2014 add at least one child line.",
|
|
3888
|
+
"If clade colors don't appear, check every member id in `clade X = (\u2026)` exactly matches a leaf label in the Newick string."
|
|
3889
|
+
]
|
|
3677
3890
|
},
|
|
3678
3891
|
sociogram: {
|
|
3679
3892
|
type: "sociogram",
|
|
3680
3893
|
header: 'sociogram "Title"',
|
|
3681
|
-
mode: "declared nodes +
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3894
|
+
mode: "declared nodes + edge operators + config",
|
|
3895
|
+
keywords: 'nodeId [label:"\u2026" group:id role:star|isolate|bridge|neglectee|rejected size:small|medium|large] \xB7 group id [label:"\u2026" color:"#hex"] + indented members \xB7 edge ops positive: -> <-> -- ==> <==> === \xB7 negative: -x> <x-> -x- \xB7 neutral: -.> <.-> -.- \xB7 [weight:N label:"\u2026"] on edge \xB7 config: layout = circular|force-directed|concentric \xB7 config: sizing = uniform|in-degree|betweenness \xB7 config: coloring = default|group|role',
|
|
3896
|
+
forms: [
|
|
3897
|
+
'alice [label: "Alice"] [role: star]',
|
|
3898
|
+
'bob [label: "Bob"] [group: teamA]',
|
|
3899
|
+
'group teamA [label: "Team A", color: "#1976D2"]',
|
|
3900
|
+
" alice; bob",
|
|
3901
|
+
'alice <-> bob [label: "study partners"]',
|
|
3902
|
+
'carol -x> dave [label: "conflict"]',
|
|
3903
|
+
"config: layout = force-directed"
|
|
3904
|
+
],
|
|
3905
|
+
prefer: [
|
|
3906
|
+
"Declare nodes explicitly before edge lines when you need `role:`, `group:`, or `size:` \u2014 the parser auto-registers undeclared ids, but only named declarations carry attributes.",
|
|
3907
|
+
"Use `group id [label:\u2026]` + indented members to cluster nodes; coloring follows when `config: coloring = group` is set.",
|
|
3908
|
+
"Pick the edge operator by valence: `->`/`<->`/`--` positive, `-x>`/`-x-` negative (rejection/conflict), `-.>`/`-.-` neutral; heavier `==>`/`===` encode strong-weight ties."
|
|
3909
|
+
],
|
|
3910
|
+
avoid: [
|
|
3911
|
+
"Don't borrow ecomap operators \u2014 in a sociogram `===` is an undirected strong tie, not an ecomap stress line; every operator encodes direction and valence.",
|
|
3912
|
+
"Don't set `config: layout` to an unsupported value \u2014 only `circular`, `force-directed`, `concentric` are accepted; unknown values are silently ignored.",
|
|
3913
|
+
"Don't omit the spaces around an edge operator: `alice->bob` is not parsed; it must be `alice -> bob`."
|
|
3914
|
+
],
|
|
3915
|
+
repair: [
|
|
3916
|
+
"'Sociogram must start with' -> the first non-blank line must be `sociogram` (optionally with a quoted title); fix a missing or misspelled header.",
|
|
3917
|
+
'A node referenced only on edge lines auto-registers with no label \u2014 if the rendered label is the raw id, add an explicit `nodeId [label: "\u2026"]` declaration.',
|
|
3918
|
+
"An unrecognised `config:` value (e.g. `layout = radial`) is silently dropped and defaults to `circular` \u2014 check spelling against the accepted enum."
|
|
3919
|
+
]
|
|
3686
3920
|
},
|
|
3687
3921
|
timing: {
|
|
3688
3922
|
type: "timing",
|
|
3689
3923
|
header: 'timing "Title"',
|
|
3690
3924
|
mode: "WaveDrom signals, with clock/run-length shorthands",
|
|
3925
|
+
keywords: 'timing "title" [hscale: N] \xB7 SIGNAME: wave_spec \xB7 wave chars 0 1 x z = . u d p P n N h H l L 2-9 \xB7 clock N [neg] \xB7 rle <state>*<count> \u2026 \xB7 data: ["a","b"] for = and digit segments \xB7 [GroupName] or group "name" { \u2026 } \xB7 --- spacer \xB7 phase: FLOAT (0.0\u20131.0)',
|
|
3691
3926
|
forms: [
|
|
3692
|
-
"
|
|
3693
|
-
"
|
|
3694
|
-
|
|
3927
|
+
'timing "Synchronous Bus Read"',
|
|
3928
|
+
"CLK: clock 8",
|
|
3929
|
+
"RST: rle 1*2 0*6",
|
|
3930
|
+
"EN: rle 0*2 1*4 0*2",
|
|
3931
|
+
'DATA: zz====zz data: ["D0","D1","D2","D3"]'
|
|
3695
3932
|
],
|
|
3696
3933
|
prefer: [
|
|
3697
|
-
"Use `clock N` for clocks instead of counting `p` characters.",
|
|
3698
|
-
"Use `rle <state>*<count>
|
|
3699
|
-
|
|
3700
|
-
"
|
|
3934
|
+
"Use `clock N` for clocks instead of counting `p` characters \u2014 `CLK: clock 8` is immune to count errors.",
|
|
3935
|
+
"Use `rle <state>*<count> \u2026` for level/data signals \u2014 `RST: rle 1*2 0*6` makes length explicit and auto-aligns.",
|
|
3936
|
+
'Drop to a raw wave string only for fine control (e.g. `DATA: zz====zz`); label bus segments (`=` or digit states) with `data: ["A","B",\u2026]`.',
|
|
3937
|
+
"Keep all signals the same total cell count so they align; `clock N` and `rle` make this trivial to verify."
|
|
3938
|
+
],
|
|
3939
|
+
avoid: [
|
|
3940
|
+
"Avoid hand-counting long runs of identical characters \u2014 mismatched counts are the main source of misaligned waves.",
|
|
3941
|
+
"Don't mix `clock`/`rle` and a raw wave string for the same signal; pick one form per signal.",
|
|
3942
|
+
"Don't use a wave character outside `0 1 x z = . p P n N h H l L u d 2-9`."
|
|
3701
3943
|
],
|
|
3702
|
-
avoid: ["Avoid hand-counting long runs of identical characters \u2014 that is the main source of misaligned waves."],
|
|
3703
3944
|
repair: [
|
|
3704
|
-
"
|
|
3705
|
-
"
|
|
3945
|
+
"'clock needs a positive cycle count' -> provide an integer >= 1 after `clock`, e.g. `CLK: clock 8`.",
|
|
3946
|
+
"'rle segment must be' -> each rle token must match `<char>*<N>` with a valid state char, e.g. `rle 1*3 0*5`.",
|
|
3947
|
+
"'is not a valid state' -> valid states are `0 1 x z = . p P n N h H l L u d 2-9`; replace the offending character, or use `clock`/`rle`."
|
|
3706
3948
|
]
|
|
3707
3949
|
},
|
|
3708
3950
|
logic: {
|
|
3709
3951
|
type: "logic",
|
|
3710
3952
|
header: 'logic "Title"',
|
|
3711
|
-
mode: "logic netlist",
|
|
3712
|
-
|
|
3953
|
+
mode: "logic netlist \u2014 INPUT/OUTPUT declarations + gate assignments; optional module grouping",
|
|
3954
|
+
keywords: 'logic ["Title"] [style: ansi|iec] \xB7 INPUT id, \u2026 \xB7 OUTPUT id, \u2026 \xB7 id = GATE(in1, in2, \u2026) \xB7 active-low prefix ~ on any signal \xB7 module "Label" { \u2026 } \xB7 combinational: AND OR NOT NAND NOR XOR XNOR BUF \xB7 output-buffer: TRISTATE_BUF TRISTATE_INV OPEN_DRAIN SCHMITT \xB7 flip-flops: DFF JKFF SRFF TFF \xB7 latches: LATCH_SR LATCH_D \xB7 complex: MUX DEMUX DECODER ENCODER COUNTER SHIFT_REG',
|
|
3955
|
+
forms: [
|
|
3956
|
+
'logic "1-bit Full Adder"',
|
|
3957
|
+
"input A, B, Cin",
|
|
3958
|
+
"output Sum, Cout",
|
|
3959
|
+
"s1 = XOR(A, B)",
|
|
3960
|
+
"Sum = XOR(s1, Cin)",
|
|
3961
|
+
"c1 = AND(A, B)",
|
|
3962
|
+
"c2 = AND(s1, Cin)",
|
|
3963
|
+
"Cout = OR(c1, c2)"
|
|
3964
|
+
],
|
|
3713
3965
|
prefer: [
|
|
3714
|
-
"Gate form is `id = TYPE(in1, in2, \u2026)`; declare `INPUT`/`OUTPUT` ports explicitly. Prefix
|
|
3715
|
-
"Use only
|
|
3966
|
+
"Gate form is `id = TYPE(in1, in2, \u2026)`; declare `INPUT`/`OUTPUT` ports explicitly. Prefix any signal with `~` for active-low.",
|
|
3967
|
+
"Use only canonical gate types \u2014 combinational `AND` `OR` `NOT` `NAND` `NOR` `XOR` `XNOR` `BUF`; buffers `TRISTATE_BUF` `TRISTATE_INV` `OPEN_DRAIN` `SCHMITT`; flip-flops `DFF` `JKFF` `SRFF` `TFF`; latches `LATCH_SR` `LATCH_D`; complex `MUX` `DEMUX` `DECODER` `ENCODER` `COUNTER` `SHIFT_REG`.",
|
|
3968
|
+
'Group related gates with `module "Label" { \u2026 }` to render a named bounding box.'
|
|
3969
|
+
],
|
|
3970
|
+
avoid: [
|
|
3971
|
+
"Avoid circuit component names (`R`, `C`, transistors) or FBD block names (`TON`, `CTU`) inside logic diagrams \u2014 they are not valid gate types.",
|
|
3972
|
+
"Don't leave a `module { \u2026 }` unclosed \u2014 an unclosed module block throws `Unclosed module`.",
|
|
3973
|
+
"Don't rely on auto-declaration of undeclared signals \u2014 the parser warns and adds them silently; explicit `INPUT` lines are cleaner."
|
|
3716
3974
|
],
|
|
3717
|
-
|
|
3718
|
-
|
|
3975
|
+
repair: [
|
|
3976
|
+
"'has unrecognised type' -> replace with the closest canonical gate (e.g. `LOAD`/`REG` -> `DFF`, `INV` -> `NOT`, `BUFFER` -> `BUF`); the lint hint names the nearest match.",
|
|
3977
|
+
"'Unclosed module' -> add a closing `}` for every `module \"\u2026\" {` block.",
|
|
3978
|
+
"'was not declared; auto-declared as input' -> add an explicit `input X` line to make the port intentional."
|
|
3979
|
+
]
|
|
3719
3980
|
},
|
|
3720
3981
|
circuit: {
|
|
3721
3982
|
type: "circuit",
|
|
3722
3983
|
header: 'circuit "Title" netlist',
|
|
3723
3984
|
mode: "SPICE-style netlist (recommended for generation)",
|
|
3985
|
+
keywords: 'header: circuit "name" netlist \xB7 ID net1 net2 [value] [key=value \u2026] \xB7 prefixes R(resistor) C(capacitor) L(inductor) D(diode) V(voltage_source) I(current_source) Q(BJT) M(MOSFET) J(jfet) S(switch) F(fuse) B(battery) K(relay) U/X(ic) W(wire) T(terminal) \xB7 ground nets 0/gnd/ground/earth/vss/agnd/dgnd \xB7 type= override \xB7 dir=(right|left|up|down) \xB7 pins="\u2026" \xB7 positional mode (no netlist): id: type dir [label= value= at=] \xB7 wire right|left|up|down \xB7 at: id.pin \xB7 net NAME \xB7 ground vcc no_connect',
|
|
3724
3986
|
forms: [
|
|
3725
|
-
"
|
|
3726
|
-
"
|
|
3727
|
-
"
|
|
3987
|
+
'circuit "Bridge Rectifier Supply" netlist',
|
|
3988
|
+
"V1 ac1 ac2 12Vac",
|
|
3989
|
+
"D1 ac1 vout 1N4007",
|
|
3990
|
+
"D2 ac2 vout 1N4007",
|
|
3991
|
+
"D3 0 ac1 1N4007",
|
|
3992
|
+
"D4 0 ac2 1N4007",
|
|
3993
|
+
"C1 vout 0 470u",
|
|
3994
|
+
"Rload vout 0 1k"
|
|
3728
3995
|
],
|
|
3729
3996
|
prefer: [
|
|
3730
|
-
|
|
3731
|
-
"Two components
|
|
3732
|
-
"The
|
|
3733
|
-
"Optional
|
|
3997
|
+
'Always use netlist mode (`circuit "name" netlist`). Each line is one component; no cursor state to track.',
|
|
3998
|
+
"Two components sharing a net name are wired together. Ground is `0`, `GND`, or an alias (`AGND`, `VSS`, `earth`); all normalise to one GND rail.",
|
|
3999
|
+
"The id first letter sets the type (R=resistor, C=capacitor, L=inductor, D=diode, V=voltage_source, Q=BJT, M=MOSFET). Use `type=` only when the prefix is ambiguous.",
|
|
4000
|
+
"Optional `dir=right|left|up|down` nudges a symbol's orientation (e.g. `C1 vout 0 100n dir=down` for a shunt cap); it does not set position."
|
|
3734
4001
|
],
|
|
3735
4002
|
avoid: [
|
|
3736
|
-
"Avoid positional cursor
|
|
3737
|
-
"Do not invent coordinates; the layout engine places components from
|
|
4003
|
+
"Avoid positional cursor mode (`wire`, `at:`) \u2014 it requires tracking mental cursor state and is not recommended for generation.",
|
|
4004
|
+
"Do not invent coordinates; the auto-layout engine places components from net connectivity. `dir=` only rotates a symbol.",
|
|
4005
|
+
"Don't give a multi-terminal part fewer nets than it has pins (a `transformer` needs 4: `T1 p1 p2 s1 s2 type=transformer`)."
|
|
3738
4006
|
],
|
|
3739
|
-
repair: [
|
|
4007
|
+
repair: [
|
|
4008
|
+
"'Cannot infer type from id' -> rename to a SPICE-prefix id (R*, C*, L*, D*, V*, Q*, M*\u2026) or add `type=<name>` (e.g. `N1 in out type=nmos`).",
|
|
4009
|
+
"'must be unique' -> a reference designator is declared more than once; rename the duplicates.",
|
|
4010
|
+
"'no ground reference' -> tie a return node to ground by naming a net `0` or `GND` (e.g. `V1 vin 0 5V`).",
|
|
4011
|
+
"'connects to only one pin' -> wire the net to a second pin, or mark the open pin with a `no_connect` symbol."
|
|
4012
|
+
]
|
|
3740
4013
|
},
|
|
3741
4014
|
blockdiagram: {
|
|
3742
4015
|
type: "blockdiagram",
|
|
3743
4016
|
header: 'blockdiagram "Title"',
|
|
3744
|
-
mode: "
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
4017
|
+
mode: "named block/sum/signal decls + directed -> chains",
|
|
4018
|
+
keywords: 'ID = block("label") [role:\u2026][route:above|below] \xB7 ID = sum(+a, -b) \xB7 ID = signal("label") [discrete] \xB7 connect ids with -> (chainable a -> b -> c) \xB7 in / out boundary ports \xB7 edge label ["text"] | roles: controller plant sensor actuator reference disturbance generic',
|
|
4019
|
+
forms: [
|
|
4020
|
+
'C = block("PID C(s)") [role: controller]',
|
|
4021
|
+
'G = block("Plant G(s)") [role: plant]',
|
|
4022
|
+
"err = sum(+r, -y)",
|
|
4023
|
+
"in -> err -> C -> G -> y",
|
|
4024
|
+
"G -> err"
|
|
4025
|
+
],
|
|
4026
|
+
prefer: [
|
|
4027
|
+
'Declare blocks `ID = block("label") [role: \u2026]`, junctions `ID = sum(+a, -b)`, and signals `ID = signal("label")`, then wire ids with directed `->` (chainable: `a -> b -> c`).',
|
|
4028
|
+
"Model feedback through an explicit `sum(+ref, -fb)` \u2014 the signs are visual (+ enters, \u2212 subtracts), not computed; send a long return path over the top with `[route: above]` on the sensor block.",
|
|
4029
|
+
'Roles for styling: controller, plant, sensor, actuator, reference, disturbance, generic. Use the auto-provided `in`/`out` ports for the system boundary, and annotate an edge with `["label"]`.'
|
|
4030
|
+
],
|
|
4031
|
+
avoid: [
|
|
4032
|
+
"An unknown id on a `->` line does NOT error \u2014 it silently becomes a stray generic `block`, so a typo'd id creates a phantom box. Keep ids consistent.",
|
|
4033
|
+
"Avoid drawing feedback as a bare reverse arrow with no junction; route it into a `sum(...)` so the loop reads correctly.",
|
|
4034
|
+
'Don\'t quote ids; quotes belong only inside `block("\u2026")` / `signal("\u2026")` labels and edge `["\u2026"]` labels.'
|
|
4035
|
+
],
|
|
4036
|
+
repair: [
|
|
4037
|
+
"'Invalid connection: <line>' -> a `->` line needs an id on both sides (e.g. `err -> C`); `C ->` or `-> C` alone is rejected.",
|
|
4038
|
+
"Most ids auto-declare, so few lines hard-fail \u2014 if a box is unexpectedly empty or duplicated, look for an id typo (see avoid)."
|
|
4039
|
+
]
|
|
3749
4040
|
},
|
|
3750
4041
|
ladder: {
|
|
3751
4042
|
type: "ladder",
|
|
3752
4043
|
header: 'ladder "Title"',
|
|
3753
|
-
mode: "rungs
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
4044
|
+
mode: "rungs with IEC 61131-3 contacts / coils / function blocks; OR branches via parallel:/branch:",
|
|
4045
|
+
keywords: 'rung N ["comment"]: \xB7 contacts XIC XIO ONS OSF \xB7 coils OTE OTL OTU OTN RES \xB7 function blocks TON TOFF TP CTU CTD CTUD ADD SUB MUL DIV MOV EQU NEQ GRT LES GEQ LEQ \xB7 parallel: branch: (OR branch block) \xB7 element syntax ELEM(tag [, address] [, name="\u2026"])',
|
|
4046
|
+
forms: [
|
|
4047
|
+
'ladder "Motor Start/Stop"',
|
|
4048
|
+
'rung 1 "Seal-in circuit":',
|
|
4049
|
+
" parallel:",
|
|
4050
|
+
" branch:",
|
|
4051
|
+
' XIC(START_PB, "IN 1.0", name="Start Button")',
|
|
4052
|
+
" branch:",
|
|
4053
|
+
' XIC(MOTOR_AUX, "BIT 3.0", name="Aux Contact")',
|
|
4054
|
+
' XIO(STOP_PB, "IN 1.1", name="Stop Button")',
|
|
4055
|
+
' OTE(MOTOR_CMD, "OUT 2.0", name="Motor Command")'
|
|
4056
|
+
],
|
|
4057
|
+
prefer: [
|
|
4058
|
+
"Use uppercase element names: contacts `XIC` `XIO` `ONS` `OSF`; coils `OTE` `OTL` `OTU` `OTN` `RES`; function blocks `TON` `TOFF` `TP` `CTU` `CTD` `CTUD` `ADD` `SUB` `MUL` `DIV` `MOV` `EQU` `NEQ` `GRT` `LES` `GEQ` `LEQ`.",
|
|
4059
|
+
'Keep the tag as the first argument in parentheses; optional address (second positional) and `name=` follow: `XIC(START_PB, "IN 1.0", name="Start Button")`.',
|
|
4060
|
+
"Model parallel contacts (OR logic) with an indented `parallel:` block containing two or more `branch:` sub-blocks."
|
|
4061
|
+
],
|
|
4062
|
+
avoid: [
|
|
4063
|
+
"Don't invent element types \u2014 an unrecognised name throws `unknown element type` and halts the parse; use only the canonical list.",
|
|
4064
|
+
"Don't write an empty rung; every rung must contain at least one element or the parser throws `empty rung`.",
|
|
4065
|
+
"Don't use `branch:` outside a `parallel:` block \u2014 it throws `branch: without parallel:`."
|
|
4066
|
+
],
|
|
4067
|
+
repair: [
|
|
4068
|
+
"'unknown element type' -> replace with the closest canonical name (e.g. `LATCH` -> `OTL`, `UNLATCH` -> `OTU`, `OSR` -> `ONS`); the parser's did-you-mean hint names the nearest match.",
|
|
4069
|
+
"'empty rung' -> add at least one contact or coil element inside the rung.",
|
|
4070
|
+
"'branch: without parallel:' -> wrap the `branch:` block inside a `parallel:` block first.",
|
|
4071
|
+
"'element outside of rung' -> every element line must appear after a `rung N:` header."
|
|
4072
|
+
]
|
|
3758
4073
|
},
|
|
3759
4074
|
sld: {
|
|
3760
4075
|
type: "sld",
|
|
3761
4076
|
header: 'sld "Title"',
|
|
3762
|
-
mode: "equipment
|
|
3763
|
-
|
|
4077
|
+
mode: "equipment declarations + directed power-flow edges",
|
|
4078
|
+
keywords: 'sld "title" [standard: ansi|iec|abnt|as-nzs] \xB7 ID = nodeType [label:"\u2026" voltage:"\u2026" rating:"\u2026" device:"\u2026"] \xB7 ID -> ID [cable:"\u2026" label:"\u2026"] \xB7 sources: utility generator solar wind ups \xB7 transformers: transformer transformer_dy transformer_yd transformer_yy transformer_dd autotransformer transformer_3winding \xB7 buses: bus bus_tie hub \xB7 switching: breaker breaker_vacuum switch switch_load ground_switch ats recloser sectionalizer fuse fuse_cl \xB7 protection: ct pt relay surge_arrester ground_fault \xB7 loads: motor load capacitor_bank harmonic_filter vfd \xB7 metering: watthour_meter demand_meter \xB7 aliases: mcb/mccb->breaker rcd/rcbo/rccb->ground_fault isolator/disconnector->switch_load panel/consumer_unit/distribution_board->bus',
|
|
4079
|
+
forms: [
|
|
4080
|
+
'sld "Utility + Generator Backup"',
|
|
4081
|
+
'UTIL = utility [voltage: "480V", label: "Utility"]',
|
|
4082
|
+
'GEN = generator [rating: "500 kW", voltage: "480V"]',
|
|
4083
|
+
'ATS1 = ats [rating: "800A"]',
|
|
4084
|
+
'BUS1 = bus [voltage: "480V"]',
|
|
4085
|
+
'CB1 = breaker [rating: "200A"]',
|
|
4086
|
+
'L1 = load [label: "Critical Load"]',
|
|
4087
|
+
"UTIL -> ATS1",
|
|
4088
|
+
"GEN -> ATS1",
|
|
4089
|
+
"ATS1 -> BUS1",
|
|
4090
|
+
"BUS1 -> CB1",
|
|
4091
|
+
"CB1 -> L1"
|
|
4092
|
+
],
|
|
3764
4093
|
prefer: [
|
|
3765
|
-
"Declare
|
|
3766
|
-
"Use
|
|
3767
|
-
|
|
4094
|
+
"Declare every node as `id = nodeType [attrs]` before any `->` connection references it.",
|
|
4095
|
+
"Use one `from -> to` edge per line \u2014 SLD does not support chained arrows like `a -> b -> c`.",
|
|
4096
|
+
'Annotate nodes with `[label: "\u2026", rating: "\u2026", voltage: "\u2026"]`; annotate edges with `[cable: "\u2026", label: "\u2026"]`.'
|
|
4097
|
+
],
|
|
4098
|
+
avoid: [
|
|
4099
|
+
"Avoid nodeTypes not in the catalog \u2014 an unrecognised type renders as a flagged `?` placeholder; pick the closest canonical type or alias (meter->watthour_meter, inverter->vfd, isolator->switch_load).",
|
|
4100
|
+
"Avoid chained arrow syntax (`a -> b -> c`) \u2014 each connection must be its own line.",
|
|
4101
|
+
"Avoid using `[standard: iec]` with ANSI-only devices (`recloser`, `sectionalizer`, `watthour_meter`) \u2014 they have no IEC symbol and render with a warning."
|
|
3768
4102
|
],
|
|
3769
|
-
|
|
3770
|
-
|
|
4103
|
+
repair: [
|
|
4104
|
+
"'Connection references unknown node' -> declare the node with `id = nodeType` before the `->` line that names it.",
|
|
4105
|
+
"'Duplicate node id' -> each id must appear on exactly one `id = nodeType` line; rename the second occurrence.",
|
|
4106
|
+
"'Cannot parse line' -> every non-blank line must be the `sld` header, a node declaration (`id = type [attrs]`), or a connection (`id -> id [attrs]`).",
|
|
4107
|
+
"'unrecognised type' -> replace the unknown type with a catalog type or alias (e.g. `inverter` -> `vfd`)."
|
|
4108
|
+
]
|
|
3771
4109
|
},
|
|
3772
4110
|
entity: {
|
|
3773
4111
|
type: "entity",
|
|
3774
4112
|
header: 'entity-structure "Title"',
|
|
3775
|
-
mode: "legal
|
|
4113
|
+
mode: "legal entity declarations + typed ownership edges",
|
|
4114
|
+
keywords: 'entity ID "Name" TYPE[@JX] [status:new|eliminated|modified tax:ccorp|passthrough|scorp|trust|disregarded|foundation|individual role:"\u2026" note:"\u2026"] \xB7 types: corp llc lp trust individual/person foundation disregarded/branch placeholder/tbf pool \xB7 edges: -> (ownership) ==> (voting-only) -.-> (pool/option) -~-> (license/management) --> (distribution) \xB7 edge attrs [class:"\u2026" label:"\u2026"] \xB7 percentage: "100%" or "V 75% / E 50%" \xB7 jurisdiction CODE "Name" [color:"#hex"] \xB7 cluster "Name" [members: [id1, id2], color:"#hex"]',
|
|
3776
4115
|
forms: [
|
|
3777
|
-
'entity
|
|
3778
|
-
'entity
|
|
3779
|
-
|
|
3780
|
-
|
|
4116
|
+
'entity parent "Acme Global, Inc." corp@US [note: "Ultimate Parent"]',
|
|
4117
|
+
'entity ie-holdco "Acme Ireland Holdings" corp@IE',
|
|
4118
|
+
'entity ie-ip "Acme IP Ltd" corp@KY',
|
|
4119
|
+
"parent -> ie-holdco : 100%",
|
|
4120
|
+
'ie-ip -~-> ie-holdco [label: "IP License \xB7 royalty"]',
|
|
4121
|
+
'jurisdiction US "United States" [color: "#3b82f6"]',
|
|
4122
|
+
'cluster "Ireland / Cayman IP" [members: [ie-holdco, ie-ip]]'
|
|
3781
4123
|
],
|
|
3782
4124
|
prefer: [
|
|
3783
|
-
"
|
|
3784
|
-
"
|
|
3785
|
-
|
|
4125
|
+
"Declare all `entity` nodes before any edge lines; the entity type goes after the quoted name (`corp`, `llc`, `lp`, `trust`, `individual`, `foundation`, `disregarded`, `pool`).",
|
|
4126
|
+
"Append `@JX` jurisdiction code directly to the type token (`corp@DE`, `trust@SD`) \u2014 no space; omit only when jurisdiction is unknown.",
|
|
4127
|
+
"Use the right edge operator for semantics: `->` ownership, `==>` voting-only control, `-~->` contractual (license/management), `-->` distribution, `-.->` option pool."
|
|
4128
|
+
],
|
|
4129
|
+
avoid: [
|
|
4130
|
+
"Don't use `fund` as an entity type \u2014 only canonical types are accepted; use `lp` for funds/LPs.",
|
|
4131
|
+
'Don\'t put edge properties outside brackets: `[class: "Series A Pref"]`, not `: Series A Pref class`.',
|
|
4132
|
+
"Don't write `cluster` without a bracketed `[members: [...]]` list \u2014 the members value must be a bracket-enclosed comma list."
|
|
3786
4133
|
],
|
|
3787
|
-
|
|
3788
|
-
|
|
4134
|
+
repair: [
|
|
4135
|
+
"'Unknown entity type' -> replace with a canonical type: corp llc lp trust individual foundation disregarded placeholder pool.",
|
|
4136
|
+
"'Edge references unknown entity' -> add the `entity <id> \u2026` declaration before the edge line.",
|
|
4137
|
+
"'has no entities' -> the document needs at least one `entity` line."
|
|
4138
|
+
]
|
|
3789
4139
|
},
|
|
3790
4140
|
fishbone: {
|
|
3791
4141
|
type: "fishbone",
|
|
3792
4142
|
header: 'fishbone "Title"',
|
|
3793
|
-
mode: "effect + cause
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
4143
|
+
mode: "effect + structured category ribs + cause lines",
|
|
4144
|
+
keywords: 'effect "\u2026" \xB7 category id "Label" [side:top|bottom order:N color:"#hex"] \xB7 catId : "cause text" \xB7 compact: category Label: cause1; cause2 \xB7 sub-cause: indent >=2 + "- text" \xB7 config direction = left|right \xB7 config sides = both|top|bottom \xB7 config density = compact|normal|spacious',
|
|
4145
|
+
forms: [
|
|
4146
|
+
'fishbone "Manufacturing defect spike"',
|
|
4147
|
+
'effect "Solder joint defect > 3%"',
|
|
4148
|
+
'category man "Man"',
|
|
4149
|
+
'category machine "Machine"',
|
|
4150
|
+
'category method "Method"',
|
|
4151
|
+
'man : "Operator training gaps"',
|
|
4152
|
+
'machine : "Reflow oven calibration"',
|
|
4153
|
+
' - "Temperature profile not updated"',
|
|
4154
|
+
'method : "No incoming inspection"'
|
|
4155
|
+
],
|
|
4156
|
+
prefer: [
|
|
4157
|
+
'Declare each `category id "Label"` before referencing `id : "cause"` \u2014 the structured form keeps category ids unambiguous.',
|
|
4158
|
+
"Use `[side: top]` / `[side: bottom]` and `[order: N]` on a category to pin important categories (e.g. the 6M) to a specific rib instead of auto-alternating.",
|
|
4159
|
+
"For second-level sub-causes, indent >= 2 spaces and prefix with `- `; they attach to the last Level-1 cause above them."
|
|
4160
|
+
],
|
|
4161
|
+
avoid: [
|
|
4162
|
+
"Don't reference a `catId :` cause before declaring that category \u2014 the parser throws `Unknown category`.",
|
|
4163
|
+
'Don\'t omit `effect` \u2014 without an `effect` line the fish head falls back to the title; an explicit `effect "\u2026"` is clearer.',
|
|
4164
|
+
"Don't mix compact shorthand (`category Label: cause1; cause2`) and structured `catId :` lines for the same category \u2014 the compact id is a slug of the label, so a mismatch silently creates a duplicate."
|
|
4165
|
+
],
|
|
4166
|
+
repair: [
|
|
4167
|
+
'\'Unknown category\' -> add `category X "Label"` before any `X : "cause"` line.',
|
|
4168
|
+
"'requires at least one' -> the document has no `category` lines; add at least one `category id \"Label\"`.",
|
|
4169
|
+
"'Sub-cause has no preceding Level-1 cause' -> a `- sub text` line appeared before any `catId : \"cause\"` line in that category; add a Level-1 cause above it."
|
|
4170
|
+
]
|
|
3798
4171
|
},
|
|
3799
4172
|
venn: {
|
|
3800
4173
|
type: "venn",
|
|
3801
4174
|
header: 'venn "Title"',
|
|
3802
|
-
mode: "declared
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
4175
|
+
mode: "declared sets + region counts (primary); enumeration or Euler relations as alternates",
|
|
4176
|
+
keywords: 'set ID "Label" [color:"#hex"] \xB7 A & B : <integer|percent%|"text"|[list]> \xB7 A only : N \xB7 region A & B : N \xB7 enumeration: ID = { item, item, \u2026 } \xB7 Euler: ID subset|disjoint|overlap ID \xB7 layout venn|euler|auto \xB7 config: proportional=true|false \xB7 config: showCounts=true|false|auto \xB7 config: showPercent=true|false',
|
|
4177
|
+
forms: [
|
|
4178
|
+
'venn "Customer Segments"',
|
|
4179
|
+
'set email "Email subscribers" [color: "#1E88E5"]',
|
|
4180
|
+
'set paid "Paid users" [color: "#E53935"]',
|
|
4181
|
+
'set mobile "Mobile app users" [color: "#43A047"]',
|
|
4182
|
+
"email & paid : 1840",
|
|
4183
|
+
"email & mobile : 920",
|
|
4184
|
+
"email & paid & mobile : 650",
|
|
4185
|
+
"email only : 12400",
|
|
4186
|
+
"paid only : 3200"
|
|
4187
|
+
],
|
|
4188
|
+
prefer: [
|
|
4189
|
+
'Declare every `set ID "Label"` before any region line that references it.',
|
|
4190
|
+
"Use integer counts for research overlap, `%` values for audience overlap, and `[list]` values when each region should show enumerated items.",
|
|
4191
|
+
"Use the Euler relation form (`A subset B`, `A disjoint B`) only when the structural relationship matters more than counts \u2014 it triggers Euler layout mode."
|
|
4192
|
+
],
|
|
4193
|
+
avoid: [
|
|
4194
|
+
"Don't mix enumeration mode (`ID = { \u2026 }`) with explicit `A & B :` region counts in the same document \u2014 enumeration auto-derives regions, so adding counts duplicates them.",
|
|
4195
|
+
"Don't use a set id in a region line that was never declared with `set ID \u2026` \u2014 the parser throws `unknown set id`.",
|
|
4196
|
+
"Don't add 5+ sets expecting a readable Venn \u2014 it degrades to an UpSet plot automatically; prefer Euler `disjoint`/`subset` when structure is sparse."
|
|
4197
|
+
],
|
|
4198
|
+
repair: [
|
|
4199
|
+
"'unknown set id' -> declare `set X \"Label\"` before the region line that uses it.",
|
|
4200
|
+
"'duplicate set id' -> each set id must appear in exactly one `set` declaration; rename or remove the second.",
|
|
4201
|
+
"'could not parse line' -> every non-blank, non-header line must match `set`, `region`, `A & B :`, `A only :`, `ID = { }`, a Euler relation, `layout`, or `config:`."
|
|
4202
|
+
]
|
|
3807
4203
|
},
|
|
3808
4204
|
flowchart: {
|
|
3809
4205
|
type: "flowchart",
|
|
3810
|
-
header:
|
|
3811
|
-
mode: "Mermaid-compatible nodes + edges",
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
4206
|
+
header: "flowchart TD",
|
|
4207
|
+
mode: "Mermaid-compatible nodes + edges (Mermaid prior: prefer this syntax)",
|
|
4208
|
+
keywords: 'flowchart TD|TB|BT|LR|RL \xB7 nodes: A[rect] A(round) A([stadium]) A{diamond} A[/parallelogram/] A[[subroutine]] A[(cylinder)] A((circle)) A{{hexagon}} A>asymmetric] \xB7 edges: --> --- -.-> ==> --x --o --|label| -- label --> \xB7 fan-out: A & B --> C & D \xB7 subgraph "Title" \u2026 end \xB7 class A,B name \xB7 classDef name fill:\u2026 \xB7 style A fill:\u2026',
|
|
4209
|
+
forms: [
|
|
4210
|
+
"flowchart LR",
|
|
4211
|
+
" start([New order received])",
|
|
4212
|
+
" start --> validate{Inventory available?}",
|
|
4213
|
+
" validate -->|Yes| reserve[Reserve items]",
|
|
4214
|
+
" validate -->|No| notify[Notify customer]",
|
|
4215
|
+
" reserve --> payment{Payment authorized?}",
|
|
4216
|
+
" payment -->|Yes| ship[Ship order]",
|
|
4217
|
+
" ship --> done([End])",
|
|
4218
|
+
" notify --> done"
|
|
4219
|
+
],
|
|
4220
|
+
prefer: [
|
|
4221
|
+
"Use Mermaid `flowchart TD` (or `LR`) as the header \u2014 matches the dominant training prior; `graph TD` is also accepted.",
|
|
4222
|
+
"Label decision branches with `-->|Yes|` / `-->|No|` pipe syntax; use `--` inline for longer edge text: `A -- approved --> B`.",
|
|
4223
|
+
"Use `([\u2026])` stadium for terminals, `{\u2026}` diamond for decisions, `[\u2026]` rect for steps, `[(\u2026)]` cylinder for datastores."
|
|
4224
|
+
],
|
|
4225
|
+
avoid: [
|
|
4226
|
+
"Don't omit the direction token \u2014 a bare `flowchart` defaults to TB; always declare direction explicitly.",
|
|
4227
|
+
"Avoid `subgraph` nesting deeper than one level in generated output; deep nesting is valid but rarely needed.",
|
|
4228
|
+
"Don't use inline `:::className` syntax in generated output \u2014 use separate `class A,B name` or `classDef` statements."
|
|
4229
|
+
],
|
|
4230
|
+
repair: [
|
|
4231
|
+
"'expected' header -> the first non-comment line must be `flowchart TD` (or another direction); a missing or misspelled header rejects the document.",
|
|
4232
|
+
"'unknown direction' -> direction must be one of TD TB BT LR RL (case-insensitive).",
|
|
4233
|
+
"'expected node identifier' -> every edge must start with a valid id token; a bare `-->` without a left-hand node id is rejected."
|
|
4234
|
+
]
|
|
3816
4235
|
},
|
|
3817
4236
|
mindmap: {
|
|
3818
4237
|
type: "mindmap",
|
|
3819
4238
|
header: "mindmap",
|
|
3820
|
-
mode: "Markdown headings + bullets",
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
4239
|
+
mode: "Markdown headings + bullets; %% directives for style/theme",
|
|
4240
|
+
keywords: "# root (exactly 1) \xB7 ## H2 branch \xB7 ### deeper headings \xB7 - / * / + bullet (2-space indent = 1 depth level) \xB7 %% style: map|logic-right|futureswheel|driver \xB7 %% theme: default|monochrome|dark \xB7 %% maxLabelWidth: N \xB7 inline: **bold** *italic* `code` [text](url) [x]/[ ] checkbox",
|
|
4241
|
+
forms: [
|
|
4242
|
+
"mindmap",
|
|
4243
|
+
"",
|
|
4244
|
+
"# Product Launch Plan",
|
|
4245
|
+
"",
|
|
4246
|
+
"## Market readiness",
|
|
4247
|
+
"- Competitive analysis",
|
|
4248
|
+
"- Pricing benchmarks",
|
|
4249
|
+
"",
|
|
4250
|
+
"## Engineering",
|
|
4251
|
+
"### Feature freeze",
|
|
4252
|
+
"- Core API complete",
|
|
4253
|
+
"",
|
|
4254
|
+
"## Go-to-market",
|
|
4255
|
+
"- Landing page live"
|
|
4256
|
+
],
|
|
4257
|
+
prefer: [
|
|
4258
|
+
"Open with exactly one `# Root` heading \u2014 the parser recovers a placeholder when it is missing (with a warning), but an explicit `# Title` is correct.",
|
|
4259
|
+
"Use `%% style: logic-right` for outlines, the default `map` for balanced radial brainstorms, `%% style: futureswheel` for consequence mapping, `%% style: driver` for IHI diagrams.",
|
|
4260
|
+
"Use 2-space indented bullets (` - child`) to add depth under a heading without an extra `###` level \u2014 each 2-space step is one level deeper."
|
|
4261
|
+
],
|
|
4262
|
+
avoid: [
|
|
4263
|
+
"Don't write more than one `#` root heading \u2014 the parser throws `multiple` center nodes not allowed on the second.",
|
|
4264
|
+
"Don't use graph-edge syntax (`A -> B`) inside a mindmap; the format is heading/bullet hierarchy only.",
|
|
4265
|
+
"Don't place `%%` directives mid-document; they are only processed before the first heading and are otherwise ignored."
|
|
4266
|
+
],
|
|
4267
|
+
repair: [
|
|
4268
|
+
"'missing central topic' -> add a `# Your Topic` line as the first content line.",
|
|
4269
|
+
"'multiple' center nodes not allowed -> demote all but the first `#` heading to `##` or deeper.",
|
|
4270
|
+
"'no `# Title` heading found' (warning) -> the parser adopted the first line as the topic; add an explicit `# Title` at the top."
|
|
4271
|
+
]
|
|
3825
4272
|
},
|
|
3826
4273
|
matrix: {
|
|
3827
4274
|
type: "matrix",
|
|
3828
4275
|
header: 'matrix "Title"',
|
|
3829
|
-
mode: "quadrant scatter",
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
4276
|
+
mode: "quadrant scatter (default) | named templates | heatmap | sipoc | qfd | punnett",
|
|
4277
|
+
keywords: 'header variants: matrix "Title" | matrix <template> "Title" | matrix heatmap NxM | matrix correlation | matrix sipoc | matrix qfd | matrix punnett \xB7 templates: eisenhower impact-effort rice bcg ansoff johari 9-box risk-matrix \xB7 quadrant: x-axis: Low -> High \xB7 y-axis: Low -> High \xB7 "Label" at (x,y) [size:N category:C shape:circle|square|triangle|diamond] \xB7 quadrant Q1..Q4 "name" \xB7 Q1:/"Q1: text" cell shortcuts \xB7 style: table \xB7 config: offChartPolicy=clamp-badge|drop bubbleScale=area|radius',
|
|
4278
|
+
forms: [
|
|
4279
|
+
'matrix eisenhower "This Week"',
|
|
4280
|
+
"style: table",
|
|
4281
|
+
'Q2: "Ship hotfix"',
|
|
4282
|
+
'Q1: "Write Q3 OKRs"',
|
|
4283
|
+
'Q3: "Reorganize Slack channels"',
|
|
4284
|
+
"",
|
|
4285
|
+
'matrix bcg "Product Portfolio"',
|
|
4286
|
+
'"Platform SDK" at (0.8, 0.8) size: 5 category: star',
|
|
4287
|
+
'"Legacy API" at (0.85, 0.15) size: 4 category: cashcow'
|
|
4288
|
+
],
|
|
4289
|
+
prefer: [
|
|
4290
|
+
"Use a named template (`eisenhower`, `impact-effort`, `bcg`, `ansoff`, `johari`, `9-box`, `risk-matrix`, `rice`) for first-shot generation \u2014 it pre-fills axes and quadrant labels.",
|
|
4291
|
+
"Add `style: table` with `Q1:`/`Q2:`/`Q3:`/`Q4:` item lines for the four-cell list layout instead of a scatter.",
|
|
4292
|
+
"Quadrant scatter coordinates are normalized `[0,1]` fractions; add `size: N` for a bubble chart and `category:` to drive legend color."
|
|
4293
|
+
],
|
|
4294
|
+
avoid: [
|
|
4295
|
+
"Don't mix `sipoc:`/`qfd:`/`punnett:` sub-keywords in plain quadrant mode \u2014 they activate only under the matching header mode (`matrix sipoc`).",
|
|
4296
|
+
"Don't set point coordinates outside `[0,1]` expecting the canvas to expand \u2014 they are clamped and badged (use `offChartPolicy: drop` to hide).",
|
|
4297
|
+
"Don't use percentages or raw data values in `at (x, y)` \u2014 coordinates are fractions."
|
|
4298
|
+
],
|
|
4299
|
+
repair: [
|
|
4300
|
+
"A point that doesn't appear usually has coordinates outside `[0,1]` with `offChartPolicy` defaulting to `clamp-badge` \u2014 check `at (x, y)` are fractions.",
|
|
4301
|
+
'An empty `qfd`/`sipoc` chart means the header was `matrix "Title"` (quadrant mode) not `matrix qfd "Title"` \u2014 add the mode keyword after `matrix`.',
|
|
4302
|
+
"In `punnett` mode, a missing grid means the `cross:` line was not parsed \u2014 use even-length letter pairs (e.g. `Bb`) separated by `x`."
|
|
4303
|
+
]
|
|
3834
4304
|
},
|
|
3835
4305
|
orgchart: {
|
|
3836
4306
|
type: "orgchart",
|
|
3837
4307
|
header: 'orgchart "Title"',
|
|
3838
|
-
mode: "indented hierarchy",
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
4308
|
+
mode: "indented hierarchy with pipe-separated fields; explicit edges for matrix/dotted lines",
|
|
4309
|
+
keywords: 'id : "Name" | Title | Dept [props] \xB7 node kinds: person role open draft tbh advisor external \xB7 props: role(ceo|cto|cfo|coo|engineer|designer|sales|hr|legal|ops|product|data|advisor|intern|vacant) status(new|leaving|on-leave) assistant-of \xB7 edge ops: -> (report) -.-> (matrix/dotted) === (co-leaders) \xB7 config: direction=TD|LR layout=tree|list',
|
|
4310
|
+
forms: [
|
|
4311
|
+
'ceo: "Jamie Torres" | CEO [role: ceo]',
|
|
4312
|
+
' cto: "Raj Patel" | CTO [role: cto]',
|
|
4313
|
+
' eng1: "Priya Nair" | Eng Lead | Engineering [role: engineer]',
|
|
4314
|
+
' cfo: "Ellen Wu" | CFO [role: cfo]',
|
|
4315
|
+
'advisor adv1: "Dr. Alan Ford" | Board Advisor [role: advisor]',
|
|
4316
|
+
"pm_core -.-> lead_core"
|
|
4317
|
+
],
|
|
4318
|
+
prefer: [
|
|
4319
|
+
'Use 2-space indentation per level for the reporting tree \u2014 this is the implicit `->` edge. Fields are `id : "Name" | Title | Department`, pipe-separated.',
|
|
4320
|
+
"Use node-kind prefixes `role`/`open` for vacant positions (dashed yellow + HIRING pill), `draft`/`tbh` for planned roles, `advisor`/`external` for contractors.",
|
|
4321
|
+
"Add `[role: ceo]` (cto/cfo/engineer/designer/sales/hr/legal/ops/product/data/advisor/intern/vacant, case-insensitive) for the built-in role icon; draw dotted matrix lines as explicit `a -.-> b` edges."
|
|
4322
|
+
],
|
|
4323
|
+
avoid: [
|
|
4324
|
+
"Don't mix indentation hierarchy with an explicit `->` edge on the same parent\u2013child pair \u2014 only one is needed; both duplicate the report edge.",
|
|
4325
|
+
'Don\'t omit the colon in node lines (`id : "Name"`); a line without a colon is silently skipped with a warning.',
|
|
4326
|
+
"Don't reuse an id \u2014 the duplicate is dropped silently, losing its name/title."
|
|
4327
|
+
],
|
|
4328
|
+
repair: [
|
|
4329
|
+
"'skipped a line that is neither a node nor an edge' -> the line is missing a colon; rewrite as `id : \"Name\" | Title`.",
|
|
4330
|
+
"'kept the first declaration of duplicate node id' -> each person needs a unique id; rename the second declaration.",
|
|
4331
|
+
"'created node(s) from edges that were never declared' -> declare `x : \"Name\" | Title` so the card renders a real label instead of the bare id."
|
|
4332
|
+
]
|
|
3843
4333
|
},
|
|
3844
4334
|
decisiontree: {
|
|
3845
4335
|
type: "decisiontree",
|
|
3846
4336
|
header: 'decisiontree "Title"',
|
|
3847
|
-
mode: "taxonomy
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
4337
|
+
mode: "taxonomy (default) | decision | ml | influence \u2014 select via header suffix",
|
|
4338
|
+
keywords: 'header: decisiontree[:decision|:ml|:influence] "Title" \xB7 config: direction=top-down|left-right \xB7 taxonomy: question/q "\u2026" \xB7 answer/a/leaf "\u2026" \xB7 branch prefixes yes: no: label "X": \xB7 decision mode: decision chance end/outcome \xB7 choice "label" prob N \xB7 payoff=N \xB7 ml mode: split "\u2026" feature=F threshold=V gini/entropy/mse=N value=[N,\u2026] class=C \xB7 influence mode: decision chance value nodes + directed arcs',
|
|
4339
|
+
forms: [
|
|
4340
|
+
'decisiontree "Customer Support Triage"',
|
|
4341
|
+
"direction: top-down",
|
|
4342
|
+
"",
|
|
4343
|
+
'question "Is the service completely down?"',
|
|
4344
|
+
' yes: question "Outage confirmed on status page?"',
|
|
4345
|
+
' yes: answer "Follow incident protocol \u2014 page on-call"',
|
|
4346
|
+
' no: answer "Check monitoring \u2014 open severity-1 ticket"',
|
|
4347
|
+
' no: answer "Escalate to billing team"'
|
|
4348
|
+
],
|
|
4349
|
+
prefer: [
|
|
4350
|
+
"Default mode is `taxonomy` \u2014 use `question`/`answer` (or `q`/`a`) with `yes:`/`no:` branch prefixes and 2-space indentation.",
|
|
4351
|
+
'For decision analysis use `decisiontree:decision`; nodes are `decision` (square), `chance` (circle), `end` (triangle); label choices with `choice "label"` and probabilities with `prob N` on chance children; `payoff=N` on `end` nodes.',
|
|
4352
|
+
"For ML visualization use `decisiontree:ml`; split nodes carry `feature=`/`threshold=`/`gini=`; leaves carry `value=[N,\u2026]` plus optional `class=`."
|
|
4353
|
+
],
|
|
4354
|
+
avoid: [
|
|
4355
|
+
"Don't use `decision`/`chance`/`end` in taxonomy mode \u2014 they throw `Unknown taxonomy node kind`.",
|
|
4356
|
+
"Don't use `question`/`answer` in `:ml` mode \u2014 they throw `Unknown ML node kind`.",
|
|
4357
|
+
"Don't let a chance node's `prob` children sum to anything but 1 \u2014 the parser throws `probabilities do not sum to 1.0`."
|
|
4358
|
+
],
|
|
4359
|
+
repair: [
|
|
4360
|
+
"'Unknown node kind' -> valid decision-mode kinds are `decision`, `chance`, `end`, `outcome`; switch mode or fix the keyword.",
|
|
4361
|
+
"'Unknown taxonomy node kind' -> valid taxonomy kinds are `question`/`q` and `answer`/`a`/`leaf`.",
|
|
4362
|
+
"'probabilities do not sum to 1.0' -> the `prob N` values on a chance node's children must add to exactly 1.0.",
|
|
4363
|
+
"'Orphan line (bad indent)' -> every non-root node must be indented at least 2 spaces under its parent."
|
|
4364
|
+
]
|
|
3852
4365
|
},
|
|
3853
4366
|
timeline: {
|
|
3854
4367
|
type: "timeline",
|
|
3855
4368
|
header: 'timeline "Title"',
|
|
3856
|
-
mode: "dated events",
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
4369
|
+
mode: "dated events on a time axis \u2014 swimlane (default), gantt, or lollipop styles",
|
|
4370
|
+
keywords: 'DATE: "label" \xB7 DATE - DATE: "label" (range) \xB7 DATE: milestone "label" \xB7 era DATE - DATE: "label" \xB7 track "Name": / section Name (lanes) \xB7 config: style=swimlane|gantt|lollipop orientation=horizontal|vertical scale=proportional|equidistant|log \xB7 point props [side:above|below shape:circle|square|diamond|star|flag color:#hex category:\u2026] \xB7 dates: YYYY YYYY-MM YYYY-MM-DD, BC years, ordinal keys (Phase 1, Q1 2024)',
|
|
4371
|
+
forms: [
|
|
4372
|
+
'timeline "Platform v2 Launch"',
|
|
4373
|
+
"config: style = gantt",
|
|
4374
|
+
"",
|
|
4375
|
+
'2025-07-01 - 2025-08-15: "Engineering build" [category: "engineering"]',
|
|
4376
|
+
'2025-08-20: milestone "Feature freeze" [color: #E53935]',
|
|
4377
|
+
'2025-09-15: milestone "Public launch" [color: #2E7D32]'
|
|
4378
|
+
],
|
|
4379
|
+
prefer: [
|
|
4380
|
+
"Use ISO dates (`YYYY-MM-DD`/`YYYY-MM`/`YYYY`) for the row key for proportional layout; for non-date groupings (Phase 1, Q1 2024) use an ordinal key placed in declaration order.",
|
|
4381
|
+
"Use `config: style = gantt` for roadmaps (overlapping bars), `lollipop` for milestone stories, default `swimlane` for multi-track streams.",
|
|
4382
|
+
'Use `milestone` before the quoted label for diamond headline events; group events with `track "Name":` or Mermaid `section Name`; add era bands with `era START - END: "label"`.'
|
|
4383
|
+
],
|
|
4384
|
+
avoid: [
|
|
4385
|
+
"Don't omit the colon after the date/range \u2014 `Expected ':' after date` is thrown when no colon separator is found.",
|
|
4386
|
+
"Don't use `config: style = X` with a value other than `swimlane`, `gantt`, `lollipop` \u2014 throws `Invalid style`.",
|
|
4387
|
+
"Don't write `era` with a single date instead of a range \u2014 throws `era requires a date range`."
|
|
4388
|
+
],
|
|
4389
|
+
repair: [
|
|
4390
|
+
"'Unrecognized line' -> an event line must be a date/range, then `:`, then a quoted label (optionally preceded by `milestone`).",
|
|
4391
|
+
"'Invalid style' -> valid `config: style` values are `swimlane`, `gantt`, `lollipop`.",
|
|
4392
|
+
"'era requires a date range' -> write `era 2020 - 2025: \"label\"` (two dates separated by ` - `)."
|
|
4393
|
+
]
|
|
3861
4394
|
},
|
|
3862
4395
|
state: {
|
|
3863
4396
|
type: "state",
|
|
3864
4397
|
header: "stateDiagram-v2",
|
|
3865
|
-
mode: "Mermaid stateDiagram-v2 (recommended
|
|
4398
|
+
mode: "Mermaid stateDiagram-v2 (recommended; native 'state' header also accepted)",
|
|
4399
|
+
keywords: 'stateDiagram-v2 (or state "Title" [direction: LR]) \xB7 [*] --> S / S --> [*] \xB7 S --> T : trigger [guard] / action \xB7 state "Long name" as ID \xB7 state ID <<choice>> | <<fork>> | <<join>> | <<end>> \xB7 composite state ID { \u2026 } with -- for concurrent regions \xB7 note right_of X : text \xB7 direction TB|LR \xB7 native pseudo-states: initial final choice junction fork join history dhistory terminate entry_point exit_point',
|
|
3866
4400
|
forms: [
|
|
3867
|
-
"
|
|
3868
|
-
"
|
|
3869
|
-
"
|
|
3870
|
-
"
|
|
4401
|
+
"stateDiagram-v2",
|
|
4402
|
+
" [*] --> Idle",
|
|
4403
|
+
" Idle --> Running : start",
|
|
4404
|
+
" Running --> Paused : pause",
|
|
4405
|
+
" Paused --> Running : resume",
|
|
4406
|
+
" Running --> Done : finish",
|
|
4407
|
+
" Done --> [*]"
|
|
3871
4408
|
],
|
|
3872
4409
|
prefer: [
|
|
3873
|
-
|
|
3874
|
-
|
|
4410
|
+
'Use Mermaid `stateDiagram-v2` with `[*]` for initial/final pseudo-states and `-->` for transitions \u2014 matches the dominant training prior and is less error-prone than the native `state "Title"` + `initial`/`final` form.',
|
|
4411
|
+
"Write transition labels as `: trigger [guard] / action` \u2014 all three segments optional, but the colon is required if any label follows the arrow.",
|
|
4412
|
+
"For composite states use `state ID { \u2026 }` (Mermaid) or `composite ID { \u2026 }` (native); separate concurrent regions with `--` inside the block."
|
|
3875
4413
|
],
|
|
3876
4414
|
avoid: [
|
|
3877
|
-
"
|
|
3878
|
-
"
|
|
4415
|
+
"Don't mix the two header styles \u2014 `[*]` (Mermaid) and `initial X` (native) are both accepted but must not appear together.",
|
|
4416
|
+
"Don't invent pseudo-state kinds \u2014 valid are `initial`/`final`/`choice`/`junction`/`fork`/`join`/`history`/`dhistory`/`terminate`/`entry_point`/`exit_point` and `<<choice>>`/`<<fork>>`/`<<join>>`/`<<end>>`.",
|
|
4417
|
+
"Don't leave a composite `{` block unclosed \u2014 an unclosed brace is a hard parse error."
|
|
3879
4418
|
],
|
|
3880
4419
|
repair: [
|
|
3881
|
-
"
|
|
3882
|
-
'
|
|
4420
|
+
"'Expected' header -> the first non-comment line must be `stateDiagram-v2`, `stateDiagram`, or `state`.",
|
|
4421
|
+
"'Unparseable line' -> check for an unsupported pseudo-state keyword, a missing `-->` arrow, or a line that is neither a transition, declaration, nor directive.",
|
|
4422
|
+
"'Unclosed composite block' -> every `state ID {` or `composite ID {` must be closed with a matching `}`."
|
|
3883
4423
|
]
|
|
3884
4424
|
},
|
|
3885
4425
|
pid: {
|
|
3886
4426
|
type: "pid",
|
|
3887
4427
|
header: 'pid "Title"',
|
|
3888
|
-
mode: "equipment + process lines",
|
|
4428
|
+
mode: "equipment + process/signal lines + instrument declarations",
|
|
4429
|
+
keywords: 'pid "title" [direction: LR|TB] \xB7 equip ID : type [tag:"\u2026"] \xB7 line ID from A[.port] to B[.port] [type: process|process_minor|pneumatic|electric|hydraulic|capillary|software|mechanical, size:"\u2026", service:"\u2026"] \xB7 inst TAG : category + indented measures EQUIP_OR_LINE / controls EQUIP \xB7 equipment: tank_atm tank_cone_roof vessel_v vessel_h sphere column_tray column_packed hx_shell_tube hx_air_cooled reboiler condenser pump_centrifugal pump_pd compressor blower reactor_cstr reactor_pfr filter cyclone flare cooling_tower valve_gate valve_ball valve_globe valve_butterfly valve_check valve_control valve_psv \xB7 instrument categories: field_discrete field_shared field_computer field_plc cr_discrete cr_shared cr_computer cr_plc local_discrete local_shared',
|
|
3889
4430
|
forms: [
|
|
3890
|
-
"
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
"
|
|
4431
|
+
'pid "Water Pump Flow Control"',
|
|
4432
|
+
'equip T-101 : tank_atm [tag: "Feed Tank"]',
|
|
4433
|
+
'equip P-101 : pump_centrifugal [tag: "Feed Pump"]',
|
|
4434
|
+
"equip V-101 : valve_control",
|
|
4435
|
+
'line L1 from T-101.bottom to P-101.in [service: "water", type: "process"]',
|
|
4436
|
+
'line L2 from P-101.out to V-101.in [type: "process"]',
|
|
4437
|
+
"inst FT-101 : field_discrete",
|
|
4438
|
+
" measures L2",
|
|
4439
|
+
"inst FIC-101 : cr_shared",
|
|
4440
|
+
" controls V-101",
|
|
4441
|
+
'line s1 from FT-101 to FIC-101 [type: "electric"]',
|
|
4442
|
+
'line s2 from FIC-101 to V-101 [type: "pneumatic"]'
|
|
3894
4443
|
],
|
|
3895
4444
|
prefer: [
|
|
3896
|
-
"Declare
|
|
3897
|
-
"Use
|
|
3898
|
-
"
|
|
4445
|
+
"Declare `equip` first, then `line` connections, then `inst` bubbles. Use ISA tag conventions (`FT-101` flow transmitter, `FIC-101` flow indicating controller).",
|
|
4446
|
+
"Use the indented `measures LINE_OR_EQUIP` and `controls EQUIP` continuations under an `inst` to declare loop membership.",
|
|
4447
|
+
"Use canonical `[type: \u2026]` line types: `electric` for transmitter->controller, `pneumatic` for controller->control-valve, `software` for DCS/PLC bus."
|
|
4448
|
+
],
|
|
4449
|
+
avoid: [
|
|
4450
|
+
"Avoid SLD electrical nodes (`transformer`, `breaker`, `bus`) inside a P&ID \u2014 use `sld` for electrical single-lines.",
|
|
4451
|
+
"Don't invent equipment types; an unrecognised type renders as a flagged placeholder (use `hx_shell_tube` not `heat_exchanger`, `vessel_h` not `vessel_horizontal`, `reactor_cstr` not `cstr`).",
|
|
4452
|
+
"Don't omit `[type: electric]` on a transmitter->controller line or `[type: pneumatic]` on a controller->control-valve line \u2014 both default to `process` pipe with a warning."
|
|
3899
4453
|
],
|
|
3900
|
-
|
|
3901
|
-
|
|
4454
|
+
repair: [
|
|
4455
|
+
"'Unparseable line' -> every body line must start with `equip`, `line`, `inst`, `measures`, or `controls`.",
|
|
4456
|
+
"'unrecognised type' -> replace the unknown equipment type with a catalog type (exchanger->hx_shell_tube, vessel_horizontal->vessel_h, cstr->reactor_cstr).",
|
|
4457
|
+
"'no signal path to a controller' -> add a signal line from the transmitter to a controller (C in the tag, e.g. FIC), or add the `controls` continuation under the controller."
|
|
4458
|
+
]
|
|
3902
4459
|
},
|
|
3903
4460
|
erd: {
|
|
3904
4461
|
type: "erd",
|
|
3905
4462
|
header: "erDiagram",
|
|
3906
4463
|
mode: "Mermaid erDiagram (recommended for generation)",
|
|
4464
|
+
keywords: 'erDiagram (Mermaid) \xB7 ENTITY { type name PK|FK|UK } \xB7 A ||--o{ B : label \xB7 glyphs: || one-mandatory \xB7 |o/o| zero-or-one \xB7 }|/|{ one-many \xB7 }o/o{ zero-many \xB7 erd (native) \xB7 table NAME { name type PK|FK|UK|NN } \xB7 ref A <card> -- <card> B : "label" \xB7 named cards: one-mandatory one-optional many-mandatory many-optional \xB7 notation: crowsfoot (v0.1) \xB7 direction: LR|TB',
|
|
3907
4465
|
forms: [
|
|
3908
4466
|
"CUSTOMER ||--o{ ORDER : places",
|
|
3909
4467
|
"ORDER {",
|
|
@@ -3912,83 +4470,284 @@ var PROFILES = {
|
|
|
3912
4470
|
"}"
|
|
3913
4471
|
],
|
|
3914
4472
|
prefer: [
|
|
3915
|
-
"Use Mermaid `erDiagram`
|
|
3916
|
-
"
|
|
3917
|
-
"
|
|
4473
|
+
"Use the Mermaid `erDiagram` header; entities auto-create from relationship lines and only need a `{ \u2026 }` block to list attributes.",
|
|
4474
|
+
"Attributes are type-first under `erDiagram`: `int id PK`, `varchar email UK` \u2014 never name-first.",
|
|
4475
|
+
"Relationship syntax is `A <left-glyph>--<right-glyph> B : label`; use `||--o{` for one-to-many-optional, `||--|{` for one-to-many-mandatory."
|
|
4476
|
+
],
|
|
4477
|
+
avoid: [
|
|
4478
|
+
"Do not mix header styles: under `erDiagram` attrs are type-first; under native `erd` they are name-first with `table` blocks and `ref` lines.",
|
|
4479
|
+
"Do not write `notation: chen` or `notation: barker` \u2014 only `crowsfoot` is implemented in v0.1.",
|
|
4480
|
+
"Do not invent glyph pairs; left glyphs are `||` `|o` `}o` `}|`, right glyphs are `||` `o|` `o{` `|{`."
|
|
3918
4481
|
],
|
|
3919
|
-
avoid: ["Do not mix the two header styles; under `erDiagram`, attributes are type-first (`int id PK`), not name-first."],
|
|
3920
4482
|
repair: [
|
|
3921
|
-
"
|
|
3922
|
-
"
|
|
4483
|
+
"'Invalid Mermaid cardinality glyph' -> the left glyph must be `||`/`|o`/`}o`/`}|` and the right `||`/`o|`/`o{`/`|{`; fix the pair.",
|
|
4484
|
+
"'Unrecognized erDiagram line' -> only relationship lines, entity blocks (`NAME {`), and `}` are valid under `erDiagram`; remove native `table`/`ref` lines.",
|
|
4485
|
+
"'not yet implemented in v0.1; use' -> drop the `notation:` line or set `notation: crowsfoot`."
|
|
3923
4486
|
]
|
|
3924
4487
|
},
|
|
3925
4488
|
breadboard: {
|
|
3926
4489
|
type: "breadboard",
|
|
3927
4490
|
header: "breadboard",
|
|
3928
|
-
mode: "parts + wires
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
4491
|
+
mode: "parts section + wires section; breadboard-native hole/rail coordinates",
|
|
4492
|
+
keywords: 'breadboard \xB7 board: mini|half|full \xB7 title: "\u2026" \xB7 parts section: id: KIND [args] @placement \xB7 wire kinds: resistor led cap-elec cap-ceramic diode button dip header \xB7 mcu uno|nano|esp32|pico \xB7 sensor hcsr04|dht11|dht22 \xB7 display oled-ssd1306|lcd-1602-i2c \xB7 actuator servo-sg90 \xB7 placement: @5e (hole) @5e..9e (span) @+t8 @-t8 @+b14 @-b14 (rails) @beside-left @beside-right @above @below \xB7 wires section: ep --color-- ep [via @coord] \xB7 colors: red black blue yellow orange green white purple brown grey \xB7 endpoints: @coord or partId:pin',
|
|
4493
|
+
forms: [
|
|
4494
|
+
"breadboard",
|
|
4495
|
+
"board: half",
|
|
4496
|
+
'title: "Blink LED \u2014 Arduino Uno"',
|
|
4497
|
+
"parts",
|
|
4498
|
+
" uno: mcu uno @beside-left",
|
|
4499
|
+
" r1: resistor 220 @5e..9e",
|
|
4500
|
+
" d1: led red @10e..10f",
|
|
4501
|
+
"wires",
|
|
4502
|
+
" uno:5V --red-- @+t1",
|
|
4503
|
+
" uno:GND --black-- @-t1",
|
|
4504
|
+
" uno:D13 --yellow-- @9a"
|
|
4505
|
+
],
|
|
4506
|
+
prefer: [
|
|
4507
|
+
"Declare every part in the `parts` section before referencing it in `wires`; the part `id` is what you use as `partId:pin` in wire endpoints.",
|
|
4508
|
+
"Use breadboard-native coordinates: `@5e` for hole column 5 row e, `@5e..9e` for a span, `@+t8`/`@-t8` for top positive/negative rail.",
|
|
4509
|
+
"Wire color carries convention \u2014 `red` for +V, `black`/`blue` for GND, signal colors (`yellow`, `orange`, `green`) for data; all wire lines are `ep --color-- ep`."
|
|
4510
|
+
],
|
|
4511
|
+
avoid: [
|
|
4512
|
+
"Don't use rail coordinates (`@+t8`) on a `board: mini` \u2014 mini boards have no power rails and the parser throws `Mini boards have no power rails`.",
|
|
4513
|
+
"Don't omit the `@` placement from a part \u2014 `missing placement` is thrown when the `@` token is absent.",
|
|
4514
|
+
"Don't reference a part id in wires that was not declared in the parts section \u2014 `Wire references unknown part` fails validation."
|
|
4515
|
+
],
|
|
4516
|
+
repair: [
|
|
4517
|
+
"'Unknown board' -> set `board:` to `mini`, `half`, or `full`.",
|
|
4518
|
+
"'Unknown part kind' -> use a supported kind (`resistor` `led` `cap-elec` `diode` `button` `dip` `header`) or a compound (`mcu uno`, `sensor hcsr04`, `display oled-ssd1306`).",
|
|
4519
|
+
"'Wire references unknown part' -> add `X: KIND @placement` to the `parts` section before `wires`."
|
|
4520
|
+
]
|
|
3933
4521
|
},
|
|
3934
4522
|
bpmn: {
|
|
3935
4523
|
type: "bpmn",
|
|
3936
4524
|
header: "bpmn",
|
|
3937
|
-
mode: "pool/lane objects + flows",
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
4525
|
+
mode: "pool/lane declarations + flow objects + flows block",
|
|
4526
|
+
keywords: 'bpmn [direction: LR|TB] [title: "\u2026"] \xB7 pool "Label" { \u2026 } \xB7 pool "Label" blackbox \xB7 lane "Label" { \u2026 } \xB7 id: start|intermediate|end [message|timer] ["label"] \xB7 id: task [user|service|send|receive|manual|script] "label" \xB7 id: subprocess "label" [collapsed] \xB7 id: gateway xor|or|and|event ["label"] \xB7 flows \xB7 A --> B (sequence) \xB7 G --? "cond" --> B (conditional) \xB7 G --* "default" --> B (default) \xB7 "Pool" ~~> id : "label" (message flow)',
|
|
4527
|
+
forms: [
|
|
4528
|
+
"bpmn",
|
|
4529
|
+
"direction: LR",
|
|
4530
|
+
'title: "Loan Application Approval"',
|
|
4531
|
+
'pool "Bank" {',
|
|
4532
|
+
' lane "Clerk" {',
|
|
4533
|
+
' A: start "Application received"',
|
|
4534
|
+
' B: task user "Check completeness"',
|
|
4535
|
+
' G1: gateway xor "Complete?"',
|
|
4536
|
+
" }",
|
|
4537
|
+
' lane "Underwriter" {',
|
|
4538
|
+
' C: task service "Risk score"',
|
|
4539
|
+
' E: end "Approved"',
|
|
4540
|
+
' F: end "Rejected"',
|
|
4541
|
+
" }",
|
|
4542
|
+
"}",
|
|
4543
|
+
"flows",
|
|
4544
|
+
"A --> B",
|
|
4545
|
+
"B --> G1",
|
|
4546
|
+
'G1 --? "yes" --> C',
|
|
4547
|
+
'G1 --* "no" --> F',
|
|
4548
|
+
"C --> E"
|
|
4549
|
+
],
|
|
4550
|
+
prefer: [
|
|
4551
|
+
'Declare flow objects inside `lane "Label" { id: kind \u2026 }` nested in `pool "Label" { \u2026 }`. The `id:` prefix before the keyword is required; labels must be quoted.',
|
|
4552
|
+
"Event kinds `start`/`intermediate`/`end` with optional trigger `message`/`timer`; task markers `user`/`service`/`send`/`receive`/`manual`/`script`; gateway kinds `xor`/`or`/`and`/`event`.",
|
|
4553
|
+
"Put all flows in a single `flows` block. Sequence flow `-->` stays inside one pool; use `~~>` only for cross-pool message flow; `--?` is a conditional branch with one `--*` default per gateway."
|
|
4554
|
+
],
|
|
4555
|
+
avoid: [
|
|
4556
|
+
"Don't use `-->` across pool boundaries \u2014 it is rejected with `crosses pool boundary \u2014 use message flow`.",
|
|
4557
|
+
"Don't add lanes or tasks inside a `blackbox` pool \u2014 rejected with `black-box pool` cannot contain flow objects.",
|
|
4558
|
+
"Don't give a `task` without a quoted label, and don't put more than one `--*` default flow on the same gateway."
|
|
4559
|
+
],
|
|
4560
|
+
repair: [
|
|
4561
|
+
"'crosses pool boundary \u2014 use message flow' -> replace `-->` with `~~>` and ensure source/target are in different pools.",
|
|
4562
|
+
"'unknown flow-object kind' -> the word after `id:` must be `start`, `end`, `intermediate`, `task`, `subprocess`, or `gateway`.",
|
|
4563
|
+
"'kind must be xor / or / and / event' -> a gateway declaration needs one of those four kinds after the `gateway` keyword."
|
|
4564
|
+
]
|
|
3942
4565
|
},
|
|
3943
4566
|
fbd: {
|
|
3944
4567
|
type: "fbd",
|
|
3945
4568
|
header: 'fbd "Title"',
|
|
3946
|
-
mode: "
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
4569
|
+
mode: "variable declarations + numbered networks of indented assignment statements",
|
|
4570
|
+
keywords: 'var NAME: TYPE [= init] \xB7 scopes: var var_input var_output var_in_out var_global var_external \xB7 types: bool int dint uint real lreal time string byte word dword timer counter \xB7 network [N] ["title"]: \xB7 Inst = BLOCK(args) \xB7 negation: ~varName \xB7 named args: PORT: value \xB7 nested: BLOCK(BLOCK(\u2026)) \xB7 port ref: Inst.PORT \xB7 boolean: AND OR NOT NAND NOR XOR XNOR BUF \xB7 edge: R_TRIG F_TRIG \xB7 bistable: SR RS \xB7 timers: TON TOF TP \xB7 counters: CTU CTD \xB7 math: ADD SUB MUL DIV MOD ABS NEG MOVE \xB7 compare: EQ NE GT GE LT LE \xB7 select: SEL MUX MAX MIN LIMIT',
|
|
4571
|
+
forms: [
|
|
4572
|
+
'fbd "Motor Control"',
|
|
4573
|
+
"var Start: bool",
|
|
4574
|
+
"var Stop: bool",
|
|
4575
|
+
"var MotorOut: bool",
|
|
4576
|
+
"var Latch: bool",
|
|
4577
|
+
'network 0 "Start latch":',
|
|
4578
|
+
" Latch = OR(Start, AND(Latch, ~Stop))",
|
|
4579
|
+
'network 1 "Drive output":',
|
|
4580
|
+
" MotorOut = MOVE(Latch)"
|
|
4581
|
+
],
|
|
4582
|
+
prefer: [
|
|
4583
|
+
"Declare variables with `var NAME: TYPE` before any `network` line; use `~varName` on an input to place a negation bubble inline instead of a `NOT` block.",
|
|
4584
|
+
'Each `network [N] ["title"]:` header is followed by indented `Inst = BLOCK(args)` body lines until the next `network`.',
|
|
4585
|
+
"Variadic blocks (`AND`, `OR`, `ADD`, `MUL`, `MAX`, `MIN`) accept any number of positional args and expand `IN1..INn` automatically."
|
|
4586
|
+
],
|
|
4587
|
+
avoid: [
|
|
4588
|
+
"Don't use ladder element names (`XIC`, `OTE`, ladder-style `TON`) inside FBD networks \u2014 they are not valid FBD blocks.",
|
|
4589
|
+
"Don't reference an instance port (`Inst.PORT`) before that instance is assigned in the same network.",
|
|
4590
|
+
"Don't use ladder comparison aliases \u2014 FBD uses `EQ NE GT GE LT LE`, not `EQU NEQ GRT LES GEQ LEQ`."
|
|
4591
|
+
],
|
|
4592
|
+
repair: [
|
|
4593
|
+
"'Unknown function block' -> replace with the closest IEC standard block (e.g. `EQUAL` -> `EQ`, `GREATER` -> `GT`, `TIMER_ON` -> `TON`).",
|
|
4594
|
+
"'Duplicate instance name' -> each `Inst =` assignment in a program must use a unique left-hand name.",
|
|
4595
|
+
"'Unrecognized network statement' -> the line must match `Inst = BLOCK(args)` or a bare `BLOCK(args)`; check for missing parentheses.",
|
|
4596
|
+
"'Too many positional arguments' -> drop excess args or switch to named-port form `PORT: value`."
|
|
4597
|
+
]
|
|
3951
4598
|
},
|
|
3952
4599
|
sfc: {
|
|
3953
4600
|
type: "sfc",
|
|
3954
4601
|
header: 'sfc "Title"',
|
|
3955
|
-
mode: "steps + transitions",
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
4602
|
+
mode: "steps with indented actions + from:/to: transitions",
|
|
4603
|
+
keywords: 'step ID [initial|final|label:"\u2026"] \xB7 var NAME: TYPE \xB7 transition [id] from: A to: B: COND \xB7 jump from: A to: B \xB7 alt from: STEP: / sim from: STEP: COND with branch [priority:N]: + merge_to: STEP[: COND] \xB7 action line \xABQUAL Name [T#\u2026]\xBB | qualifiers: N S R L D P P0 P1 SD DS SL (L/D/SD/DS/SL need T#\u2026) | var types: bool int real time timer counter',
|
|
4604
|
+
forms: [
|
|
4605
|
+
"step S0 [initial]",
|
|
4606
|
+
" N FillValve_Closed",
|
|
4607
|
+
'step S1 [label: "Filling"]',
|
|
4608
|
+
" N FillValve_Open",
|
|
4609
|
+
"transition from: S0 to: S1: StartBtn",
|
|
4610
|
+
"transition from: S1 to: S0: TankLevel >= 80.0"
|
|
4611
|
+
],
|
|
4612
|
+
prefer: [
|
|
4613
|
+
'Declare each `step ID [initial|final|label: "\u2026"]` first; put actions on indented lines under the step as `<QUAL> ActionName`.',
|
|
4614
|
+
"Wire steps with `transition from: A to: B: CONDITION` \u2014 the condition is free text (e.g. `TankLevel >= 80.0`), stored verbatim, never evaluated.",
|
|
4615
|
+
"Qualifiers are N S R L D P P0 P1 SD DS SL; the timed ones take a literal, e.g. `D Oven_Run T#15m`, `L Cooler_On T#5m`.",
|
|
4616
|
+
"Concurrency: `sim from: STEP: COND` + `branch:` blocks + `merge_to: STEP: COND`. Choice: `alt from: STEP:` + `branch [priority: N]:` (each with `transition: COND`) + `merge_to: STEP`."
|
|
4617
|
+
],
|
|
4618
|
+
avoid: [
|
|
4619
|
+
"Don't use arrow transitions like `S0 -> S1 : cond` \u2014 SFC only accepts `transition from: S0 to: S1: cond` (a bare arrow line is rejected as 'Unrecognized SFC line').",
|
|
4620
|
+
"Avoid a second `[initial]` step; if none is marked, the first declared step is promoted automatically.",
|
|
4621
|
+
"Don't invent qualifiers \u2014 only N/S/R/L/D/P/P0/P1/SD/DS/SL are valid, and L/D/SD/DS/SL need a `T#\u2026` time literal."
|
|
4622
|
+
],
|
|
4623
|
+
repair: [
|
|
4624
|
+
"'Transition references unknown step: X' -> declare `step X` (or fix the id) before any transition that names it.",
|
|
4625
|
+
"'Multiple [initial] steps: A and B' -> mark only one step `[initial]`.",
|
|
4626
|
+
"'Unrecognized SFC line: \u2026' -> a transition must be `transition from: A to: B: cond`; an action line must start with a qualifier and sit indented under its step.",
|
|
4627
|
+
"'sim block missing merge_to clause' -> end the branch block with `merge_to: STEP: CONDITION` (alt uses `merge_to: STEP`)."
|
|
4628
|
+
]
|
|
3960
4629
|
},
|
|
3961
4630
|
prisma: {
|
|
3962
4631
|
type: "prisma",
|
|
3963
4632
|
header: "prisma",
|
|
3964
|
-
mode: "PRISMA 2020
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
4633
|
+
mode: "indentation-structured PRISMA 2020 flow diagram (2-space indent)",
|
|
4634
|
+
keywords: "prisma \xB7 mode: 2020-single|2020-dual|2009 \xB7 kind: systematic-review|scoping-review|ipd|nma \xB7 validate-counts: strict|warn|off \xB7 stages: previous-studies \xB7 identification: -> databases: (n: sources: duplicates-removed:) [other: (n:)] \xB7 screening: -> records-screened: excluded: (n: reasons: name=count,\u2026) \xB7 eligibility: -> full-text-assessed: excluded: (n: reasons:) \xB7 included: -> studies: [reports:]",
|
|
4635
|
+
forms: [
|
|
4636
|
+
"prisma",
|
|
4637
|
+
"mode: 2020-single",
|
|
4638
|
+
"title: Exercise for chronic low-back pain \u2014 SR",
|
|
4639
|
+
"",
|
|
4640
|
+
"identification:",
|
|
4641
|
+
" databases:",
|
|
4642
|
+
" n: 1418",
|
|
4643
|
+
" sources: PubMed=600, Embase=450, Cochrane=184, Web of Science=184",
|
|
4644
|
+
" duplicates-removed: 318",
|
|
4645
|
+
"",
|
|
4646
|
+
"screening:",
|
|
4647
|
+
" records-screened: 1100",
|
|
4648
|
+
" excluded:",
|
|
4649
|
+
" n: 870",
|
|
4650
|
+
" reasons: irrelevant title=750, non-English=120",
|
|
4651
|
+
"",
|
|
4652
|
+
"eligibility:",
|
|
4653
|
+
" full-text-assessed: 230",
|
|
4654
|
+
" excluded:",
|
|
4655
|
+
" n: 195",
|
|
4656
|
+
" reasons: wrong population=80, wrong intervention=60, wrong outcome=55",
|
|
4657
|
+
"",
|
|
4658
|
+
"included:",
|
|
4659
|
+
" studies: 35"
|
|
4660
|
+
],
|
|
4661
|
+
prefer: [
|
|
4662
|
+
"All four stages `identification:`, `screening:`, `eligibility:`, `included:` are required \u2014 the parser throws if any is missing.",
|
|
4663
|
+
"Use 2-space indentation per level: stage keys at indent 0, sub-keys at indent 1, sub-sub-keys at indent 2.",
|
|
4664
|
+
"Put reason breakdowns as `name=count` pairs on one `reasons:` line; for dual-pipeline add an `other:` block under `identification:` (auto-switches to 2020-dual)."
|
|
4665
|
+
],
|
|
4666
|
+
avoid: [
|
|
4667
|
+
"Don't write free-form stage keys \u2014 only `previous-studies`, `identification`, `screening`, `eligibility`, `included` are valid at the top level.",
|
|
4668
|
+
"Don't omit `n:` inside any stage block \u2014 it is required.",
|
|
4669
|
+
"Don't malform `reasons:` \u2014 pairs must be `name=count`; a missing `=` is an error."
|
|
4670
|
+
],
|
|
4671
|
+
repair: [
|
|
4672
|
+
"'required stage' is missing -> add the missing stage block (`identification:` needs a nested `databases:` with at least `n:`).",
|
|
4673
|
+
"'is missing required' field -> add the required sub-key (e.g. `n:`, or an `excluded:` block under `screening:`).",
|
|
4674
|
+
"'sources sum to' N but n = M -> make the `sources:` counts add up to the `n:` value, or remove `sources:`.",
|
|
4675
|
+
"'unknown stage' -> valid top-level keys are `previous-studies`, `identification`, `screening`, `eligibility`, `included`."
|
|
4676
|
+
]
|
|
3969
4677
|
},
|
|
3970
4678
|
usecase: {
|
|
3971
4679
|
type: "usecase",
|
|
3972
4680
|
header: "usecase",
|
|
3973
|
-
mode: "declarative
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
4681
|
+
mode: "declarative actor/usecase declarations + typed relationship lines",
|
|
4682
|
+
keywords: 'usecase \xB7 title: "\u2026" \xB7 system: "\u2026" \xB7 direction: LR|TB \xB7 actor: Name [as ID] [(external|business|system)] [(left|right)] \xB7 usecase: "Name" [as ID] [\xABstereotype\xBB] [{ extension point: name }] \xB7 relations: -- association \xB7 --> directed \xB7 ..> include \xB7 <.. extend \xB7 --|> generalization \xB7 multiplicity: "1" "0..*" \xB7 note "label" { id, id } \xB7 PlantUML inline: :Name: (Name)',
|
|
4683
|
+
forms: [
|
|
4684
|
+
"usecase",
|
|
4685
|
+
'title: "ATM"',
|
|
4686
|
+
'system: "ATM System"',
|
|
4687
|
+
"actor: Customer",
|
|
4688
|
+
"actor: Bank (external)",
|
|
4689
|
+
'usecase: "Withdraw Cash" as Withdraw',
|
|
4690
|
+
'usecase: "Check Balance" as Check',
|
|
4691
|
+
"Customer -- Withdraw",
|
|
4692
|
+
"Customer -- Check",
|
|
4693
|
+
"Withdraw -- Bank"
|
|
4694
|
+
],
|
|
4695
|
+
prefer: [
|
|
4696
|
+
"Declare all `actor:` and `usecase:` lines before relationship lines \u2014 an unknown id on a relation is a hard error.",
|
|
4697
|
+
"Use `actor: Name (external)` for system actors (rectangle), `(business)` for in-org actors, bare for stick figures; add `(left)`/`(right)` to pin placement.",
|
|
4698
|
+
"Use `..>` for \xABinclude\xBB (arrow points to the included use case) and `<..` for \xABextend\xBB (arrow points to the base) \u2014 the directions are opposite and both enforced."
|
|
4699
|
+
],
|
|
4700
|
+
avoid: [
|
|
4701
|
+
"Don't use `--` between two actors, or `..>`/`<..` involving an actor \u2014 both are hard errors.",
|
|
4702
|
+
"Don't use `--|>` between an actor and a use case \u2014 generalization must be actor\u2194actor or usecase\u2194usecase.",
|
|
4703
|
+
"Don't skip the `as ID` alias when reusing a multi-word name in relationships \u2014 the auto-id replaces spaces with underscores."
|
|
4704
|
+
],
|
|
4705
|
+
repair: [
|
|
4706
|
+
"'unknown identifier' -> declare `actor: X` or `usecase: \"X\" as X` before the relation line that references it.",
|
|
4707
|
+
"'must connect an actor and a use case' -> use `--|>` for actor generalization, not `--`.",
|
|
4708
|
+
"'endpoints must be use cases' -> both sides of `..>`/`<..` must be use cases, not actors.",
|
|
4709
|
+
"'first non-comment line must start with' -> the document must open with the bare keyword `usecase`."
|
|
4710
|
+
]
|
|
3978
4711
|
},
|
|
3979
4712
|
pert: {
|
|
3980
4713
|
type: "pert",
|
|
3981
4714
|
header: "pert",
|
|
3982
|
-
mode: "AON tasks
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
4715
|
+
mode: "AON tasks with computed schedule (ES/EF/LS/LF/slack/critical path)",
|
|
4716
|
+
keywords: 'pert \xB7 title: "\u2026" \xB7 unit: days|weeks|hours|abstract \xB7 direction: LR|TB \xB7 layout: network|timescaled|aoa \xB7 critical-tolerance: N \xB7 task ID "label" duration: N|O/M/P [after: ref,\u2026] [milestone] [lane: "Name"] \xB7 dependency refs: ID (FS) \xB7 ID FS|SS|FF|SF[+N|-N][d|w|h] \xB7 ID+N (FS lag sugar)',
|
|
4717
|
+
forms: [
|
|
4718
|
+
"pert",
|
|
4719
|
+
'title: "Q3 Product Launch"',
|
|
4720
|
+
"unit: days",
|
|
4721
|
+
"",
|
|
4722
|
+
'task A "Market research" duration: 5',
|
|
4723
|
+
'task B "Design mockups" duration: 8 after: A',
|
|
4724
|
+
'task C "Backend API" duration: 15 after: A',
|
|
4725
|
+
'task D "Frontend build" duration: 10 after: B, C',
|
|
4726
|
+
'task E "QA / testing" duration: 5 after: D',
|
|
4727
|
+
'task G "Launch event" duration: 2 after: E'
|
|
4728
|
+
],
|
|
4729
|
+
prefer: [
|
|
4730
|
+
'Each `task ID "label" duration: N` is one activity; wire dependencies with `after: A, B` (comma-separated, forward references allowed). The engine computes ES/EF/LS/LF and the critical path \u2014 never write those yourself.',
|
|
4731
|
+
"Use three-point estimation `duration: O/M/P` (e.g. `2/3/5`) for uncertainty \u2014 the engine computes `te = (O+4M+P)/6` and variance; add `critical-tolerance: 0.01` when mixing estimate kinds.",
|
|
4732
|
+
'Declare dependency types when needed: `after: A FS`, `after: A SS+2`, `after: B FF-1` (default FS, zero lag); group activities with `lane: "Team"`.'
|
|
4733
|
+
],
|
|
4734
|
+
avoid: [
|
|
4735
|
+
"Don't write `ES:`, `EF:`, `LS:`, `LF:`, or `slack:` yourself \u2014 they are computed outputs.",
|
|
4736
|
+
"Don't create a cycle in `after:` references, and don't reference an undeclared predecessor.",
|
|
4737
|
+
"Don't mix lag unit suffixes that don't match `unit:` \u2014 e.g. `FS+2d` with `unit: weeks`."
|
|
4738
|
+
],
|
|
4739
|
+
repair: [
|
|
4740
|
+
"'is missing' duration -> add `duration: N` or append the bare word `milestone` to the task line.",
|
|
4741
|
+
"'references undeclared predecessor' -> declare `task Y \u2026` anywhere (forward references are allowed).",
|
|
4742
|
+
"'O <= M <= P' -> reorder a three-point estimate so optimistic <= most-likely <= pessimistic.",
|
|
4743
|
+
"'duplicate task id' -> every task needs a unique id; rename the second occurrence."
|
|
4744
|
+
]
|
|
3987
4745
|
},
|
|
3988
4746
|
sequence: {
|
|
3989
4747
|
type: "sequence",
|
|
3990
4748
|
header: "sequenceDiagram",
|
|
3991
4749
|
mode: "Mermaid sequenceDiagram (recommended for generation)",
|
|
4750
|
+
keywords: 'sequenceDiagram (Mermaid) | sequence "Title" (native) \xB7 participant actor boundary control entity database collections queue \xB7 "as" alias \xB7 \xABstereotype\xBB \xB7 -> sync \xB7 ->> async \xB7 --> reply \xB7 -) async \xB7 -x lost \xB7 *Target create \xB7 +/- activation suffix \xB7 activate/deactivate \xB7 note over|left of|right of A[,B]: text \xB7 ref over A,B: text \xB7 == divider == \xB7 autonumber \xB7 fragments: alt else end / opt loop break critical neg ignore consider assert par seq strict and end',
|
|
3992
4751
|
forms: [
|
|
3993
4752
|
"participant Alice",
|
|
3994
4753
|
"participant Bob",
|
|
@@ -3997,20 +4756,26 @@ var PROFILES = {
|
|
|
3997
4756
|
"Note over Alice,Bob: handshake"
|
|
3998
4757
|
],
|
|
3999
4758
|
prefer: [
|
|
4000
|
-
"Use
|
|
4001
|
-
|
|
4002
|
-
"
|
|
4759
|
+
"Use the `sequenceDiagram` header (Mermaid mode): `->>` is a sync call and `-->>` is the reply/return \u2014 matches the dominant training prior.",
|
|
4760
|
+
"Declare lifeline kinds with `participant`/`actor`/`boundary`/`control`/`entity`/`database`/`collections`/`queue` before use; undeclared ids auto-create as plain `participant`.",
|
|
4761
|
+
"Use `->+` / `-->-` to open/close activation bars inline; use `alt \u2026 else \u2026 end`, `loop`, `opt`, `par \u2026 and \u2026 end` for fragments."
|
|
4762
|
+
],
|
|
4763
|
+
avoid: [
|
|
4764
|
+
"Do not mix `sequenceDiagram` and native `sequence` headers \u2014 in Mermaid mode `->>` is sync, in native mode it is async; pick one and keep arrows consistent.",
|
|
4765
|
+
"Do not use `else` outside an `alt`, or `and` outside `par`/`seq`/`strict`.",
|
|
4766
|
+
"Do not leave a combined fragment open \u2014 every `alt`/`opt`/`loop`/`par`/`break`/`critical` must close with `end`."
|
|
4003
4767
|
],
|
|
4004
|
-
avoid: ["Do not mix the two header styles; pick `sequenceDiagram` and keep Mermaid arrow meanings throughout."],
|
|
4005
4768
|
repair: [
|
|
4006
|
-
"
|
|
4007
|
-
'
|
|
4769
|
+
"'must start with the keyword' -> fix the first line to exactly `sequenceDiagram` or `sequence \"Title\"`.",
|
|
4770
|
+
"'is only valid inside an' -> move the `else` inside an `alt \u2026 end` block (or `and` inside `par`).",
|
|
4771
|
+
"'without a matching combined fragment' -> add the missing `end`, or remove the dangling `else`/`and`."
|
|
4008
4772
|
]
|
|
4009
4773
|
},
|
|
4010
4774
|
petri: {
|
|
4011
4775
|
type: "petri",
|
|
4012
4776
|
header: 'petri "Title"',
|
|
4013
4777
|
mode: "declared places + transitions + arcs",
|
|
4778
|
+
keywords: 'place ID ["label"] *N|tokens:N [capacity:N] \xB7 transition ID ["label"] [immediate|timed] [rate:N] [priority:N] [guard: expr] \xB7 arc types: -> (standard) | -o (inhibitor, P\u2192T only) | -- (read) | => (reset, P\u2192T only) \xB7 weight: N or *N on arc \xB7 layout: lr|tb \xB7 marking: id=n,\u2026 \xB7 fire: T1, T2, \u2026 (simulate firing)',
|
|
4014
4779
|
forms: [
|
|
4015
4780
|
"place P1 *1",
|
|
4016
4781
|
"transition T1",
|
|
@@ -4028,7 +4793,7 @@ var PROFILES = {
|
|
|
4028
4793
|
"Avoid `-o`/`=>` arcs from a transition; inhibitor and reset arcs are place\u2192transition only."
|
|
4029
4794
|
],
|
|
4030
4795
|
repair: [
|
|
4031
|
-
"
|
|
4796
|
+
"'arc references unknown node' -> an arc references an undeclared place/transition; declare it first.",
|
|
4032
4797
|
"Set the initial marking so the transitions you intend to be enabled actually have enough input tokens."
|
|
4033
4798
|
]
|
|
4034
4799
|
},
|
|
@@ -4036,27 +4801,28 @@ var PROFILES = {
|
|
|
4036
4801
|
type: "network",
|
|
4037
4802
|
header: 'network "Title"',
|
|
4038
4803
|
mode: "device declarations + links (annotations are optional)",
|
|
4804
|
+
keywords: "device kinds: router switch l3switch firewall loadbalancer ap wlc gateway modem ids proxy vpngw server serverfarm pc laptop mobile ipphone printer storage camera nvr dvr poeswitch encoder monitor internet wan cloud pstn lan \xB7 aliases: multilayer->l3switch wifi->ap workstation->pc nas/san->storage \xB7 device attrs: tier:edge|core|distribution|access ip: model: count: type:fixed|bullet|dome|ptz|turret at:x,y \xB7 link connectors: -- (undirected) | -> (directed) | == (LAG) \xB7 link annotations: copper|fiber|wireless|serial|poe|vpn|lag trunk|access speed(1G/10G/100M) vlan:N port:near>far \xB7 groups: site rack subnet vlan zone dmz { \u2026 } \xB7 layout: tiered|tree|star|ring|bus|mesh|spine-leaf|manual \xB7 spines: / leaves:",
|
|
4039
4805
|
forms: [
|
|
4040
|
-
'router r1 "Edge Router"
|
|
4041
|
-
'l3switch core1 "Core" tier: core
|
|
4806
|
+
'router r1 "Edge Router"',
|
|
4807
|
+
'l3switch core1 "Core" tier: core',
|
|
4042
4808
|
'switch acc1 "Access" tier: access',
|
|
4043
4809
|
'pc pc1 "Workstation"',
|
|
4044
|
-
"r1 -- core1
|
|
4810
|
+
"r1 -- core1",
|
|
4045
4811
|
"core1 -- acc1",
|
|
4046
4812
|
"acc1 -- pc1"
|
|
4047
4813
|
],
|
|
4048
4814
|
prefer: [
|
|
4049
4815
|
'Start from the skeleton: `kind id "label"` device lines plus `a -- b` links. That alone renders a complete, valid diagram.',
|
|
4050
4816
|
"Declare every device before any link references it.",
|
|
4051
|
-
"Keep the cheap structural hints `layout:` (tiered/tree/star/ring/bus/mesh/spine-leaf) and `tier:` (edge/core/distribution/access) \u2014 they
|
|
4817
|
+
"Keep the cheap structural hints `layout:` (tiered/tree/star/ring/bus/mesh/spine-leaf) and `tier:` (edge/core/distribution/access) \u2014 they drive a readable hierarchy.",
|
|
4052
4818
|
"Common kinds: router, switch, l3switch, firewall, ap, server, pc, laptop, camera, nvr, poeswitch, internet, cloud."
|
|
4053
4819
|
],
|
|
4054
4820
|
avoid: [
|
|
4055
4821
|
"Avoid linking to an undeclared device id.",
|
|
4056
|
-
'Add
|
|
4822
|
+
'Add verbose per-link annotations (`vlan:`, `port:`, speeds, `trunk`/`access`) and `subnet "cidr" { ... }` boundaries ONLY when the request needs them \u2014 they don\'t affect layout and are where generation most often breaks.'
|
|
4057
4823
|
],
|
|
4058
4824
|
repair: [
|
|
4059
|
-
"
|
|
4825
|
+
"'undeclared device' -> a link references an id with no `kind id` declaration; declare it first.",
|
|
4060
4826
|
"If the layout looks flat/messy, add `layout: tiered` + `tier:` on infrastructure; if unsure about per-link annotations, drop them \u2014 the skeleton always renders."
|
|
4061
4827
|
]
|
|
4062
4828
|
},
|
|
@@ -4064,40 +4830,42 @@ var PROFILES = {
|
|
|
4064
4830
|
type: "umlclass",
|
|
4065
4831
|
header: "umlclass",
|
|
4066
4832
|
mode: "classifier declarations + relationship lines (PlantUML-flavoured, Mermaid aliases accepted)",
|
|
4833
|
+
keywords: 'header: umlclass | class-diagram | classDiagram \xB7 classifiers: class | abstract class | interface | enum (or enumeration) | datatype | primitive \xB7 stereotype: \xABword\xBB or <<word>> \xB7 members in { }: visibility + - # ~ \xB7 modifiers {static} {abstract} \xB7 derived /name \xB7 multiplicity [1..*] \xB7 tilde-generics List~T~ -> List<T> \xB7 single-line: ClassName : +member \xB7 connectors: <|-- --|> generalization \xB7 <|.. ..|> realization \xB7 *-- --* composition \xB7 o-- --o aggregation \xB7 --> <-- directed assoc \xB7 ..> <.. dependency \xB7 -- association \xB7 multiplicity "1" "0..*" quoted next to endpoint \xB7 namespace A.B.C { } \xB7 direction: tb|lr',
|
|
4067
4834
|
forms: [
|
|
4068
|
-
"class Order { + id : String + place() : void }
|
|
4069
|
-
"\xABinterface\xBB Shape { + area() : double }
|
|
4835
|
+
"class Order { + id : String + place() : void }",
|
|
4836
|
+
"\xABinterface\xBB Shape { + area() : double }",
|
|
4070
4837
|
"abstract class AbstractShape { + area() : double {abstract} }",
|
|
4071
|
-
"\xABenumeration\xBB Suit { HEARTS DIAMONDS CLUBS SPADES }
|
|
4072
|
-
"Animal <|-- Dog
|
|
4073
|
-
"Shape <|.. Circle
|
|
4074
|
-
'Order *-- "1..*" LineItem : contains
|
|
4075
|
-
'Customer o-- "0..*" Address
|
|
4076
|
-
'A "1" --> "*" B : owns
|
|
4077
|
-
"X ..> Y
|
|
4838
|
+
"\xABenumeration\xBB Suit { HEARTS DIAMONDS CLUBS SPADES }",
|
|
4839
|
+
"Animal <|-- Dog",
|
|
4840
|
+
"Shape <|.. Circle",
|
|
4841
|
+
'Order *-- "1..*" LineItem : contains',
|
|
4842
|
+
'Customer o-- "0..*" Address',
|
|
4843
|
+
'A "1" --> "*" B : owns',
|
|
4844
|
+
"X ..> Y"
|
|
4078
4845
|
],
|
|
4079
4846
|
prefer: [
|
|
4080
4847
|
"Single-word keyword is `umlclass` (also accepts `class-diagram` and Mermaid's `classDiagram`).",
|
|
4081
4848
|
"Use `class`, `abstract class`, `\xABinterface\xBB`, `\xABenumeration\xBB`, or any custom `\xABstereotype\xBB` above the name.",
|
|
4082
4849
|
"Members go in `{ \u2026 }`; visibility glyphs are `+ - # ~`; `{static}` underlines, `{abstract}` italicises, `/name` marks a derived attribute.",
|
|
4083
|
-
'Multiplicity is the quoted token next to an endpoint: `"1"`, `"0..*"`, `"1..*"`. The
|
|
4850
|
+
'Multiplicity is the quoted token next to an endpoint: `"1"`, `"0..*"`, `"1..*"`. The label after `:` is the association name.',
|
|
4084
4851
|
"PlantUML connectors are primary; the Mermaid reversed forms `--|>`, `..|>`, `--*`, `--o` are accepted and normalised."
|
|
4085
4852
|
],
|
|
4086
4853
|
avoid: [
|
|
4087
|
-
"Don't use bare `class` as the diagram keyword \u2014 that's a reserved
|
|
4088
|
-
"Don't put `-->` for dependency: `-->` is
|
|
4089
|
-
"Don't declare a classifier with an empty
|
|
4854
|
+
"Don't use bare `class` as the diagram keyword \u2014 that's a reserved word; the engine keyword is `umlclass`.",
|
|
4855
|
+
"Don't put `-->` for dependency: `-->` is directed association; dependency is the dashed `..>`.",
|
|
4856
|
+
"Don't declare a classifier with an empty `{}` for a name-only box \u2014 write `class Foo` on its own line."
|
|
4090
4857
|
],
|
|
4091
4858
|
repair: [
|
|
4092
|
-
"
|
|
4093
|
-
"
|
|
4094
|
-
"If a class appears as
|
|
4859
|
+
"'malformed relationship' -> no connector glyph was found between two ids; use one of `<|--` `<|..` `*--` `o--` `-->` `..>` `--` `..`.",
|
|
4860
|
+
"'generalization cycle' -> inheritance edges form a loop; fix the parent/child direction of one edge in the cycle.",
|
|
4861
|
+
"If a class appears as an unexpected empty box, the parser auto-created it from an arc reference \u2014 declare it explicitly or fix the relationship id typo."
|
|
4095
4862
|
]
|
|
4096
4863
|
},
|
|
4097
4864
|
faulttree: {
|
|
4098
4865
|
type: "faulttree",
|
|
4099
4866
|
header: 'faulttree "Title"',
|
|
4100
4867
|
mode: "flat event/gate declarations wired by id (top + gates + leaves)",
|
|
4868
|
+
keywords: "header: faulttree | fta \xB7 event kinds: top | gate | basic | undeveloped | house | condition \xB7 gate exprs: AND(a,b,\u2026) | OR(\u2026) | XOR(\u2026) | VOTING(k/n; \u2026) | INHIBIT(x) if cond | PAND(a,b) [order: a,b] \xB7 leaf attr: p: N (or prob:, sci 1e-3) \xB7 house attr: state: 0|1 \xB7 analysis: cutsets | probability | pathsets \xB7 prob: rare|mcub|exact \xB7 layout: tb|bt \xB7 style: ansi|iec",
|
|
4101
4869
|
forms: [
|
|
4102
4870
|
"analysis: cutsets, probability",
|
|
4103
4871
|
'top T "System fails" = OR(G1, G2)',
|
|
@@ -4121,9 +4889,9 @@ var PROFILES = {
|
|
|
4121
4889
|
"Don't declare more than one `top`, and don't create cycles (a gate may not transitively reference itself)."
|
|
4122
4890
|
],
|
|
4123
4891
|
repair: [
|
|
4124
|
-
"'references undefined event'
|
|
4125
|
-
"'must have exactly one top'
|
|
4126
|
-
"'
|
|
4892
|
+
"'references undefined event' -> a gate input id was never declared; add the `basic`/`gate`/\u2026 line.",
|
|
4893
|
+
"'must have exactly one top' -> keep a single `top`; downgrade the others to `gate`.",
|
|
4894
|
+
"'n must equal the number of inputs' -> in `VOTING(k/n; \u2026)` make n match the listed inputs.",
|
|
4127
4895
|
"If P(top) shows 'n/a', a basic event in a cut set is missing its `p:`."
|
|
4128
4896
|
]
|
|
4129
4897
|
},
|
|
@@ -4131,6 +4899,7 @@ var PROFILES = {
|
|
|
4131
4899
|
type: "bowtie",
|
|
4132
4900
|
header: 'bowtie "Title"',
|
|
4133
4901
|
mode: "indentation-structured: hazard + topevent, then threat/consequence blocks with indented barrier chains",
|
|
4902
|
+
keywords: 'hazard "\u2026" \xB7 topevent "\u2026" \xB7 threat "\u2026" \xB7 prevent "\u2026" \xB7 consequence "\u2026" \xB7 mitigate "\u2026" \xB7 escalation "\u2026" \xB7 barrier "\u2026" \xB7 layout: symmetric|compact \xB7 legend: on|off|bottom|bottom-right|top',
|
|
4134
4903
|
forms: [
|
|
4135
4904
|
'hazard "Working at height"',
|
|
4136
4905
|
'topevent "Person falls from height"',
|
|
@@ -4144,7 +4913,7 @@ var PROFILES = {
|
|
|
4144
4913
|
],
|
|
4145
4914
|
prefer: [
|
|
4146
4915
|
"Single-word keyword is `bowtie`. Declare exactly one `topevent` (the knot) and an optional `hazard` header.",
|
|
4147
|
-
"Each `threat` needs
|
|
4916
|
+
"Each `threat` needs >= 1 indented `prevent` barrier; each `consequence` needs >= 1 indented `mitigate` barrier (the engine rejects a bare threat/consequence).",
|
|
4148
4917
|
"Barrier order = declaration order (first = outermost, nearest the threat/consequence; last = innermost, nearest the knot).",
|
|
4149
4918
|
"`escalation` nests (4 spaces) under the `prevent`/`mitigate` barrier it degrades; an escalation-factor `barrier` nests (6 spaces) under the escalation.",
|
|
4150
4919
|
"Bowtie is qualitative \u2014 no probabilities. For Boolean gates + cut sets behind one threat, use a separate `faulttree`."
|
|
@@ -4156,16 +4925,17 @@ var PROFILES = {
|
|
|
4156
4925
|
"Don't declare more than one `topevent` or more than one `hazard`."
|
|
4157
4926
|
],
|
|
4158
4927
|
repair: [
|
|
4159
|
-
"'has no preventative barrier' / 'no mitigative barrier'
|
|
4160
|
-
"'not attached to a barrier'
|
|
4161
|
-
"'needs at least one threat/consequence'
|
|
4162
|
-
"'exactly one top event'
|
|
4928
|
+
"'has no preventative barrier' / 'no mitigative barrier' -> add a `prevent`/`mitigate` line under the threat/consequence.",
|
|
4929
|
+
"'not attached to a barrier' -> move the `escalation` so it follows a `prevent`/`mitigate` line.",
|
|
4930
|
+
"'needs at least one threat/consequence' -> a one-wing diagram is a fault tree or event tree; add the missing wing.",
|
|
4931
|
+
"'exactly one top event' -> keep a single `topevent` line."
|
|
4163
4932
|
]
|
|
4164
4933
|
},
|
|
4165
4934
|
eventtree: {
|
|
4166
4935
|
type: "eventtree",
|
|
4167
4936
|
header: 'eventtree "Title"',
|
|
4168
4937
|
mode: "initiating event + ordered safety functions, then outcome rows with s/f/* branch patterns",
|
|
4938
|
+
keywords: 'eventtree|eta "Title" \xB7 initiating ID "label" freq: <number|1e-4> \xB7 function ID "label" p: <0..1> \xB7 outcome <s|f|*>\u2026 -> "label" \xB7 layout: lr \xB7 # and // comments',
|
|
4169
4939
|
forms: [
|
|
4170
4940
|
'initiating LOCA "Large LOCA" freq: 1e-4',
|
|
4171
4941
|
'function A "ECCS injects" p: 0.001',
|
|
@@ -4176,24 +4946,25 @@ var PROFILES = {
|
|
|
4176
4946
|
],
|
|
4177
4947
|
prefer: [
|
|
4178
4948
|
"Keyword `eventtree` (or `eta`). One `initiating` line with a `freq:`; then `function` lines in left-to-right order, each with its failure probability `p:` (success is auto-complemented to 1\u2212p).",
|
|
4179
|
-
'Each `outcome` row gives a `s`/`f`/`*` pattern (one symbol per function) then `-> "label"`. `*` = path already terminated (pruned)
|
|
4949
|
+
'Each `outcome` row gives a `s`/`f`/`*` pattern (one symbol per function) then `-> "label"`. `*` = path already terminated (pruned).',
|
|
4180
4950
|
"Let the engine compute path frequencies (f_initiating \xD7 \u03A0 branch-probs) \u2014 don't hand-write them."
|
|
4181
4951
|
],
|
|
4182
4952
|
avoid: [
|
|
4183
|
-
"Don't try to make a balanced 2
|
|
4953
|
+
"Don't try to make a balanced 2^n tree \u2014 prune with `*` where a sequence ends early.",
|
|
4184
4954
|
"Don't put probabilities on outcome rows; `p:` belongs on `function` lines.",
|
|
4185
4955
|
"Don't reverse the success/failure convention \u2014 success branches up, failure down."
|
|
4186
4956
|
],
|
|
4187
4957
|
repair: [
|
|
4188
|
-
"'outcome pattern length'
|
|
4189
|
-
"'no initiating event'
|
|
4190
|
-
"'once pruned stays pruned'
|
|
4958
|
+
"'outcome pattern length' -> give exactly one s/f/* per declared function.",
|
|
4959
|
+
"'no initiating event' -> add one `initiating <id> \"\u2026\" freq: \u2026` line.",
|
|
4960
|
+
"'once pruned stays pruned' -> after a `*` in a pattern, the rest must also be `*`."
|
|
4191
4961
|
]
|
|
4192
4962
|
},
|
|
4193
4963
|
fmea: {
|
|
4194
4964
|
type: "fmea",
|
|
4195
4965
|
header: 'fmea "Title"',
|
|
4196
4966
|
mode: "indentation-structured worksheet: item \u2192 failure mode \u2192 effect/cause/controls with S/O/D scores",
|
|
4967
|
+
keywords: 'fmea "Title" \xB7 type: design|dfmea|process|pfmea|msr \xB7 rank: ap|rpn \xB7 flag: ap>=High|rpn>100 \xB7 item "\u2026" fn "\u2026" \xB7 mode "\u2026" \xB7 effect "\u2026" sev: 1..10 \xB7 cause "\u2026" occ: 1..10 \xB7 controls prevention: "\u2026" detection: "\u2026" det: 1..10 \xB7 action "mode" do: "\u2026" owner: "\u2026" target: DATE \xB7 revised sev:/occ:/det:',
|
|
4197
4968
|
forms: [
|
|
4198
4969
|
'fmea "Brake System DFMEA"',
|
|
4199
4970
|
' item "Master cylinder" fn "Generate pressure"',
|
|
@@ -4213,40 +4984,47 @@ var PROFILES = {
|
|
|
4213
4984
|
"Don't put `occ:` on an effect or `sev:` on a cause \u2014 they bind to the wrong column."
|
|
4214
4985
|
],
|
|
4215
4986
|
repair: [
|
|
4216
|
-
"'score out of range'
|
|
4217
|
-
"'
|
|
4987
|
+
"'score out of range' -> keep S/O/D in 1\u201310.",
|
|
4988
|
+
"'has no effect/cause' -> every failure mode needs at least one effect and one cause."
|
|
4218
4989
|
]
|
|
4219
4990
|
},
|
|
4220
4991
|
causalloop: {
|
|
4221
4992
|
type: "causalloop",
|
|
4222
4993
|
header: 'causalloop "Title"',
|
|
4223
4994
|
mode: "signed causal links between variables; engine detects R/B loops",
|
|
4995
|
+
keywords: 'causalloop "Title" (alias: cld) \xB7 A -> B : + | - | s | o | same | opposite \xB7 "multi-word var" -> Target : + \xB7 A -> B : + delay \xB7 var "Variable name" \xB7 loop R1 "phrase" | loop B1 "phrase" \xB7 layout: auto | circle',
|
|
4224
4996
|
forms: [
|
|
4225
|
-
'causalloop "
|
|
4226
|
-
'"
|
|
4227
|
-
'
|
|
4228
|
-
'"
|
|
4229
|
-
'
|
|
4230
|
-
'
|
|
4997
|
+
'causalloop "Startup growth engine"',
|
|
4998
|
+
'"Active users" -> "Word of mouth" : +',
|
|
4999
|
+
'"Word of mouth" -> "New signups" : +',
|
|
5000
|
+
'"New signups" -> "Active users" : +',
|
|
5001
|
+
'"Active users" -> "Server load" : +',
|
|
5002
|
+
'"Server load" -> "App performance" : -',
|
|
5003
|
+
'"App performance" -> "Active users" : + delay',
|
|
5004
|
+
'loop R1 "Viral flywheel"',
|
|
5005
|
+
'loop B1 "Scaling strain"'
|
|
4231
5006
|
],
|
|
4232
5007
|
prefer: [
|
|
4233
|
-
"
|
|
4234
|
-
'
|
|
4235
|
-
|
|
5008
|
+
"Put every polarity after the `->` as `: +` or `: -` \u2014 every causal link must be signed.",
|
|
5009
|
+
'Wrap multi-word variable names in double quotes: `"Active users"`. Single-token names (e.g. `Revenue`) need no quotes.',
|
|
5010
|
+
'Let the engine classify loops R/B automatically \u2014 use `loop R1 "phrase"` only to name a loop it already detected.'
|
|
4236
5011
|
],
|
|
4237
5012
|
avoid: [
|
|
4238
|
-
"Don't
|
|
4239
|
-
"Don't
|
|
5013
|
+
"Don't omit the polarity separator: `A -> B : +` is the canonical form.",
|
|
5014
|
+
"Don't use `s`/`o`/`same`/`opposite` in generated output \u2014 they normalise to `+`/`-` but reduce readability.",
|
|
5015
|
+
"Don't draw boxes around variables \u2014 CLD variables are boxless text labels; there is no shape syntax."
|
|
4240
5016
|
],
|
|
4241
5017
|
repair: [
|
|
4242
|
-
"'
|
|
4243
|
-
"'
|
|
5018
|
+
"'is missing a polarity' -> append `: +` or `: -` after the target variable name.",
|
|
5019
|
+
"'needs at least one causal link' -> add at least one signed link; a document with only `loop` declarations is rejected.",
|
|
5020
|
+
"'malformed link (expected' -> each link line must contain `->` between the source and target variable names."
|
|
4244
5021
|
]
|
|
4245
5022
|
},
|
|
4246
5023
|
markov: {
|
|
4247
5024
|
type: "markov",
|
|
4248
5025
|
header: 'markov "Title"',
|
|
4249
5026
|
mode: "probability-labelled state transitions; engine computes stationary distribution + classification",
|
|
5027
|
+
keywords: 'markov | markovchain ["Title"] \xB7 state <id> ["Label"] [absorbing] \xB7 <from> -> <to> : <prob> (colon form) | <from> -> <to> <prob> (space form) \xB7 layout: ring|layered \xB7 normalize: true|false \xB7 analysis: stationary classify absorbing period all',
|
|
4250
5028
|
forms: [
|
|
4251
5029
|
'markov "Weather"',
|
|
4252
5030
|
"Sunny -> Sunny : 0.9",
|
|
@@ -4255,23 +5033,26 @@ var PROFILES = {
|
|
|
4255
5033
|
"Rainy -> Rainy : 0.5"
|
|
4256
5034
|
],
|
|
4257
5035
|
prefer: [
|
|
4258
|
-
"
|
|
4259
|
-
"
|
|
4260
|
-
"
|
|
5036
|
+
"Write `S1 -> S2 : 0.3` transitions (colon form is canonical); every state's outgoing probabilities must sum to 1 unless `normalize: true` is set.",
|
|
5037
|
+
"Declare absorbing states with the `absorbing` keyword (`state Broke absorbing`); the engine validates it against the computed structure.",
|
|
5038
|
+
"Use `analysis: classify, stationary` for ergodic chains; add `absorbing` for the fundamental matrix, absorption probabilities, and expected steps."
|
|
4261
5039
|
],
|
|
4262
5040
|
avoid: [
|
|
4263
|
-
"Don't let a state's
|
|
4264
|
-
"Don't
|
|
5041
|
+
"Don't let a state's outgoing probabilities sum to anything but 1 \u2014 this hard-errors unless `normalize: true`.",
|
|
5042
|
+
"Don't declare a state `absorbing` unless it has a self-loop of probability 1 and no other out-edges.",
|
|
5043
|
+
"Don't hand-compute the stationary distribution or absorption probabilities \u2014 they are derived."
|
|
4265
5044
|
],
|
|
4266
5045
|
repair: [
|
|
4267
|
-
"'
|
|
4268
|
-
"'
|
|
5046
|
+
"'outgoing probabilities sum to' -> adjust that state's transitions to sum to exactly 1, or add `normalize: true`.",
|
|
5047
|
+
"'is missing a probability' -> add `: <prob>` after the target state id.",
|
|
5048
|
+
"'is declared absorbing but is' -> add `<id> -> <id> : 1` and remove other out-edges, or drop the `absorbing` keyword."
|
|
4269
5049
|
]
|
|
4270
5050
|
},
|
|
4271
5051
|
gitgraph: {
|
|
4272
5052
|
type: "gitgraph",
|
|
4273
5053
|
header: "gitGraph",
|
|
4274
5054
|
mode: "Mermaid-compatible ordered git operations (commit/branch/checkout/merge)",
|
|
5055
|
+
keywords: 'gitGraph [LR:|TB:|BT:] \xB7 commit [id:"\u2026"] [tag:"\u2026"] [type:NORMAL|REVERSE|HIGHLIGHT] \xB7 branch <name> [order:N] \xB7 checkout <name> | switch <name> \xB7 merge <name> [id:"\u2026"] [tag:"\u2026"] \xB7 cherry-pick id:"\u2026" [parent:"\u2026"] \xB7 %% comment \xB7 config: mainBranchName showBranches showCommitLabel',
|
|
4275
5056
|
forms: [
|
|
4276
5057
|
"gitGraph",
|
|
4277
5058
|
' commit id: "init"',
|
|
@@ -4282,136 +5063,168 @@ var PROFILES = {
|
|
|
4282
5063
|
" merge develop"
|
|
4283
5064
|
],
|
|
4284
5065
|
prefer: [
|
|
4285
|
-
|
|
4286
|
-
'Annotate commits with `id: "\u2026"`, `tag: "\u2026"`, `type: HIGHLIGHT
|
|
4287
|
-
"`
|
|
5066
|
+
"Operations must be in execution order: `branch <name>` opens a lane, `checkout <name>` (or `switch`) switches HEAD, `commit` adds a node on the current branch, `merge <name>` merges that branch into the current one.",
|
|
5067
|
+
'Annotate commits with `id: "\u2026"`, `tag: "\u2026"`, and `type: HIGHLIGHT`/`REVERSE`/`NORMAL`; `cherry-pick id: "\u2026"` copies a commit by id.',
|
|
5068
|
+
"Use `gitGraph LR:` (default) for left-to-right time; add `TB:`/`BT:` inline on the header to change orientation."
|
|
4288
5069
|
],
|
|
4289
5070
|
avoid: [
|
|
4290
|
-
"Don't `
|
|
4291
|
-
"Don't merge a branch into itself."
|
|
5071
|
+
"Don't `checkout` or `merge` a branch you have not created with `branch <name>` first.",
|
|
5072
|
+
"Don't `merge` a branch into itself.",
|
|
5073
|
+
"Don't use an option key other than `id`, `tag`, `type`, `order`, `parent`."
|
|
4292
5074
|
],
|
|
4293
5075
|
repair: [
|
|
4294
|
-
"'
|
|
4295
|
-
"'cannot merge
|
|
5076
|
+
"'checkout of undeclared branch' -> add a `branch <name>` operation before the `checkout`.",
|
|
5077
|
+
"'cannot merge branch' into itself -> `checkout` a different branch before the `merge`.",
|
|
5078
|
+
"'cherry-pick of merge commit' requires parent -> add `parent: \"<id>\"` to the `cherry-pick` line."
|
|
4296
5079
|
]
|
|
4297
5080
|
},
|
|
4298
5081
|
epc: {
|
|
4299
5082
|
type: "epc",
|
|
4300
5083
|
header: 'epc "Title"',
|
|
4301
|
-
mode: "alternating events/functions joined by
|
|
5084
|
+
mode: "alternating events/functions joined by and/or/xor connectors; alternation validated",
|
|
5085
|
+
keywords: 'epc ["title"] [layout: tb|lr] \xB7 event ID ["label"] \xB7 function ID ["label"] (alias: func) \xB7 and ID \xB7 or ID \xB7 xor ID \xB7 A -> B (edge, chainable A -> B -> C) \xB7 A -> B : "label" \xB7 rules: strict event/function alternation; start/end are events; an event may not source an OR/XOR split',
|
|
4302
5086
|
forms: [
|
|
4303
5087
|
'epc "Order fulfilment"',
|
|
5088
|
+
" layout: tb",
|
|
4304
5089
|
' event E1 "Order received"',
|
|
4305
5090
|
' function F1 "Check credit"',
|
|
4306
5091
|
" xor X1",
|
|
4307
5092
|
' event E2 "Credit OK"',
|
|
4308
5093
|
' event E3 "Credit rejected"',
|
|
5094
|
+
' function F2 "Ship goods"',
|
|
5095
|
+
' function F3 "Notify customer"',
|
|
5096
|
+
' event E4 "Order shipped"',
|
|
5097
|
+
' event E5 "Order cancelled"',
|
|
4309
5098
|
" E1 -> F1 -> X1",
|
|
4310
5099
|
" X1 -> E2",
|
|
4311
|
-
" X1 -> E3"
|
|
5100
|
+
" X1 -> E3",
|
|
5101
|
+
" E2 -> F2 -> E4",
|
|
5102
|
+
" E3 -> F3 -> E5"
|
|
4312
5103
|
],
|
|
4313
5104
|
prefer: [
|
|
4314
|
-
"
|
|
4315
|
-
"Strictly alternate events and functions
|
|
4316
|
-
"Use a connector node to split
|
|
5105
|
+
"Declare `event`, `function`, and connector (`and`/`or`/`xor`) nodes with ids first; then wire them with `A -> B` edge lines (chainable: `A -> B -> C`).",
|
|
5106
|
+
"Strictly alternate events and functions: every path follows event \u2192 function \u2192 event \u2192 \u2026 Connectors sit between them but the next typed node must be the opposite kind.",
|
|
5107
|
+
"Use a connector node to split or join; place the connector after a function for any OR/XOR split."
|
|
4317
5108
|
],
|
|
4318
5109
|
avoid: [
|
|
4319
|
-
"Don't make an event the source of an
|
|
4320
|
-
"Don't
|
|
5110
|
+
"Don't make an event the source of an `or`/`xor` split \u2014 only a function may precede an OR/XOR split.",
|
|
5111
|
+
"Don't give an event or function more than one outgoing arc without a connector \u2014 the split belongs on a connector.",
|
|
5112
|
+
"Don't connect two events or two functions in sequence without an intervening node."
|
|
4321
5113
|
],
|
|
4322
5114
|
repair: [
|
|
4323
|
-
"'
|
|
4324
|
-
"'
|
|
5115
|
+
"'is the source of a XOR split' -> insert a `function` between the event and the `xor`/`or` connector.",
|
|
5116
|
+
"'must have a single output' -> add an `and`/`or`/`xor` node and route the multiple arcs from the connector.",
|
|
5117
|
+
"'is used in an edge but never declared' -> add the missing `event`/`function`/connector declaration before the edge."
|
|
4325
5118
|
]
|
|
4326
5119
|
},
|
|
4327
5120
|
idef0: {
|
|
4328
5121
|
type: "idef0",
|
|
4329
5122
|
header: 'idef0 "Title"',
|
|
4330
5123
|
mode: "function boxes + positional ICOM arrows (input-left, control-top, output-right, mechanism-bottom)",
|
|
5124
|
+
keywords: 'idef0 ["title"] \xB7 node <id> \xB7 purpose "\u2026" \xB7 viewpoint "\u2026" \xB7 function ID "name" [n:N] \xB7 input ID "label" (left) \xB7 control ID "label" (top) \xB7 output ID "label" (right) \xB7 mechanism ID "label" (bottom) \xB7 call ID "label" \xB7 A1 -> A2 "label" (bare target = .input) \xB7 A1 -> A2.input|.control|.mechanism "label" \xB7 (tunnel) flag \xB7 ICOM codes I1/C1/O1/M1 auto-assigned',
|
|
4331
5125
|
forms: [
|
|
4332
|
-
'idef0 "
|
|
4333
|
-
|
|
4334
|
-
'
|
|
4335
|
-
'
|
|
4336
|
-
'
|
|
4337
|
-
'
|
|
4338
|
-
'
|
|
4339
|
-
'
|
|
5126
|
+
'idef0 "Fulfil customer order"',
|
|
5127
|
+
"node A0",
|
|
5128
|
+
'function A1 "Validate order"',
|
|
5129
|
+
'function A2 "Pick and pack"',
|
|
5130
|
+
'function A3 "Ship and invoice"',
|
|
5131
|
+
'input A1 "Customer order"',
|
|
5132
|
+
'control A1 "Credit policy"',
|
|
5133
|
+
'mechanism A1 "Order management system"',
|
|
5134
|
+
'A1 -> A2 "Validated order"',
|
|
5135
|
+
'mechanism A2 "Warehouse staff"',
|
|
5136
|
+
'A2 -> A3 "Packed shipment"',
|
|
5137
|
+
'output A3 "Delivered order"'
|
|
4340
5138
|
],
|
|
4341
5139
|
prefer: [
|
|
4342
|
-
|
|
4343
|
-
'Box
|
|
4344
|
-
"Remember
|
|
5140
|
+
'Declare `function ID "name"` boxes first; attach boundary arrows with `input`/`control`/`output`/`mechanism` + box id + quoted label. Box numbers and ICOM codes are assigned automatically.',
|
|
5141
|
+
'Box-to-box flow `A1 -> A2 "label"` lands on A2\'s left (`input`) by default; use `A1 -> A2.control "\u2026"` or `A1 -> A2.mechanism "\u2026"` for the top or bottom edge.',
|
|
5142
|
+
"Remember ICOM: Inputs enter left, Controls enter top, Outputs exit right, Mechanisms enter bottom. Use 3\u20136 boxes per diagram (FIPS 183)."
|
|
4345
5143
|
],
|
|
4346
5144
|
avoid: [
|
|
4347
|
-
"Don't
|
|
4348
|
-
"Don't hand-number
|
|
5145
|
+
"Don't land a flow on the target's `.output` edge \u2014 outputs exit a box; use `.input`/`.control`/`.mechanism`.",
|
|
5146
|
+
"Don't hand-number boxes with `n:N` unless you number every box \u2014 mixing explicit and auto numbering is an error.",
|
|
5147
|
+
"Don't reference a box id in an arrow before declaring it with `function`."
|
|
4349
5148
|
],
|
|
4350
5149
|
repair: [
|
|
4351
|
-
"'
|
|
4352
|
-
"'
|
|
5150
|
+
"'arrow references undefined function box' -> add a `function ID \"name\"` line before any arrow that references it.",
|
|
5151
|
+
"'cannot land on the target's .output' -> change `.output` to `.input`, `.control`, or `.mechanism`.",
|
|
5152
|
+
"'must declare at least one' function box -> add at least one `function ID \"name\"` line; a diagram cannot be only arrows."
|
|
4353
5153
|
]
|
|
4354
5154
|
},
|
|
4355
5155
|
threatmodel: {
|
|
4356
5156
|
type: "threatmodel",
|
|
4357
5157
|
header: 'threatmodel "Title"',
|
|
4358
|
-
mode: "DFD elements + data flows + trust boundaries; engine maps STRIDE + flags boundary crossings",
|
|
5158
|
+
mode: "DFD elements + data flows + trust boundaries; engine maps STRIDE-per-element + flags boundary crossings",
|
|
5159
|
+
keywords: 'external: Label | external ID: Label \xB7 process ID: Label \xB7 datastore ID: Label [log|audit|journal -> R auto-enabled] \xB7 A -> B : "label" (label required) \xB7 A <-> B : "label" (bidirectional) \xB7 boundary "Name" { id, id } \xB7 title: "\u2026" \xB7 STRIDE-per-element: external S,R \xB7 process all six \xB7 store T,I,D (R conditional) \xB7 flow T,I,D',
|
|
4359
5160
|
forms: [
|
|
4360
|
-
'threatmodel "
|
|
4361
|
-
"external:
|
|
4362
|
-
"
|
|
4363
|
-
"
|
|
4364
|
-
"
|
|
4365
|
-
"
|
|
4366
|
-
|
|
4367
|
-
'
|
|
5161
|
+
'threatmodel "E-commerce checkout"',
|
|
5162
|
+
"external: Customer",
|
|
5163
|
+
"external Payment_Gateway: Payment Gateway",
|
|
5164
|
+
"process 1.0: Web App",
|
|
5165
|
+
"process 2.0: Order Service",
|
|
5166
|
+
"datastore D1: Orders DB",
|
|
5167
|
+
"datastore D2: Audit Log",
|
|
5168
|
+
'Customer -> 1.0 : "HTTPS Checkout"',
|
|
5169
|
+
'1.0 -> 2.0 : "Place order"',
|
|
5170
|
+
'2.0 -> D1 : "Write order"',
|
|
5171
|
+
'2.0 -> Payment_Gateway : "Charge card"',
|
|
5172
|
+
'boundary "Internet" { Customer, Payment_Gateway }',
|
|
5173
|
+
'boundary "DMZ" { 1.0 }',
|
|
5174
|
+
'boundary "Internal" { 2.0, D1, D2 }'
|
|
4368
5175
|
],
|
|
4369
5176
|
prefer: [
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
"Name audit/log stores with `log`/`audit`/`journal`
|
|
5177
|
+
"Keyword `threatmodel` (alias `stride`). Declare all `external:`, `process ID:`, `datastore ID:` elements first, then flows, then `boundary` groups.",
|
|
5178
|
+
'Every flow `A -> B : "label"` requires a label \u2014 the colon and label are mandatory; use `<->` for a bidirectional shorthand.',
|
|
5179
|
+
"Name audit/log stores with `log`/`audit`/`journal` to auto-enable the conditional Repudiation threat; let the engine annotate STRIDE and flag boundary-crossing flows."
|
|
4373
5180
|
],
|
|
4374
5181
|
avoid: [
|
|
4375
|
-
"Don't connect
|
|
4376
|
-
"Don't
|
|
5182
|
+
"Don't connect `datastore \u2192 datastore` or `external \u2192 external` directly \u2014 both are hard DFD violations.",
|
|
5183
|
+
"Don't omit the `: label` on a flow; a bare `A -> B` line is rejected.",
|
|
5184
|
+
"Don't put an element id in two different `boundary` blocks \u2014 each element belongs to at most one boundary."
|
|
4377
5185
|
],
|
|
4378
5186
|
repair: [
|
|
4379
|
-
|
|
4380
|
-
"'
|
|
5187
|
+
'\'has no label\' -> add `: "label"` after the target id (e.g. `1.0 -> D1 : "Lookup"`).',
|
|
5188
|
+
"'references unknown element' -> declare the `external:`/`process`/`datastore` before the flow that references it.",
|
|
5189
|
+
"'directly to data store' -> route the flow through a `process` node in between.",
|
|
5190
|
+
"'lists unknown element' -> declare the element before the `boundary { \u2026 }` block that references it."
|
|
4381
5191
|
]
|
|
4382
5192
|
},
|
|
4383
5193
|
welding: {
|
|
4384
5194
|
type: "welding",
|
|
4385
5195
|
header: "welding [standard: aws|iso-a|iso-b]",
|
|
4386
5196
|
mode: "reference-line callouts; one joint block per joint, weld glyphs above/below the line",
|
|
5197
|
+
keywords: 'joint "label" { arrow: <weldspec> \xB7 other: <weldspec> \xB7 both: <weldspec> \xB7 around \xB7 field \xB7 tail: "\u2026" } \xB7 weldspec = <type> [size=n] [len=n] [pitch=n] [angle=deg] [root=n] [throat=n] [contour=flush|convex|concave] [finish=G|M|C|R|H|U] \xB7 types: fillet square vgroove bevel ugroove jgroove flarev flarebevel plug slot spot seam back backing surfacing edge \xB7 standard: aws (default) iso-a iso-b',
|
|
4387
5198
|
forms: [
|
|
4388
|
-
'welding "Bracket
|
|
4389
|
-
'joint "
|
|
5199
|
+
'welding "Bracket assembly"',
|
|
5200
|
+
'joint "gusset to column" {',
|
|
4390
5201
|
" arrow: fillet size=8 len=50 pitch=150",
|
|
4391
5202
|
" other: fillet size=6",
|
|
4392
5203
|
" around",
|
|
4393
5204
|
" field",
|
|
4394
|
-
' tail: "
|
|
5205
|
+
' tail: "GMAW"',
|
|
4395
5206
|
"}",
|
|
4396
|
-
'joint "butt
|
|
4397
|
-
" arrow: vgroove angle=60 root=3 throat=12",
|
|
5207
|
+
'joint "splice plate (butt)" {',
|
|
5208
|
+
" arrow: vgroove angle=60 root=3 throat=12 contour=flush finish=G",
|
|
4398
5209
|
" other: backing",
|
|
5210
|
+
' tail: "SMAW; E7018"',
|
|
4399
5211
|
"}"
|
|
4400
5212
|
],
|
|
4401
5213
|
prefer: [
|
|
4402
|
-
'
|
|
4403
|
-
"A weldspec is `<type> key=value \u2026`: `size=` (
|
|
4404
|
-
'
|
|
4405
|
-
"
|
|
5214
|
+
'One `joint "label" { \u2026 }` block per joint. Weld sides are `arrow:` (arrow side), `other:` (other side), or `both:` (same spec both sides).',
|
|
5215
|
+
"A weldspec is `<type> key=value \u2026`: `size=` (leg size / plug diameter), `len=`/`pitch=` (intermittent), `angle=`/`root=` (groove only), `throat=`, `contour=flush|convex|concave`, `finish=G|M|C|R|H|U`.",
|
|
5216
|
+
'Supplementary symbols on their own line inside the joint: `around` (weld-all-around), `field` (site weld). Process/spec/NDE goes in `tail: "GTAW; WPS-12"`.',
|
|
5217
|
+
"Choose `standard: iso-a` for the dual solid+dashed reference line; default `aws` uses a single line."
|
|
4406
5218
|
],
|
|
4407
5219
|
avoid: [
|
|
4408
|
-
"Don't put `angle=` on a fillet
|
|
4409
|
-
"Don't use `both:` for plug
|
|
4410
|
-
"Don't give a fillet without `size=`, or a `pitch=` without `len
|
|
5220
|
+
"Don't put `angle=` on a `fillet`, `plug`, `spot`, or `seam` \u2014 angle is groove-only (the engine warns).",
|
|
5221
|
+
"Don't use `both:` for `plug`, `slot`, or `surfacing` \u2014 those are single-side; `surfacing` is arrow-side only.",
|
|
5222
|
+
"Don't give a `fillet` without `size=`, or a `pitch=` without `len=` (an intermittent weld is length-pitch)."
|
|
4411
5223
|
],
|
|
4412
5224
|
repair: [
|
|
4413
|
-
"'a fillet weld needs a leg size'
|
|
4414
|
-
"'angle= only applies to groove welds'
|
|
5225
|
+
"'a fillet weld needs a leg size' -> add `size=N` to the fillet weldspec (e.g. `arrow: fillet size=8`).",
|
|
5226
|
+
"'angle= only applies to groove welds' -> drop `angle=`, or change the type to a groove such as `vgroove`.",
|
|
5227
|
+
"'pitch= needs a length=' -> add `len=N` alongside `pitch=N` on the same weldspec."
|
|
4415
5228
|
]
|
|
4416
5229
|
}
|
|
4417
5230
|
};
|
|
@@ -4441,6 +5254,7 @@ function buildCanonicalSyntax(profile) {
|
|
|
4441
5254
|
`- Canonical type: \`${profile.type}\``,
|
|
4442
5255
|
`- Canonical header: \`${profile.header}\``,
|
|
4443
5256
|
`- Preferred mode: ${profile.mode}`,
|
|
5257
|
+
profile.keywords ? `- Keywords: ${profile.keywords}` : "",
|
|
4444
5258
|
bulletSection("Core forms", profile.forms),
|
|
4445
5259
|
bulletSection("Prefer", profile.prefer),
|
|
4446
5260
|
bulletSection("Avoid by default", profile.avoid),
|
|
@@ -4462,7 +5276,9 @@ function listDiagrams() {
|
|
|
4462
5276
|
tagline: d.tagline,
|
|
4463
5277
|
useWhen: d.useWhen,
|
|
4464
5278
|
cluster: d.cluster,
|
|
4465
|
-
standard: d.standard
|
|
5279
|
+
standard: d.standard,
|
|
5280
|
+
...d.aliases ? { aliases: d.aliases } : {},
|
|
5281
|
+
...d.keywords ? { keywords: d.keywords } : {}
|
|
4466
5282
|
}));
|
|
4467
5283
|
}
|
|
4468
5284
|
function getSyntax(type, opts = {}) {
|
|
@@ -4551,18 +5367,27 @@ function toValidationError(diagnostic, type) {
|
|
|
4551
5367
|
column: diagnostic.column,
|
|
4552
5368
|
source: diagnostic.source,
|
|
4553
5369
|
message: diagnostic.message,
|
|
4554
|
-
hint: diagnostic.hint ?? repairHint(type)
|
|
5370
|
+
hint: diagnostic.hint ?? repairHint(type, diagnostic.message)
|
|
4555
5371
|
};
|
|
4556
5372
|
}
|
|
4557
|
-
function repairHint(type) {
|
|
5373
|
+
function repairHint(type, message) {
|
|
4558
5374
|
const resolved = type ? resolveDiagramType(type) : void 0;
|
|
4559
5375
|
const profile = resolved ? getGenerationProfile(resolved) : void 0;
|
|
4560
|
-
const typeHint = profile?.repair[0];
|
|
5376
|
+
const typeHint = message ? profile ? matchRepair(profile.repair, message) : void 0 : profile?.repair[0];
|
|
4561
5377
|
return [
|
|
4562
5378
|
typeHint,
|
|
4563
5379
|
"Fix the reported DSL error, then call validateDsl again before rendering or returning DSL."
|
|
4564
5380
|
].filter(Boolean).join(" ");
|
|
4565
5381
|
}
|
|
5382
|
+
function matchRepair(repairs, message) {
|
|
5383
|
+
for (const r of repairs) {
|
|
5384
|
+
const quoted = r.match(/^['"]([^'"]+)['"]/);
|
|
5385
|
+
if (!quoted) continue;
|
|
5386
|
+
const fragment = quoted[1].split(":")[0].trim();
|
|
5387
|
+
if (fragment.length >= 6 && message.includes(fragment)) return r;
|
|
5388
|
+
}
|
|
5389
|
+
return void 0;
|
|
5390
|
+
}
|
|
4566
5391
|
|
|
4567
5392
|
exports.DIAGRAM_REGISTRY = DIAGRAM_REGISTRY;
|
|
4568
5393
|
exports.DIAGRAM_SINCE = DIAGRAM_SINCE;
|
|
@@ -4575,5 +5400,5 @@ exports.listDiagrams = listDiagrams;
|
|
|
4575
5400
|
exports.renderDsl = renderDsl;
|
|
4576
5401
|
exports.resolveDiagramType = resolveDiagramType;
|
|
4577
5402
|
exports.validateDsl = validateDsl;
|
|
4578
|
-
//# sourceMappingURL=chunk-
|
|
4579
|
-
//# sourceMappingURL=chunk-
|
|
5403
|
+
//# sourceMappingURL=chunk-HKOPXQYU.cjs.map
|
|
5404
|
+
//# sourceMappingURL=chunk-HKOPXQYU.cjs.map
|