schematex 0.6.2 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/dist/ai/ai-sdk.cjs +23 -23
  2. package/dist/ai/ai-sdk.d.cts +4 -4
  3. package/dist/ai/ai-sdk.d.ts +4 -4
  4. package/dist/ai/ai-sdk.js +18 -18
  5. package/dist/ai/index.cjs +29 -29
  6. package/dist/ai/index.d.cts +3 -3
  7. package/dist/ai/index.d.ts +3 -3
  8. package/dist/ai/index.js +18 -18
  9. package/dist/{api-XWHHAhQI.d.ts → api-BIqZjEDf.d.ts} +2 -2
  10. package/dist/{api-qVDutqXH.d.cts → api-BXkOT7GL.d.cts} +2 -2
  11. package/dist/browser.cjs +24 -24
  12. package/dist/browser.d.cts +3 -3
  13. package/dist/browser.d.ts +3 -3
  14. package/dist/browser.js +18 -18
  15. package/dist/{chunk-JVAJ6ZLO.js → chunk-35XCP2E4.js} +3 -3
  16. package/dist/{chunk-JVAJ6ZLO.js.map → chunk-35XCP2E4.js.map} +1 -1
  17. package/dist/{chunk-VTSH4YPT.cjs → chunk-3C5DKCBJ.cjs} +12 -12
  18. package/dist/{chunk-VTSH4YPT.cjs.map → chunk-3C5DKCBJ.cjs.map} +1 -1
  19. package/dist/{chunk-HWVBHU3O.cjs → chunk-4THUHX2D.cjs} +5 -5
  20. package/dist/{chunk-HWVBHU3O.cjs.map → chunk-4THUHX2D.cjs.map} +1 -1
  21. package/dist/{chunk-KSNUMQGS.cjs → chunk-624UQ5R6.cjs} +3756 -363
  22. package/dist/chunk-624UQ5R6.cjs.map +1 -0
  23. package/dist/{chunk-LRI4RH2N.js → chunk-AORGFBEH.js} +127 -3
  24. package/dist/chunk-AORGFBEH.js.map +1 -0
  25. package/dist/{chunk-DOK7LKLO.js → chunk-B7ATOBL7.js} +3 -3
  26. package/dist/{chunk-DOK7LKLO.js.map → chunk-B7ATOBL7.js.map} +1 -1
  27. package/dist/{chunk-FKJBXGWP.cjs → chunk-BXNOXOE4.cjs} +4 -4
  28. package/dist/{chunk-FKJBXGWP.cjs.map → chunk-BXNOXOE4.cjs.map} +1 -1
  29. package/dist/{chunk-H4MT5TJP.js → chunk-FHZTWWI6.js} +3 -3
  30. package/dist/{chunk-H4MT5TJP.js.map → chunk-FHZTWWI6.js.map} +1 -1
  31. package/dist/{chunk-2L4YXZAZ.cjs → chunk-FXPOHPBE.cjs} +5 -5
  32. package/dist/{chunk-2L4YXZAZ.cjs.map → chunk-FXPOHPBE.cjs.map} +1 -1
  33. package/dist/{chunk-3VB5AT4R.js → chunk-GPC5BWLI.js} +3 -3
  34. package/dist/{chunk-3VB5AT4R.js.map → chunk-GPC5BWLI.js.map} +1 -1
  35. package/dist/{chunk-MVIEIKOI.js → chunk-GV5QLYTW.js} +3 -3
  36. package/dist/{chunk-MVIEIKOI.js.map → chunk-GV5QLYTW.js.map} +1 -1
  37. package/dist/{chunk-WQDIZH2Z.cjs → chunk-HCBXTBFA.cjs} +12 -12
  38. package/dist/{chunk-WQDIZH2Z.cjs.map → chunk-HCBXTBFA.cjs.map} +1 -1
  39. package/dist/{chunk-6JI6FWLZ.cjs → chunk-I6UJR4SG.cjs} +4 -4
  40. package/dist/{chunk-6JI6FWLZ.cjs.map → chunk-I6UJR4SG.cjs.map} +1 -1
  41. package/dist/{chunk-RJMCWT7Z.js → chunk-IPEHLRTI.js} +3 -3
  42. package/dist/{chunk-RJMCWT7Z.js.map → chunk-IPEHLRTI.js.map} +1 -1
  43. package/dist/{chunk-N5B242WY.js → chunk-KPKGMOTS.js} +3 -3
  44. package/dist/{chunk-N5B242WY.js.map → chunk-KPKGMOTS.js.map} +1 -1
  45. package/dist/{chunk-TWLKXV2O.js → chunk-LGFB4H5B.js} +4 -4
  46. package/dist/{chunk-TWLKXV2O.js.map → chunk-LGFB4H5B.js.map} +1 -1
  47. package/dist/{chunk-IZWKJVIC.js → chunk-MI77LY6A.js} +3728 -337
  48. package/dist/chunk-MI77LY6A.js.map +1 -0
  49. package/dist/{chunk-7F76AWOI.js → chunk-MKECYIWN.js} +3 -3
  50. package/dist/{chunk-7F76AWOI.js.map → chunk-MKECYIWN.js.map} +1 -1
  51. package/dist/{chunk-LGABFD3L.js → chunk-OANWVUBA.js} +100 -25
  52. package/dist/chunk-OANWVUBA.js.map +1 -0
  53. package/dist/{chunk-YS6CGUNH.js → chunk-OHLNH7IO.js} +3 -3
  54. package/dist/{chunk-YS6CGUNH.js.map → chunk-OHLNH7IO.js.map} +1 -1
  55. package/dist/{chunk-L7POWM5B.cjs → chunk-R5E2LSN2.cjs} +129 -2
  56. package/dist/chunk-R5E2LSN2.cjs.map +1 -0
  57. package/dist/{chunk-S3RMAXH5.cjs → chunk-ROX5KEZM.cjs} +15 -15
  58. package/dist/{chunk-S3RMAXH5.cjs.map → chunk-ROX5KEZM.cjs.map} +1 -1
  59. package/dist/{chunk-3IE7KZY4.js → chunk-RVHOCGHT.js} +96 -10
  60. package/dist/chunk-RVHOCGHT.js.map +1 -0
  61. package/dist/{chunk-4UFR2LB6.cjs → chunk-S2CHBZ4A.cjs} +13 -13
  62. package/dist/{chunk-4UFR2LB6.cjs.map → chunk-S2CHBZ4A.cjs.map} +1 -1
  63. package/dist/{chunk-SD6VDTQR.cjs → chunk-T3ZN5P32.cjs} +305 -16
  64. package/dist/chunk-T3ZN5P32.cjs.map +1 -0
  65. package/dist/{chunk-R66QG3XT.cjs → chunk-VZO2SX6Q.cjs} +98 -10
  66. package/dist/chunk-VZO2SX6Q.cjs.map +1 -0
  67. package/dist/{chunk-ECD5XHBM.cjs → chunk-W3IXH6BN.cjs} +100 -25
  68. package/dist/chunk-W3IXH6BN.cjs.map +1 -0
  69. package/dist/{chunk-V4GILQR6.cjs → chunk-WZ5QBGPZ.cjs} +4 -4
  70. package/dist/{chunk-V4GILQR6.cjs.map → chunk-WZ5QBGPZ.cjs.map} +1 -1
  71. package/dist/{chunk-FBS3PACU.js → chunk-XEIVA2CT.js} +3 -3
  72. package/dist/{chunk-FBS3PACU.js.map → chunk-XEIVA2CT.js.map} +1 -1
  73. package/dist/{chunk-3JAI3OVG.cjs → chunk-XJJUJ2EF.cjs} +4 -4
  74. package/dist/{chunk-3JAI3OVG.cjs.map → chunk-XJJUJ2EF.cjs.map} +1 -1
  75. package/dist/{chunk-C5C5EF3W.cjs → chunk-XO7WW3I6.cjs} +4 -4
  76. package/dist/{chunk-C5C5EF3W.cjs.map → chunk-XO7WW3I6.cjs.map} +1 -1
  77. package/dist/{chunk-HAZALB7U.js → chunk-XSPENTEG.js} +3 -3
  78. package/dist/{chunk-HAZALB7U.js.map → chunk-XSPENTEG.js.map} +1 -1
  79. package/dist/{chunk-YB4XJY5L.cjs → chunk-ZZFPXCAK.cjs} +12 -12
  80. package/dist/{chunk-YB4XJY5L.cjs.map → chunk-ZZFPXCAK.cjs.map} +1 -1
  81. package/dist/{chunk-ITUPR7G5.js → chunk-ZZHQBAC3.js} +303 -14
  82. package/dist/chunk-ZZHQBAC3.js.map +1 -0
  83. package/dist/{diagnostics-DRxhodP6.d.ts → diagnostics-CzHW0RCo.d.cts} +7 -3
  84. package/dist/{diagnostics-DRxhodP6.d.cts → diagnostics-CzHW0RCo.d.ts} +7 -3
  85. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  86. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  87. package/dist/diagrams/circuit/index.cjs +8 -8
  88. package/dist/diagrams/circuit/index.d.cts +1 -1
  89. package/dist/diagrams/circuit/index.d.ts +1 -1
  90. package/dist/diagrams/circuit/index.js +2 -2
  91. package/dist/diagrams/ecomap/index.cjs +7 -7
  92. package/dist/diagrams/ecomap/index.d.cts +1 -1
  93. package/dist/diagrams/ecomap/index.d.ts +1 -1
  94. package/dist/diagrams/ecomap/index.js +2 -2
  95. package/dist/diagrams/entity/index.cjs +6 -6
  96. package/dist/diagrams/entity/index.d.cts +1 -1
  97. package/dist/diagrams/entity/index.d.ts +1 -1
  98. package/dist/diagrams/entity/index.js +2 -2
  99. package/dist/diagrams/fishbone/index.cjs +8 -8
  100. package/dist/diagrams/fishbone/index.d.cts +1 -1
  101. package/dist/diagrams/fishbone/index.d.ts +1 -1
  102. package/dist/diagrams/fishbone/index.js +2 -2
  103. package/dist/diagrams/flowchart/index.cjs +8 -8
  104. package/dist/diagrams/flowchart/index.d.cts +2 -2
  105. package/dist/diagrams/flowchart/index.d.ts +2 -2
  106. package/dist/diagrams/flowchart/index.js +2 -2
  107. package/dist/diagrams/genogram/index.cjs +9 -9
  108. package/dist/diagrams/genogram/index.d.cts +1 -1
  109. package/dist/diagrams/genogram/index.d.ts +1 -1
  110. package/dist/diagrams/genogram/index.js +2 -2
  111. package/dist/diagrams/ladder/index.cjs +7 -7
  112. package/dist/diagrams/ladder/index.d.cts +1 -1
  113. package/dist/diagrams/ladder/index.d.ts +1 -1
  114. package/dist/diagrams/ladder/index.js +3 -3
  115. package/dist/diagrams/logic/index.cjs +15 -6
  116. package/dist/diagrams/logic/index.d.cts +7 -2
  117. package/dist/diagrams/logic/index.d.ts +7 -2
  118. package/dist/diagrams/logic/index.js +3 -2
  119. package/dist/diagrams/orgchart/index.cjs +7 -7
  120. package/dist/diagrams/orgchart/index.d.cts +1 -1
  121. package/dist/diagrams/orgchart/index.d.ts +1 -1
  122. package/dist/diagrams/orgchart/index.js +2 -2
  123. package/dist/diagrams/pedigree/index.cjs +7 -7
  124. package/dist/diagrams/pedigree/index.d.cts +1 -1
  125. package/dist/diagrams/pedigree/index.d.ts +1 -1
  126. package/dist/diagrams/pedigree/index.js +2 -2
  127. package/dist/diagrams/phylo/index.cjs +7 -7
  128. package/dist/diagrams/phylo/index.d.cts +1 -1
  129. package/dist/diagrams/phylo/index.d.ts +1 -1
  130. package/dist/diagrams/phylo/index.js +2 -2
  131. package/dist/diagrams/sld/index.cjs +9 -9
  132. package/dist/diagrams/sld/index.d.cts +1 -1
  133. package/dist/diagrams/sld/index.d.ts +1 -1
  134. package/dist/diagrams/sld/index.js +3 -3
  135. package/dist/diagrams/sociogram/index.cjs +6 -6
  136. package/dist/diagrams/sociogram/index.d.cts +1 -1
  137. package/dist/diagrams/sociogram/index.d.ts +1 -1
  138. package/dist/diagrams/sociogram/index.js +2 -2
  139. package/dist/diagrams/timing/index.d.cts +1 -1
  140. package/dist/diagrams/timing/index.d.ts +1 -1
  141. package/dist/diagrams/venn/index.cjs +9 -9
  142. package/dist/diagrams/venn/index.d.cts +1 -1
  143. package/dist/diagrams/venn/index.d.ts +1 -1
  144. package/dist/diagrams/venn/index.js +2 -2
  145. package/dist/{index-C7SN-FB3.d.ts → index-DdR1Auby.d.ts} +1 -1
  146. package/dist/{index-BRIkOPnd.d.cts → index-R0IwpG20.d.cts} +1 -1
  147. package/dist/index.cjs +80 -72
  148. package/dist/index.d.cts +9 -5
  149. package/dist/index.d.ts +9 -5
  150. package/dist/index.js +22 -22
  151. package/dist/react.cjs +18 -18
  152. package/dist/react.d.cts +2 -2
  153. package/dist/react.d.ts +2 -2
  154. package/dist/react.js +17 -17
  155. package/dist/{tools-BVeUNdsU.d.ts → tools-B7EqXLgD.d.ts} +3 -3
  156. package/dist/{tools-DdhP1kWY.d.cts → tools-DHSVXHM9.d.cts} +3 -3
  157. package/package.json +1 -1
  158. package/dist/chunk-3IE7KZY4.js.map +0 -1
  159. package/dist/chunk-ECD5XHBM.cjs.map +0 -1
  160. package/dist/chunk-ITUPR7G5.js.map +0 -1
  161. package/dist/chunk-IZWKJVIC.js.map +0 -1
  162. package/dist/chunk-KSNUMQGS.cjs.map +0 -1
  163. package/dist/chunk-L7POWM5B.cjs.map +0 -1
  164. package/dist/chunk-LGABFD3L.js.map +0 -1
  165. package/dist/chunk-LRI4RH2N.js.map +0 -1
  166. package/dist/chunk-R66QG3XT.cjs.map +0 -1
  167. package/dist/chunk-SD6VDTQR.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { parseResult, renderResult } from './chunk-IZWKJVIC.js';
