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
|
@@ -347,7 +347,18 @@ var DIAGRAM_REGISTRY = [
|
|
|
347
347
|
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.",
|
|
348
348
|
cluster: "risk-reliability",
|
|
349
349
|
standard: "IEC 62502:2010 \xB7 NUREG/CR-2300 (PRA) \xB7 ISO 31010 Annex B; see 39-EVENT-TREE-STANDARD.md",
|
|
350
|
-
syntaxKey: "eventtree"
|
|
350
|
+
syntaxKey: "eventtree",
|
|
351
|
+
aliases: ["Event Tree Analysis", "ETA diagram", "event tree", "\u4E8B\u4EF6\u6811\u5206\u6790"],
|
|
352
|
+
keywords: [
|
|
353
|
+
"probabilistic risk assessment",
|
|
354
|
+
"PRA",
|
|
355
|
+
"safety function",
|
|
356
|
+
"accident sequence",
|
|
357
|
+
"barrier analysis",
|
|
358
|
+
"consequence analysis",
|
|
359
|
+
"nuclear safety",
|
|
360
|
+
"IEC 62502"
|
|
361
|
+
]
|
|
351
362
|
},
|
|
352
363
|
{
|
|
353
364
|
type: "fmea",
|
|
@@ -356,7 +367,25 @@ var DIAGRAM_REGISTRY = [
|
|
|
356
367
|
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.",
|
|
357
368
|
cluster: "risk-reliability",
|
|
358
369
|
standard: "AIAG-VDA FMEA Handbook (2019) \xB7 IEC 60812:2018 \xB7 SAE J1739 \xB7 MIL-STD-1629A; see 40-FMEA-STANDARD.md",
|
|
359
|
-
syntaxKey: "fmea"
|
|
370
|
+
syntaxKey: "fmea",
|
|
371
|
+
aliases: [
|
|
372
|
+
"FMEA",
|
|
373
|
+
"Failure Mode and Effects Analysis",
|
|
374
|
+
"FMECA",
|
|
375
|
+
"failure mode analysis",
|
|
376
|
+
"\u6545\u969C\u6A21\u5F0F\u4E0E\u5F71\u54CD\u5206\u6790"
|
|
377
|
+
],
|
|
378
|
+
keywords: [
|
|
379
|
+
"RPN",
|
|
380
|
+
"risk priority number",
|
|
381
|
+
"Action Priority",
|
|
382
|
+
"AIAG-VDA",
|
|
383
|
+
"DFMEA",
|
|
384
|
+
"PFMEA",
|
|
385
|
+
"severity occurrence detection",
|
|
386
|
+
"reliability engineering",
|
|
387
|
+
"IEC 60812"
|
|
388
|
+
]
|
|
360
389
|
},
|
|
361
390
|
// ── Systems thinking / stochastic ────────────────────────────
|
|
362
391
|
{
|
|
@@ -366,7 +395,23 @@ var DIAGRAM_REGISTRY = [
|
|
|
366
395
|
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).',
|
|
367
396
|
cluster: "causality-analysis",
|
|
368
397
|
standard: "Sterman, Business Dynamics (2000) \xB7 Meadows, Thinking in Systems; see 41-CAUSAL-LOOP-STANDARD.md",
|
|
369
|
-
syntaxKey: "causalloop"
|
|
398
|
+
syntaxKey: "causalloop",
|
|
399
|
+
aliases: [
|
|
400
|
+
"Causal Loop Diagram",
|
|
401
|
+
"CLD",
|
|
402
|
+
"feedback loop diagram",
|
|
403
|
+
"systems thinking diagram",
|
|
404
|
+
"\u56E0\u679C\u56DE\u8DEF\u56FE"
|
|
405
|
+
],
|
|
406
|
+
keywords: [
|
|
407
|
+
"system dynamics",
|
|
408
|
+
"reinforcing loop",
|
|
409
|
+
"balancing loop",
|
|
410
|
+
"feedback loop",
|
|
411
|
+
"stock and flow",
|
|
412
|
+
"Sterman",
|
|
413
|
+
"Meadows"
|
|
414
|
+
]
|
|
370
415
|
},
|
|
371
416
|
{
|
|
372
417
|
type: "markov",
|
|
@@ -375,7 +420,22 @@ var DIAGRAM_REGISTRY = [
|
|
|
375
420
|
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`.",
|
|
376
421
|
cluster: "behavior-modeling",
|
|
377
422
|
standard: "Norris, Markov Chains (1997) \xB7 Kemeny & Snell, Finite Markov Chains; see 42-MARKOV-CHAIN-STANDARD.md",
|
|
378
|
-
syntaxKey: "markov"
|
|
423
|
+
syntaxKey: "markov",
|
|
424
|
+
aliases: [
|
|
425
|
+
"Markov chain",
|
|
426
|
+
"Markov chain diagram",
|
|
427
|
+
"stochastic state transition diagram",
|
|
428
|
+
"\u9A6C\u5C14\u53EF\u592B\u94FE"
|
|
429
|
+
],
|
|
430
|
+
keywords: [
|
|
431
|
+
"stationary distribution",
|
|
432
|
+
"stochastic process",
|
|
433
|
+
"transition matrix",
|
|
434
|
+
"transition probability",
|
|
435
|
+
"absorbing state",
|
|
436
|
+
"steady state",
|
|
437
|
+
"discrete-time"
|
|
438
|
+
]
|
|
379
439
|
},
|
|
380
440
|
// ── Software / process engineering ───────────────────────────
|
|
381
441
|
{
|
|
@@ -385,7 +445,23 @@ var DIAGRAM_REGISTRY = [
|
|
|
385
445
|
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.',
|
|
386
446
|
cluster: "software-uml",
|
|
387
447
|
standard: "Mermaid gitGraph syntax \xB7 git DAG model; see 43-GIT-GRAPH-STANDARD.md",
|
|
388
|
-
syntaxKey: "gitgraph"
|
|
448
|
+
syntaxKey: "gitgraph",
|
|
449
|
+
aliases: [
|
|
450
|
+
"Git commit graph",
|
|
451
|
+
"git graph",
|
|
452
|
+
"git branch diagram",
|
|
453
|
+
"branching diagram",
|
|
454
|
+
"Git \u63D0\u4EA4\u56FE"
|
|
455
|
+
],
|
|
456
|
+
keywords: [
|
|
457
|
+
"branching strategy",
|
|
458
|
+
"git history",
|
|
459
|
+
"merge",
|
|
460
|
+
"cherry-pick",
|
|
461
|
+
"GitFlow",
|
|
462
|
+
"Mermaid gitGraph",
|
|
463
|
+
"commit history"
|
|
464
|
+
]
|
|
389
465
|
},
|
|
390
466
|
{
|
|
391
467
|
type: "epc",
|
|
@@ -394,7 +470,22 @@ var DIAGRAM_REGISTRY = [
|
|
|
394
470
|
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.",
|
|
395
471
|
cluster: "corporate-legal",
|
|
396
472
|
standard: "ARIS / Keller, N\xFCttgens & Scheer (1992); see 44-EPC-STANDARD.md",
|
|
397
|
-
syntaxKey: "epc"
|
|
473
|
+
syntaxKey: "epc",
|
|
474
|
+
aliases: [
|
|
475
|
+
"Event-driven Process Chain",
|
|
476
|
+
"EPC diagram",
|
|
477
|
+
"ARIS EPC",
|
|
478
|
+
"\u4E8B\u4EF6\u9A71\u52A8\u8FC7\u7A0B\u94FE"
|
|
479
|
+
],
|
|
480
|
+
keywords: [
|
|
481
|
+
"ARIS",
|
|
482
|
+
"business process modeling",
|
|
483
|
+
"SAP",
|
|
484
|
+
"BPM",
|
|
485
|
+
"process chain",
|
|
486
|
+
"enterprise architecture",
|
|
487
|
+
"Scheer"
|
|
488
|
+
]
|
|
398
489
|
},
|
|
399
490
|
{
|
|
400
491
|
type: "idef0",
|
|
@@ -403,7 +494,23 @@ var DIAGRAM_REGISTRY = [
|
|
|
403
494
|
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.",
|
|
404
495
|
cluster: "project-management",
|
|
405
496
|
standard: "FIPS PUB 183 (1993) \xB7 SADT (Ross); see 45-IDEF0-STANDARD.md",
|
|
406
|
-
syntaxKey: "idef0"
|
|
497
|
+
syntaxKey: "idef0",
|
|
498
|
+
aliases: [
|
|
499
|
+
"IDEF0",
|
|
500
|
+
"IDEF0 function model",
|
|
501
|
+
"SADT diagram",
|
|
502
|
+
"function model",
|
|
503
|
+
"ICOM diagram"
|
|
504
|
+
],
|
|
505
|
+
keywords: [
|
|
506
|
+
"functional modeling",
|
|
507
|
+
"FIPS 183",
|
|
508
|
+
"systems engineering",
|
|
509
|
+
"activity model",
|
|
510
|
+
"ICOM",
|
|
511
|
+
"process model",
|
|
512
|
+
"enterprise architecture"
|
|
513
|
+
]
|
|
407
514
|
},
|
|
408
515
|
{
|
|
409
516
|
type: "threatmodel",
|
|
@@ -412,7 +519,25 @@ var DIAGRAM_REGISTRY = [
|
|
|
412
519
|
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).",
|
|
413
520
|
cluster: "network-infrastructure",
|
|
414
521
|
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",
|
|
415
|
-
syntaxKey: "threatmodel"
|
|
522
|
+
syntaxKey: "threatmodel",
|
|
523
|
+
aliases: [
|
|
524
|
+
"Threat model",
|
|
525
|
+
"STRIDE diagram",
|
|
526
|
+
"DFD threat model",
|
|
527
|
+
"data flow diagram",
|
|
528
|
+
"DFD",
|
|
529
|
+
"\u5A01\u80C1\u5EFA\u6A21"
|
|
530
|
+
],
|
|
531
|
+
keywords: [
|
|
532
|
+
"STRIDE",
|
|
533
|
+
"security threat modeling",
|
|
534
|
+
"Microsoft SDL",
|
|
535
|
+
"OWASP Threat Dragon",
|
|
536
|
+
"trust boundary",
|
|
537
|
+
"attack surface",
|
|
538
|
+
"application security",
|
|
539
|
+
"Shostack"
|
|
540
|
+
]
|
|
416
541
|
},
|
|
417
542
|
{
|
|
418
543
|
type: "welding",
|
|
@@ -421,7 +546,24 @@ var DIAGRAM_REGISTRY = [
|
|
|
421
546
|
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.',
|
|
422
547
|
cluster: "electrical-industrial",
|
|
423
548
|
standard: "AWS A2.4:2020 \xB7 ISO 2553:2019; see 47-WELDING-SYMBOL-STANDARD.md",
|
|
424
|
-
syntaxKey: "welding"
|
|
549
|
+
syntaxKey: "welding",
|
|
550
|
+
aliases: [
|
|
551
|
+
"Welding symbols",
|
|
552
|
+
"weld symbol",
|
|
553
|
+
"welding callout",
|
|
554
|
+
"weld joint symbol",
|
|
555
|
+
"\u710A\u63A5\u7B26\u53F7"
|
|
556
|
+
],
|
|
557
|
+
keywords: [
|
|
558
|
+
"AWS A2.4",
|
|
559
|
+
"ISO 2553",
|
|
560
|
+
"fillet weld",
|
|
561
|
+
"groove weld",
|
|
562
|
+
"weld notation",
|
|
563
|
+
"engineering drawing",
|
|
564
|
+
"fabrication",
|
|
565
|
+
"weld dimensions"
|
|
566
|
+
]
|
|
425
567
|
}
|
|
426
568
|
];
|
|
427
569
|
var DIAGRAM_SINCE = {
|
|
@@ -544,7 +686,7 @@ var EXAMPLES = [
|
|
|
544
686
|
"signal-flow"
|
|
545
687
|
],
|
|
546
688
|
"complexity": 2,
|
|
547
|
-
"featured":
|
|
689
|
+
"featured": true,
|
|
548
690
|
"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',
|
|
549
691
|
"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.'
|
|
550
692
|
},
|
|
@@ -780,7 +922,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
780
922
|
"balancing"
|
|
781
923
|
],
|
|
782
924
|
"complexity": 3,
|
|
783
|
-
"featured":
|
|
925
|
+
"featured": true,
|
|
784
926
|
"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"',
|
|
785
927
|
"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.'
|
|
786
928
|
},
|
|
@@ -817,7 +959,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
817
959
|
"netlist"
|
|
818
960
|
],
|
|
819
961
|
"complexity": 2,
|
|
820
|
-
"featured":
|
|
962
|
+
"featured": true,
|
|
821
963
|
"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',
|
|
822
964
|
"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`."
|
|
823
965
|
},
|
|
@@ -1107,7 +1249,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1107
1249
|
"control-flow"
|
|
1108
1250
|
],
|
|
1109
1251
|
"complexity": 3,
|
|
1110
|
-
"featured":
|
|
1252
|
+
"featured": true,
|
|
1111
1253
|
"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',
|
|
1112
1254
|
"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.'
|
|
1113
1255
|
},
|
|
@@ -1219,7 +1361,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1219
1361
|
"core-damage"
|
|
1220
1362
|
],
|
|
1221
1363
|
"complexity": 3,
|
|
1222
|
-
"featured":
|
|
1364
|
+
"featured": true,
|
|
1223
1365
|
"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"',
|
|
1224
1366
|
"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.'
|
|
1225
1367
|
},
|
|
@@ -1463,7 +1605,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1463
1605
|
"automotive"
|
|
1464
1606
|
],
|
|
1465
1607
|
"complexity": 3,
|
|
1466
|
-
"featured":
|
|
1608
|
+
"featured": true,
|
|
1467
1609
|
"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',
|
|
1468
1610
|
"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."
|
|
1469
1611
|
},
|
|
@@ -1590,7 +1732,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1590
1732
|
"hotfix"
|
|
1591
1733
|
],
|
|
1592
1734
|
"complexity": 3,
|
|
1593
|
-
"featured":
|
|
1735
|
+
"featured": true,
|
|
1594
1736
|
"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',
|
|
1595
1737
|
"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."
|
|
1596
1738
|
},
|
|
@@ -1609,7 +1751,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1609
1751
|
"structured-analysis"
|
|
1610
1752
|
],
|
|
1611
1753
|
"complexity": 3,
|
|
1612
|
-
"featured":
|
|
1754
|
+
"featured": true,
|
|
1613
1755
|
"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"',
|
|
1614
1756
|
"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.'
|
|
1615
1757
|
},
|
|
@@ -1738,7 +1880,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
1738
1880
|
"steady-state"
|
|
1739
1881
|
],
|
|
1740
1882
|
"complexity": 2,
|
|
1741
|
-
"featured":
|
|
1883
|
+
"featured": true,
|
|
1742
1884
|
"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',
|
|
1743
1885
|
"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."
|
|
1744
1886
|
},
|
|
@@ -2494,7 +2636,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
2494
2636
|
"color-coding"
|
|
2495
2637
|
],
|
|
2496
2638
|
"complexity": 3,
|
|
2497
|
-
"featured":
|
|
2639
|
+
"featured": true,
|
|
2498
2640
|
"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"',
|
|
2499
2641
|
"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.'
|
|
2500
2642
|
},
|
|
@@ -3099,7 +3241,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
3099
3241
|
"data-flow"
|
|
3100
3242
|
],
|
|
3101
3243
|
"complexity": 3,
|
|
3102
|
-
"featured":
|
|
3244
|
+
"featured": true,
|
|
3103
3245
|
"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 }',
|
|
3104
3246
|
"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-*`."
|
|
3105
3247
|
},
|
|
@@ -3172,7 +3314,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
3172
3314
|
"bus-read"
|
|
3173
3315
|
],
|
|
3174
3316
|
"complexity": 1,
|
|
3175
|
-
"featured":
|
|
3317
|
+
"featured": true,
|
|
3176
3318
|
"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"]',
|
|
3177
3319
|
"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."
|
|
3178
3320
|
},
|
|
@@ -3400,7 +3542,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
3400
3542
|
"fabrication"
|
|
3401
3543
|
],
|
|
3402
3544
|
"complexity": 3,
|
|
3403
|
-
"featured":
|
|
3545
|
+
"featured": true,
|
|
3404
3546
|
"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}',
|
|
3405
3547
|
"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."
|
|
3406
3548
|
}
|
|
@@ -3628,280 +3770,696 @@ var PROFILES = {
|
|
|
3628
3770
|
genogram: {
|
|
3629
3771
|
type: "genogram",
|
|
3630
3772
|
header: 'genogram "Title"',
|
|
3631
|
-
mode: "
|
|
3773
|
+
mode: "individual declarations + couple lines + indented children",
|
|
3774
|
+
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',
|
|
3632
3775
|
forms: [
|
|
3633
|
-
"
|
|
3634
|
-
|
|
3635
|
-
"
|
|
3776
|
+
'genogram "Smith Family"',
|
|
3777
|
+
" john [male, 1975]",
|
|
3778
|
+
" mary [female, 1977]",
|
|
3779
|
+
' john -- mary "m. 2002"',
|
|
3780
|
+
" alice [female, 2005, index]",
|
|
3781
|
+
" john -conflict- mary"
|
|
3782
|
+
],
|
|
3783
|
+
prefer: [
|
|
3784
|
+
"Declare every individual (`id [sex, year, attrs]`) before any couple or emotional line that references them.",
|
|
3785
|
+
"Use couple operators `--` (married), `~/~` (cohabiting-ended), `~x~` (divorced), `-/-` (separated), `==` (consanguineous), `~` (cohabiting) on their own line; indent children beneath.",
|
|
3786
|
+
"Annotate conditions as `conditions: name(fill, #color) + name2(fill2)`, e.g. `conditions: diabetes(half-left, #ff9800) + cancer(quad-tr, #9c27b0)`.",
|
|
3787
|
+
"Mark the identified patient with the `index` attribute so the concentric double-border is drawn."
|
|
3636
3788
|
],
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3789
|
+
avoid: [
|
|
3790
|
+
"Don't use pedigree genetic-status tokens (`affected`, `carrier`, `proband`) in a genogram \u2014 use `conditions:` fill patterns instead.",
|
|
3791
|
+
'Don\'t attach emotional-operator labels with `[label:]`; place the optional quoted label after the right-hand id: `john -conflict- mary "ongoing"`.',
|
|
3792
|
+
"Don't invent fill patterns \u2014 use only `full`, `half-left/right/top/bottom`, `quad-tl/tr/bl/br`, `quarter`, `striped`, `dotted`."
|
|
3793
|
+
],
|
|
3794
|
+
repair: [
|
|
3795
|
+
"'Unknown individual' -> declare `id [sex]` before any couple or emotional line that references that id.",
|
|
3796
|
+
"'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.",
|
|
3797
|
+
"'Conflicting sex for' -> an individual was declared with two different sexes \u2014 keep sex in the first declaration only.",
|
|
3798
|
+
"'Invalid birth status' -> `birth:` accepts only `legitimate`, `out-of-wedlock`, or `adopted`."
|
|
3799
|
+
]
|
|
3640
3800
|
},
|
|
3641
3801
|
ecomap: {
|
|
3642
3802
|
type: "ecomap",
|
|
3643
3803
|
header: 'ecomap "Title"',
|
|
3644
|
-
mode: "center + external systems",
|
|
3804
|
+
mode: "center declaration + external systems + connection operators",
|
|
3805
|
+
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',
|
|
3645
3806
|
forms: [
|
|
3646
|
-
'
|
|
3647
|
-
'
|
|
3648
|
-
'
|
|
3807
|
+
'ecomap "Marcus, age 15"',
|
|
3808
|
+
' center: client [label: "Marcus"]',
|
|
3809
|
+
' mom [label: "Mother", category: family]',
|
|
3810
|
+
' school [label: "East High School", category: education]',
|
|
3811
|
+
' therapist [label: "Ms. Chen", category: mental-health]',
|
|
3812
|
+
' mom === client [label: "primary caregiver"]',
|
|
3813
|
+
" school === client",
|
|
3814
|
+
' therapist <-> client [label: "weekly"]'
|
|
3815
|
+
],
|
|
3816
|
+
prefer: [
|
|
3817
|
+
"Declare exactly one `center: ID [props]` first; this is the central individual or family unit.",
|
|
3818
|
+
'Declare all external systems (`ID [label: "\u2026", category: \u2026]`) before their connection lines.',
|
|
3819
|
+
"Choose connection strength from `===` (strong), `==` (moderate), `---` (normal), `~~~` (stressful), `-/-` (broken); add a directional arrow variant (`-->`, `<->`, `==>`) when energy-flow direction matters."
|
|
3820
|
+
],
|
|
3821
|
+
avoid: [
|
|
3822
|
+
"Don't use genogram couple operators (`--`, `~/~`) inside an ecomap \u2014 they are not connection operators here.",
|
|
3823
|
+
"Don't omit the `center:` line; a diagram with no center is structurally invalid even if it renders.",
|
|
3824
|
+
"Don't nest family members under `center:` like a genogram; the ecomap center is a single node (use `sociogram` for network structure)."
|
|
3649
3825
|
],
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3826
|
+
repair: [
|
|
3827
|
+
"'Unexpected:' -> the line is not a center declaration, a system declaration, or a valid connection \u2014 check operator spelling (`~x~` has the letter x).",
|
|
3828
|
+
"'Expected ecomap header' -> the first non-blank line must start with `ecomap`; add or fix the header.",
|
|
3829
|
+
'A connection to an undeclared id silently creates a stray node \u2014 declare `systemId [label: "\u2026"]` before the connection line.'
|
|
3830
|
+
]
|
|
3653
3831
|
},
|
|
3654
3832
|
pedigree: {
|
|
3655
3833
|
type: "pedigree",
|
|
3656
3834
|
header: 'pedigree "Title"',
|
|
3657
|
-
mode: "
|
|
3835
|
+
mode: "individual declarations + couple lines + indented offspring (NSGC notation)",
|
|
3836
|
+
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',
|
|
3658
3837
|
forms: [
|
|
3659
|
-
"
|
|
3660
|
-
"
|
|
3661
|
-
"
|
|
3838
|
+
'pedigree "Hemophilia A"',
|
|
3839
|
+
" I-1 [male, unaffected]",
|
|
3840
|
+
" I-2 [female, carrier-x]",
|
|
3841
|
+
" I-1 -- I-2",
|
|
3842
|
+
" II-1 [male, affected]",
|
|
3843
|
+
" II-2 [female, carrier-x]",
|
|
3844
|
+
" II-3 [male, unaffected]"
|
|
3845
|
+
],
|
|
3846
|
+
prefer: [
|
|
3847
|
+
"Use Roman-numeral generation labels (`I-1`, `II-3`) for individual ids \u2014 the NSGC clinical convention.",
|
|
3848
|
+
"Declare genetic status on each individual: `affected`, `carrier`, `carrier-x` (X-linked dot), `obligate-carrier`, `presymptomatic`, or `unaffected`.",
|
|
3849
|
+
"Mark the index case with `proband`; mark a family member seeking advice with `consultand`."
|
|
3662
3850
|
],
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3851
|
+
avoid: [
|
|
3852
|
+
"Don't use genogram emotional-relationship operators (`-conflict-`, `-abuse->`) in a pedigree \u2014 only couple and parent-child lines are valid.",
|
|
3853
|
+
"Don't mix pedigree status with genogram `conditions:` fill syntax; pedigree uses `affected`/`carrier` tokens, not `conditions:name(fill)`.",
|
|
3854
|
+
"Don't invent sex tokens; valid values are `male`, `female`, `unknown`, `amab`, `afab`, `uaab`."
|
|
3855
|
+
],
|
|
3856
|
+
repair: [
|
|
3857
|
+
"'Unknown individual' -> declare `id [sex, geneticStatus]` before any couple line that references that id.",
|
|
3858
|
+
"'Expected pedigree header' -> the first non-blank line must start with `pedigree`; the optional `:mode` suffix and title follow.",
|
|
3859
|
+
"'Conflicting' -> keep one canonical declaration per individual; redeclarations should add only the missing couple reference."
|
|
3860
|
+
]
|
|
3666
3861
|
},
|
|
3667
3862
|
phylo: {
|
|
3668
3863
|
type: "phylo",
|
|
3669
3864
|
header: 'phylo "Title"',
|
|
3670
|
-
mode: "
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3865
|
+
mode: "Newick string (newick:) or indented-tree DSL, with optional clade highlights",
|
|
3866
|
+
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)',
|
|
3867
|
+
forms: [
|
|
3868
|
+
'phylo "Bacterial Diversity"',
|
|
3869
|
+
' newick: "((Ecoli:0.1,Salmonella:0.12):0.05,Vibrio:0.2);"',
|
|
3870
|
+
' clade Gamma = (Ecoli, Salmonella, Vibrio) [color: "#1E88E5", label: "Gammaproteobacteria"]',
|
|
3871
|
+
' scale "substitutions/site"'
|
|
3872
|
+
],
|
|
3873
|
+
prefer: [
|
|
3874
|
+
'Use `newick: "\u2026"` for first-shot generation \u2014 a Newick string with branch lengths (`Name:length`); NHX annotations `[&&NHX:B=98]` carry bootstrap values.',
|
|
3875
|
+
'Add `clade ID = (leaf1, leaf2, \u2026) [color: "#hex", label: "\u2026"]` after the newick line to highlight named clades.',
|
|
3876
|
+
'Use `[mode: chronogram, mrsd: "YYYY"]` for time-calibrated trees and `[mode: cladogram]` when branch lengths are absent.'
|
|
3877
|
+
],
|
|
3878
|
+
avoid: [
|
|
3879
|
+
"Don't use the indent-tree mode (`root:` + indented names) for first-shot generation \u2014 Newick is more compact.",
|
|
3880
|
+
"Don't omit branch lengths in phylogram mode; without them the layout collapses (use `[mode: cladogram]` explicitly instead).",
|
|
3881
|
+
"Don't reference clade member names that don't match the Newick leaf labels exactly \u2014 highlighting silently does nothing on a mismatch."
|
|
3882
|
+
],
|
|
3883
|
+
repair: [
|
|
3884
|
+
"'No tree definition found (newick: or indent tree)' -> add a `newick: \"\u2026;\"` line or an indent tree starting with `root:` after the header.",
|
|
3885
|
+
"'Empty indent tree definition' -> the `root:` block has no indented content \u2014 add at least one child line.",
|
|
3886
|
+
"If clade colors don't appear, check every member id in `clade X = (\u2026)` exactly matches a leaf label in the Newick string."
|
|
3887
|
+
]
|
|
3675
3888
|
},
|
|
3676
3889
|
sociogram: {
|
|
3677
3890
|
type: "sociogram",
|
|
3678
3891
|
header: 'sociogram "Title"',
|
|
3679
|
-
mode: "declared nodes +
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3892
|
+
mode: "declared nodes + edge operators + config",
|
|
3893
|
+
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',
|
|
3894
|
+
forms: [
|
|
3895
|
+
'alice [label: "Alice"] [role: star]',
|
|
3896
|
+
'bob [label: "Bob"] [group: teamA]',
|
|
3897
|
+
'group teamA [label: "Team A", color: "#1976D2"]',
|
|
3898
|
+
" alice; bob",
|
|
3899
|
+
'alice <-> bob [label: "study partners"]',
|
|
3900
|
+
'carol -x> dave [label: "conflict"]',
|
|
3901
|
+
"config: layout = force-directed"
|
|
3902
|
+
],
|
|
3903
|
+
prefer: [
|
|
3904
|
+
"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.",
|
|
3905
|
+
"Use `group id [label:\u2026]` + indented members to cluster nodes; coloring follows when `config: coloring = group` is set.",
|
|
3906
|
+
"Pick the edge operator by valence: `->`/`<->`/`--` positive, `-x>`/`-x-` negative (rejection/conflict), `-.>`/`-.-` neutral; heavier `==>`/`===` encode strong-weight ties."
|
|
3907
|
+
],
|
|
3908
|
+
avoid: [
|
|
3909
|
+
"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.",
|
|
3910
|
+
"Don't set `config: layout` to an unsupported value \u2014 only `circular`, `force-directed`, `concentric` are accepted; unknown values are silently ignored.",
|
|
3911
|
+
"Don't omit the spaces around an edge operator: `alice->bob` is not parsed; it must be `alice -> bob`."
|
|
3912
|
+
],
|
|
3913
|
+
repair: [
|
|
3914
|
+
"'Sociogram must start with' -> the first non-blank line must be `sociogram` (optionally with a quoted title); fix a missing or misspelled header.",
|
|
3915
|
+
'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.',
|
|
3916
|
+
"An unrecognised `config:` value (e.g. `layout = radial`) is silently dropped and defaults to `circular` \u2014 check spelling against the accepted enum."
|
|
3917
|
+
]
|
|
3684
3918
|
},
|
|
3685
3919
|
timing: {
|
|
3686
3920
|
type: "timing",
|
|
3687
3921
|
header: 'timing "Title"',
|
|
3688
3922
|
mode: "WaveDrom signals, with clock/run-length shorthands",
|
|
3923
|
+
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)',
|
|
3689
3924
|
forms: [
|
|
3690
|
-
"
|
|
3691
|
-
"
|
|
3692
|
-
|
|
3925
|
+
'timing "Synchronous Bus Read"',
|
|
3926
|
+
"CLK: clock 8",
|
|
3927
|
+
"RST: rle 1*2 0*6",
|
|
3928
|
+
"EN: rle 0*2 1*4 0*2",
|
|
3929
|
+
'DATA: zz====zz data: ["D0","D1","D2","D3"]'
|
|
3693
3930
|
],
|
|
3694
3931
|
prefer: [
|
|
3695
|
-
"Use `clock N` for clocks instead of counting `p` characters.",
|
|
3696
|
-
"Use `rle <state>*<count>
|
|
3697
|
-
|
|
3698
|
-
"
|
|
3932
|
+
"Use `clock N` for clocks instead of counting `p` characters \u2014 `CLK: clock 8` is immune to count errors.",
|
|
3933
|
+
"Use `rle <state>*<count> \u2026` for level/data signals \u2014 `RST: rle 1*2 0*6` makes length explicit and auto-aligns.",
|
|
3934
|
+
'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]`.',
|
|
3935
|
+
"Keep all signals the same total cell count so they align; `clock N` and `rle` make this trivial to verify."
|
|
3936
|
+
],
|
|
3937
|
+
avoid: [
|
|
3938
|
+
"Avoid hand-counting long runs of identical characters \u2014 mismatched counts are the main source of misaligned waves.",
|
|
3939
|
+
"Don't mix `clock`/`rle` and a raw wave string for the same signal; pick one form per signal.",
|
|
3940
|
+
"Don't use a wave character outside `0 1 x z = . p P n N h H l L u d 2-9`."
|
|
3699
3941
|
],
|
|
3700
|
-
avoid: ["Avoid hand-counting long runs of identical characters \u2014 that is the main source of misaligned waves."],
|
|
3701
3942
|
repair: [
|
|
3702
|
-
"
|
|
3703
|
-
"
|
|
3943
|
+
"'clock needs a positive cycle count' -> provide an integer >= 1 after `clock`, e.g. `CLK: clock 8`.",
|
|
3944
|
+
"'rle segment must be' -> each rle token must match `<char>*<N>` with a valid state char, e.g. `rle 1*3 0*5`.",
|
|
3945
|
+
"'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`."
|
|
3704
3946
|
]
|
|
3705
3947
|
},
|
|
3706
3948
|
logic: {
|
|
3707
3949
|
type: "logic",
|
|
3708
3950
|
header: 'logic "Title"',
|
|
3709
|
-
mode: "logic netlist",
|
|
3710
|
-
|
|
3951
|
+
mode: "logic netlist \u2014 INPUT/OUTPUT declarations + gate assignments; optional module grouping",
|
|
3952
|
+
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',
|
|
3953
|
+
forms: [
|
|
3954
|
+
'logic "1-bit Full Adder"',
|
|
3955
|
+
"input A, B, Cin",
|
|
3956
|
+
"output Sum, Cout",
|
|
3957
|
+
"s1 = XOR(A, B)",
|
|
3958
|
+
"Sum = XOR(s1, Cin)",
|
|
3959
|
+
"c1 = AND(A, B)",
|
|
3960
|
+
"c2 = AND(s1, Cin)",
|
|
3961
|
+
"Cout = OR(c1, c2)"
|
|
3962
|
+
],
|
|
3711
3963
|
prefer: [
|
|
3712
|
-
"Gate form is `id = TYPE(in1, in2, \u2026)`; declare `INPUT`/`OUTPUT` ports explicitly. Prefix
|
|
3713
|
-
"Use only
|
|
3964
|
+
"Gate form is `id = TYPE(in1, in2, \u2026)`; declare `INPUT`/`OUTPUT` ports explicitly. Prefix any signal with `~` for active-low.",
|
|
3965
|
+
"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`.",
|
|
3966
|
+
'Group related gates with `module "Label" { \u2026 }` to render a named bounding box.'
|
|
3967
|
+
],
|
|
3968
|
+
avoid: [
|
|
3969
|
+
"Avoid circuit component names (`R`, `C`, transistors) or FBD block names (`TON`, `CTU`) inside logic diagrams \u2014 they are not valid gate types.",
|
|
3970
|
+
"Don't leave a `module { \u2026 }` unclosed \u2014 an unclosed module block throws `Unclosed module`.",
|
|
3971
|
+
"Don't rely on auto-declaration of undeclared signals \u2014 the parser warns and adds them silently; explicit `INPUT` lines are cleaner."
|
|
3714
3972
|
],
|
|
3715
|
-
|
|
3716
|
-
|
|
3973
|
+
repair: [
|
|
3974
|
+
"'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.",
|
|
3975
|
+
"'Unclosed module' -> add a closing `}` for every `module \"\u2026\" {` block.",
|
|
3976
|
+
"'was not declared; auto-declared as input' -> add an explicit `input X` line to make the port intentional."
|
|
3977
|
+
]
|
|
3717
3978
|
},
|
|
3718
3979
|
circuit: {
|
|
3719
3980
|
type: "circuit",
|
|
3720
3981
|
header: 'circuit "Title" netlist',
|
|
3721
3982
|
mode: "SPICE-style netlist (recommended for generation)",
|
|
3983
|
+
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',
|
|
3722
3984
|
forms: [
|
|
3723
|
-
"
|
|
3724
|
-
"
|
|
3725
|
-
"
|
|
3985
|
+
'circuit "Bridge Rectifier Supply" netlist',
|
|
3986
|
+
"V1 ac1 ac2 12Vac",
|
|
3987
|
+
"D1 ac1 vout 1N4007",
|
|
3988
|
+
"D2 ac2 vout 1N4007",
|
|
3989
|
+
"D3 0 ac1 1N4007",
|
|
3990
|
+
"D4 0 ac2 1N4007",
|
|
3991
|
+
"C1 vout 0 470u",
|
|
3992
|
+
"Rload vout 0 1k"
|
|
3726
3993
|
],
|
|
3727
3994
|
prefer: [
|
|
3728
|
-
|
|
3729
|
-
"Two components
|
|
3730
|
-
"The
|
|
3731
|
-
"Optional
|
|
3995
|
+
'Always use netlist mode (`circuit "name" netlist`). Each line is one component; no cursor state to track.',
|
|
3996
|
+
"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.",
|
|
3997
|
+
"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.",
|
|
3998
|
+
"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."
|
|
3732
3999
|
],
|
|
3733
4000
|
avoid: [
|
|
3734
|
-
"Avoid positional cursor
|
|
3735
|
-
"Do not invent coordinates; the layout engine places components from
|
|
4001
|
+
"Avoid positional cursor mode (`wire`, `at:`) \u2014 it requires tracking mental cursor state and is not recommended for generation.",
|
|
4002
|
+
"Do not invent coordinates; the auto-layout engine places components from net connectivity. `dir=` only rotates a symbol.",
|
|
4003
|
+
"Don't give a multi-terminal part fewer nets than it has pins (a `transformer` needs 4: `T1 p1 p2 s1 s2 type=transformer`)."
|
|
3736
4004
|
],
|
|
3737
|
-
repair: [
|
|
4005
|
+
repair: [
|
|
4006
|
+
"'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`).",
|
|
4007
|
+
"'must be unique' -> a reference designator is declared more than once; rename the duplicates.",
|
|
4008
|
+
"'no ground reference' -> tie a return node to ground by naming a net `0` or `GND` (e.g. `V1 vin 0 5V`).",
|
|
4009
|
+
"'connects to only one pin' -> wire the net to a second pin, or mark the open pin with a `no_connect` symbol."
|
|
4010
|
+
]
|
|
3738
4011
|
},
|
|
3739
4012
|
blockdiagram: {
|
|
3740
4013
|
type: "blockdiagram",
|
|
3741
4014
|
header: 'blockdiagram "Title"',
|
|
3742
|
-
mode: "
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
4015
|
+
mode: "named block/sum/signal decls + directed -> chains",
|
|
4016
|
+
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',
|
|
4017
|
+
forms: [
|
|
4018
|
+
'C = block("PID C(s)") [role: controller]',
|
|
4019
|
+
'G = block("Plant G(s)") [role: plant]',
|
|
4020
|
+
"err = sum(+r, -y)",
|
|
4021
|
+
"in -> err -> C -> G -> y",
|
|
4022
|
+
"G -> err"
|
|
4023
|
+
],
|
|
4024
|
+
prefer: [
|
|
4025
|
+
'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`).',
|
|
4026
|
+
"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.",
|
|
4027
|
+
'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"]`.'
|
|
4028
|
+
],
|
|
4029
|
+
avoid: [
|
|
4030
|
+
"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.",
|
|
4031
|
+
"Avoid drawing feedback as a bare reverse arrow with no junction; route it into a `sum(...)` so the loop reads correctly.",
|
|
4032
|
+
'Don\'t quote ids; quotes belong only inside `block("\u2026")` / `signal("\u2026")` labels and edge `["\u2026"]` labels.'
|
|
4033
|
+
],
|
|
4034
|
+
repair: [
|
|
4035
|
+
"'Invalid connection: <line>' -> a `->` line needs an id on both sides (e.g. `err -> C`); `C ->` or `-> C` alone is rejected.",
|
|
4036
|
+
"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)."
|
|
4037
|
+
]
|
|
3747
4038
|
},
|
|
3748
4039
|
ladder: {
|
|
3749
4040
|
type: "ladder",
|
|
3750
4041
|
header: 'ladder "Title"',
|
|
3751
|
-
mode: "rungs
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
4042
|
+
mode: "rungs with IEC 61131-3 contacts / coils / function blocks; OR branches via parallel:/branch:",
|
|
4043
|
+
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"])',
|
|
4044
|
+
forms: [
|
|
4045
|
+
'ladder "Motor Start/Stop"',
|
|
4046
|
+
'rung 1 "Seal-in circuit":',
|
|
4047
|
+
" parallel:",
|
|
4048
|
+
" branch:",
|
|
4049
|
+
' XIC(START_PB, "IN 1.0", name="Start Button")',
|
|
4050
|
+
" branch:",
|
|
4051
|
+
' XIC(MOTOR_AUX, "BIT 3.0", name="Aux Contact")',
|
|
4052
|
+
' XIO(STOP_PB, "IN 1.1", name="Stop Button")',
|
|
4053
|
+
' OTE(MOTOR_CMD, "OUT 2.0", name="Motor Command")'
|
|
4054
|
+
],
|
|
4055
|
+
prefer: [
|
|
4056
|
+
"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`.",
|
|
4057
|
+
'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")`.',
|
|
4058
|
+
"Model parallel contacts (OR logic) with an indented `parallel:` block containing two or more `branch:` sub-blocks."
|
|
4059
|
+
],
|
|
4060
|
+
avoid: [
|
|
4061
|
+
"Don't invent element types \u2014 an unrecognised name throws `unknown element type` and halts the parse; use only the canonical list.",
|
|
4062
|
+
"Don't write an empty rung; every rung must contain at least one element or the parser throws `empty rung`.",
|
|
4063
|
+
"Don't use `branch:` outside a `parallel:` block \u2014 it throws `branch: without parallel:`."
|
|
4064
|
+
],
|
|
4065
|
+
repair: [
|
|
4066
|
+
"'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.",
|
|
4067
|
+
"'empty rung' -> add at least one contact or coil element inside the rung.",
|
|
4068
|
+
"'branch: without parallel:' -> wrap the `branch:` block inside a `parallel:` block first.",
|
|
4069
|
+
"'element outside of rung' -> every element line must appear after a `rung N:` header."
|
|
4070
|
+
]
|
|
3756
4071
|
},
|
|
3757
4072
|
sld: {
|
|
3758
4073
|
type: "sld",
|
|
3759
4074
|
header: 'sld "Title"',
|
|
3760
|
-
mode: "equipment
|
|
3761
|
-
|
|
4075
|
+
mode: "equipment declarations + directed power-flow edges",
|
|
4076
|
+
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',
|
|
4077
|
+
forms: [
|
|
4078
|
+
'sld "Utility + Generator Backup"',
|
|
4079
|
+
'UTIL = utility [voltage: "480V", label: "Utility"]',
|
|
4080
|
+
'GEN = generator [rating: "500 kW", voltage: "480V"]',
|
|
4081
|
+
'ATS1 = ats [rating: "800A"]',
|
|
4082
|
+
'BUS1 = bus [voltage: "480V"]',
|
|
4083
|
+
'CB1 = breaker [rating: "200A"]',
|
|
4084
|
+
'L1 = load [label: "Critical Load"]',
|
|
4085
|
+
"UTIL -> ATS1",
|
|
4086
|
+
"GEN -> ATS1",
|
|
4087
|
+
"ATS1 -> BUS1",
|
|
4088
|
+
"BUS1 -> CB1",
|
|
4089
|
+
"CB1 -> L1"
|
|
4090
|
+
],
|
|
3762
4091
|
prefer: [
|
|
3763
|
-
"Declare
|
|
3764
|
-
"Use
|
|
3765
|
-
|
|
4092
|
+
"Declare every node as `id = nodeType [attrs]` before any `->` connection references it.",
|
|
4093
|
+
"Use one `from -> to` edge per line \u2014 SLD does not support chained arrows like `a -> b -> c`.",
|
|
4094
|
+
'Annotate nodes with `[label: "\u2026", rating: "\u2026", voltage: "\u2026"]`; annotate edges with `[cable: "\u2026", label: "\u2026"]`.'
|
|
4095
|
+
],
|
|
4096
|
+
avoid: [
|
|
4097
|
+
"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).",
|
|
4098
|
+
"Avoid chained arrow syntax (`a -> b -> c`) \u2014 each connection must be its own line.",
|
|
4099
|
+
"Avoid using `[standard: iec]` with ANSI-only devices (`recloser`, `sectionalizer`, `watthour_meter`) \u2014 they have no IEC symbol and render with a warning."
|
|
3766
4100
|
],
|
|
3767
|
-
|
|
3768
|
-
|
|
4101
|
+
repair: [
|
|
4102
|
+
"'Connection references unknown node' -> declare the node with `id = nodeType` before the `->` line that names it.",
|
|
4103
|
+
"'Duplicate node id' -> each id must appear on exactly one `id = nodeType` line; rename the second occurrence.",
|
|
4104
|
+
"'Cannot parse line' -> every non-blank line must be the `sld` header, a node declaration (`id = type [attrs]`), or a connection (`id -> id [attrs]`).",
|
|
4105
|
+
"'unrecognised type' -> replace the unknown type with a catalog type or alias (e.g. `inverter` -> `vfd`)."
|
|
4106
|
+
]
|
|
3769
4107
|
},
|
|
3770
4108
|
entity: {
|
|
3771
4109
|
type: "entity",
|
|
3772
4110
|
header: 'entity-structure "Title"',
|
|
3773
|
-
mode: "legal
|
|
4111
|
+
mode: "legal entity declarations + typed ownership edges",
|
|
4112
|
+
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"]',
|
|
3774
4113
|
forms: [
|
|
3775
|
-
'entity
|
|
3776
|
-
'entity
|
|
3777
|
-
|
|
3778
|
-
|
|
4114
|
+
'entity parent "Acme Global, Inc." corp@US [note: "Ultimate Parent"]',
|
|
4115
|
+
'entity ie-holdco "Acme Ireland Holdings" corp@IE',
|
|
4116
|
+
'entity ie-ip "Acme IP Ltd" corp@KY',
|
|
4117
|
+
"parent -> ie-holdco : 100%",
|
|
4118
|
+
'ie-ip -~-> ie-holdco [label: "IP License \xB7 royalty"]',
|
|
4119
|
+
'jurisdiction US "United States" [color: "#3b82f6"]',
|
|
4120
|
+
'cluster "Ireland / Cayman IP" [members: [ie-holdco, ie-ip]]'
|
|
3779
4121
|
],
|
|
3780
4122
|
prefer: [
|
|
3781
|
-
"
|
|
3782
|
-
"
|
|
3783
|
-
|
|
4123
|
+
"Declare all `entity` nodes before any edge lines; the entity type goes after the quoted name (`corp`, `llc`, `lp`, `trust`, `individual`, `foundation`, `disregarded`, `pool`).",
|
|
4124
|
+
"Append `@JX` jurisdiction code directly to the type token (`corp@DE`, `trust@SD`) \u2014 no space; omit only when jurisdiction is unknown.",
|
|
4125
|
+
"Use the right edge operator for semantics: `->` ownership, `==>` voting-only control, `-~->` contractual (license/management), `-->` distribution, `-.->` option pool."
|
|
4126
|
+
],
|
|
4127
|
+
avoid: [
|
|
4128
|
+
"Don't use `fund` as an entity type \u2014 only canonical types are accepted; use `lp` for funds/LPs.",
|
|
4129
|
+
'Don\'t put edge properties outside brackets: `[class: "Series A Pref"]`, not `: Series A Pref class`.',
|
|
4130
|
+
"Don't write `cluster` without a bracketed `[members: [...]]` list \u2014 the members value must be a bracket-enclosed comma list."
|
|
3784
4131
|
],
|
|
3785
|
-
|
|
3786
|
-
|
|
4132
|
+
repair: [
|
|
4133
|
+
"'Unknown entity type' -> replace with a canonical type: corp llc lp trust individual foundation disregarded placeholder pool.",
|
|
4134
|
+
"'Edge references unknown entity' -> add the `entity <id> \u2026` declaration before the edge line.",
|
|
4135
|
+
"'has no entities' -> the document needs at least one `entity` line."
|
|
4136
|
+
]
|
|
3787
4137
|
},
|
|
3788
4138
|
fishbone: {
|
|
3789
4139
|
type: "fishbone",
|
|
3790
4140
|
header: 'fishbone "Title"',
|
|
3791
|
-
mode: "effect + cause
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
4141
|
+
mode: "effect + structured category ribs + cause lines",
|
|
4142
|
+
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',
|
|
4143
|
+
forms: [
|
|
4144
|
+
'fishbone "Manufacturing defect spike"',
|
|
4145
|
+
'effect "Solder joint defect > 3%"',
|
|
4146
|
+
'category man "Man"',
|
|
4147
|
+
'category machine "Machine"',
|
|
4148
|
+
'category method "Method"',
|
|
4149
|
+
'man : "Operator training gaps"',
|
|
4150
|
+
'machine : "Reflow oven calibration"',
|
|
4151
|
+
' - "Temperature profile not updated"',
|
|
4152
|
+
'method : "No incoming inspection"'
|
|
4153
|
+
],
|
|
4154
|
+
prefer: [
|
|
4155
|
+
'Declare each `category id "Label"` before referencing `id : "cause"` \u2014 the structured form keeps category ids unambiguous.',
|
|
4156
|
+
"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.",
|
|
4157
|
+
"For second-level sub-causes, indent >= 2 spaces and prefix with `- `; they attach to the last Level-1 cause above them."
|
|
4158
|
+
],
|
|
4159
|
+
avoid: [
|
|
4160
|
+
"Don't reference a `catId :` cause before declaring that category \u2014 the parser throws `Unknown category`.",
|
|
4161
|
+
'Don\'t omit `effect` \u2014 without an `effect` line the fish head falls back to the title; an explicit `effect "\u2026"` is clearer.',
|
|
4162
|
+
"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."
|
|
4163
|
+
],
|
|
4164
|
+
repair: [
|
|
4165
|
+
'\'Unknown category\' -> add `category X "Label"` before any `X : "cause"` line.',
|
|
4166
|
+
"'requires at least one' -> the document has no `category` lines; add at least one `category id \"Label\"`.",
|
|
4167
|
+
"'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."
|
|
4168
|
+
]
|
|
3796
4169
|
},
|
|
3797
4170
|
venn: {
|
|
3798
4171
|
type: "venn",
|
|
3799
4172
|
header: 'venn "Title"',
|
|
3800
|
-
mode: "declared
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
4173
|
+
mode: "declared sets + region counts (primary); enumeration or Euler relations as alternates",
|
|
4174
|
+
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',
|
|
4175
|
+
forms: [
|
|
4176
|
+
'venn "Customer Segments"',
|
|
4177
|
+
'set email "Email subscribers" [color: "#1E88E5"]',
|
|
4178
|
+
'set paid "Paid users" [color: "#E53935"]',
|
|
4179
|
+
'set mobile "Mobile app users" [color: "#43A047"]',
|
|
4180
|
+
"email & paid : 1840",
|
|
4181
|
+
"email & mobile : 920",
|
|
4182
|
+
"email & paid & mobile : 650",
|
|
4183
|
+
"email only : 12400",
|
|
4184
|
+
"paid only : 3200"
|
|
4185
|
+
],
|
|
4186
|
+
prefer: [
|
|
4187
|
+
'Declare every `set ID "Label"` before any region line that references it.',
|
|
4188
|
+
"Use integer counts for research overlap, `%` values for audience overlap, and `[list]` values when each region should show enumerated items.",
|
|
4189
|
+
"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."
|
|
4190
|
+
],
|
|
4191
|
+
avoid: [
|
|
4192
|
+
"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.",
|
|
4193
|
+
"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`.",
|
|
4194
|
+
"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."
|
|
4195
|
+
],
|
|
4196
|
+
repair: [
|
|
4197
|
+
"'unknown set id' -> declare `set X \"Label\"` before the region line that uses it.",
|
|
4198
|
+
"'duplicate set id' -> each set id must appear in exactly one `set` declaration; rename or remove the second.",
|
|
4199
|
+
"'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:`."
|
|
4200
|
+
]
|
|
3805
4201
|
},
|
|
3806
4202
|
flowchart: {
|
|
3807
4203
|
type: "flowchart",
|
|
3808
|
-
header:
|
|
3809
|
-
mode: "Mermaid-compatible nodes + edges",
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
4204
|
+
header: "flowchart TD",
|
|
4205
|
+
mode: "Mermaid-compatible nodes + edges (Mermaid prior: prefer this syntax)",
|
|
4206
|
+
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',
|
|
4207
|
+
forms: [
|
|
4208
|
+
"flowchart LR",
|
|
4209
|
+
" start([New order received])",
|
|
4210
|
+
" start --> validate{Inventory available?}",
|
|
4211
|
+
" validate -->|Yes| reserve[Reserve items]",
|
|
4212
|
+
" validate -->|No| notify[Notify customer]",
|
|
4213
|
+
" reserve --> payment{Payment authorized?}",
|
|
4214
|
+
" payment -->|Yes| ship[Ship order]",
|
|
4215
|
+
" ship --> done([End])",
|
|
4216
|
+
" notify --> done"
|
|
4217
|
+
],
|
|
4218
|
+
prefer: [
|
|
4219
|
+
"Use Mermaid `flowchart TD` (or `LR`) as the header \u2014 matches the dominant training prior; `graph TD` is also accepted.",
|
|
4220
|
+
"Label decision branches with `-->|Yes|` / `-->|No|` pipe syntax; use `--` inline for longer edge text: `A -- approved --> B`.",
|
|
4221
|
+
"Use `([\u2026])` stadium for terminals, `{\u2026}` diamond for decisions, `[\u2026]` rect for steps, `[(\u2026)]` cylinder for datastores."
|
|
4222
|
+
],
|
|
4223
|
+
avoid: [
|
|
4224
|
+
"Don't omit the direction token \u2014 a bare `flowchart` defaults to TB; always declare direction explicitly.",
|
|
4225
|
+
"Avoid `subgraph` nesting deeper than one level in generated output; deep nesting is valid but rarely needed.",
|
|
4226
|
+
"Don't use inline `:::className` syntax in generated output \u2014 use separate `class A,B name` or `classDef` statements."
|
|
4227
|
+
],
|
|
4228
|
+
repair: [
|
|
4229
|
+
"'expected' header -> the first non-comment line must be `flowchart TD` (or another direction); a missing or misspelled header rejects the document.",
|
|
4230
|
+
"'unknown direction' -> direction must be one of TD TB BT LR RL (case-insensitive).",
|
|
4231
|
+
"'expected node identifier' -> every edge must start with a valid id token; a bare `-->` without a left-hand node id is rejected."
|
|
4232
|
+
]
|
|
3814
4233
|
},
|
|
3815
4234
|
mindmap: {
|
|
3816
4235
|
type: "mindmap",
|
|
3817
4236
|
header: "mindmap",
|
|
3818
|
-
mode: "Markdown headings + bullets",
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
4237
|
+
mode: "Markdown headings + bullets; %% directives for style/theme",
|
|
4238
|
+
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",
|
|
4239
|
+
forms: [
|
|
4240
|
+
"mindmap",
|
|
4241
|
+
"",
|
|
4242
|
+
"# Product Launch Plan",
|
|
4243
|
+
"",
|
|
4244
|
+
"## Market readiness",
|
|
4245
|
+
"- Competitive analysis",
|
|
4246
|
+
"- Pricing benchmarks",
|
|
4247
|
+
"",
|
|
4248
|
+
"## Engineering",
|
|
4249
|
+
"### Feature freeze",
|
|
4250
|
+
"- Core API complete",
|
|
4251
|
+
"",
|
|
4252
|
+
"## Go-to-market",
|
|
4253
|
+
"- Landing page live"
|
|
4254
|
+
],
|
|
4255
|
+
prefer: [
|
|
4256
|
+
"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.",
|
|
4257
|
+
"Use `%% style: logic-right` for outlines, the default `map` for balanced radial brainstorms, `%% style: futureswheel` for consequence mapping, `%% style: driver` for IHI diagrams.",
|
|
4258
|
+
"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."
|
|
4259
|
+
],
|
|
4260
|
+
avoid: [
|
|
4261
|
+
"Don't write more than one `#` root heading \u2014 the parser throws `multiple` center nodes not allowed on the second.",
|
|
4262
|
+
"Don't use graph-edge syntax (`A -> B`) inside a mindmap; the format is heading/bullet hierarchy only.",
|
|
4263
|
+
"Don't place `%%` directives mid-document; they are only processed before the first heading and are otherwise ignored."
|
|
4264
|
+
],
|
|
4265
|
+
repair: [
|
|
4266
|
+
"'missing central topic' -> add a `# Your Topic` line as the first content line.",
|
|
4267
|
+
"'multiple' center nodes not allowed -> demote all but the first `#` heading to `##` or deeper.",
|
|
4268
|
+
"'no `# Title` heading found' (warning) -> the parser adopted the first line as the topic; add an explicit `# Title` at the top."
|
|
4269
|
+
]
|
|
3823
4270
|
},
|
|
3824
4271
|
matrix: {
|
|
3825
4272
|
type: "matrix",
|
|
3826
4273
|
header: 'matrix "Title"',
|
|
3827
|
-
mode: "quadrant scatter",
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
4274
|
+
mode: "quadrant scatter (default) | named templates | heatmap | sipoc | qfd | punnett",
|
|
4275
|
+
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',
|
|
4276
|
+
forms: [
|
|
4277
|
+
'matrix eisenhower "This Week"',
|
|
4278
|
+
"style: table",
|
|
4279
|
+
'Q2: "Ship hotfix"',
|
|
4280
|
+
'Q1: "Write Q3 OKRs"',
|
|
4281
|
+
'Q3: "Reorganize Slack channels"',
|
|
4282
|
+
"",
|
|
4283
|
+
'matrix bcg "Product Portfolio"',
|
|
4284
|
+
'"Platform SDK" at (0.8, 0.8) size: 5 category: star',
|
|
4285
|
+
'"Legacy API" at (0.85, 0.15) size: 4 category: cashcow'
|
|
4286
|
+
],
|
|
4287
|
+
prefer: [
|
|
4288
|
+
"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.",
|
|
4289
|
+
"Add `style: table` with `Q1:`/`Q2:`/`Q3:`/`Q4:` item lines for the four-cell list layout instead of a scatter.",
|
|
4290
|
+
"Quadrant scatter coordinates are normalized `[0,1]` fractions; add `size: N` for a bubble chart and `category:` to drive legend color."
|
|
4291
|
+
],
|
|
4292
|
+
avoid: [
|
|
4293
|
+
"Don't mix `sipoc:`/`qfd:`/`punnett:` sub-keywords in plain quadrant mode \u2014 they activate only under the matching header mode (`matrix sipoc`).",
|
|
4294
|
+
"Don't set point coordinates outside `[0,1]` expecting the canvas to expand \u2014 they are clamped and badged (use `offChartPolicy: drop` to hide).",
|
|
4295
|
+
"Don't use percentages or raw data values in `at (x, y)` \u2014 coordinates are fractions."
|
|
4296
|
+
],
|
|
4297
|
+
repair: [
|
|
4298
|
+
"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.",
|
|
4299
|
+
'An empty `qfd`/`sipoc` chart means the header was `matrix "Title"` (quadrant mode) not `matrix qfd "Title"` \u2014 add the mode keyword after `matrix`.',
|
|
4300
|
+
"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`."
|
|
4301
|
+
]
|
|
3832
4302
|
},
|
|
3833
4303
|
orgchart: {
|
|
3834
4304
|
type: "orgchart",
|
|
3835
4305
|
header: 'orgchart "Title"',
|
|
3836
|
-
mode: "indented hierarchy",
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
4306
|
+
mode: "indented hierarchy with pipe-separated fields; explicit edges for matrix/dotted lines",
|
|
4307
|
+
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',
|
|
4308
|
+
forms: [
|
|
4309
|
+
'ceo: "Jamie Torres" | CEO [role: ceo]',
|
|
4310
|
+
' cto: "Raj Patel" | CTO [role: cto]',
|
|
4311
|
+
' eng1: "Priya Nair" | Eng Lead | Engineering [role: engineer]',
|
|
4312
|
+
' cfo: "Ellen Wu" | CFO [role: cfo]',
|
|
4313
|
+
'advisor adv1: "Dr. Alan Ford" | Board Advisor [role: advisor]',
|
|
4314
|
+
"pm_core -.-> lead_core"
|
|
4315
|
+
],
|
|
4316
|
+
prefer: [
|
|
4317
|
+
'Use 2-space indentation per level for the reporting tree \u2014 this is the implicit `->` edge. Fields are `id : "Name" | Title | Department`, pipe-separated.',
|
|
4318
|
+
"Use node-kind prefixes `role`/`open` for vacant positions (dashed yellow + HIRING pill), `draft`/`tbh` for planned roles, `advisor`/`external` for contractors.",
|
|
4319
|
+
"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."
|
|
4320
|
+
],
|
|
4321
|
+
avoid: [
|
|
4322
|
+
"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.",
|
|
4323
|
+
'Don\'t omit the colon in node lines (`id : "Name"`); a line without a colon is silently skipped with a warning.',
|
|
4324
|
+
"Don't reuse an id \u2014 the duplicate is dropped silently, losing its name/title."
|
|
4325
|
+
],
|
|
4326
|
+
repair: [
|
|
4327
|
+
"'skipped a line that is neither a node nor an edge' -> the line is missing a colon; rewrite as `id : \"Name\" | Title`.",
|
|
4328
|
+
"'kept the first declaration of duplicate node id' -> each person needs a unique id; rename the second declaration.",
|
|
4329
|
+
"'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."
|
|
4330
|
+
]
|
|
3841
4331
|
},
|
|
3842
4332
|
decisiontree: {
|
|
3843
4333
|
type: "decisiontree",
|
|
3844
4334
|
header: 'decisiontree "Title"',
|
|
3845
|
-
mode: "taxonomy
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
4335
|
+
mode: "taxonomy (default) | decision | ml | influence \u2014 select via header suffix",
|
|
4336
|
+
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',
|
|
4337
|
+
forms: [
|
|
4338
|
+
'decisiontree "Customer Support Triage"',
|
|
4339
|
+
"direction: top-down",
|
|
4340
|
+
"",
|
|
4341
|
+
'question "Is the service completely down?"',
|
|
4342
|
+
' yes: question "Outage confirmed on status page?"',
|
|
4343
|
+
' yes: answer "Follow incident protocol \u2014 page on-call"',
|
|
4344
|
+
' no: answer "Check monitoring \u2014 open severity-1 ticket"',
|
|
4345
|
+
' no: answer "Escalate to billing team"'
|
|
4346
|
+
],
|
|
4347
|
+
prefer: [
|
|
4348
|
+
"Default mode is `taxonomy` \u2014 use `question`/`answer` (or `q`/`a`) with `yes:`/`no:` branch prefixes and 2-space indentation.",
|
|
4349
|
+
'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.',
|
|
4350
|
+
"For ML visualization use `decisiontree:ml`; split nodes carry `feature=`/`threshold=`/`gini=`; leaves carry `value=[N,\u2026]` plus optional `class=`."
|
|
4351
|
+
],
|
|
4352
|
+
avoid: [
|
|
4353
|
+
"Don't use `decision`/`chance`/`end` in taxonomy mode \u2014 they throw `Unknown taxonomy node kind`.",
|
|
4354
|
+
"Don't use `question`/`answer` in `:ml` mode \u2014 they throw `Unknown ML node kind`.",
|
|
4355
|
+
"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`."
|
|
4356
|
+
],
|
|
4357
|
+
repair: [
|
|
4358
|
+
"'Unknown node kind' -> valid decision-mode kinds are `decision`, `chance`, `end`, `outcome`; switch mode or fix the keyword.",
|
|
4359
|
+
"'Unknown taxonomy node kind' -> valid taxonomy kinds are `question`/`q` and `answer`/`a`/`leaf`.",
|
|
4360
|
+
"'probabilities do not sum to 1.0' -> the `prob N` values on a chance node's children must add to exactly 1.0.",
|
|
4361
|
+
"'Orphan line (bad indent)' -> every non-root node must be indented at least 2 spaces under its parent."
|
|
4362
|
+
]
|
|
3850
4363
|
},
|
|
3851
4364
|
timeline: {
|
|
3852
4365
|
type: "timeline",
|
|
3853
4366
|
header: 'timeline "Title"',
|
|
3854
|
-
mode: "dated events",
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
4367
|
+
mode: "dated events on a time axis \u2014 swimlane (default), gantt, or lollipop styles",
|
|
4368
|
+
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)',
|
|
4369
|
+
forms: [
|
|
4370
|
+
'timeline "Platform v2 Launch"',
|
|
4371
|
+
"config: style = gantt",
|
|
4372
|
+
"",
|
|
4373
|
+
'2025-07-01 - 2025-08-15: "Engineering build" [category: "engineering"]',
|
|
4374
|
+
'2025-08-20: milestone "Feature freeze" [color: #E53935]',
|
|
4375
|
+
'2025-09-15: milestone "Public launch" [color: #2E7D32]'
|
|
4376
|
+
],
|
|
4377
|
+
prefer: [
|
|
4378
|
+
"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.",
|
|
4379
|
+
"Use `config: style = gantt` for roadmaps (overlapping bars), `lollipop` for milestone stories, default `swimlane` for multi-track streams.",
|
|
4380
|
+
'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"`.'
|
|
4381
|
+
],
|
|
4382
|
+
avoid: [
|
|
4383
|
+
"Don't omit the colon after the date/range \u2014 `Expected ':' after date` is thrown when no colon separator is found.",
|
|
4384
|
+
"Don't use `config: style = X` with a value other than `swimlane`, `gantt`, `lollipop` \u2014 throws `Invalid style`.",
|
|
4385
|
+
"Don't write `era` with a single date instead of a range \u2014 throws `era requires a date range`."
|
|
4386
|
+
],
|
|
4387
|
+
repair: [
|
|
4388
|
+
"'Unrecognized line' -> an event line must be a date/range, then `:`, then a quoted label (optionally preceded by `milestone`).",
|
|
4389
|
+
"'Invalid style' -> valid `config: style` values are `swimlane`, `gantt`, `lollipop`.",
|
|
4390
|
+
"'era requires a date range' -> write `era 2020 - 2025: \"label\"` (two dates separated by ` - `)."
|
|
4391
|
+
]
|
|
3859
4392
|
},
|
|
3860
4393
|
state: {
|
|
3861
4394
|
type: "state",
|
|
3862
4395
|
header: "stateDiagram-v2",
|
|
3863
|
-
mode: "Mermaid stateDiagram-v2 (recommended
|
|
4396
|
+
mode: "Mermaid stateDiagram-v2 (recommended; native 'state' header also accepted)",
|
|
4397
|
+
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',
|
|
3864
4398
|
forms: [
|
|
3865
|
-
"
|
|
3866
|
-
"
|
|
3867
|
-
"
|
|
3868
|
-
"
|
|
4399
|
+
"stateDiagram-v2",
|
|
4400
|
+
" [*] --> Idle",
|
|
4401
|
+
" Idle --> Running : start",
|
|
4402
|
+
" Running --> Paused : pause",
|
|
4403
|
+
" Paused --> Running : resume",
|
|
4404
|
+
" Running --> Done : finish",
|
|
4405
|
+
" Done --> [*]"
|
|
3869
4406
|
],
|
|
3870
4407
|
prefer: [
|
|
3871
|
-
|
|
3872
|
-
|
|
4408
|
+
'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.',
|
|
4409
|
+
"Write transition labels as `: trigger [guard] / action` \u2014 all three segments optional, but the colon is required if any label follows the arrow.",
|
|
4410
|
+
"For composite states use `state ID { \u2026 }` (Mermaid) or `composite ID { \u2026 }` (native); separate concurrent regions with `--` inside the block."
|
|
3873
4411
|
],
|
|
3874
4412
|
avoid: [
|
|
3875
|
-
"
|
|
3876
|
-
"
|
|
4413
|
+
"Don't mix the two header styles \u2014 `[*]` (Mermaid) and `initial X` (native) are both accepted but must not appear together.",
|
|
4414
|
+
"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>>`.",
|
|
4415
|
+
"Don't leave a composite `{` block unclosed \u2014 an unclosed brace is a hard parse error."
|
|
3877
4416
|
],
|
|
3878
4417
|
repair: [
|
|
3879
|
-
"
|
|
3880
|
-
'
|
|
4418
|
+
"'Expected' header -> the first non-comment line must be `stateDiagram-v2`, `stateDiagram`, or `state`.",
|
|
4419
|
+
"'Unparseable line' -> check for an unsupported pseudo-state keyword, a missing `-->` arrow, or a line that is neither a transition, declaration, nor directive.",
|
|
4420
|
+
"'Unclosed composite block' -> every `state ID {` or `composite ID {` must be closed with a matching `}`."
|
|
3881
4421
|
]
|
|
3882
4422
|
},
|
|
3883
4423
|
pid: {
|
|
3884
4424
|
type: "pid",
|
|
3885
4425
|
header: 'pid "Title"',
|
|
3886
|
-
mode: "equipment + process lines",
|
|
4426
|
+
mode: "equipment + process/signal lines + instrument declarations",
|
|
4427
|
+
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',
|
|
3887
4428
|
forms: [
|
|
3888
|
-
"
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
"
|
|
4429
|
+
'pid "Water Pump Flow Control"',
|
|
4430
|
+
'equip T-101 : tank_atm [tag: "Feed Tank"]',
|
|
4431
|
+
'equip P-101 : pump_centrifugal [tag: "Feed Pump"]',
|
|
4432
|
+
"equip V-101 : valve_control",
|
|
4433
|
+
'line L1 from T-101.bottom to P-101.in [service: "water", type: "process"]',
|
|
4434
|
+
'line L2 from P-101.out to V-101.in [type: "process"]',
|
|
4435
|
+
"inst FT-101 : field_discrete",
|
|
4436
|
+
" measures L2",
|
|
4437
|
+
"inst FIC-101 : cr_shared",
|
|
4438
|
+
" controls V-101",
|
|
4439
|
+
'line s1 from FT-101 to FIC-101 [type: "electric"]',
|
|
4440
|
+
'line s2 from FIC-101 to V-101 [type: "pneumatic"]'
|
|
3892
4441
|
],
|
|
3893
4442
|
prefer: [
|
|
3894
|
-
"Declare
|
|
3895
|
-
"Use
|
|
3896
|
-
"
|
|
4443
|
+
"Declare `equip` first, then `line` connections, then `inst` bubbles. Use ISA tag conventions (`FT-101` flow transmitter, `FIC-101` flow indicating controller).",
|
|
4444
|
+
"Use the indented `measures LINE_OR_EQUIP` and `controls EQUIP` continuations under an `inst` to declare loop membership.",
|
|
4445
|
+
"Use canonical `[type: \u2026]` line types: `electric` for transmitter->controller, `pneumatic` for controller->control-valve, `software` for DCS/PLC bus."
|
|
4446
|
+
],
|
|
4447
|
+
avoid: [
|
|
4448
|
+
"Avoid SLD electrical nodes (`transformer`, `breaker`, `bus`) inside a P&ID \u2014 use `sld` for electrical single-lines.",
|
|
4449
|
+
"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`).",
|
|
4450
|
+
"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."
|
|
3897
4451
|
],
|
|
3898
|
-
|
|
3899
|
-
|
|
4452
|
+
repair: [
|
|
4453
|
+
"'Unparseable line' -> every body line must start with `equip`, `line`, `inst`, `measures`, or `controls`.",
|
|
4454
|
+
"'unrecognised type' -> replace the unknown equipment type with a catalog type (exchanger->hx_shell_tube, vessel_horizontal->vessel_h, cstr->reactor_cstr).",
|
|
4455
|
+
"'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."
|
|
4456
|
+
]
|
|
3900
4457
|
},
|
|
3901
4458
|
erd: {
|
|
3902
4459
|
type: "erd",
|
|
3903
4460
|
header: "erDiagram",
|
|
3904
4461
|
mode: "Mermaid erDiagram (recommended for generation)",
|
|
4462
|
+
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',
|
|
3905
4463
|
forms: [
|
|
3906
4464
|
"CUSTOMER ||--o{ ORDER : places",
|
|
3907
4465
|
"ORDER {",
|
|
@@ -3910,83 +4468,284 @@ var PROFILES = {
|
|
|
3910
4468
|
"}"
|
|
3911
4469
|
],
|
|
3912
4470
|
prefer: [
|
|
3913
|
-
"Use Mermaid `erDiagram`
|
|
3914
|
-
"
|
|
3915
|
-
"
|
|
4471
|
+
"Use the Mermaid `erDiagram` header; entities auto-create from relationship lines and only need a `{ \u2026 }` block to list attributes.",
|
|
4472
|
+
"Attributes are type-first under `erDiagram`: `int id PK`, `varchar email UK` \u2014 never name-first.",
|
|
4473
|
+
"Relationship syntax is `A <left-glyph>--<right-glyph> B : label`; use `||--o{` for one-to-many-optional, `||--|{` for one-to-many-mandatory."
|
|
4474
|
+
],
|
|
4475
|
+
avoid: [
|
|
4476
|
+
"Do not mix header styles: under `erDiagram` attrs are type-first; under native `erd` they are name-first with `table` blocks and `ref` lines.",
|
|
4477
|
+
"Do not write `notation: chen` or `notation: barker` \u2014 only `crowsfoot` is implemented in v0.1.",
|
|
4478
|
+
"Do not invent glyph pairs; left glyphs are `||` `|o` `}o` `}|`, right glyphs are `||` `o|` `o{` `|{`."
|
|
3916
4479
|
],
|
|
3917
|
-
avoid: ["Do not mix the two header styles; under `erDiagram`, attributes are type-first (`int id PK`), not name-first."],
|
|
3918
4480
|
repair: [
|
|
3919
|
-
"
|
|
3920
|
-
"
|
|
4481
|
+
"'Invalid Mermaid cardinality glyph' -> the left glyph must be `||`/`|o`/`}o`/`}|` and the right `||`/`o|`/`o{`/`|{`; fix the pair.",
|
|
4482
|
+
"'Unrecognized erDiagram line' -> only relationship lines, entity blocks (`NAME {`), and `}` are valid under `erDiagram`; remove native `table`/`ref` lines.",
|
|
4483
|
+
"'not yet implemented in v0.1; use' -> drop the `notation:` line or set `notation: crowsfoot`."
|
|
3921
4484
|
]
|
|
3922
4485
|
},
|
|
3923
4486
|
breadboard: {
|
|
3924
4487
|
type: "breadboard",
|
|
3925
4488
|
header: "breadboard",
|
|
3926
|
-
mode: "parts + wires
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
4489
|
+
mode: "parts section + wires section; breadboard-native hole/rail coordinates",
|
|
4490
|
+
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',
|
|
4491
|
+
forms: [
|
|
4492
|
+
"breadboard",
|
|
4493
|
+
"board: half",
|
|
4494
|
+
'title: "Blink LED \u2014 Arduino Uno"',
|
|
4495
|
+
"parts",
|
|
4496
|
+
" uno: mcu uno @beside-left",
|
|
4497
|
+
" r1: resistor 220 @5e..9e",
|
|
4498
|
+
" d1: led red @10e..10f",
|
|
4499
|
+
"wires",
|
|
4500
|
+
" uno:5V --red-- @+t1",
|
|
4501
|
+
" uno:GND --black-- @-t1",
|
|
4502
|
+
" uno:D13 --yellow-- @9a"
|
|
4503
|
+
],
|
|
4504
|
+
prefer: [
|
|
4505
|
+
"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.",
|
|
4506
|
+
"Use breadboard-native coordinates: `@5e` for hole column 5 row e, `@5e..9e` for a span, `@+t8`/`@-t8` for top positive/negative rail.",
|
|
4507
|
+
"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`."
|
|
4508
|
+
],
|
|
4509
|
+
avoid: [
|
|
4510
|
+
"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`.",
|
|
4511
|
+
"Don't omit the `@` placement from a part \u2014 `missing placement` is thrown when the `@` token is absent.",
|
|
4512
|
+
"Don't reference a part id in wires that was not declared in the parts section \u2014 `Wire references unknown part` fails validation."
|
|
4513
|
+
],
|
|
4514
|
+
repair: [
|
|
4515
|
+
"'Unknown board' -> set `board:` to `mini`, `half`, or `full`.",
|
|
4516
|
+
"'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`).",
|
|
4517
|
+
"'Wire references unknown part' -> add `X: KIND @placement` to the `parts` section before `wires`."
|
|
4518
|
+
]
|
|
3931
4519
|
},
|
|
3932
4520
|
bpmn: {
|
|
3933
4521
|
type: "bpmn",
|
|
3934
4522
|
header: "bpmn",
|
|
3935
|
-
mode: "pool/lane objects + flows",
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
4523
|
+
mode: "pool/lane declarations + flow objects + flows block",
|
|
4524
|
+
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)',
|
|
4525
|
+
forms: [
|
|
4526
|
+
"bpmn",
|
|
4527
|
+
"direction: LR",
|
|
4528
|
+
'title: "Loan Application Approval"',
|
|
4529
|
+
'pool "Bank" {',
|
|
4530
|
+
' lane "Clerk" {',
|
|
4531
|
+
' A: start "Application received"',
|
|
4532
|
+
' B: task user "Check completeness"',
|
|
4533
|
+
' G1: gateway xor "Complete?"',
|
|
4534
|
+
" }",
|
|
4535
|
+
' lane "Underwriter" {',
|
|
4536
|
+
' C: task service "Risk score"',
|
|
4537
|
+
' E: end "Approved"',
|
|
4538
|
+
' F: end "Rejected"',
|
|
4539
|
+
" }",
|
|
4540
|
+
"}",
|
|
4541
|
+
"flows",
|
|
4542
|
+
"A --> B",
|
|
4543
|
+
"B --> G1",
|
|
4544
|
+
'G1 --? "yes" --> C',
|
|
4545
|
+
'G1 --* "no" --> F',
|
|
4546
|
+
"C --> E"
|
|
4547
|
+
],
|
|
4548
|
+
prefer: [
|
|
4549
|
+
'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.',
|
|
4550
|
+
"Event kinds `start`/`intermediate`/`end` with optional trigger `message`/`timer`; task markers `user`/`service`/`send`/`receive`/`manual`/`script`; gateway kinds `xor`/`or`/`and`/`event`.",
|
|
4551
|
+
"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."
|
|
4552
|
+
],
|
|
4553
|
+
avoid: [
|
|
4554
|
+
"Don't use `-->` across pool boundaries \u2014 it is rejected with `crosses pool boundary \u2014 use message flow`.",
|
|
4555
|
+
"Don't add lanes or tasks inside a `blackbox` pool \u2014 rejected with `black-box pool` cannot contain flow objects.",
|
|
4556
|
+
"Don't give a `task` without a quoted label, and don't put more than one `--*` default flow on the same gateway."
|
|
4557
|
+
],
|
|
4558
|
+
repair: [
|
|
4559
|
+
"'crosses pool boundary \u2014 use message flow' -> replace `-->` with `~~>` and ensure source/target are in different pools.",
|
|
4560
|
+
"'unknown flow-object kind' -> the word after `id:` must be `start`, `end`, `intermediate`, `task`, `subprocess`, or `gateway`.",
|
|
4561
|
+
"'kind must be xor / or / and / event' -> a gateway declaration needs one of those four kinds after the `gateway` keyword."
|
|
4562
|
+
]
|
|
3940
4563
|
},
|
|
3941
4564
|
fbd: {
|
|
3942
4565
|
type: "fbd",
|
|
3943
4566
|
header: 'fbd "Title"',
|
|
3944
|
-
mode: "
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
4567
|
+
mode: "variable declarations + numbered networks of indented assignment statements",
|
|
4568
|
+
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',
|
|
4569
|
+
forms: [
|
|
4570
|
+
'fbd "Motor Control"',
|
|
4571
|
+
"var Start: bool",
|
|
4572
|
+
"var Stop: bool",
|
|
4573
|
+
"var MotorOut: bool",
|
|
4574
|
+
"var Latch: bool",
|
|
4575
|
+
'network 0 "Start latch":',
|
|
4576
|
+
" Latch = OR(Start, AND(Latch, ~Stop))",
|
|
4577
|
+
'network 1 "Drive output":',
|
|
4578
|
+
" MotorOut = MOVE(Latch)"
|
|
4579
|
+
],
|
|
4580
|
+
prefer: [
|
|
4581
|
+
"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.",
|
|
4582
|
+
'Each `network [N] ["title"]:` header is followed by indented `Inst = BLOCK(args)` body lines until the next `network`.',
|
|
4583
|
+
"Variadic blocks (`AND`, `OR`, `ADD`, `MUL`, `MAX`, `MIN`) accept any number of positional args and expand `IN1..INn` automatically."
|
|
4584
|
+
],
|
|
4585
|
+
avoid: [
|
|
4586
|
+
"Don't use ladder element names (`XIC`, `OTE`, ladder-style `TON`) inside FBD networks \u2014 they are not valid FBD blocks.",
|
|
4587
|
+
"Don't reference an instance port (`Inst.PORT`) before that instance is assigned in the same network.",
|
|
4588
|
+
"Don't use ladder comparison aliases \u2014 FBD uses `EQ NE GT GE LT LE`, not `EQU NEQ GRT LES GEQ LEQ`."
|
|
4589
|
+
],
|
|
4590
|
+
repair: [
|
|
4591
|
+
"'Unknown function block' -> replace with the closest IEC standard block (e.g. `EQUAL` -> `EQ`, `GREATER` -> `GT`, `TIMER_ON` -> `TON`).",
|
|
4592
|
+
"'Duplicate instance name' -> each `Inst =` assignment in a program must use a unique left-hand name.",
|
|
4593
|
+
"'Unrecognized network statement' -> the line must match `Inst = BLOCK(args)` or a bare `BLOCK(args)`; check for missing parentheses.",
|
|
4594
|
+
"'Too many positional arguments' -> drop excess args or switch to named-port form `PORT: value`."
|
|
4595
|
+
]
|
|
3949
4596
|
},
|
|
3950
4597
|
sfc: {
|
|
3951
4598
|
type: "sfc",
|
|
3952
4599
|
header: 'sfc "Title"',
|
|
3953
|
-
mode: "steps + transitions",
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
4600
|
+
mode: "steps with indented actions + from:/to: transitions",
|
|
4601
|
+
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',
|
|
4602
|
+
forms: [
|
|
4603
|
+
"step S0 [initial]",
|
|
4604
|
+
" N FillValve_Closed",
|
|
4605
|
+
'step S1 [label: "Filling"]',
|
|
4606
|
+
" N FillValve_Open",
|
|
4607
|
+
"transition from: S0 to: S1: StartBtn",
|
|
4608
|
+
"transition from: S1 to: S0: TankLevel >= 80.0"
|
|
4609
|
+
],
|
|
4610
|
+
prefer: [
|
|
4611
|
+
'Declare each `step ID [initial|final|label: "\u2026"]` first; put actions on indented lines under the step as `<QUAL> ActionName`.',
|
|
4612
|
+
"Wire steps with `transition from: A to: B: CONDITION` \u2014 the condition is free text (e.g. `TankLevel >= 80.0`), stored verbatim, never evaluated.",
|
|
4613
|
+
"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`.",
|
|
4614
|
+
"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`."
|
|
4615
|
+
],
|
|
4616
|
+
avoid: [
|
|
4617
|
+
"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').",
|
|
4618
|
+
"Avoid a second `[initial]` step; if none is marked, the first declared step is promoted automatically.",
|
|
4619
|
+
"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."
|
|
4620
|
+
],
|
|
4621
|
+
repair: [
|
|
4622
|
+
"'Transition references unknown step: X' -> declare `step X` (or fix the id) before any transition that names it.",
|
|
4623
|
+
"'Multiple [initial] steps: A and B' -> mark only one step `[initial]`.",
|
|
4624
|
+
"'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.",
|
|
4625
|
+
"'sim block missing merge_to clause' -> end the branch block with `merge_to: STEP: CONDITION` (alt uses `merge_to: STEP`)."
|
|
4626
|
+
]
|
|
3958
4627
|
},
|
|
3959
4628
|
prisma: {
|
|
3960
4629
|
type: "prisma",
|
|
3961
4630
|
header: "prisma",
|
|
3962
|
-
mode: "PRISMA 2020
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
4631
|
+
mode: "indentation-structured PRISMA 2020 flow diagram (2-space indent)",
|
|
4632
|
+
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:]",
|
|
4633
|
+
forms: [
|
|
4634
|
+
"prisma",
|
|
4635
|
+
"mode: 2020-single",
|
|
4636
|
+
"title: Exercise for chronic low-back pain \u2014 SR",
|
|
4637
|
+
"",
|
|
4638
|
+
"identification:",
|
|
4639
|
+
" databases:",
|
|
4640
|
+
" n: 1418",
|
|
4641
|
+
" sources: PubMed=600, Embase=450, Cochrane=184, Web of Science=184",
|
|
4642
|
+
" duplicates-removed: 318",
|
|
4643
|
+
"",
|
|
4644
|
+
"screening:",
|
|
4645
|
+
" records-screened: 1100",
|
|
4646
|
+
" excluded:",
|
|
4647
|
+
" n: 870",
|
|
4648
|
+
" reasons: irrelevant title=750, non-English=120",
|
|
4649
|
+
"",
|
|
4650
|
+
"eligibility:",
|
|
4651
|
+
" full-text-assessed: 230",
|
|
4652
|
+
" excluded:",
|
|
4653
|
+
" n: 195",
|
|
4654
|
+
" reasons: wrong population=80, wrong intervention=60, wrong outcome=55",
|
|
4655
|
+
"",
|
|
4656
|
+
"included:",
|
|
4657
|
+
" studies: 35"
|
|
4658
|
+
],
|
|
4659
|
+
prefer: [
|
|
4660
|
+
"All four stages `identification:`, `screening:`, `eligibility:`, `included:` are required \u2014 the parser throws if any is missing.",
|
|
4661
|
+
"Use 2-space indentation per level: stage keys at indent 0, sub-keys at indent 1, sub-sub-keys at indent 2.",
|
|
4662
|
+
"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)."
|
|
4663
|
+
],
|
|
4664
|
+
avoid: [
|
|
4665
|
+
"Don't write free-form stage keys \u2014 only `previous-studies`, `identification`, `screening`, `eligibility`, `included` are valid at the top level.",
|
|
4666
|
+
"Don't omit `n:` inside any stage block \u2014 it is required.",
|
|
4667
|
+
"Don't malform `reasons:` \u2014 pairs must be `name=count`; a missing `=` is an error."
|
|
4668
|
+
],
|
|
4669
|
+
repair: [
|
|
4670
|
+
"'required stage' is missing -> add the missing stage block (`identification:` needs a nested `databases:` with at least `n:`).",
|
|
4671
|
+
"'is missing required' field -> add the required sub-key (e.g. `n:`, or an `excluded:` block under `screening:`).",
|
|
4672
|
+
"'sources sum to' N but n = M -> make the `sources:` counts add up to the `n:` value, or remove `sources:`.",
|
|
4673
|
+
"'unknown stage' -> valid top-level keys are `previous-studies`, `identification`, `screening`, `eligibility`, `included`."
|
|
4674
|
+
]
|
|
3967
4675
|
},
|
|
3968
4676
|
usecase: {
|
|
3969
4677
|
type: "usecase",
|
|
3970
4678
|
header: "usecase",
|
|
3971
|
-
mode: "declarative
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
4679
|
+
mode: "declarative actor/usecase declarations + typed relationship lines",
|
|
4680
|
+
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)',
|
|
4681
|
+
forms: [
|
|
4682
|
+
"usecase",
|
|
4683
|
+
'title: "ATM"',
|
|
4684
|
+
'system: "ATM System"',
|
|
4685
|
+
"actor: Customer",
|
|
4686
|
+
"actor: Bank (external)",
|
|
4687
|
+
'usecase: "Withdraw Cash" as Withdraw',
|
|
4688
|
+
'usecase: "Check Balance" as Check',
|
|
4689
|
+
"Customer -- Withdraw",
|
|
4690
|
+
"Customer -- Check",
|
|
4691
|
+
"Withdraw -- Bank"
|
|
4692
|
+
],
|
|
4693
|
+
prefer: [
|
|
4694
|
+
"Declare all `actor:` and `usecase:` lines before relationship lines \u2014 an unknown id on a relation is a hard error.",
|
|
4695
|
+
"Use `actor: Name (external)` for system actors (rectangle), `(business)` for in-org actors, bare for stick figures; add `(left)`/`(right)` to pin placement.",
|
|
4696
|
+
"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."
|
|
4697
|
+
],
|
|
4698
|
+
avoid: [
|
|
4699
|
+
"Don't use `--` between two actors, or `..>`/`<..` involving an actor \u2014 both are hard errors.",
|
|
4700
|
+
"Don't use `--|>` between an actor and a use case \u2014 generalization must be actor\u2194actor or usecase\u2194usecase.",
|
|
4701
|
+
"Don't skip the `as ID` alias when reusing a multi-word name in relationships \u2014 the auto-id replaces spaces with underscores."
|
|
4702
|
+
],
|
|
4703
|
+
repair: [
|
|
4704
|
+
"'unknown identifier' -> declare `actor: X` or `usecase: \"X\" as X` before the relation line that references it.",
|
|
4705
|
+
"'must connect an actor and a use case' -> use `--|>` for actor generalization, not `--`.",
|
|
4706
|
+
"'endpoints must be use cases' -> both sides of `..>`/`<..` must be use cases, not actors.",
|
|
4707
|
+
"'first non-comment line must start with' -> the document must open with the bare keyword `usecase`."
|
|
4708
|
+
]
|
|
3976
4709
|
},
|
|
3977
4710
|
pert: {
|
|
3978
4711
|
type: "pert",
|
|
3979
4712
|
header: "pert",
|
|
3980
|
-
mode: "AON tasks
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
4713
|
+
mode: "AON tasks with computed schedule (ES/EF/LS/LF/slack/critical path)",
|
|
4714
|
+
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)',
|
|
4715
|
+
forms: [
|
|
4716
|
+
"pert",
|
|
4717
|
+
'title: "Q3 Product Launch"',
|
|
4718
|
+
"unit: days",
|
|
4719
|
+
"",
|
|
4720
|
+
'task A "Market research" duration: 5',
|
|
4721
|
+
'task B "Design mockups" duration: 8 after: A',
|
|
4722
|
+
'task C "Backend API" duration: 15 after: A',
|
|
4723
|
+
'task D "Frontend build" duration: 10 after: B, C',
|
|
4724
|
+
'task E "QA / testing" duration: 5 after: D',
|
|
4725
|
+
'task G "Launch event" duration: 2 after: E'
|
|
4726
|
+
],
|
|
4727
|
+
prefer: [
|
|
4728
|
+
'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.',
|
|
4729
|
+
"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.",
|
|
4730
|
+
'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"`.'
|
|
4731
|
+
],
|
|
4732
|
+
avoid: [
|
|
4733
|
+
"Don't write `ES:`, `EF:`, `LS:`, `LF:`, or `slack:` yourself \u2014 they are computed outputs.",
|
|
4734
|
+
"Don't create a cycle in `after:` references, and don't reference an undeclared predecessor.",
|
|
4735
|
+
"Don't mix lag unit suffixes that don't match `unit:` \u2014 e.g. `FS+2d` with `unit: weeks`."
|
|
4736
|
+
],
|
|
4737
|
+
repair: [
|
|
4738
|
+
"'is missing' duration -> add `duration: N` or append the bare word `milestone` to the task line.",
|
|
4739
|
+
"'references undeclared predecessor' -> declare `task Y \u2026` anywhere (forward references are allowed).",
|
|
4740
|
+
"'O <= M <= P' -> reorder a three-point estimate so optimistic <= most-likely <= pessimistic.",
|
|
4741
|
+
"'duplicate task id' -> every task needs a unique id; rename the second occurrence."
|
|
4742
|
+
]
|
|
3985
4743
|
},
|
|
3986
4744
|
sequence: {
|
|
3987
4745
|
type: "sequence",
|
|
3988
4746
|
header: "sequenceDiagram",
|
|
3989
4747
|
mode: "Mermaid sequenceDiagram (recommended for generation)",
|
|
4748
|
+
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',
|
|
3990
4749
|
forms: [
|
|
3991
4750
|
"participant Alice",
|
|
3992
4751
|
"participant Bob",
|
|
@@ -3995,20 +4754,26 @@ var PROFILES = {
|
|
|
3995
4754
|
"Note over Alice,Bob: handshake"
|
|
3996
4755
|
],
|
|
3997
4756
|
prefer: [
|
|
3998
|
-
"Use
|
|
3999
|
-
|
|
4000
|
-
"
|
|
4757
|
+
"Use the `sequenceDiagram` header (Mermaid mode): `->>` is a sync call and `-->>` is the reply/return \u2014 matches the dominant training prior.",
|
|
4758
|
+
"Declare lifeline kinds with `participant`/`actor`/`boundary`/`control`/`entity`/`database`/`collections`/`queue` before use; undeclared ids auto-create as plain `participant`.",
|
|
4759
|
+
"Use `->+` / `-->-` to open/close activation bars inline; use `alt \u2026 else \u2026 end`, `loop`, `opt`, `par \u2026 and \u2026 end` for fragments."
|
|
4760
|
+
],
|
|
4761
|
+
avoid: [
|
|
4762
|
+
"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.",
|
|
4763
|
+
"Do not use `else` outside an `alt`, or `and` outside `par`/`seq`/`strict`.",
|
|
4764
|
+
"Do not leave a combined fragment open \u2014 every `alt`/`opt`/`loop`/`par`/`break`/`critical` must close with `end`."
|
|
4001
4765
|
],
|
|
4002
|
-
avoid: ["Do not mix the two header styles; pick `sequenceDiagram` and keep Mermaid arrow meanings throughout."],
|
|
4003
4766
|
repair: [
|
|
4004
|
-
"
|
|
4005
|
-
'
|
|
4767
|
+
"'must start with the keyword' -> fix the first line to exactly `sequenceDiagram` or `sequence \"Title\"`.",
|
|
4768
|
+
"'is only valid inside an' -> move the `else` inside an `alt \u2026 end` block (or `and` inside `par`).",
|
|
4769
|
+
"'without a matching combined fragment' -> add the missing `end`, or remove the dangling `else`/`and`."
|
|
4006
4770
|
]
|
|
4007
4771
|
},
|
|
4008
4772
|
petri: {
|
|
4009
4773
|
type: "petri",
|
|
4010
4774
|
header: 'petri "Title"',
|
|
4011
4775
|
mode: "declared places + transitions + arcs",
|
|
4776
|
+
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)',
|
|
4012
4777
|
forms: [
|
|
4013
4778
|
"place P1 *1",
|
|
4014
4779
|
"transition T1",
|
|
@@ -4026,7 +4791,7 @@ var PROFILES = {
|
|
|
4026
4791
|
"Avoid `-o`/`=>` arcs from a transition; inhibitor and reset arcs are place\u2192transition only."
|
|
4027
4792
|
],
|
|
4028
4793
|
repair: [
|
|
4029
|
-
"
|
|
4794
|
+
"'arc references unknown node' -> an arc references an undeclared place/transition; declare it first.",
|
|
4030
4795
|
"Set the initial marking so the transitions you intend to be enabled actually have enough input tokens."
|
|
4031
4796
|
]
|
|
4032
4797
|
},
|
|
@@ -4034,27 +4799,28 @@ var PROFILES = {
|
|
|
4034
4799
|
type: "network",
|
|
4035
4800
|
header: 'network "Title"',
|
|
4036
4801
|
mode: "device declarations + links (annotations are optional)",
|
|
4802
|
+
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:",
|
|
4037
4803
|
forms: [
|
|
4038
|
-
'router r1 "Edge Router"
|
|
4039
|
-
'l3switch core1 "Core" tier: core
|
|
4804
|
+
'router r1 "Edge Router"',
|
|
4805
|
+
'l3switch core1 "Core" tier: core',
|
|
4040
4806
|
'switch acc1 "Access" tier: access',
|
|
4041
4807
|
'pc pc1 "Workstation"',
|
|
4042
|
-
"r1 -- core1
|
|
4808
|
+
"r1 -- core1",
|
|
4043
4809
|
"core1 -- acc1",
|
|
4044
4810
|
"acc1 -- pc1"
|
|
4045
4811
|
],
|
|
4046
4812
|
prefer: [
|
|
4047
4813
|
'Start from the skeleton: `kind id "label"` device lines plus `a -- b` links. That alone renders a complete, valid diagram.',
|
|
4048
4814
|
"Declare every device before any link references it.",
|
|
4049
|
-
"Keep the cheap structural hints `layout:` (tiered/tree/star/ring/bus/mesh/spine-leaf) and `tier:` (edge/core/distribution/access) \u2014 they
|
|
4815
|
+
"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.",
|
|
4050
4816
|
"Common kinds: router, switch, l3switch, firewall, ap, server, pc, laptop, camera, nvr, poeswitch, internet, cloud."
|
|
4051
4817
|
],
|
|
4052
4818
|
avoid: [
|
|
4053
4819
|
"Avoid linking to an undeclared device id.",
|
|
4054
|
-
'Add
|
|
4820
|
+
'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.'
|
|
4055
4821
|
],
|
|
4056
4822
|
repair: [
|
|
4057
|
-
"
|
|
4823
|
+
"'undeclared device' -> a link references an id with no `kind id` declaration; declare it first.",
|
|
4058
4824
|
"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."
|
|
4059
4825
|
]
|
|
4060
4826
|
},
|
|
@@ -4062,40 +4828,42 @@ var PROFILES = {
|
|
|
4062
4828
|
type: "umlclass",
|
|
4063
4829
|
header: "umlclass",
|
|
4064
4830
|
mode: "classifier declarations + relationship lines (PlantUML-flavoured, Mermaid aliases accepted)",
|
|
4831
|
+
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',
|
|
4065
4832
|
forms: [
|
|
4066
|
-
"class Order { + id : String + place() : void }
|
|
4067
|
-
"\xABinterface\xBB Shape { + area() : double }
|
|
4833
|
+
"class Order { + id : String + place() : void }",
|
|
4834
|
+
"\xABinterface\xBB Shape { + area() : double }",
|
|
4068
4835
|
"abstract class AbstractShape { + area() : double {abstract} }",
|
|
4069
|
-
"\xABenumeration\xBB Suit { HEARTS DIAMONDS CLUBS SPADES }
|
|
4070
|
-
"Animal <|-- Dog
|
|
4071
|
-
"Shape <|.. Circle
|
|
4072
|
-
'Order *-- "1..*" LineItem : contains
|
|
4073
|
-
'Customer o-- "0..*" Address
|
|
4074
|
-
'A "1" --> "*" B : owns
|
|
4075
|
-
"X ..> Y
|
|
4836
|
+
"\xABenumeration\xBB Suit { HEARTS DIAMONDS CLUBS SPADES }",
|
|
4837
|
+
"Animal <|-- Dog",
|
|
4838
|
+
"Shape <|.. Circle",
|
|
4839
|
+
'Order *-- "1..*" LineItem : contains',
|
|
4840
|
+
'Customer o-- "0..*" Address',
|
|
4841
|
+
'A "1" --> "*" B : owns',
|
|
4842
|
+
"X ..> Y"
|
|
4076
4843
|
],
|
|
4077
4844
|
prefer: [
|
|
4078
4845
|
"Single-word keyword is `umlclass` (also accepts `class-diagram` and Mermaid's `classDiagram`).",
|
|
4079
4846
|
"Use `class`, `abstract class`, `\xABinterface\xBB`, `\xABenumeration\xBB`, or any custom `\xABstereotype\xBB` above the name.",
|
|
4080
4847
|
"Members go in `{ \u2026 }`; visibility glyphs are `+ - # ~`; `{static}` underlines, `{abstract}` italicises, `/name` marks a derived attribute.",
|
|
4081
|
-
'Multiplicity is the quoted token next to an endpoint: `"1"`, `"0..*"`, `"1..*"`. The
|
|
4848
|
+
'Multiplicity is the quoted token next to an endpoint: `"1"`, `"0..*"`, `"1..*"`. The label after `:` is the association name.',
|
|
4082
4849
|
"PlantUML connectors are primary; the Mermaid reversed forms `--|>`, `..|>`, `--*`, `--o` are accepted and normalised."
|
|
4083
4850
|
],
|
|
4084
4851
|
avoid: [
|
|
4085
|
-
"Don't use bare `class` as the diagram keyword \u2014 that's a reserved
|
|
4086
|
-
"Don't put `-->` for dependency: `-->` is
|
|
4087
|
-
"Don't declare a classifier with an empty
|
|
4852
|
+
"Don't use bare `class` as the diagram keyword \u2014 that's a reserved word; the engine keyword is `umlclass`.",
|
|
4853
|
+
"Don't put `-->` for dependency: `-->` is directed association; dependency is the dashed `..>`.",
|
|
4854
|
+
"Don't declare a classifier with an empty `{}` for a name-only box \u2014 write `class Foo` on its own line."
|
|
4088
4855
|
],
|
|
4089
4856
|
repair: [
|
|
4090
|
-
"
|
|
4091
|
-
"
|
|
4092
|
-
"If a class appears as
|
|
4857
|
+
"'malformed relationship' -> no connector glyph was found between two ids; use one of `<|--` `<|..` `*--` `o--` `-->` `..>` `--` `..`.",
|
|
4858
|
+
"'generalization cycle' -> inheritance edges form a loop; fix the parent/child direction of one edge in the cycle.",
|
|
4859
|
+
"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."
|
|
4093
4860
|
]
|
|
4094
4861
|
},
|
|
4095
4862
|
faulttree: {
|
|
4096
4863
|
type: "faulttree",
|
|
4097
4864
|
header: 'faulttree "Title"',
|
|
4098
4865
|
mode: "flat event/gate declarations wired by id (top + gates + leaves)",
|
|
4866
|
+
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",
|
|
4099
4867
|
forms: [
|
|
4100
4868
|
"analysis: cutsets, probability",
|
|
4101
4869
|
'top T "System fails" = OR(G1, G2)',
|
|
@@ -4119,9 +4887,9 @@ var PROFILES = {
|
|
|
4119
4887
|
"Don't declare more than one `top`, and don't create cycles (a gate may not transitively reference itself)."
|
|
4120
4888
|
],
|
|
4121
4889
|
repair: [
|
|
4122
|
-
"'references undefined event'
|
|
4123
|
-
"'must have exactly one top'
|
|
4124
|
-
"'
|
|
4890
|
+
"'references undefined event' -> a gate input id was never declared; add the `basic`/`gate`/\u2026 line.",
|
|
4891
|
+
"'must have exactly one top' -> keep a single `top`; downgrade the others to `gate`.",
|
|
4892
|
+
"'n must equal the number of inputs' -> in `VOTING(k/n; \u2026)` make n match the listed inputs.",
|
|
4125
4893
|
"If P(top) shows 'n/a', a basic event in a cut set is missing its `p:`."
|
|
4126
4894
|
]
|
|
4127
4895
|
},
|
|
@@ -4129,6 +4897,7 @@ var PROFILES = {
|
|
|
4129
4897
|
type: "bowtie",
|
|
4130
4898
|
header: 'bowtie "Title"',
|
|
4131
4899
|
mode: "indentation-structured: hazard + topevent, then threat/consequence blocks with indented barrier chains",
|
|
4900
|
+
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',
|
|
4132
4901
|
forms: [
|
|
4133
4902
|
'hazard "Working at height"',
|
|
4134
4903
|
'topevent "Person falls from height"',
|
|
@@ -4142,7 +4911,7 @@ var PROFILES = {
|
|
|
4142
4911
|
],
|
|
4143
4912
|
prefer: [
|
|
4144
4913
|
"Single-word keyword is `bowtie`. Declare exactly one `topevent` (the knot) and an optional `hazard` header.",
|
|
4145
|
-
"Each `threat` needs
|
|
4914
|
+
"Each `threat` needs >= 1 indented `prevent` barrier; each `consequence` needs >= 1 indented `mitigate` barrier (the engine rejects a bare threat/consequence).",
|
|
4146
4915
|
"Barrier order = declaration order (first = outermost, nearest the threat/consequence; last = innermost, nearest the knot).",
|
|
4147
4916
|
"`escalation` nests (4 spaces) under the `prevent`/`mitigate` barrier it degrades; an escalation-factor `barrier` nests (6 spaces) under the escalation.",
|
|
4148
4917
|
"Bowtie is qualitative \u2014 no probabilities. For Boolean gates + cut sets behind one threat, use a separate `faulttree`."
|
|
@@ -4154,16 +4923,17 @@ var PROFILES = {
|
|
|
4154
4923
|
"Don't declare more than one `topevent` or more than one `hazard`."
|
|
4155
4924
|
],
|
|
4156
4925
|
repair: [
|
|
4157
|
-
"'has no preventative barrier' / 'no mitigative barrier'
|
|
4158
|
-
"'not attached to a barrier'
|
|
4159
|
-
"'needs at least one threat/consequence'
|
|
4160
|
-
"'exactly one top event'
|
|
4926
|
+
"'has no preventative barrier' / 'no mitigative barrier' -> add a `prevent`/`mitigate` line under the threat/consequence.",
|
|
4927
|
+
"'not attached to a barrier' -> move the `escalation` so it follows a `prevent`/`mitigate` line.",
|
|
4928
|
+
"'needs at least one threat/consequence' -> a one-wing diagram is a fault tree or event tree; add the missing wing.",
|
|
4929
|
+
"'exactly one top event' -> keep a single `topevent` line."
|
|
4161
4930
|
]
|
|
4162
4931
|
},
|
|
4163
4932
|
eventtree: {
|
|
4164
4933
|
type: "eventtree",
|
|
4165
4934
|
header: 'eventtree "Title"',
|
|
4166
4935
|
mode: "initiating event + ordered safety functions, then outcome rows with s/f/* branch patterns",
|
|
4936
|
+
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',
|
|
4167
4937
|
forms: [
|
|
4168
4938
|
'initiating LOCA "Large LOCA" freq: 1e-4',
|
|
4169
4939
|
'function A "ECCS injects" p: 0.001',
|
|
@@ -4174,24 +4944,25 @@ var PROFILES = {
|
|
|
4174
4944
|
],
|
|
4175
4945
|
prefer: [
|
|
4176
4946
|
"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).",
|
|
4177
|
-
'Each `outcome` row gives a `s`/`f`/`*` pattern (one symbol per function) then `-> "label"`. `*` = path already terminated (pruned)
|
|
4947
|
+
'Each `outcome` row gives a `s`/`f`/`*` pattern (one symbol per function) then `-> "label"`. `*` = path already terminated (pruned).',
|
|
4178
4948
|
"Let the engine compute path frequencies (f_initiating \xD7 \u03A0 branch-probs) \u2014 don't hand-write them."
|
|
4179
4949
|
],
|
|
4180
4950
|
avoid: [
|
|
4181
|
-
"Don't try to make a balanced 2
|
|
4951
|
+
"Don't try to make a balanced 2^n tree \u2014 prune with `*` where a sequence ends early.",
|
|
4182
4952
|
"Don't put probabilities on outcome rows; `p:` belongs on `function` lines.",
|
|
4183
4953
|
"Don't reverse the success/failure convention \u2014 success branches up, failure down."
|
|
4184
4954
|
],
|
|
4185
4955
|
repair: [
|
|
4186
|
-
"'outcome pattern length'
|
|
4187
|
-
"'no initiating event'
|
|
4188
|
-
"'once pruned stays pruned'
|
|
4956
|
+
"'outcome pattern length' -> give exactly one s/f/* per declared function.",
|
|
4957
|
+
"'no initiating event' -> add one `initiating <id> \"\u2026\" freq: \u2026` line.",
|
|
4958
|
+
"'once pruned stays pruned' -> after a `*` in a pattern, the rest must also be `*`."
|
|
4189
4959
|
]
|
|
4190
4960
|
},
|
|
4191
4961
|
fmea: {
|
|
4192
4962
|
type: "fmea",
|
|
4193
4963
|
header: 'fmea "Title"',
|
|
4194
4964
|
mode: "indentation-structured worksheet: item \u2192 failure mode \u2192 effect/cause/controls with S/O/D scores",
|
|
4965
|
+
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:',
|
|
4195
4966
|
forms: [
|
|
4196
4967
|
'fmea "Brake System DFMEA"',
|
|
4197
4968
|
' item "Master cylinder" fn "Generate pressure"',
|
|
@@ -4211,40 +4982,47 @@ var PROFILES = {
|
|
|
4211
4982
|
"Don't put `occ:` on an effect or `sev:` on a cause \u2014 they bind to the wrong column."
|
|
4212
4983
|
],
|
|
4213
4984
|
repair: [
|
|
4214
|
-
"'score out of range'
|
|
4215
|
-
"'
|
|
4985
|
+
"'score out of range' -> keep S/O/D in 1\u201310.",
|
|
4986
|
+
"'has no effect/cause' -> every failure mode needs at least one effect and one cause."
|
|
4216
4987
|
]
|
|
4217
4988
|
},
|
|
4218
4989
|
causalloop: {
|
|
4219
4990
|
type: "causalloop",
|
|
4220
4991
|
header: 'causalloop "Title"',
|
|
4221
4992
|
mode: "signed causal links between variables; engine detects R/B loops",
|
|
4993
|
+
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',
|
|
4222
4994
|
forms: [
|
|
4223
|
-
'causalloop "
|
|
4224
|
-
'"
|
|
4225
|
-
'
|
|
4226
|
-
'"
|
|
4227
|
-
'
|
|
4228
|
-
'
|
|
4995
|
+
'causalloop "Startup growth engine"',
|
|
4996
|
+
'"Active users" -> "Word of mouth" : +',
|
|
4997
|
+
'"Word of mouth" -> "New signups" : +',
|
|
4998
|
+
'"New signups" -> "Active users" : +',
|
|
4999
|
+
'"Active users" -> "Server load" : +',
|
|
5000
|
+
'"Server load" -> "App performance" : -',
|
|
5001
|
+
'"App performance" -> "Active users" : + delay',
|
|
5002
|
+
'loop R1 "Viral flywheel"',
|
|
5003
|
+
'loop B1 "Scaling strain"'
|
|
4229
5004
|
],
|
|
4230
5005
|
prefer: [
|
|
4231
|
-
"
|
|
4232
|
-
'
|
|
4233
|
-
|
|
5006
|
+
"Put every polarity after the `->` as `: +` or `: -` \u2014 every causal link must be signed.",
|
|
5007
|
+
'Wrap multi-word variable names in double quotes: `"Active users"`. Single-token names (e.g. `Revenue`) need no quotes.',
|
|
5008
|
+
'Let the engine classify loops R/B automatically \u2014 use `loop R1 "phrase"` only to name a loop it already detected.'
|
|
4234
5009
|
],
|
|
4235
5010
|
avoid: [
|
|
4236
|
-
"Don't
|
|
4237
|
-
"Don't
|
|
5011
|
+
"Don't omit the polarity separator: `A -> B : +` is the canonical form.",
|
|
5012
|
+
"Don't use `s`/`o`/`same`/`opposite` in generated output \u2014 they normalise to `+`/`-` but reduce readability.",
|
|
5013
|
+
"Don't draw boxes around variables \u2014 CLD variables are boxless text labels; there is no shape syntax."
|
|
4238
5014
|
],
|
|
4239
5015
|
repair: [
|
|
4240
|
-
"'
|
|
4241
|
-
"'
|
|
5016
|
+
"'is missing a polarity' -> append `: +` or `: -` after the target variable name.",
|
|
5017
|
+
"'needs at least one causal link' -> add at least one signed link; a document with only `loop` declarations is rejected.",
|
|
5018
|
+
"'malformed link (expected' -> each link line must contain `->` between the source and target variable names."
|
|
4242
5019
|
]
|
|
4243
5020
|
},
|
|
4244
5021
|
markov: {
|
|
4245
5022
|
type: "markov",
|
|
4246
5023
|
header: 'markov "Title"',
|
|
4247
5024
|
mode: "probability-labelled state transitions; engine computes stationary distribution + classification",
|
|
5025
|
+
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',
|
|
4248
5026
|
forms: [
|
|
4249
5027
|
'markov "Weather"',
|
|
4250
5028
|
"Sunny -> Sunny : 0.9",
|
|
@@ -4253,23 +5031,26 @@ var PROFILES = {
|
|
|
4253
5031
|
"Rainy -> Rainy : 0.5"
|
|
4254
5032
|
],
|
|
4255
5033
|
prefer: [
|
|
4256
|
-
"
|
|
4257
|
-
"
|
|
4258
|
-
"
|
|
5034
|
+
"Write `S1 -> S2 : 0.3` transitions (colon form is canonical); every state's outgoing probabilities must sum to 1 unless `normalize: true` is set.",
|
|
5035
|
+
"Declare absorbing states with the `absorbing` keyword (`state Broke absorbing`); the engine validates it against the computed structure.",
|
|
5036
|
+
"Use `analysis: classify, stationary` for ergodic chains; add `absorbing` for the fundamental matrix, absorption probabilities, and expected steps."
|
|
4259
5037
|
],
|
|
4260
5038
|
avoid: [
|
|
4261
|
-
"Don't let a state's
|
|
4262
|
-
"Don't
|
|
5039
|
+
"Don't let a state's outgoing probabilities sum to anything but 1 \u2014 this hard-errors unless `normalize: true`.",
|
|
5040
|
+
"Don't declare a state `absorbing` unless it has a self-loop of probability 1 and no other out-edges.",
|
|
5041
|
+
"Don't hand-compute the stationary distribution or absorption probabilities \u2014 they are derived."
|
|
4263
5042
|
],
|
|
4264
5043
|
repair: [
|
|
4265
|
-
"'
|
|
4266
|
-
"'
|
|
5044
|
+
"'outgoing probabilities sum to' -> adjust that state's transitions to sum to exactly 1, or add `normalize: true`.",
|
|
5045
|
+
"'is missing a probability' -> add `: <prob>` after the target state id.",
|
|
5046
|
+
"'is declared absorbing but is' -> add `<id> -> <id> : 1` and remove other out-edges, or drop the `absorbing` keyword."
|
|
4267
5047
|
]
|
|
4268
5048
|
},
|
|
4269
5049
|
gitgraph: {
|
|
4270
5050
|
type: "gitgraph",
|
|
4271
5051
|
header: "gitGraph",
|
|
4272
5052
|
mode: "Mermaid-compatible ordered git operations (commit/branch/checkout/merge)",
|
|
5053
|
+
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',
|
|
4273
5054
|
forms: [
|
|
4274
5055
|
"gitGraph",
|
|
4275
5056
|
' commit id: "init"',
|
|
@@ -4280,136 +5061,168 @@ var PROFILES = {
|
|
|
4280
5061
|
" merge develop"
|
|
4281
5062
|
],
|
|
4282
5063
|
prefer: [
|
|
4283
|
-
|
|
4284
|
-
'Annotate commits with `id: "\u2026"`, `tag: "\u2026"`, `type: HIGHLIGHT
|
|
4285
|
-
"`
|
|
5064
|
+
"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.",
|
|
5065
|
+
'Annotate commits with `id: "\u2026"`, `tag: "\u2026"`, and `type: HIGHLIGHT`/`REVERSE`/`NORMAL`; `cherry-pick id: "\u2026"` copies a commit by id.',
|
|
5066
|
+
"Use `gitGraph LR:` (default) for left-to-right time; add `TB:`/`BT:` inline on the header to change orientation."
|
|
4286
5067
|
],
|
|
4287
5068
|
avoid: [
|
|
4288
|
-
"Don't `
|
|
4289
|
-
"Don't merge a branch into itself."
|
|
5069
|
+
"Don't `checkout` or `merge` a branch you have not created with `branch <name>` first.",
|
|
5070
|
+
"Don't `merge` a branch into itself.",
|
|
5071
|
+
"Don't use an option key other than `id`, `tag`, `type`, `order`, `parent`."
|
|
4290
5072
|
],
|
|
4291
5073
|
repair: [
|
|
4292
|
-
"'
|
|
4293
|
-
"'cannot merge
|
|
5074
|
+
"'checkout of undeclared branch' -> add a `branch <name>` operation before the `checkout`.",
|
|
5075
|
+
"'cannot merge branch' into itself -> `checkout` a different branch before the `merge`.",
|
|
5076
|
+
"'cherry-pick of merge commit' requires parent -> add `parent: \"<id>\"` to the `cherry-pick` line."
|
|
4294
5077
|
]
|
|
4295
5078
|
},
|
|
4296
5079
|
epc: {
|
|
4297
5080
|
type: "epc",
|
|
4298
5081
|
header: 'epc "Title"',
|
|
4299
|
-
mode: "alternating events/functions joined by
|
|
5082
|
+
mode: "alternating events/functions joined by and/or/xor connectors; alternation validated",
|
|
5083
|
+
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',
|
|
4300
5084
|
forms: [
|
|
4301
5085
|
'epc "Order fulfilment"',
|
|
5086
|
+
" layout: tb",
|
|
4302
5087
|
' event E1 "Order received"',
|
|
4303
5088
|
' function F1 "Check credit"',
|
|
4304
5089
|
" xor X1",
|
|
4305
5090
|
' event E2 "Credit OK"',
|
|
4306
5091
|
' event E3 "Credit rejected"',
|
|
5092
|
+
' function F2 "Ship goods"',
|
|
5093
|
+
' function F3 "Notify customer"',
|
|
5094
|
+
' event E4 "Order shipped"',
|
|
5095
|
+
' event E5 "Order cancelled"',
|
|
4307
5096
|
" E1 -> F1 -> X1",
|
|
4308
5097
|
" X1 -> E2",
|
|
4309
|
-
" X1 -> E3"
|
|
5098
|
+
" X1 -> E3",
|
|
5099
|
+
" E2 -> F2 -> E4",
|
|
5100
|
+
" E3 -> F3 -> E5"
|
|
4310
5101
|
],
|
|
4311
5102
|
prefer: [
|
|
4312
|
-
"
|
|
4313
|
-
"Strictly alternate events and functions
|
|
4314
|
-
"Use a connector node to split
|
|
5103
|
+
"Declare `event`, `function`, and connector (`and`/`or`/`xor`) nodes with ids first; then wire them with `A -> B` edge lines (chainable: `A -> B -> C`).",
|
|
5104
|
+
"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.",
|
|
5105
|
+
"Use a connector node to split or join; place the connector after a function for any OR/XOR split."
|
|
4315
5106
|
],
|
|
4316
5107
|
avoid: [
|
|
4317
|
-
"Don't make an event the source of an
|
|
4318
|
-
"Don't
|
|
5108
|
+
"Don't make an event the source of an `or`/`xor` split \u2014 only a function may precede an OR/XOR split.",
|
|
5109
|
+
"Don't give an event or function more than one outgoing arc without a connector \u2014 the split belongs on a connector.",
|
|
5110
|
+
"Don't connect two events or two functions in sequence without an intervening node."
|
|
4319
5111
|
],
|
|
4320
5112
|
repair: [
|
|
4321
|
-
"'
|
|
4322
|
-
"'
|
|
5113
|
+
"'is the source of a XOR split' -> insert a `function` between the event and the `xor`/`or` connector.",
|
|
5114
|
+
"'must have a single output' -> add an `and`/`or`/`xor` node and route the multiple arcs from the connector.",
|
|
5115
|
+
"'is used in an edge but never declared' -> add the missing `event`/`function`/connector declaration before the edge."
|
|
4323
5116
|
]
|
|
4324
5117
|
},
|
|
4325
5118
|
idef0: {
|
|
4326
5119
|
type: "idef0",
|
|
4327
5120
|
header: 'idef0 "Title"',
|
|
4328
5121
|
mode: "function boxes + positional ICOM arrows (input-left, control-top, output-right, mechanism-bottom)",
|
|
5122
|
+
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',
|
|
4329
5123
|
forms: [
|
|
4330
|
-
'idef0 "
|
|
4331
|
-
|
|
4332
|
-
'
|
|
4333
|
-
'
|
|
4334
|
-
'
|
|
4335
|
-
'
|
|
4336
|
-
'
|
|
4337
|
-
'
|
|
5124
|
+
'idef0 "Fulfil customer order"',
|
|
5125
|
+
"node A0",
|
|
5126
|
+
'function A1 "Validate order"',
|
|
5127
|
+
'function A2 "Pick and pack"',
|
|
5128
|
+
'function A3 "Ship and invoice"',
|
|
5129
|
+
'input A1 "Customer order"',
|
|
5130
|
+
'control A1 "Credit policy"',
|
|
5131
|
+
'mechanism A1 "Order management system"',
|
|
5132
|
+
'A1 -> A2 "Validated order"',
|
|
5133
|
+
'mechanism A2 "Warehouse staff"',
|
|
5134
|
+
'A2 -> A3 "Packed shipment"',
|
|
5135
|
+
'output A3 "Delivered order"'
|
|
4338
5136
|
],
|
|
4339
5137
|
prefer: [
|
|
4340
|
-
|
|
4341
|
-
'Box
|
|
4342
|
-
"Remember
|
|
5138
|
+
'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.',
|
|
5139
|
+
'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.',
|
|
5140
|
+
"Remember ICOM: Inputs enter left, Controls enter top, Outputs exit right, Mechanisms enter bottom. Use 3\u20136 boxes per diagram (FIPS 183)."
|
|
4343
5141
|
],
|
|
4344
5142
|
avoid: [
|
|
4345
|
-
"Don't
|
|
4346
|
-
"Don't hand-number
|
|
5143
|
+
"Don't land a flow on the target's `.output` edge \u2014 outputs exit a box; use `.input`/`.control`/`.mechanism`.",
|
|
5144
|
+
"Don't hand-number boxes with `n:N` unless you number every box \u2014 mixing explicit and auto numbering is an error.",
|
|
5145
|
+
"Don't reference a box id in an arrow before declaring it with `function`."
|
|
4347
5146
|
],
|
|
4348
5147
|
repair: [
|
|
4349
|
-
"'
|
|
4350
|
-
"'
|
|
5148
|
+
"'arrow references undefined function box' -> add a `function ID \"name\"` line before any arrow that references it.",
|
|
5149
|
+
"'cannot land on the target's .output' -> change `.output` to `.input`, `.control`, or `.mechanism`.",
|
|
5150
|
+
"'must declare at least one' function box -> add at least one `function ID \"name\"` line; a diagram cannot be only arrows."
|
|
4351
5151
|
]
|
|
4352
5152
|
},
|
|
4353
5153
|
threatmodel: {
|
|
4354
5154
|
type: "threatmodel",
|
|
4355
5155
|
header: 'threatmodel "Title"',
|
|
4356
|
-
mode: "DFD elements + data flows + trust boundaries; engine maps STRIDE + flags boundary crossings",
|
|
5156
|
+
mode: "DFD elements + data flows + trust boundaries; engine maps STRIDE-per-element + flags boundary crossings",
|
|
5157
|
+
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',
|
|
4357
5158
|
forms: [
|
|
4358
|
-
'threatmodel "
|
|
4359
|
-
"external:
|
|
4360
|
-
"
|
|
4361
|
-
"
|
|
4362
|
-
"
|
|
4363
|
-
"
|
|
4364
|
-
|
|
4365
|
-
'
|
|
5159
|
+
'threatmodel "E-commerce checkout"',
|
|
5160
|
+
"external: Customer",
|
|
5161
|
+
"external Payment_Gateway: Payment Gateway",
|
|
5162
|
+
"process 1.0: Web App",
|
|
5163
|
+
"process 2.0: Order Service",
|
|
5164
|
+
"datastore D1: Orders DB",
|
|
5165
|
+
"datastore D2: Audit Log",
|
|
5166
|
+
'Customer -> 1.0 : "HTTPS Checkout"',
|
|
5167
|
+
'1.0 -> 2.0 : "Place order"',
|
|
5168
|
+
'2.0 -> D1 : "Write order"',
|
|
5169
|
+
'2.0 -> Payment_Gateway : "Charge card"',
|
|
5170
|
+
'boundary "Internet" { Customer, Payment_Gateway }',
|
|
5171
|
+
'boundary "DMZ" { 1.0 }',
|
|
5172
|
+
'boundary "Internal" { 2.0, D1, D2 }'
|
|
4366
5173
|
],
|
|
4367
5174
|
prefer: [
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
"Name audit/log stores with `log`/`audit`/`journal`
|
|
5175
|
+
"Keyword `threatmodel` (alias `stride`). Declare all `external:`, `process ID:`, `datastore ID:` elements first, then flows, then `boundary` groups.",
|
|
5176
|
+
'Every flow `A -> B : "label"` requires a label \u2014 the colon and label are mandatory; use `<->` for a bidirectional shorthand.',
|
|
5177
|
+
"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."
|
|
4371
5178
|
],
|
|
4372
5179
|
avoid: [
|
|
4373
|
-
"Don't connect
|
|
4374
|
-
"Don't
|
|
5180
|
+
"Don't connect `datastore \u2192 datastore` or `external \u2192 external` directly \u2014 both are hard DFD violations.",
|
|
5181
|
+
"Don't omit the `: label` on a flow; a bare `A -> B` line is rejected.",
|
|
5182
|
+
"Don't put an element id in two different `boundary` blocks \u2014 each element belongs to at most one boundary."
|
|
4375
5183
|
],
|
|
4376
5184
|
repair: [
|
|
4377
|
-
|
|
4378
|
-
"'
|
|
5185
|
+
'\'has no label\' -> add `: "label"` after the target id (e.g. `1.0 -> D1 : "Lookup"`).',
|
|
5186
|
+
"'references unknown element' -> declare the `external:`/`process`/`datastore` before the flow that references it.",
|
|
5187
|
+
"'directly to data store' -> route the flow through a `process` node in between.",
|
|
5188
|
+
"'lists unknown element' -> declare the element before the `boundary { \u2026 }` block that references it."
|
|
4379
5189
|
]
|
|
4380
5190
|
},
|
|
4381
5191
|
welding: {
|
|
4382
5192
|
type: "welding",
|
|
4383
5193
|
header: "welding [standard: aws|iso-a|iso-b]",
|
|
4384
5194
|
mode: "reference-line callouts; one joint block per joint, weld glyphs above/below the line",
|
|
5195
|
+
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',
|
|
4385
5196
|
forms: [
|
|
4386
|
-
'welding "Bracket
|
|
4387
|
-
'joint "
|
|
5197
|
+
'welding "Bracket assembly"',
|
|
5198
|
+
'joint "gusset to column" {',
|
|
4388
5199
|
" arrow: fillet size=8 len=50 pitch=150",
|
|
4389
5200
|
" other: fillet size=6",
|
|
4390
5201
|
" around",
|
|
4391
5202
|
" field",
|
|
4392
|
-
' tail: "
|
|
5203
|
+
' tail: "GMAW"',
|
|
4393
5204
|
"}",
|
|
4394
|
-
'joint "butt
|
|
4395
|
-
" arrow: vgroove angle=60 root=3 throat=12",
|
|
5205
|
+
'joint "splice plate (butt)" {',
|
|
5206
|
+
" arrow: vgroove angle=60 root=3 throat=12 contour=flush finish=G",
|
|
4396
5207
|
" other: backing",
|
|
5208
|
+
' tail: "SMAW; E7018"',
|
|
4397
5209
|
"}"
|
|
4398
5210
|
],
|
|
4399
5211
|
prefer: [
|
|
4400
|
-
'
|
|
4401
|
-
"A weldspec is `<type> key=value \u2026`: `size=` (
|
|
4402
|
-
'
|
|
4403
|
-
"
|
|
5212
|
+
'One `joint "label" { \u2026 }` block per joint. Weld sides are `arrow:` (arrow side), `other:` (other side), or `both:` (same spec both sides).',
|
|
5213
|
+
"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`.",
|
|
5214
|
+
'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"`.',
|
|
5215
|
+
"Choose `standard: iso-a` for the dual solid+dashed reference line; default `aws` uses a single line."
|
|
4404
5216
|
],
|
|
4405
5217
|
avoid: [
|
|
4406
|
-
"Don't put `angle=` on a fillet
|
|
4407
|
-
"Don't use `both:` for plug
|
|
4408
|
-
"Don't give a fillet without `size=`, or a `pitch=` without `len
|
|
5218
|
+
"Don't put `angle=` on a `fillet`, `plug`, `spot`, or `seam` \u2014 angle is groove-only (the engine warns).",
|
|
5219
|
+
"Don't use `both:` for `plug`, `slot`, or `surfacing` \u2014 those are single-side; `surfacing` is arrow-side only.",
|
|
5220
|
+
"Don't give a `fillet` without `size=`, or a `pitch=` without `len=` (an intermittent weld is length-pitch)."
|
|
4409
5221
|
],
|
|
4410
5222
|
repair: [
|
|
4411
|
-
"'a fillet weld needs a leg size'
|
|
4412
|
-
"'angle= only applies to groove welds'
|
|
5223
|
+
"'a fillet weld needs a leg size' -> add `size=N` to the fillet weldspec (e.g. `arrow: fillet size=8`).",
|
|
5224
|
+
"'angle= only applies to groove welds' -> drop `angle=`, or change the type to a groove such as `vgroove`.",
|
|
5225
|
+
"'pitch= needs a length=' -> add `len=N` alongside `pitch=N` on the same weldspec."
|
|
4413
5226
|
]
|
|
4414
5227
|
}
|
|
4415
5228
|
};
|
|
@@ -4439,6 +5252,7 @@ function buildCanonicalSyntax(profile) {
|
|
|
4439
5252
|
`- Canonical type: \`${profile.type}\``,
|
|
4440
5253
|
`- Canonical header: \`${profile.header}\``,
|
|
4441
5254
|
`- Preferred mode: ${profile.mode}`,
|
|
5255
|
+
profile.keywords ? `- Keywords: ${profile.keywords}` : "",
|
|
4442
5256
|
bulletSection("Core forms", profile.forms),
|
|
4443
5257
|
bulletSection("Prefer", profile.prefer),
|
|
4444
5258
|
bulletSection("Avoid by default", profile.avoid),
|
|
@@ -4460,7 +5274,9 @@ function listDiagrams() {
|
|
|
4460
5274
|
tagline: d.tagline,
|
|
4461
5275
|
useWhen: d.useWhen,
|
|
4462
5276
|
cluster: d.cluster,
|
|
4463
|
-
standard: d.standard
|
|
5277
|
+
standard: d.standard,
|
|
5278
|
+
...d.aliases ? { aliases: d.aliases } : {},
|
|
5279
|
+
...d.keywords ? { keywords: d.keywords } : {}
|
|
4464
5280
|
}));
|
|
4465
5281
|
}
|
|
4466
5282
|
function getSyntax(type, opts = {}) {
|
|
@@ -4549,19 +5365,28 @@ function toValidationError(diagnostic, type) {
|
|
|
4549
5365
|
column: diagnostic.column,
|
|
4550
5366
|
source: diagnostic.source,
|
|
4551
5367
|
message: diagnostic.message,
|
|
4552
|
-
hint: diagnostic.hint ?? repairHint(type)
|
|
5368
|
+
hint: diagnostic.hint ?? repairHint(type, diagnostic.message)
|
|
4553
5369
|
};
|
|
4554
5370
|
}
|
|
4555
|
-
function repairHint(type) {
|
|
5371
|
+
function repairHint(type, message) {
|
|
4556
5372
|
const resolved = type ? resolveDiagramType(type) : void 0;
|
|
4557
5373
|
const profile = resolved ? getGenerationProfile(resolved) : void 0;
|
|
4558
|
-
const typeHint = profile?.repair[0];
|
|
5374
|
+
const typeHint = message ? profile ? matchRepair(profile.repair, message) : void 0 : profile?.repair[0];
|
|
4559
5375
|
return [
|
|
4560
5376
|
typeHint,
|
|
4561
5377
|
"Fix the reported DSL error, then call validateDsl again before rendering or returning DSL."
|
|
4562
5378
|
].filter(Boolean).join(" ");
|
|
4563
5379
|
}
|
|
5380
|
+
function matchRepair(repairs, message) {
|
|
5381
|
+
for (const r of repairs) {
|
|
5382
|
+
const quoted = r.match(/^['"]([^'"]+)['"]/);
|
|
5383
|
+
if (!quoted) continue;
|
|
5384
|
+
const fragment = quoted[1].split(":")[0].trim();
|
|
5385
|
+
if (fragment.length >= 6 && message.includes(fragment)) return r;
|
|
5386
|
+
}
|
|
5387
|
+
return void 0;
|
|
5388
|
+
}
|
|
4564
5389
|
|
|
4565
5390
|
export { DIAGRAM_REGISTRY, DIAGRAM_SINCE, getAllDiagramTypes, getDiagramMeta, getDiagramSince, getExamples, getSyntax, listDiagrams, renderDsl, resolveDiagramType, validateDsl };
|
|
4566
|
-
//# sourceMappingURL=chunk-
|
|
4567
|
-
//# sourceMappingURL=chunk-
|
|
5391
|
+
//# sourceMappingURL=chunk-PR6IAGVP.js.map
|
|
5392
|
+
//# sourceMappingURL=chunk-PR6IAGVP.js.map
|