1
+ import { parseResult, renderResult } from './chunk-MI77LY6A.js';
2
2
 
3
3
  // src/ai/registry.ts
4
4
  var DIAGRAM_REGISTRY = [
@@ -263,6 +263,25 @@ var DIAGRAM_REGISTRY = [
263
263
  standard: "PMI PMBOK 7 + Moder 1983 (AON/PDM); see 32-PERT-STANDARD.md",
264
264
  syntaxKey: "pert"
265
265
  },
266
+ // ── Structural UML ───────────────────────────────────────────
267
+ {
268
+ type: "umlclass",
269
+ name: "UML Class Diagram",
270
+ tagline: "OMG UML 2.5.1 class diagram \u2014 classifiers (class / abstract / interface / enum / datatype / primitive) joined by the six relationship kinds, with visibility, multiplicity, and stereotypes.",
271
+ useWhen: "Use for OO design \u2014 the static type structure of a software system. Declare `class X { + name: T }` / `\xABinterface\xBB Y { + op(): R }` / `\xABenumeration\xBB Z { A B C }`, then connect with PlantUML-flavoured glyphs: `<|--` generalization (hollow triangle to parent), `<|..` realization (dashed + hollow triangle to interface), `*--` composition (filled diamond at the whole), `o--` aggregation (hollow diamond at the whole), `-->` directed association (open arrow to target), `..>` dependency (dashed + open arrow), `--` plain association. Adornment placement is normalised regardless of which id is typed first (reversed forms accepted). Mermaid `classDiagram` glyphs work as aliases. Layout is generalization-driven (parents on top by default). Distinct from `erd` (data tables + crow's-foot \u2014 no visibility/methods/inheritance) and from `entity` (legal/corporate ownership). This is the C4 (\xA730) Code-level engine.",
272
+ cluster: "software-uml",
273
+ standard: "OMG UML 2.5.1 \xA79\u2013\xA711 (Classification / Classifiers / Associations) + ISO/IEC 19505-2:2012; see 36-UMLCLASS-STANDARD.md",
274
+ syntaxKey: "umlclass"
275
+ },
276
+ {
277
+ type: "faulttree",
278
+ name: "Fault Tree Analysis",
279
+ tagline: "Deductive top-down reliability analysis \u2014 decompose one undesired top event through Boolean AND/OR/voting gates to basic component failures; the engine computes the minimal cut sets and the top-event probability.",
280
+ useWhen: 'Use for safety / reliability analysis: start from one top event and decompose its causes through gates down to basic events with known failure probabilities. Flat declaration wired by id: `top T "\u2026" = OR(G1, G2)`, `gate G1 = AND(A, B)`, `basic A "\u2026" p: 0.01`. Gates: AND/OR/XOR(a,b,\u2026), VOTING(k/n; \u2026), INHIBIT(x) if cond, PAND(a,b). `house H state: 0|1` switches branches; `undeveloped` for unanalysed causes. The engine *computes* the minimal cut sets (MOCUS) and P(top) (`prob: rare|mcub|exact`) and highlights single points of failure \u2014 the differentiator over a shape stencil. Keyword `faulttree` (alias `fta`). Distinct from `logic` (left-right signal netlist), `decisiontree` (expected-value rollback), and `fishbone` (qualitative, unquantified).',
281
+ cluster: "risk-reliability",
282
+ standard: "NUREG-0492 Fault Tree Handbook + IEC 61025:2006 + NASA FT Handbook 2002; MOCUS cut sets (Fussell-Vesely 1972); see 37-FAULT-TREE-STANDARD.md",
283
+ syntaxKey: "faulttree"
284
+ },
266
285
  // ── Generic process / flow ───────────────────────────────────
267
286
  {
268
287
  type: "flowchart",
@@ -354,7 +373,11 @@ var DIAGRAM_SINCE = {
354
373
  // 0.6.0 — upcoming (committed post-0.5.2, not yet released)
355
374
  pert: "0.6.0",
356
375
  petri: "0.6.0",
357
- network: "0.6.0"
376
+ network: "0.6.0",
377
+ // 0.6.4
378
+ umlclass: "0.6.4",
379
+ // 0.6.5
380
+ faulttree: "0.6.5"
358
381
  };
359
382
  function getDiagramSince(type) {
360
383
  const resolved = resolveDiagramType(type);
@@ -885,6 +908,83 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
885
908
  "dsl": 'erd\ntitle: "University Schema"\n\ntable Student {\n student_id int PK\n name varchar\n email varchar UK\n major_id int FK -> Major.major_id\n}\n\ntable Major {\n major_id int PK\n name varchar\n}\n\ntable Course {\n course_id int PK\n title varchar\n credits int\n}\n\ntable Enrollment {\n student_id int PK FK -> Student.student_id\n course_id int PK FK -> Course.course_id\n grade char\n}\n\nref Student.major_id many-mandatory -- one-mandatory Major.major_id : "majors in"\nref Enrollment.student_id many-mandatory -- one-mandatory Student.student_id\nref Enrollment.course_id many-mandatory -- one-mandatory Course.course_id',
886
909
  "notes": "The university schema is the canonical introduction to associative entities. The M:N relationship between Student and Course is resolved through Enrollment, which carries the relationship attribute `grade`. Both Student and Course join Enrollment via composite primary keys (each FK column doubles as part of the PK)."
887
910
  },
911
+ {
912
+ "slug": "faulttree-pump-redundancy",
913
+ "diagram": "faulttree",
914
+ "title": "Redundant pump failure (AND gate)",
915
+ "description": "The smallest quantified fault tree \u2014 two redundant pumps in an AND gate, so the system fails only if both fail. One minimal cut set, no single point of failure, with a computed top-event probability.",
916
+ "standard": "NUREG-0492 / IEC 61025",
917
+ "tags": [
918
+ "faulttree",
919
+ "fta",
920
+ "reliability",
921
+ "and-gate",
922
+ "cut-sets",
923
+ "probability"
924
+ ],
925
+ "complexity": 1,
926
+ "featured": true,
927
+ "dsl": 'faulttree "Both pumps fail"\n analysis: cutsets, probability\n top T "Both redundant pumps fail" = AND(PA, PB)\n basic PA "Pump A fails" p: 0.01\n basic PB "Pump B fails" p: 0.01',
928
+ "notes": "## What this shows\n\nThe canonical reliability argument for redundancy. The top event occurs only when **both** pumps fail, so the gate is an **AND** (drawn as the flat-bottomed dome). The engine computes the one **minimal cut set `{PA, PB}`** (order 2, boxed in red) and \u2014 because no single component alone causes the top event \u2014 reports **no single point of failure**.\n\n**P(top) is computed, not drawn.** With independent basic events, `P(top) \u2248 P(PA)\xB7P(PB) = 1.0e-4` (rare-event). Adding a second pump turned two 1-in-100 components into a 1-in-10,000 system \u2014 exactly the quantified payoff redundancy is meant to deliver."
929
+ },
930
+ {
931
+ "slug": "faulttree-repeated-event",
932
+ "diagram": "faulttree",
933
+ "title": "Repeated event with cut-set absorption",
934
+ "description": "A shared basic event feeds two gates \u2014 the case naive fault-tree tools get wrong. MOCUS applies absorption so the supersets collapse, leaving two single points of failure that a shape stencil would miss.",
935
+ "standard": "NUREG-0492 / MOCUS (Fussell-Vesely 1972)",
936
+ "tags": [
937
+ "faulttree",
938
+ "fta",
939
+ "cut-sets",
940
+ "repeated-event",
941
+ "absorption",
942
+ "spof"
943
+ ],
944
+ "complexity": 2,
945
+ "featured": true,
946
+ "dsl": 'faulttree "Product not removed"\n analysis: cutsets, probability\n top T "Failure to remove product" = OR(G1, G2)\n gate G1 "Arm jams or collides" = AND(MSF, G3)\n gate G2 "Wrong slot commanded" = OR(CDM, MSF)\n gate G3 "Loss of position feedback" = OR(ESF, RCF)\n basic MSF "Manipulator system failure" p: 0.0035\n basic CDM "Controller command error" p: 0.0009\n basic ESF "Encoder sensor failure" p: 0.0021\n basic RCF "Resolver cable fault" p: 0.0012',
947
+ "notes": "## What this shows\n\n`MSF` feeds **both** `G1` and `G2` \u2014 a *repeated event*, the DAG case that separates a real engine from a shape stencil. It is drawn once per reference with the shared-event mark, but the cut-set engine treats every instance as the same Boolean variable.\n\n**Absorption is the point.** MOCUS first expands the tree to `{MSF, ESF}`, `{MSF, RCF}`, `{MSF}`, `{CDM}`. Because `{MSF}` is itself a cut set (via `G2`), the larger sets `{MSF, ESF}` and `{MSF, RCF}` are *absorbed* \u2014 a superset of a cut set is not minimal. The **two minimal cut sets are `{MSF}` and `{CDM}`**, both order-1 **single points of failure** (boxed in the strongest red). A naive expander that forgets absorption would wrongly report four. `P(top) \u2248 P(MSF) + P(CDM) = 0.0044`."
948
+ },
949
+ {
950
+ "slug": "faulttree-vessel-rupture",
951
+ "diagram": "faulttree",
952
+ "title": "Pressure vessel rupture (full vocabulary)",
953
+ "description": "Voting, inhibit, house and undeveloped events in one tree \u2014 a 2-of-2 relief group, an over-pressure inhibited by a heater condition, and an order-3 minimal cut set with the tighter MCUB probability.",
954
+ "standard": "NUREG-0492 / IEC 61025",
955
+ "tags": [
956
+ "faulttree",
957
+ "fta",
958
+ "voting",
959
+ "inhibit",
960
+ "house-event",
961
+ "undeveloped",
962
+ "mcub"
963
+ ],
964
+ "complexity": 3,
965
+ "featured": false,
966
+ "dsl": 'faulttree "Vessel ruptures"\n analysis: cutsets, probability\n prob: mcub\n top TOP "Pressure vessel ruptures" = AND(OVP, RELIEF)\n gate OVP "Sustained over-pressure" = INHIBIT(PUMP) if HEATER\n gate RELIEF "Both reliefs fail" = VOTING(2/2; PRV_A, PRV_B)\n basic PUMP "Pump runaway" p: 0.004\n basic PRV_A "Relief A stuck" p: 0.02\n basic PRV_B "Relief B stuck" p: 0.02\n house HEATER "Heater energised" state: 1\n undeveloped EXT "External fire (not modelled)"',
967
+ "notes": "## What this shows\n\nThe full NUREG-0492 vocabulary in one tree. **INHIBIT** renders as a hexagon with the `HEATER` conditioning event as an ellipse on its side; because `HEATER` is a **house event** forced to `state: 1`, it is absorbed as a constant TRUE and `OVP` reduces to `{PUMP}`. **VOTING `2/2`** is a redundant relief group that fails only when both valves stick.\n\nThe single **minimal cut set is `{PUMP, PRV_A, PRV_B}`** (order 3), and `prob: mcub` reports the minimal-cut-set upper bound \u2014 tighter than the rare-event default. `EXT` is an **undeveloped event** (diamond) that is declared but referenced by no gate, so it is noted as unconnected in the diagram description. Switching the heater to `state: 0` would prune the over-pressure branch entirely and make the top event unsatisfiable."
968
+ },
969
+ {
970
+ "slug": "faulttree-water-overheating",
971
+ "diagram": "faulttree",
972
+ "title": "Water overheating (classic textbook tree)",
973
+ "description": "The canonical introductory fault tree \u2014 an OR top over an AND sub-fault and an OR no-voltage branch, with a probability on every basic event. A faithful, quantified reproduction of the standard worked example.",
974
+ "standard": "NUREG-0492 / IEC 61025",
975
+ "tags": [
976
+ "faulttree",
977
+ "fta",
978
+ "and-or",
979
+ "cut-sets",
980
+ "probability",
981
+ "textbook"
982
+ ],
983
+ "complexity": 2,
984
+ "featured": false,
985
+ "dsl": 'faulttree "Water overheating"\n analysis: cutsets, probability\n top T "Water overheating" = OR(F, E, G)\n gate F "Circuit failure and no warning lamp" = AND(A, B)\n gate G "No voltage at input" = OR(C, D)\n basic E "Booster failure" p: 0.02\n basic A "Chip failure" p: 0.05\n basic B "Warning lamp burned" p: 0.03\n basic C "No burn in network" p: 0.12\n basic D "Fuse blown" p: 0.23',
986
+ "notes": "## What this shows\n\nThe fault tree every reliability course opens with, rendered with computed cut sets. The top event **OR**s three branches: an **AND** sub-fault `F` (a circuit failure *and* a dead warning lamp must coincide), a direct booster failure `E`, and an **OR** no-voltage branch `G`.\n\nThe minimal cut sets mix orders: `{E}`, `{C}`, `{D}` are order-1 **single points of failure** (any one trips the top event), while `{A, B}` is order-2 (both the chip and the lamp must fail together). Each is boxed in red, single points of failure in the strongest red, and the top-event probability is computed from the per-event values \u2014 the deductive, quantified reading a fault tree exists to give."
987
+ },
888
988
  {
889
989
  "slug": "fbd-bottle-counter",
890
990
  "diagram": "fbd",
@@ -2486,6 +2586,104 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
2486
2586
  "dsl": 'timing "SPI Transaction"\nCLK: pppppppp\nCS_N: 10000001\nMOSI: x======= data: ["0xAB","0xCD","0xEF","0x01","0x02","0x03","0x04","0x05"]\nMISO: zzzz==== data: ["","","","","0xFF","0x12","0x34","0x56"]',
2487
2587
  "notes": "## Scenario\n\nA firmware engineer or hardware designer documents an 8-byte SPI master-to-slave transaction for a device driver review or datasheet. The WaveDrom-compatible syntax means the same DSL can be pasted directly into WaveDrom's online editor or embedded in documentation pipelines.\n\n## Annotation key\n\n- `p` \u2014 clock pulse (high period followed by low); each `p` is one clock cycle\n- `1` / `0` \u2014 logic high / logic low\n- `=` \u2014 data bus: stable data (value unchanged from previous cycle)\n- `x` \u2014 don't-care or undefined state (transition state)\n- `z` \u2014 high-impedance (floating / tri-state)\n- `data: [...]` \u2014 optional data labels for each stable segment, rendered inside the bus bar\n- `CS_N` \u2014 active-low chip select; `1` = deselected, `0` = selected\n\n## How to read\n\nThe clock runs for 8 cycles. CS_N goes low at cycle 1 and returns high at cycle 8, framing the transaction. MOSI (master out) sends 8 bytes starting at cycle 1. MISO (slave in) is high-Z for the first 4 cycles (slave preparing the response) then transitions to stable data bytes 5\u20138. The transaction completes when CS_N de-asserts."
2488
2588
  },
2589
+ {
2590
+ "slug": "umlclass-generics-mermaid",
2591
+ "diagram": "umlclass",
2592
+ "title": "Generics and Mermaid-compatible syntax",
2593
+ "description": "A generic repository written in Mermaid classDiagram shorthand \u2014 tilde-generics, single-line members, and member classifiers \u2014 all rendered with standard-correct adornments, so a Mermaid snippet migrates in one line.",
2594
+ "standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
2595
+ "tags": [
2596
+ "umlclass",
2597
+ "uml",
2598
+ "mermaid",
2599
+ "generics",
2600
+ "interface",
2601
+ "realization"
2602
+ ],
2603
+ "complexity": 2,
2604
+ "featured": false,
2605
+ "dsl": "classDiagram\nclass Repository~T~ {\n +findAll() List~T~\n +findById(id : ID) Optional~T~\n +cache : Map~String,List~int~~\n +count$\n +flush()*\n}\nclass CrudService\nCrudService : <<service>>\nCrudService : +repo : Repository~User~\nCrudService : +save(e : User) User\nRepository~T~ <|.. CrudService",
2606
+ "notes": "## What this shows\n\nThe same diagram a developer would paste from a Mermaid `classDiagram`, rendered with Schematex's standard-correct adornments and layered layout.\n\n**Tilde-generics** convert to angle brackets: `List~T~` \u2192 `List`, and they nest \u2014 `Map~String,List~int~~` \u2192 `Map>`. The generic also works on the class name itself (`class Repository~T~` \u2192 `Repository`).\n\n**Single-line members** append to a class: `CrudService : +repo : Repository~User~` adds an attribute, and `CrudService : <<service>>` sets the stereotype \u2014 no `{ \u2026 }` block required.\n\n**Member classifiers** are the Mermaid suffixes: `flush()*` marks an abstract operation (rendered italic) and `count$` a static member (rendered underlined). Return types may be space-separated (`findAll() List~T~`) the way Mermaid writes them. A lone leading `~` is still the package-visibility glyph, so the two never collide."
2607
+ },
2608
+ {
2609
+ "slug": "umlclass-namespaces",
2610
+ "diagram": "umlclass",
2611
+ "title": "Packages and namespaces",
2612
+ "description": "Group classifiers into labelled containment frames with namespace blocks \u2014 dot-notation auto-creates parent packages, and blocks nest, so a layered architecture reads as nested boxes the way an architect draws it.",
2613
+ "standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
2614
+ "tags": [
2615
+ "umlclass",
2616
+ "uml",
2617
+ "namespace",
2618
+ "package",
2619
+ "architecture",
2620
+ "mermaid"
2621
+ ],
2622
+ "complexity": 2,
2623
+ "featured": false,
2624
+ "dsl": 'umlclass\ntitle: "Layered packages"\n\nnamespace Platform {\nnamespace Auth {\nclass UserService {\n + login()\n + logout()\n}\n}\nnamespace Data {\nclass Repository {\n + find()\n + save()\n}\n}\n}\n\nclass Gateway {\n + route()\n}\n\nGateway --> UserService : delegates\nGateway --> Repository : delegates',
2625
+ "notes": '## What this shows\n\nA **`namespace` block** groups its classifiers into a labelled bounding frame. Frames are computed as the **union of their members plus any nested sub-packages**, padded, with a label band on top \u2014 the same C4-style containment Schematex uses for the `network` engine\'s site/zone boundaries. Here `Platform` contains `Auth` and `Data`, each holding one service; `Gateway` lives outside the package and delegates into both.\n\n**Frames never overlap and always enclose.** A package-clustering pass keeps same-package classifiers contiguous within each layout rank, so the frame stays a clean rectangle instead of a ragged shape that swallows unrelated boxes.\n\n**Dot-notation also works.** Writing `namespace Company.Engineering.Backend { \u2026 }` auto-creates `Company` and `Company.Engineering` as parent frames, so you can declare a deep package in one line. An explicit label is available too: `namespace plat["Platform Layer"] { \u2026 }`.'
2626
+ },
2627
+ {
2628
+ "slug": "umlclass-order-model",
2629
+ "diagram": "umlclass",
2630
+ "title": "Order model \u2014 aggregation, composition, and dependency",
2631
+ "description": "A small domain model that exercises every relationship-end adornment that confuses first-time UML readers \u2014 filled diamond for composition, hollow diamond for aggregation, plain association, and a dashed dependency.",
2632
+ "standard": "OMG UML 2.5.1 \xA711.5 (Associations)",
2633
+ "tags": [
2634
+ "umlclass",
2635
+ "uml",
2636
+ "composition",
2637
+ "aggregation",
2638
+ "dependency",
2639
+ "multiplicity",
2640
+ "static",
2641
+ "derived"
2642
+ ],
2643
+ "complexity": 2,
2644
+ "featured": true,
2645
+ "dsl": 'umlclass\ntitle: "Order model"\n\nclass Order {\n - id : String\n + total : Money {readOnly}\n + place() : void\n + count : int {static}\n}\n\nclass LineItem {\n + qty : int\n + subtotal() : Money\n}\n\nclass Customer {\n + name : String\n}\n\nclass Address {\n + city : String\n}\n\nclass TaxPolicy {\n + rate(c : Country) : Percent\n}\n\nOrder *-- "1..*" LineItem : contains\nCustomer o-- "0..*" Address : has\nCustomer "1" -- "*" Order : places\nOrder ..> TaxPolicy : uses',
2646
+ "notes": "## Why the diamonds are not interchangeable\n\nUML's two diamond shapes encode genuinely different lifetime semantics, and they're the single most-confused pair on the notation.\n\n**Composition** (filled diamond) means *the part dies with the whole*: when an `Order` is deleted, its `LineItem`s are deleted with it \u2014 the line items have no independent existence. The filled diamond sits at the `Order` (whole) end of `*--`, regardless of which id the author typed first.\n\n**Aggregation** (hollow diamond) means *the part outlives the whole*: an `Address` exists in its own right and a `Customer` aggregating it is just a structural reference \u2014 deleting the customer should not delete the address.\n\n**Plain association** (no diamond) is just \"these two types are structurally linked\" \u2014 the line carries multiplicity (`1` \u2194 `*`) and a name (`places`) but makes no claim about ownership.\n\n**Dependency** (dashed + open arrow) says `Order` *uses* `TaxPolicy` without holding a reference to it \u2014 typically a method parameter or a transient call. The dashed line distinguishes a using-relationship from a structural one at a glance.\n\nThe `{readOnly}`, `{static}`, and `{abstract}` property strings render as the standard UML annotations; `count` is underlined to mark it as class-scope."
2647
+ },
2648
+ {
2649
+ "slug": "umlclass-payment-strategy",
2650
+ "diagram": "umlclass",
2651
+ "title": "Payment strategy pattern with enum + custom stereotype",
2652
+ "description": "The Strategy pattern as a UML class diagram \u2014 a payment service depending on an interface that three concrete strategies realize, plus an enumeration for the supported methods and a custom \xABservice\xBB stereotype.",
2653
+ "standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
2654
+ "tags": [
2655
+ "umlclass",
2656
+ "uml",
2657
+ "strategy-pattern",
2658
+ "interface",
2659
+ "enum",
2660
+ "stereotype",
2661
+ "dependency"
2662
+ ],
2663
+ "complexity": 2,
2664
+ "featured": false,
2665
+ "dsl": 'umlclass\ntitle: "Payment strategy"\n\n\xABenumeration\xBB PaymentMethod {\n CARD\n BANK_TRANSFER\n WALLET\n}\n\n\xABinterface\xBB PaymentStrategy {\n + authorize(amount : Money) : AuthResult\n + capture(auth : AuthResult) : Receipt\n}\n\n\xABservice\xBB class CheckoutService {\n - strategies : Map<PaymentMethod, PaymentStrategy>\n + pay(method : PaymentMethod, amount : Money) : Receipt\n}\n\nclass CardStrategy { + authorize(amount : Money) : AuthResult + capture(auth : AuthResult) : Receipt }\nclass BankStrategy { + authorize(amount : Money) : AuthResult + capture(auth : AuthResult) : Receipt }\nclass WalletStrategy { + authorize(amount : Money) : AuthResult + capture(auth : AuthResult) : Receipt }\n\nPaymentStrategy <|.. CardStrategy\nPaymentStrategy <|.. BankStrategy\nPaymentStrategy <|.. WalletStrategy\n\nCheckoutService ..> PaymentStrategy : delegates to\nCheckoutService ..> PaymentMethod : selects by',
2666
+ "notes": "## Reading the diagram\n\nThe Strategy pattern is one of the canonical Gang-of-Four examples and is almost always introduced as a UML class diagram for a reason: a single picture says exactly what an interface-based design buys you.\n\n**`\xABenumeration\xBB` and `\xABservice\xBB` are both stereotypes.** The enum keyword is a standard UML stereotype that swaps the rendering: literals sit in the attribute compartment without visibility glyphs, and there's no operations compartment populated. The `\xABservice\xBB` keyword on `CheckoutService` is a *custom* stereotype \u2014 any guillemet-wrapped word above a class name. Custom stereotypes are how teams tag classifiers with their architectural role (`\xABservice\xBB`, `\xABcontroller\xBB`, `\xABentity\xBB`, `\xABrepository\xBB`) without inventing new visual primitives.\n\n**Realization vs dependency at a glance.** The three concrete strategies *realize* the interface \u2014 dashed line, hollow triangle, drawn three times pointing at the same interface (a future render pass may merge the triangle heads into a single shared head). The `CheckoutService`'s relationship is a *dependency* \u2014 it uses both `PaymentStrategy` and `PaymentMethod` through its public API but does not commit to a structural containment. The dashed-line-with-open-arrow encoding makes the using-relationship visible without implying ownership.\n\nThe `Map` attribute type renders inline as text \u2014 generic type *names* are part of v0.1; parameterised classifier *boxes* (`List`) are deferred."
2667
+ },
2668
+ {
2669
+ "slug": "umlclass-shape-hierarchy",
2670
+ "diagram": "umlclass",
2671
+ "title": "Shape class hierarchy with an interface",
2672
+ "description": "The canonical UML 2.5.1 class diagram \u2014 an interface, an abstract base class, and two concrete leaves \u2014 showing generalization, realization, and a generalization-driven layered layout where parents float to the top.",
2673
+ "standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
2674
+ "tags": [
2675
+ "umlclass",
2676
+ "uml",
2677
+ "generalization",
2678
+ "realization",
2679
+ "interface",
2680
+ "abstract-class"
2681
+ ],
2682
+ "complexity": 1,
2683
+ "featured": true,
2684
+ "dsl": 'umlclass\ntitle: "Shape hierarchy"\n\n\xABinterface\xBB Shape {\n + area() : double\n + perimeter() : double\n}\n\nabstract class AbstractShape {\n # name : String\n + area() : double {abstract}\n + perimeter() : double {abstract}\n + describe() : String\n}\n\nclass Circle {\n + radius : double\n + area() : double\n + perimeter() : double\n}\n\nclass Square {\n + side : double\n + area() : double\n + perimeter() : double\n}\n\nShape <|.. AbstractShape\nAbstractShape <|-- Circle\nAbstractShape <|-- Square',
2685
+ "notes": "## What this shows\n\nThe smallest diagram that exercises the three notations every UML primer covers in the first hour: an **interface** (rendered with the `\xABinterface\xBB` keyword), an **abstract class** (rendered in *italics*, with an abstract `area()` operation also in italics), and two concrete leaves.\n\n**Layering is generalization-driven.** Inheritance edges (`<|--`) and realization edges (`<|..`) define the rank hierarchy, so the interface floats to the very top, the abstract base sits below it, and the two concrete classes anchor the bottom \u2014 without any author-side layout hints. This is the visual default a UML textbook expects, and it's why a class diagram should not ride a generic flowchart layout.\n\n**Adornments carry the semantics.** Realization is dashed + hollow triangle; generalization is solid + hollow triangle. The two distinctions render identically in `theme: monochrome` because the meaning is in the shape, not the colour \u2014 exactly the point of UML 2.5.1."
2686
+ },
2489
2687
  {
2490
2688
  "slug": "usecase-atm",
2491
2689
  "diagram": "usecase",
@@ -2692,6 +2890,14 @@ var SYNTAX = {
2692
2890
  "network": {
2693
2891
  "title": "Network Topology",
2694
2892
  "content": '## 1. Your first diagram\n\nA complete network diagram needs only two kinds of line: **device declarations** and **links**. Nothing else is required.\n\n```\nnetwork "Tiny LAN"\nrouter r1 "Edge Router"\nswitch sw1 "Core Switch"\npc pc1 "Workstation"\nr1 -- sw1\nsw1 -- pc1\n```\n\nThat\'s it \u2014 a valid, laid-out diagram. Just two rules:\n\n- `<kind> <id> ["label"]` \u2014 a typed device. The kind picks the icon.\n- `<a> -- <b>` \u2014 an undirected link between two declared devices.\n\n**Everything else is optional and additive \u2014 but not all of it is equal.** Two cheap, high-value structural hints are worth adding whenever hierarchy matters: `layout:` (tiered/tree/star/ring/bus/mesh/spine-leaf) and `tier:` (edge/core/distribution/access). They drive a readable top-down hierarchy at almost no syntax cost:\n\n```\nnetwork "Branch"\n layout: tiered\n router r1 "Edge Router" tier: edge\n l3switch core1 "Core SW" tier: core\n switch acc1 "Access SW" tier: access\n pc pc1 "Workstation"\n r1 -- core1\n core1 -- acc1\n acc1 -- pc1\n```\n\nBy contrast, the **per-link annotations** \u2014 link types (`fiber`/`wireless`/`poe`\u2026), speeds, `vlan:`, `port:`, `trunk`/`access`, and `subnet { }` boundaries \u2014 don\'t affect layout and are where generation most often breaks. Add them only when the request calls for them. Rule of thumb: keep the structural hints, drop the decorative annotations unless asked.\n\nDevices are **not** auto-declared from links \u2014 an undeclared id can\'t be safely typed, so a link to an unknown device is a readable error. Use `;` to put several statements on one line, and `a b c : kind` shorthand to declare several same-kind devices at once.\n\nOnce the skeleton works, you can layer on direction and annotations \u2014 `->` is a directed link, `==` is a LAG, and anything after `:` is the link spec:\n\n```\nnetwork "Home"\n layout: star\n router gw "Gateway"\n pc pc1\n laptop lt1\n gw -- pc1\n gw -- lt1 : wireless\n```\n\n---\n\n## 2. Device kinds\n\nPick the kind that matches the box; the icon follows the Cisco-convention silhouette.\n\n- **Infrastructure** \u2014 `router`, `switch`, `l3switch`, `firewall`, `loadbalancer`, `ap`, `wlc`, `gateway`, `modem`, `ids`, `proxy`, `vpngw`\n- **Endpoints** \u2014 `server`, `serverfarm` (`count: n`), `pc`, `laptop`, `mobile`, `ipphone`, `printer`, `storage`\n- **CCTV / security** \u2014 `camera` (with `type: fixed | bullet | dome | ptz | turret`), `nvr`, `dvr`, `poeswitch`, `encoder`, `monitor`\n- **Clouds** \u2014 `internet`, `wan`, `pstn`, `cloud`, plus `lan` (a bus bar)\n\nAliases are accepted: `multilayer`\u2192`l3switch`, `workstation`\u2192`pc`, `wifi`\u2192`ap`, `nas`/`san`\u2192`storage`, `voip`\u2192`ipphone`.\n\n```\ncamera cam1 type: dome ip: 192.168.20.11\nserverfarm farm "Server Farm" count: 4\nl3switch core1 tier: core model: "C9500"\n```\n\n---\n\n## 3. Links & annotations\n\nA link\'s appearance follows its type; everything after `:` is order-free.\n\n```\na -- b # copper / ethernet (default solid)\na -- b : fiber 10G # fiber \u2014 orange with slash ticks\na -- b : wireless # dashed\na -- b : serial # leased / WAN circuit\na -- b : poe # Power-over-Ethernet (green + tag)\na -- b : vpn "site-to-site" # dashed tunnel\na == b : lag 40G # aggregated / EtherChannel (double line)\na -- b : trunk vlan: 10,20 1G port: Gi0/1>Gi1/0/24\n```\n\n- `trunk` / `access` \u2014 port mode (a trunk should connect switch-class devices).\n- `vlan: 10` or `vlan: 10,20` \u2014 a single VLAN tints the link (skipping the reserved alarm-red).\n- `1G` / `10G` / `100M` / `40G` \u2014 speed, shown mid-link.\n- `port: near>far` \u2014 interface labels at each end.\n\n---\n\n## 4. Layout modes\n\n```\nlayout: tiered # default \u2014 band by tier: edge \u2192 core \u2192 distribution \u2192 access\nlayout: tree # hierarchical from the root\nlayout: star # hub at center, spokes on a ring\nlayout: ring # nodes on a circle\nlayout: bus # shared backbone\nlayout: mesh # full/partial mesh on a circle\nlayout: spine-leaf # two rows, every leaf auto-meshed to every spine\nlayout: manual # explicit at: x,y per device\ndirection: tb | lr # flow axis for tiered/tree\n```\n\nFor `tiered`, set `tier:` (`edge` / `core` / `distribution` / `access`) on infrastructure; untiered endpoints are placed below their switch. For `spine-leaf`, declare `spines:` and `leaves:` and the spine\u2194leaf links are generated for you.\n\n---\n\n## 5. Boundaries: sites, racks, subnets, VLANs\n\nA device can live inside nested boundary blocks. **Physical** containers (site/rack) draw a solid border; **logical** overlays (subnet/VLAN/zone/DMZ) draw a dashed tinted region.\n\n```\nnetwork "Branch"\n site hq "HQ Building" {\n rack mdf "MDF Rack" {\n firewall fw1 tier: edge\n l3switch core1 tier: core\n }\n }\n subnet lan "10.0.10.0/24" {\n switch a1 tier: access\n pc u1 "User PC" ip: 10.0.10.50\n }\n zone dmz "DMZ" {\n server web\n }\n fw1 -- core1 : 10G\n core1 -- a1 : trunk vlan: 10\n a1 -- u1\n```\n\nA device declared inside a `subnet` whose label is a CIDR has its `ip:` validated \u2014 an address outside the range is a readable error. A bare id on its own line inside a block adds an already-declared device to that group.\n\n---\n\n## 6. Validation & the no-drop guarantee\n\nThe engine guarantees every declared device and link renders \u2014 the dropped-device failure of generic tools is structurally impossible. It also checks:\n\n- **duplicate id** \u2192 error;\n- **unknown kind** \u2192 error with the nearest suggestion (`"swtich" \u2192 did you mean "switch"?`);\n- **link to an undeclared device** \u2192 error;\n- **VLAN id outside 1\u20134094** \u2192 warning (still renders);\n- **device IP outside its subnet CIDR** \u2192 error.\n\nThe SVG `<desc>` records device/link counts, the detected topology class (star / ring / bus / mesh / tree / hierarchical / spine-leaf), and any warnings.\n\n---\n\n## 7. Themes\n\n```\ntheme: default # house "network blue" Cisco-style bodies\ntheme: monochrome # clean line-art for print/audit (link meaning via line-style + tags)\ntheme: dark # Catppuccin Mocha\n```\n\nCJK labels and `\u300C\u2026\u300D` / `"\u2026"` quotes parse cleanly:\n\n```\nnetwork "\u529E\u516C\u5BA4"\n multilayer core1 \u300C\u6838\u5FC3\u4EA4\u6362\u673A\u300D\n poeswitch poe1\n camera cam1 type: dome\n core1 -- poe1 : trunk vlan: 10\n poe1 -- cam1 : poe\n```\n\n---'
2893
+ },
2894
+ "umlclass": {
2895
+ "title": "UML Class Diagram",
2896
+ "content": '## 1. Your first diagram\n\nEvery document starts with the `umlclass` keyword (the Mermaid `classDiagram` header is also accepted), then declarations and relationships:\n\n```\numlclass\nclass Account {\n + id : String\n - balance : Money\n + deposit(amount : Money) : void\n}\nclass Customer {\n + name : String\n}\nCustomer "1" o-- "*" Account : owns\n```\n\nA `class X { \u2026 }` block declares a classifier with a name compartment, an attributes compartment, and an operations compartment. Members on their own lines inside the braces; you can also write the body on a single line (`class Account { + id : String + deposit() }`). The header accepts:\n\n- `title: "\u2026"` \u2014 a heading drawn above the diagram.\n- `direction: tb | bt | lr | rl` \u2014 rank direction, default `tb` (parents on top).\n- `theme: \u2026` \u2014 a theme override.\n\n---\n\n## 2. Classifiers\n\n```\nclass Order\n\xABinterface\xBB Repository\n\xABenumeration\xBB Status\nabstract class Shape\ndatatype Money\nprimitive int\n```\n\nThe five classifier kinds are `class`, `interface`, `enum` (alias `enumeration`), `datatype`, and `primitive`. A `\xABstereotype\xBB` (or ASCII `<<stereotype>>`) renders above the name; `abstract class` (or the `{abstract}` annotation) renders the name in italics. Use `as` to give a display name that differs from the reference id: `class "Order Service" as OrderSvc`.\n\n---\n\n## 3. Members \u2014 attributes & operations\n\n```\nclass Account {\n + id : String\n - balance : Money = 0\n / available : Money\n # owner : Customer\n ~ region : String\n + count : int {static}\n + deposit(amount : Money) : void\n + transfer(to : Account, amount : Money) : boolean {query}\n}\n```\n\n- **Visibility** glyphs: `+` public, `-` private, `#` protected, `~` package.\n- `: Type` gives the attribute type or operation return type; `= value` a default; `[0..*]` a multiplicity; `/` a derived attribute.\n- `{\u2026}` annotations: `{static}` (renders underlined), `{abstract}` (italic operation), `{readOnly}`, `{query}`, `{ordered}`, \u2026\n- `name : Type`, `name: Type`, and Java-order `Type name` are all accepted and normalised to `name : Type`.\n\n**Enum literals** are bare names inside an `enum` body:\n\n```\n\xABenumeration\xBB Status {\n ACTIVE\n SUSPENDED\n CLOSED\n}\n```\n\n---\n\n## 4. Relationships\n\n```\nVehicle <|-- Car generalization (hollow triangle \u2192 parent)\nShape <|.. Circle realization (dashed + hollow triangle \u2192 interface)\nOrder *-- LineItem composition (filled diamond at the whole)\nCustomer o-- Address aggregation (hollow diamond at the whole)\nService --> Repository directed association (open arrow \u2192 target)\nService ..> Logger dependency (dashed + open arrow \u2192 supplier)\nA -- B plain association (no head)\n```\n\nReversed forms are accepted and normalised (`Car --|> Vehicle` \u2261 `Vehicle <|-- Car`). Whitespace around a connector is optional.\n\nWhen two or more children share one parent via generalization/realization, the heads are **tree-merged**: one trunk, one shared triangle, per-child legs.\n\n---\n\n## 5. Labels & multiplicity\n\n```\nCustomer "1" o-- "0..*" Order : places\n```\n\nA trailing `: label` names the association (drawn at the line midpoint). Quoted ends are multiplicities or role names: `"1"`, `"0..1"`, `"*"`, `"1..*"`. The source end is the left of the connector, the target end the right (after reversed-form normalisation).\n\n---\n\n## 6. Namespaces / packages\n\nGroup classifiers into a labelled containment frame:\n\n```\numlclass\nnamespace Platform {\n namespace Auth {\n class UserService {\n + login()\n }\n }\n namespace Data {\n class Repository {\n + find()\n }\n }\n}\nclass Gateway {\n + route()\n}\nGateway --> UserService : delegates\nGateway --> Repository : delegates\n```\n\n- Blocks **nest** syntactically. Dot-notation auto-creates parents: `namespace Company.Engineering.Backend { \u2026 }` creates `Company` and `Company.Engineering` too.\n- An explicit label: `namespace plat["Platform Layer"] { \u2026 }`.\n- Each package renders as a frame = the union of its members (and nested sub-frames) + padding + a top label. Namespace bodies must use newlines (one declaration per line).\n\n---\n\n## 7. Mermaid-compatibility forms\n\nFor one-line migration from Mermaid `classDiagram`:\n\n```\nclassDiagram\nclass Repository~T~ {\n + findAll() List~T~\n + cache : Map~String,List~int~~\n + count$\n + flush()*\n}\nRepository : <<service>>\nRepository : + save(e : T) T\n```\n\n- **Tilde-generics** `List~T~` \u2192 `List` (nesting supported: `Map~String,List~int~~` \u2192 `Map>`); also on class names (`class Box~T~`).\n- **Single-line member**: `ClassName : +member` appends a member; `ClassName : <<interface>>` sets the kind/stereotype.\n- **Member classifiers**: trailing `*` = abstract (italic), trailing `$` = static (underlined).\n- **Space-return-type**: `getId() String` needs no colon.\n\nA lone leading `~` is still the package-visibility glyph; tilde-generics only convert balanced `~\u2026~` pairs inside a type, so the two never collide.\n\n---\n\n## 8. Theming & accessibility\n\nAll strokes and fills come from theme tokens (no inline styles); CSS classes are prefixed `sx-umlclass-*`. Visibility renders as text glyphs (`+ - # ~`), never coloured icons \u2014 standard-faithful and monochrome-safe. Every diagram carries `<title>`/`<desc>` and `data-*` attributes (`data-id`, `data-kind`, `data-from`/`data-to`/`data-kind` on relationships, `data-package-id` on frames) for interactivity.'
2897
+ },
2898
+ "faulttree": {
2899
+ "title": "Fault Tree Analysis",
2900
+ "content": '## 1. Your first diagram\n\nEvery document starts with the `faulttree` keyword (alias `fta`), an optional title, then a flat list of declarations wired by id:\n\n```\nfaulttree "Both pumps fail"\n analysis: cutsets, probability\n top T "Both redundant pumps fail" = AND(PA, PB)\n basic PA "Pump A fails" p: 0.01\n basic PB "Pump B fails" p: 0.01\n```\n\n`top` declares the single root event and the gate that produces it; `basic` declares a leaf component failure with a probability. The engine computes the minimal cut set `{PA, PB}` and P(top) = 1.0e-4. The DSL is **flat declaration + reference** (not nested by indentation) \u2014 a fault tree is a DAG, so a shared event is just referenced by id from several gates.\n\nHeader directives:\n\n- `analysis: cutsets, probability` \u2014 what to compute (also `pathsets`, `none`).\n- `prob: rare | mcub | exact` \u2014 the probability method (default `rare`, a conservative upper bound).\n- `layout: tb | bt` \u2014 top-down (default) or bottom-up.\n\n---\n\n## 2. Events\n\n```\ntop T "System fails" = OR(A, B)\ngate G1 "Sub-fault" = AND(A, B)\nbasic A "Component A fails" p: 0.01\nundeveloped EXT "External fire (not modelled)"\nhouse HX "Power on" state: 1\n```\n\n- **`top`** \u2014 the one undesired event being analysed (rectangle, emphasised border). Exactly one is required.\n- **`gate`** \u2014 an intermediate event that is itself a gate output (rectangle).\n- **`basic`** \u2014 a primary component failure, the leaf that carries `p:` (circle).\n- **`undeveloped`** \u2014 an event not developed further (diamond); may carry `p:`.\n- **`house`** \u2014 a normally-expected event forced `state: 0` or `state: 1` (house glyph) \u2014 switches branches of the tree on/off.\n\nProbabilities accept decimals or scientific notation (`p: 0.004` or `p: 1e-6`); `p:` and `prob:` are interchangeable. An event with no probability is treated symbolically (cut sets still computed; P(top) reported as n/a).\n\n---\n\n## 3. Gates\n\n```\ntop T1 = AND(A, B, C) # all inputs occur\ntop T2 = OR(A, B) # at least one input occurs\ntop T3 = XOR(A, B) # exactly one (treated as OR for cut sets)\ntop T4 = VOTING(2/3; A, B, C) # at least k of n\ngate G1 = INHIBIT(A) if COND # A occurs AND the condition holds\ngate G2 = PAND(A, B) order: A, B # A then B (order rendered, AND for cut sets)\n```\n\nGates are drawn **output-up, inputs-down** (the mirror of a `logic` gate): AND is a flat-bottomed dome, OR/XOR/VOTING a shield, INHIBIT a hexagon. The conditioning event of an `INHIBIT`/`PAND` renders as an ellipse to the side. A gate may reference another gate or any event \u2014 and the same basic event may feed several gates (a repeated event).\n\n---\n\n## 4. Computed cut sets & probability\n\nThis is the differentiator. With `analysis: cutsets`, the engine runs **MOCUS**: AND gates grow the order of a cut set, OR gates multiply the number of cut sets, then idempotence (`A\u2227A=A`) and absorption (`X \u2286 Y \u21D2 drop Y`) minimise the result.\n\n- Each **minimal cut set** is boxed in red; an **order-1 cut set is a single point of failure** (strongest red, `data-spof`).\n- A **repeated event** (one basic event under several gates) is handled by absorption \u2014 the case a naive expander gets wrong.\n- **P(top)** is computed from per-event probabilities: `rare` (\u03A3 cut-set probs, default), `mcub` (1 \u2212 \u220F(1\u2212P)), or `exact` (inclusion-exclusion, which correctly de-duplicates a shared event). The method is shown next to the top event and noted in `<desc>`.\n- A `house state: 0` can make the top event unsatisfiable \u2014 reported as "no cut sets."\n\n---\n\n## 5. Repeated events\n\n```\nfaulttree "Safety function fails"\n analysis: cutsets, probability\n prob: exact\n top T "Safety function fails" = OR(C1, C2)\n gate C1 "Channel 1" = AND(S1, L1)\n gate C2 "Channel 2" = AND(S2, L1)\n basic S1 "Sensor 1 fails" p: 0.05\n basic S2 "Sensor 2 fails" p: 0.05\n basic L1 "Shared logic solver fails" p: 0.05\n```\n\n`L1` feeds both channels \u2014 it is drawn once per reference with a shared-event mark, but the cut-set engine treats every instance as one Boolean variable. Cut sets are `{S1, L1}` and `{S2, L1}`; `prob: exact` subtracts the overlap (L1 counted once over the union), giving 0.004875 rather than the rare-event 0.005.\n\n---\n\n## 6. Transfers\n\n```\ngate OVP "Sustained over-pressure" = INHIBIT(PUMP) if HEATER\ntransfer OVP -> "OVP-detail"\n```\n\nA `transfer ID -> "name"` draws the transfer-out triangle below an event whose development lives elsewhere; a matching `transfer "name" = gate_expr` defines that named subtree and is spliced in for cut-set computation. v0.1 resolves transfers in-document.\n\n---\n\n## 7. Validation\n\nThe parser fails fast with readable errors so the cut-set math is meaningful:\n\n- exactly one `top` is required (zero or several is an error);\n- a gate referencing an undeclared id reports the id by name;\n- cycles are rejected (a fault tree is a DAG);\n- a probability outside `[0, 1]`, a `VOTING k/n` with `k > n` or `n \u2260 input count`, or an `if` condition on a non-INHIBIT/PAND gate are all reported in plain English.\n\n---\n\n## 8. Theming\n\n`default` uses the house palette \u2014 soft slate-blue event boxes, **green gates** ("logic proceeds"), **red cut-set boxes** (the computed risk), blue probability numerals, a yellow house. `monochrome` reproduces the NUREG-0492 black-and-white textbook look, where the dome/shield shape (not colour) carries the gate type. All strokes/fills come from `ReliabilityTokens`; every element carries `data-*` (`data-cutset`, `data-spof`, `data-prob`, `data-gate`) so the computed analysis is inspectable downstream.'
2695
2901
  }
2696
2902
  };
2697
2903
 
@@ -2815,9 +3021,12 @@ var PROFILES = {
2815
3021
  header: 'logic "Title"',
2816
3022
  mode: "logic netlist",
2817
3023
  forms: ["INPUT A, B", "G1 = AND(A, B)", "OUTPUT Y = G1"],
2818
- prefer: ["Use canonical gate names and explicit inputs/outputs."],
2819
- avoid: ["Avoid circuit component names inside logic diagrams."],
2820
- repair: ["Unknown gate kinds should be replaced with the closest listed logic primitive."]
3024
+ prefer: [
3025
+ "Gate form is `id = TYPE(in1, in2, \u2026)`; declare `INPUT`/`OUTPUT` ports explicitly. Prefix a signal with `~` for active-low.",
3026
+ "Use only these canonical gate TYPEs: combinational AND, OR, NOT, NAND, NOR, XOR, XNOR, BUF; output 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."
3027
+ ],
3028
+ avoid: ["Avoid circuit component names (R, C, transistors) inside logic diagrams."],
3029
+ repair: ["An unrecognised gate renders as a flagged `?` placeholder; replace it with the closest canonical gate from the list above (e.g. LOAD/REG \u2192 DFF, INV \u2192 NOT)."]
2821
3030
  },
2822
3031
  circuit: {
2823
3032
  type: "circuit",
@@ -2862,10 +3071,14 @@ var PROFILES = {
2862
3071
  type: "sld",
2863
3072
  header: 'sld "Title"',
2864
3073
  mode: "equipment assignments + power-flow edges",
2865
- forms: ['util = utility [label: "Grid"]', 'xfmr = transformer [rating: "500 kVA"]', "util -> xfmr -> load is not allowed; use one edge per line"],
2866
- prefer: ["Declare equipment as `id = nodeType [attrs]`.", "Use one `from -> to` connection per line."],
3074
+ forms: ['util = utility [label: "Grid"]', 'xfmr = transformer [rating: "500 kVA"]', "util -> xfmr (one edge per line, no chaining)"],
3075
+ prefer: [
3076
+ "Declare equipment as `id = nodeType [attrs]`, one `from -> to` connection per line.",
3077
+ "Use only these canonical nodeTypes: sources utility, generator, solar, wind, ups; transformers transformer, transformer_dy, transformer_yd, transformer_yy, transformer_dd, autotransformer, transformer_3winding; buses bus, bus_tie, hub; switching breaker, breaker_vacuum, switch, switch_load, ground_switch, ats, recloser, sectionalizer, fuse, fuse_cl; protection ct, pt, relay, surge_arrester, ground_fault; loads motor, load, capacitor_bank, harmonic_filter, vfd; metering watthour_meter, demand_meter.",
3078
+ "IEC/REBT residential aliases are also accepted: mcb/mccb\u2192breaker, rcd/rcbo/rccb\u2192ground_fault, isolator/disconnector\u2192switch_load, panel/consumer_unit/distribution_board\u2192bus."
3079
+ ],
2867
3080
  avoid: ["Avoid generic flowchart node syntax."],
2868
- repair: ["Unknown equipment types often have a suggested canonical type or alias."]
3081
+ repair: ["An unrecognised nodeType renders as a flagged `?` placeholder; pick the closest canonical type or alias from the list above (e.g. meter\u2192watthour_meter, inverter\u2192vfd)."]
2869
3082
  },
2870
3083
  entity: {
2871
3084
  type: "entity",
@@ -2975,10 +3188,19 @@ var PROFILES = {
2975
3188
  type: "pid",
2976
3189
  header: 'pid "Title"',
2977
3190
  mode: "equipment + process lines",
2978
- forms: ["equip T-101 : tank_atm", "equip P-101 : pump_centrifugal", "line L1 from T-101.bottom to P-101.in"],
2979
- prefer: ["Declare equipment first, then process/signal lines."],
2980
- avoid: ["Avoid SLD electrical nodes in a P&ID."],
2981
- repair: ["Unknown equipment and instrument categories must come from the catalog."]
3191
+ forms: [
3192
+ "equip T-101 : tank_atm",
3193
+ "equip P-101 : pump_centrifugal",
3194
+ "line L1 from T-101.bottom to P-101.in",
3195
+ "inst FIC-201 : cr_shared"
3196
+ ],
3197
+ prefer: [
3198
+ "Declare equipment first (`equip ID : type [attrs]`), then process/signal lines, then instruments (`inst TAG : category`).",
3199
+ "Use only these canonical equipment types: tanks/vessels tank_atm, tank_cone_roof, vessel_v, vessel_h, sphere; columns column_tray, column_packed; heat transfer hx_shell_tube, hx_air_cooled, reboiler, condenser; rotating pump_centrifugal, pump_pd, compressor, blower; reactors reactor_cstr, reactor_pfr; misc filter, cyclone, flare, cooling_tower; valves valve_gate, valve_ball, valve_globe, valve_butterfly, valve_check, valve_control, valve_psv.",
3200
+ "Instrument categories: field_discrete, field_shared, field_computer, field_plc, cr_discrete, cr_shared, cr_computer, cr_plc, local_discrete, local_shared. Line types (`[type: \u2026]`): process, process_minor, pneumatic, electric, hydraulic, capillary, software, mechanical."
3201
+ ],
3202
+ avoid: ["Avoid SLD electrical nodes (transformer, breaker) in a P&ID."],
3203
+ repair: ["An unrecognised equipment type renders as a flagged `?` placeholder; pick the closest canonical type from the list above (e.g. exchanger/heat_exchanger\u2192hx_shell_tube, vessel_horizontal\u2192vessel_h, cstr\u2192reactor_cstr)."]
2982
3204
  },
2983
3205
  erd: {
2984
3206
  type: "erd",
@@ -3139,6 +3361,73 @@ var PROFILES = {
3139
3361
  "An 'undeclared device' error means a link references an id with no `kind id` declaration \u2014 declare it first.",
3140
3362
  "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."
3141
3363
  ]
3364
+ },
3365
+ umlclass: {
3366
+ type: "umlclass",
3367
+ header: "umlclass",
3368
+ mode: "classifier declarations + relationship lines (PlantUML-flavoured, Mermaid aliases accepted)",
3369
+ forms: [
3370
+ "class Order { + id : String + place() : void } (visibility: + - # ~)",
3371
+ "\xABinterface\xBB Shape { + area() : double } (stereotype above name)",
3372
+ "abstract class AbstractShape { + area() : double {abstract} }",
3373
+ "\xABenumeration\xBB Suit { HEARTS DIAMONDS CLUBS SPADES } (literals in attr compartment)",
3374
+ "Animal <|-- Dog (generalization \u2014 hollow triangle to parent)",
3375
+ "Shape <|.. Circle (realization \u2014 dashed + hollow triangle)",
3376
+ 'Order *-- "1..*" LineItem : contains (composition \u2014 filled diamond at whole)',
3377
+ 'Customer o-- "0..*" Address (aggregation \u2014 hollow diamond at whole)',
3378
+ 'A "1" --> "*" B : owns (directed association \u2014 open arrow to target)',
3379
+ "X ..> Y (dependency \u2014 dashed + open arrow)"
3380
+ ],
3381
+ prefer: [
3382
+ "Single-word keyword is `umlclass` (also accepts `class-diagram` and Mermaid's `classDiagram`).",
3383
+ "Use `class`, `abstract class`, `\xABinterface\xBB`, `\xABenumeration\xBB`, or any custom `\xABstereotype\xBB` above the name.",
3384
+ "Members go in `{ \u2026 }`; visibility glyphs are `+ - # ~`; `{static}` underlines, `{abstract}` italicises, `/name` marks a derived attribute.",
3385
+ 'Multiplicity is the quoted token next to an endpoint: `"1"`, `"0..*"`, `"1..*"`. The line midpoint label after `:` is the association name.',
3386
+ "PlantUML connectors are primary; the Mermaid reversed forms `--|>`, `..|>`, `--*`, `--o` are accepted and normalised."
3387
+ ],
3388
+ avoid: [
3389
+ "Don't use bare `class` as the diagram keyword \u2014 that's a reserved programming-language word, and the engine keyword is `umlclass`.",
3390
+ "Don't put `-->` for dependency: `-->` is *directed association*; dependency is the dashed `..>` (this is a deliberate deviation from PlantUML, matching Mermaid and the usual UML reading).",
3391
+ "Don't declare a classifier with an empty body and `{}` if you want a name-only sketch box \u2014 write `class Foo` on its own line."
3392
+ ],
3393
+ repair: [
3394
+ "A 'malformed relationship' error means no connector glyph was found between two ids \u2014 check the line uses one of `<|--` `<|..` `*--` `o--` `-->` `..>` `--` `..`.",
3395
+ "A 'generalization cycle' error means inheritance edges form a loop \u2014 fix the parent/child direction of one of the edges named in the cycle.",
3396
+ "If a class appears as a one-line empty box you didn't expect, the parser auto-created it from an arc reference \u2014 declare it explicitly or fix the typo in the relationship id."
3397
+ ]
3398
+ },
3399
+ faulttree: {
3400
+ type: "faulttree",
3401
+ header: 'faulttree "Title"',
3402
+ mode: "flat event/gate declarations wired by id (top + gates + leaves)",
3403
+ forms: [
3404
+ "analysis: cutsets, probability",
3405
+ 'top T "System fails" = OR(G1, G2)',
3406
+ 'gate G1 "Sub-fault" = AND(A, B)',
3407
+ 'basic A "Component A fails" p: 0.01',
3408
+ 'undeveloped EXT "External cause"',
3409
+ 'house HX "Power on" state: 1',
3410
+ "RELIEF = VOTING(2/3; PRV_A, PRV_B, PRV_C)",
3411
+ "OVP = INHIBIT(PUMP) if HEATER"
3412
+ ],
3413
+ prefer: [
3414
+ "Single-word keyword is `faulttree` (alias `fta`). Declare exactly one `top` event.",
3415
+ "Declare every referenced event before or after use; wire gates by id (the tree is a DAG \u2014 a basic event may feed several gates).",
3416
+ "Gate expressions: AND/OR/XOR(a, b, \u2026), VOTING(k/n; \u2026), INHIBIT(x) if cond, PAND(a, b) order: a, b.",
3417
+ "Put `p: 0.001` (or scientific `1e-3`) on basic/undeveloped events; the engine computes minimal cut sets and P(top).",
3418
+ "Use `prob: rare` (default), `mcub`, or `exact`; `house \u2026 state: 0|1` switches branches on/off."
3419
+ ],
3420
+ avoid: [
3421
+ "Don't nest by indentation \u2014 fault tree is flat declaration + id reference (so repeated/shared events are unambiguous).",
3422
+ "Don't attach `if <cond>` to anything but INHIBIT (or `order:` to anything but PAND).",
3423
+ "Don't declare more than one `top`, and don't create cycles (a gate may not transitively reference itself)."
3424
+ ],
3425
+ repair: [
3426
+ "'references undefined event' means a gate input id was never declared \u2014 add the `basic`/`gate`/\u2026 line.",
3427
+ "'must have exactly one top' \u2014 keep a single `top`; downgrade the others to `gate`.",
3428
+ "'VOTING k/n: n must equal the number of inputs' \u2014 make n match the listed inputs.",
3429
+ "If P(top) shows 'n/a', a basic event in a cut set is missing its `p:`."
3430
+ ]
3142
3431
  }
3143
3432
  };
3144
3433
  function getGenerationProfile(type) {
@@ -3283,5 +3572,5 @@ function repairHint(type) {
3283
3572
  }
3284
3573
 
3285
3574
  export { DIAGRAM_REGISTRY, DIAGRAM_SINCE, getAllDiagramTypes, getDiagramMeta, getDiagramSince, getExamples, getSyntax, listDiagrams, renderDsl, resolveDiagramType, validateDsl };
3286
- //# sourceMappingURL=chunk-ITUPR7G5.js.map
3287
- //# sourceMappingURL=chunk-ITUPR7G5.js.map
3575
+ //# sourceMappingURL=chunk-ZZHQBAC3.js.map
3576
+ //# sourceMappingURL=chunk-ZZHQBAC3.js.map