schematex 0.9.7 → 0.9.9

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 (172) hide show
  1. package/README.md +43 -3
  2. package/dist/ai/ai-sdk.cjs +23 -23
  3. package/dist/ai/ai-sdk.d.cts +3 -3
  4. package/dist/ai/ai-sdk.d.ts +3 -3
  5. package/dist/ai/ai-sdk.js +18 -18
  6. package/dist/ai/index.cjs +32 -32
  7. package/dist/ai/index.d.cts +4 -4
  8. package/dist/ai/index.d.ts +4 -4
  9. package/dist/ai/index.js +19 -19
  10. package/dist/{api-BOJJlNb1.d.ts → api-D_d-JklT.d.ts} +1 -1
  11. package/dist/{api-v9t1T1v6.d.cts → api-DnTyW-6F.d.cts} +1 -1
  12. package/dist/browser.cjs +24 -24
  13. package/dist/browser.d.cts +3 -3
  14. package/dist/browser.d.ts +3 -3
  15. package/dist/browser.js +18 -18
  16. package/dist/{chunk-6QZQTASC.cjs → chunk-246OJILS.cjs} +12 -12
  17. package/dist/{chunk-6QZQTASC.cjs.map → chunk-246OJILS.cjs.map} +1 -1
  18. package/dist/{chunk-JEMAOC2D.js → chunk-2IRYXK4M.js} +3 -3
  19. package/dist/{chunk-JEMAOC2D.js.map → chunk-2IRYXK4M.js.map} +1 -1
  20. package/dist/{chunk-ITI3STJ6.cjs → chunk-3JN4762U.cjs} +4 -4
  21. package/dist/{chunk-ITI3STJ6.cjs.map → chunk-3JN4762U.cjs.map} +1 -1
  22. package/dist/{chunk-GAQ36VFD.cjs → chunk-4MANMKQ4.cjs} +4 -4
  23. package/dist/{chunk-GAQ36VFD.cjs.map → chunk-4MANMKQ4.cjs.map} +1 -1
  24. package/dist/{chunk-64LABNTF.js → chunk-7NO5LYLL.js} +3 -3
  25. package/dist/{chunk-64LABNTF.js.map → chunk-7NO5LYLL.js.map} +1 -1
  26. package/dist/{chunk-ENUM7GMZ.cjs → chunk-7OOUU6BL.cjs} +147 -2
  27. package/dist/chunk-7OOUU6BL.cjs.map +1 -0
  28. package/dist/{chunk-M26ORU4P.js → chunk-AETIGJXP.js} +3 -3
  29. package/dist/{chunk-M26ORU4P.js.map → chunk-AETIGJXP.js.map} +1 -1
  30. package/dist/{chunk-OJ3P4IC4.cjs → chunk-DLXDR2E7.cjs} +4 -4
  31. package/dist/{chunk-OJ3P4IC4.cjs.map → chunk-DLXDR2E7.cjs.map} +1 -1
  32. package/dist/{chunk-3J4DZPZC.js → chunk-EB7T5SEO.js} +3 -3
  33. package/dist/{chunk-3J4DZPZC.js.map → chunk-EB7T5SEO.js.map} +1 -1
  34. package/dist/{chunk-ECHPMEZX.cjs → chunk-EUN6FEGE.cjs} +181 -7
  35. package/dist/chunk-EUN6FEGE.cjs.map +1 -0
  36. package/dist/{chunk-VY6UZYYL.cjs → chunk-F5RYWDWO.cjs} +15 -15
  37. package/dist/{chunk-VY6UZYYL.cjs.map → chunk-F5RYWDWO.cjs.map} +1 -1
  38. package/dist/{chunk-INVLJYAE.cjs → chunk-GTCGATOL.cjs} +4 -4
  39. package/dist/{chunk-INVLJYAE.cjs.map → chunk-GTCGATOL.cjs.map} +1 -1
  40. package/dist/{chunk-ZCHGIWJK.js → chunk-HIWJMJJB.js} +3 -3
  41. package/dist/{chunk-ZCHGIWJK.js.map → chunk-HIWJMJJB.js.map} +1 -1
  42. package/dist/{chunk-RDYACU2G.js → chunk-IHX6J4HF.js} +3 -3
  43. package/dist/{chunk-RDYACU2G.js.map → chunk-IHX6J4HF.js.map} +1 -1
  44. package/dist/{chunk-4MRVJI7G.js → chunk-JVNV2T2T.js} +147 -3
  45. package/dist/chunk-JVNV2T2T.js.map +1 -0
  46. package/dist/{chunk-SXOAAQNY.js → chunk-KUSW5I2P.js} +3 -3
  47. package/dist/{chunk-SXOAAQNY.js.map → chunk-KUSW5I2P.js.map} +1 -1
  48. package/dist/{chunk-35NGXDT2.cjs → chunk-KYE7CRED.cjs} +12 -12
  49. package/dist/{chunk-35NGXDT2.cjs.map → chunk-KYE7CRED.cjs.map} +1 -1
  50. package/dist/{chunk-II4GLKGF.js → chunk-MVTYPWHO.js} +3 -3
  51. package/dist/chunk-MVTYPWHO.js.map +1 -0
  52. package/dist/{chunk-N3HU635X.cjs → chunk-MXV3XJFH.cjs} +4 -4
  53. package/dist/chunk-MXV3XJFH.cjs.map +1 -0
  54. package/dist/{chunk-XCCXG6RR.js → chunk-NB7MFQCZ.js} +3 -3
  55. package/dist/{chunk-XCCXG6RR.js.map → chunk-NB7MFQCZ.js.map} +1 -1
  56. package/dist/{chunk-GYYYULBL.js → chunk-NP7N3DZG.js} +3 -3
  57. package/dist/{chunk-GYYYULBL.js.map → chunk-NP7N3DZG.js.map} +1 -1
  58. package/dist/{chunk-6X7MVZZT.cjs → chunk-OY2CXLVY.cjs} +2156 -768
  59. package/dist/chunk-OY2CXLVY.cjs.map +1 -0
  60. package/dist/{chunk-3PH2MQGN.js → chunk-P4U565XH.js} +3 -3
  61. package/dist/{chunk-3PH2MQGN.js.map → chunk-P4U565XH.js.map} +1 -1
  62. package/dist/{chunk-VYQXB2RC.cjs → chunk-QC2RICQ4.cjs} +12 -12
  63. package/dist/{chunk-VYQXB2RC.cjs.map → chunk-QC2RICQ4.cjs.map} +1 -1
  64. package/dist/{chunk-3WX24RCH.js → chunk-QMJHLDGY.js} +3 -3
  65. package/dist/{chunk-3WX24RCH.js.map → chunk-QMJHLDGY.js.map} +1 -1
  66. package/dist/{chunk-DVRB64CN.js → chunk-RCR4UGKV.js} +179 -5
  67. package/dist/chunk-RCR4UGKV.js.map +1 -0
  68. package/dist/{chunk-C4Y24X3U.cjs → chunk-T55OQILI.cjs} +4 -4
  69. package/dist/{chunk-C4Y24X3U.cjs.map → chunk-T55OQILI.cjs.map} +1 -1
  70. package/dist/{chunk-3K4WCRVI.js → chunk-T5QOVX2I.js} +1953 -566
  71. package/dist/chunk-T5QOVX2I.js.map +1 -0
  72. package/dist/{chunk-6ZD7TCWO.cjs → chunk-TFUVNQNA.cjs} +15 -15
  73. package/dist/{chunk-6ZD7TCWO.cjs.map → chunk-TFUVNQNA.cjs.map} +1 -1
  74. package/dist/{chunk-4AC6I7KJ.cjs → chunk-TXWVJAMR.cjs} +4 -4
  75. package/dist/{chunk-4AC6I7KJ.cjs.map → chunk-TXWVJAMR.cjs.map} +1 -1
  76. package/dist/{chunk-4OC3CTGE.cjs → chunk-UHRNFBWY.cjs} +4 -4
  77. package/dist/{chunk-4OC3CTGE.cjs.map → chunk-UHRNFBWY.cjs.map} +1 -1
  78. package/dist/{chunk-B4CMWA6Y.js → chunk-W4UVDMUC.js} +3 -3
  79. package/dist/{chunk-B4CMWA6Y.js.map → chunk-W4UVDMUC.js.map} +1 -1
  80. package/dist/{chunk-5ZQRHDMQ.cjs → chunk-YDEQZSPQ.cjs} +4 -4
  81. package/dist/{chunk-5ZQRHDMQ.cjs.map → chunk-YDEQZSPQ.cjs.map} +1 -1
  82. package/dist/{chunk-627GHE2N.cjs → chunk-YFPDZVB7.cjs} +5 -5
  83. package/dist/{chunk-627GHE2N.cjs.map → chunk-YFPDZVB7.cjs.map} +1 -1
  84. package/dist/{chunk-NKYR4PAS.js → chunk-YXEPF3SL.js} +3 -3
  85. package/dist/{chunk-NKYR4PAS.js.map → chunk-YXEPF3SL.js.map} +1 -1
  86. package/dist/{chunk-AXMBXAEA.js → chunk-ZRFKIERV.js} +3 -3
  87. package/dist/{chunk-AXMBXAEA.js.map → chunk-ZRFKIERV.js.map} +1 -1
  88. package/dist/{diagnostics-5bVLlGNj.d.cts → diagnostics-D2qkBfFx.d.cts} +1 -1
  89. package/dist/{diagnostics-5bVLlGNj.d.ts → diagnostics-D2qkBfFx.d.ts} +1 -1
  90. package/dist/diagrams/blockdiagram/index.cjs +6 -6
  91. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  92. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  93. package/dist/diagrams/blockdiagram/index.js +2 -2
  94. package/dist/diagrams/circuit/index.cjs +9 -9
  95. package/dist/diagrams/circuit/index.d.cts +1 -1
  96. package/dist/diagrams/circuit/index.d.ts +1 -1
  97. package/dist/diagrams/circuit/index.js +2 -2
  98. package/dist/diagrams/ecomap/index.cjs +7 -7
  99. package/dist/diagrams/ecomap/index.d.cts +1 -1
  100. package/dist/diagrams/ecomap/index.d.ts +1 -1
  101. package/dist/diagrams/ecomap/index.js +2 -2
  102. package/dist/diagrams/entity/index.cjs +6 -6
  103. package/dist/diagrams/entity/index.d.cts +1 -1
  104. package/dist/diagrams/entity/index.d.ts +1 -1
  105. package/dist/diagrams/entity/index.js +2 -2
  106. package/dist/diagrams/fishbone/index.cjs +8 -8
  107. package/dist/diagrams/fishbone/index.d.cts +1 -1
  108. package/dist/diagrams/fishbone/index.d.ts +1 -1
  109. package/dist/diagrams/fishbone/index.js +2 -2
  110. package/dist/diagrams/flowchart/index.cjs +8 -8
  111. package/dist/diagrams/flowchart/index.d.cts +2 -2
  112. package/dist/diagrams/flowchart/index.d.ts +2 -2
  113. package/dist/diagrams/flowchart/index.js +2 -2
  114. package/dist/diagrams/genogram/index.cjs +9 -9
  115. package/dist/diagrams/genogram/index.d.cts +1 -1
  116. package/dist/diagrams/genogram/index.d.ts +1 -1
  117. package/dist/diagrams/genogram/index.js +2 -2
  118. package/dist/diagrams/ladder/index.cjs +6 -6
  119. package/dist/diagrams/ladder/index.d.cts +1 -1
  120. package/dist/diagrams/ladder/index.d.ts +1 -1
  121. package/dist/diagrams/ladder/index.js +2 -2
  122. package/dist/diagrams/logic/index.cjs +8 -8
  123. package/dist/diagrams/logic/index.d.cts +1 -1
  124. package/dist/diagrams/logic/index.d.ts +1 -1
  125. package/dist/diagrams/logic/index.js +2 -2
  126. package/dist/diagrams/orgchart/index.cjs +8 -8
  127. package/dist/diagrams/orgchart/index.d.cts +1 -1
  128. package/dist/diagrams/orgchart/index.d.ts +1 -1
  129. package/dist/diagrams/orgchart/index.js +2 -2
  130. package/dist/diagrams/pedigree/index.cjs +7 -7
  131. package/dist/diagrams/pedigree/index.d.cts +1 -1
  132. package/dist/diagrams/pedigree/index.d.ts +1 -1
  133. package/dist/diagrams/pedigree/index.js +2 -2
  134. package/dist/diagrams/phylo/index.cjs +7 -7
  135. package/dist/diagrams/phylo/index.d.cts +1 -1
  136. package/dist/diagrams/phylo/index.d.ts +1 -1
  137. package/dist/diagrams/phylo/index.js +2 -2
  138. package/dist/diagrams/sld/index.cjs +8 -8
  139. package/dist/diagrams/sld/index.d.cts +1 -1
  140. package/dist/diagrams/sld/index.d.ts +1 -1
  141. package/dist/diagrams/sld/index.js +2 -2
  142. package/dist/diagrams/sociogram/index.cjs +6 -6
  143. package/dist/diagrams/sociogram/index.d.cts +1 -1
  144. package/dist/diagrams/sociogram/index.d.ts +1 -1
  145. package/dist/diagrams/sociogram/index.js +2 -2
  146. package/dist/diagrams/timing/index.d.cts +1 -1
  147. package/dist/diagrams/timing/index.d.ts +1 -1
  148. package/dist/diagrams/venn/index.cjs +9 -9
  149. package/dist/diagrams/venn/index.d.cts +1 -1
  150. package/dist/diagrams/venn/index.d.ts +1 -1
  151. package/dist/diagrams/venn/index.js +2 -2
  152. package/dist/{index-syc0E5Ss.d.ts → index-D9u0YRxL.d.ts} +1 -1
  153. package/dist/{index-Cmf4Rcve.d.cts → index-JZlLiE6K.d.cts} +1 -1
  154. package/dist/index.cjs +91 -87
  155. package/dist/index.d.cts +7 -5
  156. package/dist/index.d.ts +7 -5
  157. package/dist/index.js +22 -22
  158. package/dist/react.cjs +18 -18
  159. package/dist/react.d.cts +2 -2
  160. package/dist/react.d.ts +2 -2
  161. package/dist/react.js +17 -17
  162. package/dist/{tools-B98iarLm.d.cts → tools-DAKYNcPv.d.cts} +2 -2
  163. package/dist/{tools-CCZ1IcIN.d.ts → tools-DM0aLCbc.d.ts} +2 -2
  164. package/package.json +1 -1
  165. package/dist/chunk-3K4WCRVI.js.map +0 -1
  166. package/dist/chunk-4MRVJI7G.js.map +0 -1
  167. package/dist/chunk-6X7MVZZT.cjs.map +0 -1
  168. package/dist/chunk-DVRB64CN.js.map +0 -1
  169. package/dist/chunk-ECHPMEZX.cjs.map +0 -1
  170. package/dist/chunk-ENUM7GMZ.cjs.map +0 -1
  171. package/dist/chunk-II4GLKGF.js.map +0 -1
  172. package/dist/chunk-N3HU635X.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { parseResult, renderResult } from './chunk-3K4WCRVI.js';
1
+ import { parseResult, renderResult } from './chunk-T5QOVX2I.js';
2
2
 
3
3
  // src/ai/registry.ts
4
4
  var DIAGRAM_REGISTRY = [
@@ -441,6 +441,43 @@ var DIAGRAM_REGISTRY = [
441
441
  "reliability over time"
442
442
  ]
443
443
  },
444
+ {
445
+ type: "comparison",
446
+ name: "Comparison & Decision Matrix",
447
+ tagline: "One engine for compare-and-contrast \u2014 T-chart, pros/cons, comparison matrix, and the Pugh decision matrix that computes its own winner.",
448
+ useWhen: 'Use to put options side by side and, when there are weighted criteria, to *decide*. Header `comparison "Title"` (or `tchart` / `pugh`) with `mode:` \u2014 `tchart` (2\u2013N bullet columns, also Y-chart), `pros-cons` (green \u2713 / red \u2717 valence), `matrix` (options \xD7 criteria grid; cells take text or yes/no/partial marks), `decision`/`pugh` (criteria carry `weight:`, each option a numeric score, and the engine computes every option\'s weighted total \u03A3(w\xB7s), ranks them, and highlights the winner \u2014 Stuart Pugh / ASQ concept selection), or `double-bubble` (Thinking Maps compare/contrast: shared traits in the middle, unique ones fanning out). Distinct from `matrix` (the 2\xD72 / BCG / quadrant engine, which *positions* items on two axes) \u2014 this one lays out a *table* and computes the decision.',
449
+ cluster: "strategy",
450
+ standard: "Pugh, Total Design (1991) controlled convergence \xB7 ASQ decision matrix \xB7 Hyerle Thinking Maps (double-bubble) \xB7 K-12 graphic-organizer convention; see 51-COMPARISON-STANDARD.md",
451
+ syntaxKey: "comparison",
452
+ aliases: [
453
+ "comparison chart",
454
+ "comparison table",
455
+ "T-chart",
456
+ "Y-chart",
457
+ "pros and cons",
458
+ "pros/cons",
459
+ "decision matrix",
460
+ "Pugh matrix",
461
+ "weighted scoring matrix",
462
+ "double bubble map",
463
+ "compare and contrast",
464
+ "\u5BF9\u6BD4\u56FE",
465
+ "\u51B3\u7B56\u77E9\u9635"
466
+ ],
467
+ keywords: [
468
+ "compare options",
469
+ "concept selection",
470
+ "controlled convergence",
471
+ "weighted scoring",
472
+ "vendor selection",
473
+ "feature comparison",
474
+ "pros cons list",
475
+ "graphic organizer",
476
+ "Thinking Maps",
477
+ "decision making",
478
+ "trade study"
479
+ ]
480
+ },
444
481
  // ── Systems thinking / stochastic ────────────────────────────
445
482
  {
446
483
  type: "causalloop",
@@ -746,7 +783,9 @@ var DIAGRAM_SINCE = {
746
783
  // 0.9.4 — multi-sport playbook (football X&O / basketball / soccer)
747
784
  playbook: "0.9.4",
748
785
  // 0.9.5 — reliability block diagram (IEC 61078)
749
- rbd: "0.9.5"
786
+ rbd: "0.9.5",
787
+ // 0.9.8 — comparison & decision matrix (Pugh / pros-cons / T-chart / double-bubble)
788
+ comparison: "0.9.8"
750
789
  };
751
790
  function getDiagramSince(type) {
752
791
  const resolved = resolveDiagramType(type);
@@ -1139,6 +1178,59 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
1139
1178
  "dsl": 'circuit "Pull-up + push button" netlist\nV1 vcc 0 5V\nR1 vcc sig 10k dir=down\nSW1 sig 0 type=switch\nC1 sig 0 100n',
1140
1179
  "notes": "## Scenario\n\nAn embedded engineer documents a classic active-low input: a pull-up resistor\nholds the signal high, a push button pulls it to ground, and a small capacitor\ndebounces it. The connectivity is written as a SPICE-style netlist \u2014 the engine\nplaces everything from the node names \u2014 and one optional hint refines the look.\n\n## Annotation key\n\n- **netlist line** \u2014 `id node-A node-B value`; components that share a node name\n are wired together. `0` is ground.\n- **`dir=down`** \u2014 the optional orientation hint. `R1` connects `vcc` to `sig`;\n by default the engine would lay it horizontally, but a pull-up reads best drawn\n vertically from the supply rail down to the signal node, so `dir=down` rotates\n just that symbol. Connectivity is unchanged \u2014 `dir=` only rotates the glyph.\n- **`type=switch`** \u2014 the `SW1` id prefix is ambiguous, so the component type is\n made explicit.\n\n## How to read\n\n`R1` ties `sig` up to `vcc` (drawn vertically thanks to `dir=down`). `SW1` and the\ndebounce cap `C1` both go from `sig` to ground, so the engine recognises them as\nshunt legs and drops them beneath the node. Pressing the button shorts `sig` to\nground, pulling the input low."
1141
1180
  },
1181
+ {
1182
+ "slug": "comparison-cell-double-bubble",
1183
+ "diagram": "comparison",
1184
+ "title": "Plant vs animal cell \u2014 double-bubble",
1185
+ "description": "A Thinking-Maps double-bubble compare/contrast organizer \u2014 shared traits in the middle connected to both centres, unique traits fanning out.",
1186
+ "standard": "Hyerle, Thinking Maps (1996)",
1187
+ "tags": [
1188
+ "comparison",
1189
+ "double-bubble",
1190
+ "thinking-maps",
1191
+ "education",
1192
+ "compare-contrast"
1193
+ ],
1194
+ "complexity": 1,
1195
+ "featured": false,
1196
+ "dsl": 'comparison "Plant cell vs Animal cell"\nmode: double-bubble\nleft "Plant cell"\nright "Animal cell"\nshared "Has a nucleus"\nshared "Mitochondria"\nshared "Cell membrane"\nleft-only "Cell wall"\nleft-only "Chloroplasts"\nleft-only "Large central vacuole"\nright-only "Centrioles"\nright-only "Lysosomes"\nright-only "Many small vacuoles"',
1197
+ "notes": "## What this shows\n\nThe Double-Bubble Map is the standard Thinking-Maps organizer for compare/contrast. The two subjects sit as centres; **shared** attributes go in the middle column and connect to *both* centres; attributes unique to each side fan out and connect only to their own centre. The rigid five-column geometry is produced automatically \u2014 you just list what is shared and what is unique."
1198
+ },
1199
+ {
1200
+ "slug": "comparison-cicd-decision-matrix",
1201
+ "diagram": "comparison",
1202
+ "title": "CI/CD platform \u2014 decision matrix",
1203
+ "description": "A Pugh weighted-decision matrix where the engine computes each option's weighted total, ranks them, and highlights the winner \u2014 with Jenkins as the datum baseline.",
1204
+ "standard": "Pugh, Total Design (1991) \xB7 ASQ decision matrix",
1205
+ "tags": [
1206
+ "comparison",
1207
+ "decision-matrix",
1208
+ "pugh",
1209
+ "weighted-scoring",
1210
+ "trade-study"
1211
+ ],
1212
+ "complexity": 3,
1213
+ "featured": true,
1214
+ "dsl": 'comparison "Selecting a CI/CD platform"\nmode: decision\nbaseline: "Jenkins"\noption "GitHub Actions"\noption "GitLab CI"\noption "CircleCI"\noption "Jenkins"\ncriterion "Ease of setup" weight: 5\n GitHub Actions: 5\n GitLab CI: 4\n CircleCI: 4\n Jenkins: 2\ncriterion "Build speed" weight: 4\n GitHub Actions: 4\n GitLab CI: 4\n CircleCI: 5\n Jenkins: 3\ncriterion "Cost at our scale" weight: 4\n GitHub Actions: 4\n GitLab CI: 3\n CircleCI: 3\n Jenkins: 5\ncriterion "Ecosystem / marketplace" weight: 3\n GitHub Actions: 5\n GitLab CI: 3\n CircleCI: 3\n Jenkins: 4\ncriterion "Self-host control" weight: 2\n GitHub Actions: 2\n GitLab CI: 5\n CircleCI: 2\n Jenkins: 5',
1215
+ "notes": '## What this shows\n\nThis is the engine\'s differentiator. You declare the **options** (columns), the weighted **criteria** (rows), and a score per cell \u2014 and you stop there. The **Weighted total** row, the `#1`\u2026`#4` ranks, the green winner, and the **vs datum** deltas against Jenkins are all *computed* (\u03A3 of weight \xD7 score), not typed in. Change one score and the winner can flip. That is Stuart Pugh\'s controlled-convergence method \u2014 the same "the engine computes the answer" stance as `pert` (schedule) and `faulttree` (cut sets).\n\nThe `baseline: "Jenkins"` line marks the Pugh datum: that column is shaded and every other option shows its margin over it.'
1216
+ },
1217
+ {
1218
+ "slug": "comparison-cloud-feature-matrix",
1219
+ "diagram": "comparison",
1220
+ "title": "Cloud providers \u2014 feature comparison matrix",
1221
+ "description": "An options \xD7 criteria comparison grid mixing yes/partial marks with free-text cells \u2014 the kind of feature table no quadrant chart can express.",
1222
+ "standard": "ASQ comparison matrix \xB7 graphic-organizer convention",
1223
+ "tags": [
1224
+ "comparison",
1225
+ "matrix",
1226
+ "feature-comparison",
1227
+ "cloud"
1228
+ ],
1229
+ "complexity": 2,
1230
+ "featured": false,
1231
+ "dsl": 'comparison "Cloud provider \u2014 managed services"\nmode: matrix\noption "AWS"\noption "GCP"\noption "Azure"\ncriterion "Free tier"\n AWS: "12 months"\n GCP: "Always-free"\n Azure: "12 months"\ncriterion "Managed Postgres"\n AWS: yes\n GCP: yes\n Azure: yes\ncriterion "Serverless GPU"\n AWS: partial\n GCP: yes\n Azure: partial\ncriterion "Spot discount"\n AWS: "up to 90%"\n GCP: "up to 91%"\n Azure: "up to 90%"\ncriterion "On-prem hybrid"\n AWS: partial\n GCP: partial\n Azure: yes',
1232
+ "notes": '## What this shows\n\nA straight side-by-side feature table \u2014 options across the top, criteria down the side. Cells mix **marks** (`yes` \u2192 \u2713 green, `partial` \u2192 ~ amber) with **free text** (`"up to 90%"`), so one grid carries both capability flags and figures. The option name on each cell line must match a declared `option`; a typo is flagged in the diagnostics rather than silently dropped.'
1233
+ },
1142
1234
  {
1143
1235
  "slug": "decisiontree-influence-market-entry",
1144
1236
  "diagram": "decisiontree",
@@ -1896,6 +1988,23 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
1896
1988
  "dsl": 'floorplan "Residential Lot \u2014 60 \xD7 100 ft" unit ft\nroom front "Front Yard" at 0,0 size 60x34 fill #eef7e6 nolabel\nroom house "Residence" below front size 38x46\nroom drive "Driveway" right-of house size 22x46 fill #ededed\nroom yard "Back Yard" at 0,80 size 60x20 fill #eef7e6 nolabel\ndoor house north at 50% width 3.5\ndoor between house drive at 50% width 9 type double\nfurniture tree in front at 7,18 size 8x8\nfurniture tree in front at 45,18 size 8x8\nfurniture car in drive at 3,5 size 7x15\nfurniture car in drive at 12,5 size 7x15\nfurniture tree in yard at 6,7 size 9x9\nfurniture tree in yard at 45,7 size 9x9\nfurniture round-table-4 in yard at 26,7 size 6x6',
1897
1989
  "notes": "## What this shows\n\nA site plan has no nested rooms \u2014 the lot is **tiled** by non-overlapping zones (`front`, `house`, `drive`, `yard`) that share edges, exactly as the engine models adjacency. The `Residence` footprint stays an empty hatched box, the way a permit set shows the building outline.\n\n`tree` and `car` are sized for the outdoors \u2014 trees in feet across the yards, two cars filling the driveway stalls \u2014 and `door between house drive` resolves the garage opening onto the shared wall. The engine prints the exterior dimension string in feet-and-inches."
1898
1990
  },
1991
+ {
1992
+ "slug": "floorplan-restaurant-kitchen",
1993
+ "diagram": "floorplan",
1994
+ "title": "Restaurant \u2014 dining room + commercial kitchen",
1995
+ "description": "A restaurant floor plan with the back-of-house most tools skip: booths and named tables out front, a commercial kitchen line (range, prep tables, three-compartment sink, walk-in cooler, fryer) behind the pass.",
1996
+ "standard": "Architectural Graphic Standards \xB7 US NCS v6",
1997
+ "tags": [
1998
+ "floorplan",
1999
+ "restaurant",
2000
+ "commercial-kitchen",
2001
+ "hospitality"
2002
+ ],
2003
+ "complexity": 3,
2004
+ "featured": false,
2005
+ "dsl": 'floorplan "Bistro \u2014 Floor + Kitchen" unit m\nroom dining "Dining Room" at 0,0 size 9x7\nroom kitchen "Kitchen" right-of dining size 6x7\nopening between dining kitchen at 50% width 1.2\ndoor dining south at 20% width 1.0\nfurniture booth "B1" in dining at 0.3,0.4\nfurniture booth "B2" in dining at 0.3,2.6\nfurniture booth "B3" in dining at 0.3,4.8\nfurniture round-table-4 "1" in dining at 3.4,1 seats "Ann" "Ben"\nfurniture round-table-4 "2" in dining at 6.2,1 seats "Cy" "Di"\nfurniture round-table-4 "3" in dining at 3.4,4.2 seats "Ed" "Fay"\nfurniture range in kitchen at 0.4,0.4\nfurniture fryer in kitchen at 1.6,0.4\nfurniture prep-table in kitchen at 0.4,2.2\nfurniture commercial-sink in kitchen at 0.4,4.6\nfurniture walk-in in kitchen at 3.2,4.5',
2006
+ "notes": "## What this shows\n\nFront-of-house mixes `booth` (two facing benches with a table between) and named `round-table-4` covers; back-of-house uses the restaurant/commercial-kitchen catalog that general floor-plan tools omit: `range` (commercial six-burner over an oven), `prep-table` (stainless work table with a dashed under-shelf), `commercial-sink` (the three-compartment ware-washing sink health codes require), `walk-in` (the insulated double-wall cooler with its door), and `fryer`.\n\nThe `opening between dining kitchen` resolves the shared wall automatically and punches the pass-through; area labels and exterior dimensions come for free. This is the `restaurant floor plan` / `commercial kitchen layout` request \u2014 the head commercial-floorplan search terms \u2014 answered from one paragraph of text."
2007
+ },
1899
2008
  {
1900
2009
  "slug": "floorplan-retail-boutique",
1901
2010
  "diagram": "floorplan",
@@ -1914,6 +2023,24 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
1914
2023
  "dsl": 'floorplan "Boutique \u2014 Retail Floor" unit m\nroom shop "Sales Floor" at 0,0 size 12x9\nroom stock "Stockroom" right-of shop size 4x5\nroom fit "Fitting" right-of shop below stock size 4x4\ndoor shop south at 15% width 1.8 type double\ndoor between shop stock at 50%\ndoor between shop fit at 50%\nwindow shop south at 55% width 3\nfurniture counter "Window Display" in shop at 0.3,0.2 size 4x0.6\nfurniture checkout in shop at 0.4,7.6 size 2x0.7\ngrid shelving in shop rows 2 cols 3 count 6 area 2.4,2.6 9.6,5.2 itemsize 1.8x0.6\nfurniture clothing-rack in shop at 1.2,6.3\nfurniture clothing-rack in shop at 10.2,6.3\nfurniture shelving in stock at 0.2,0.3 size 3.6x0.6\nfurniture shelving in stock at 0.2,2.6 size 3.6x0.6\nfurniture sofa in fit at 1.2,0.2 size 1.6x0.6\ngrid fitting-room in fit rows 1 cols 3 count 3 area 0.7,2.2 3.3,2.2 itemsize 1.1x1.1',
1915
2024
  "notes": "## What this shows\n\n`shelving` (gondola runs), `checkout`, `clothing-rack`, and `fitting-room` are the retail symbol set. The sales-floor gondolas come from one `grid`, leaving 1.5 m aisles, while two free-standing round racks bracket the floor.\n\nThe stockroom and fitting area chain off the sales floor with `right-of`/`below`; the three changing booths sit in a `grid fitting-room` with a waiting `sofa` opposite \u2014 and the collision check keeps the aisles walkable."
1916
2025
  },
2026
+ {
2027
+ "slug": "floorplan-seating-chart",
2028
+ "diagram": "floorplan",
2029
+ "title": "Wedding seating chart \u2014 named guests",
2030
+ "description": "A seating chart, not just a venue plan: every chair carries its guest's name. Six round tables and a head table, named with the `seats` clause; the engine writes each name onto its chair in seating order, including CJK names.",
2031
+ "standard": "Architectural Graphic Standards \xB7 US NCS v6",
2032
+ "tags": [
2033
+ "floorplan",
2034
+ "wedding",
2035
+ "event",
2036
+ "seating",
2037
+ "seating-chart"
2038
+ ],
2039
+ "complexity": 3,
2040
+ "featured": false,
2041
+ "dsl": 'floorplan "Wedding Seating Chart" unit m\nroom hall "Grand Ballroom" at 0,0 size 17x13 nolabel\ndoor hall south at 50% width 1.8\nfurniture head-table "Head Table" in hall at 5.5,0.6 size 6x0.9 seats "Bride" "Groom" "Mom" "Dad" "MOH" "Best Man"\nfurniture round-table-8 "Table 1" in hall at 1,3.6 seats "Alice" "Bob" "Carol" "Dave" "Eve" "Frank" "Grace" "Heidi"\nfurniture round-table-8 "Table 2" in hall at 7,3.6 seats "Ivan" "Judy" "Mallory" "Niaj" "Olivia" "Peggy"\nfurniture round-table-8 "Table 3" in hall at 13,3.6 seats "\u5F20\u4F1F" "\u674E\u5A1C" "\u738B\u82B3" "\u5218\u6D0B"\nfurniture round-table-8 "Table 4" in hall at 1,8.4 seats "Quinn" "Rupert" "Sybil" "Trent" "Uma" "Vera"\nfurniture round-table-8 "Table 5" in hall at 7,8.4 seats "Walt" "Xena" "Yuki" "Zane"\nfurniture dance-floor "Dance Floor" in hall at 12,8 size 4.5x4.5',
2042
+ "notes": '## What this shows\n\nEach table is an individual `furniture` statement with a `seats "\u2026"` clause, so the engine writes guest names onto the chairs in seating order \u2014 round tables clockwise from the top, the head table along its single facing edge. That is the difference between a *venue plan* (where the tables go) and a *seating chart* (who sits where), which is the deliverable guests actually read off the easel.\n\nNames map to chairs one-for-one: **Table 3** lists four guests on an eight-chair round, so four chairs are named and four stay empty \u2014 no error. CJK names (`\u5F20\u4F1F`, `\u674E\u5A1C`) are quoted like any label. Because names render horizontally, the tables are left unrotated.'
2043
+ },
1917
2044
  {
1918
2045
  "slug": "floorplan-studio-office",
1919
2046
  "diagram": "floorplan",
@@ -4602,7 +4729,7 @@ var SYNTAX = {
4602
4729
  },
4603
4730
  "floorplan": {
4604
4731
  "title": "Floor plan",
4605
- "content": '## 1. Your first floor plan\n\nA header, one room, a door, and a window:\n\n```\nfloorplan "Studio"\nroom main "Studio" at 0,0 size 4x3\ndoor main south at 20%\nwindow main north at 50%\n```\n\nThree rules cover most usage:\n\n1. Start with `floorplan`, an optional quoted title, and `unit m` (default) or `unit ft`. **All numbers are in this unit.**\n2. Rooms are rectangles: `room id "Label" at x,y size WxH`. The label and computed area render centered in the room.\n3. Openings hang on walls: a wall reference (`main south`) positions along that wall at a percentage; `between A B` finds the shared wall automatically.\n\n---\n\n## 2. Rooms and placement\n\nPlace the first room at `0,0` and chain the rest relatively \u2014 adjacent rooms share an edge exactly, and their walls merge into a single band:\n\n```\nroom living "Living Room" at 0,0 size 5.2x4.2\nroom kitchen "Kitchen" right-of living size 3.0x4.2\nroom hall "Hallway" below living size 2.0x2.6\nroom bed1 "Bedroom 1" right-of hall size 3.2x2.6\n```\n\n- `right-of` / `left-of` / `above` / `below` snap to the reference room\'s edge.\n- `align start|center|end` aligns the cross axis (default `start` = top/left edges flush); `offset n` shifts it.\n- `fill #e0f2fe` tints the floor; `nolabel` suppresses the name + area label (single-space plans like classrooms).\n- Coordinates are y-down: `at 0,0` is the top-left corner.\n\n**L/T/U-shaped rooms** use `extend` \u2014 declare the main rectangle, then grow it with edge-sharing rectangles. The walls merge along the seam, the area is summed into one number (exactly how professionals measure L-rooms), and the label centers on the largest part:\n\n```\nroom living "Living Room" at 0,0 size 5x4\nextend living at 5,2 size 2x2 # L-shape: notch at top-right\n```\n\nAn extension that doesn\'t touch the room, or overlaps it, is rejected with a quantified error. `north` (optionally `north 30` for rotated plans) adds the compass at the top right.\n\n---\n\n## 3. Doors, windows, openings\n\n```\ndoor hall west at 50% width 1.0 swing in # exterior door on a wall\ndoor between hall bed1 at 50% hinge right # interior door on the shared wall\ndoor between bed1 bath at 30% type sliding # sliding door \u2014 no arc\nopening between living kitchen at 35% width 1.2 # archway, no leaf\nwindow living north at 30% width 1.8\n```\n\n- `between A B` resolves the shared wall segment and positions at the percentage **along the overlap** \u2014 no coordinates needed. Non-adjacent rooms are rejected with the measured gap.\n- Doors default to 0.9 m wide on exterior walls, 0.8 m on `between` walls; windows default to 1.2 m.\n- `hinge left|right` picks the jamb; `swing in|out` flips the quarter-arc (default swings into the owning room \u2014 the first room named).\n- Door `type single|double|sliding|pocket|bifold`: double draws two mirrored arcs; sliding/pocket draw offset leaf lines without an arc; bifold draws the two closet-door tent peaks.\n- Window `type fixed|sliding|casement|bay`: sliding = two offset panels, casement adds the outward swing arc, bay projects a splayed trapezoid outside the wall.\n- Openings clamp to fit their wall segment (with a warning) rather than overflowing.\n\n---\n\n## 4. Furniture\n\nFurniture is placed **relative to its room\'s interior top-left corner**, with optional `size`, `rotate`, and a label:\n\n```\nfurniture sofa in living at 0.25,2.9\nfurniture desk "Teacher" in class at 2,1.5 size 5x2.5 rotate 20\nfurniture counter "Cubbies" in class at 6,24.4 size 10x1.2\n```\n\nThe catalog spans residential, commercial, and site work (sizes default to industry-standard footprints):\n\n| Cluster | Types |\n| --- | --- |\n| Residential | `bed-double` `bed-single` `bed-queen` `bed-king` `bunk-bed` `crib` `sofa` `loveseat` `sectional` `armchair` `ottoman` `coffee-table` `side-table` `tv` `tv-stand` `fireplace` `floor-lamp` `rug` `wardrobe` `dresser` `nightstand` `bookshelf` `plant` `piano` `piano-upright` `pool-table` `ceiling-fan` `dining-table` |\n| Kitchen / bath | `counter` `wall-cabinet` `kitchen-sink` `stove` `range-hood` `fridge` `dishwasher` `island` `bar-stool` `toilet` `sink` `vanity` `bidet` `urinal` `bathtub` `shower` `washer` `dryer` |\n| Classroom / office | `desk-chair` `desk` `desk-l` `chair` `whiteboard` `smartboard` `bookcase` `cubbies` `filing-cabinet` `lockers` `kidney-table` `round-table-4/6/8/10` `conference-table` |\n| Event / banquet | `banquet-table` `head-table` `stage` `dance-floor` `bar` `dj-booth` `cocktail-table` `podium` `row-chairs` |\n| Retail / warehouse | `shelving` `checkout` `clothing-rack` `fitting-room` `pallet-rack` `loading-dock` `forklift` |\n| Salon / gym | `salon-chair` `shampoo-bowl` `manicure-table` `treadmill` `weight-bench` `power-rack` `yoga-mat` |\n| Stairs / structural | `stairs` `stairs-l` `stairs-u` `spiral-stairs` `elevator` `column` |\n| Site / outdoor | `tree` `car` |\n\n**Auto-seating** is built in: `round-table-8` draws 8 chairs on its circumference (60\u2033 top; `round-table-10` uses 72\u2033), `dining-table` / `banquet-table` / `conference-table` seat both long edges at one chair per 0.65 m, `head-table` seats one side facing the room, `manicure-table` seats a client and technician chair, and `row-chairs` places a theater strip at 0.55 m pitch. `rug`, `dance-floor`, `yoga-mat`, `counter`, `island`, `wall-cabinet`, `range-hood`, and `ceiling-fan` are underlays/overheads \u2014 other furniture can overlap them without a collision warning.\n\n`tree` and `car` are sized for the outdoors (canopy disc, parking-stall footprint), so a **site plan** is just zones tiled as adjacent rooms \u2014 front yard, house footprint, driveway, back yard \u2014 with trees and parked cars placed on top.\n\n**Stairs** follow the drafting conventions: tread lines at 0.28 m (11\u2033), a direction arrow starting at the lowest tread labeled `UP` (give the item a `"DN"` label for a descending run), and the 45\xB0 zigzag break line at the imaginary 4-ft cut plane, with dashed treads beyond. `stairs` is a straight run (orient with `size`/`rotate`), `stairs-l` turns 90\xB0 over a landing, `stairs-u` switches back 180\xB0, `spiral-stairs` is a circle with radial treads and a center pole.\n\n---\n\n## 5. Arrays \u2014 grid, row, arc\n\nRepeated furniture is one statement, not thirty:\n\n```\ngrid desk-chair in class rows 5 cols 6 count 27 area 5,8 25,24 itemsize 2x2.5\nrow round-table-8 in hall cols 3 area 8.8,13.4 15.2,13.4 itemsize 2.3x2.3\narc chair in hall count 13 center 12,8 radius 5 from 200 to 340\n```\n\n- `area x1,y1 x2,y2` gives the first and last item **centers**; items spread evenly between them.\n- `count` truncates **row-major** \u2014 27 desks in a 5\xD76 grid drops the last row\'s tail, exactly like a real classroom.\n- `arc` places items on a circular arc facing the center \u2014 semicircle classrooms, ceremony seating.\n\n---\n\n## 6. Units, areas, dimension lines\n\n- `unit ft` makes every number feet; dimension lines format as `32\'` / `15\'1"` and areas as `sq ft`. Internally everything is metric (1 ft = 0.3048 m).\n- Room areas are **computed by the engine** from the declared geometry, never typed by hand.\n- Dimension lines render outside the plan with architectural slash ticks: overall width + height always, plus per-room segments along the top and left exteriors.\n\n---\n\n## 7. Validation\n\nThe engine validates what LLMs (and humans) actually get wrong, with errors that name the offending elements and a fix direction:\n\n**Errors** (block rendering, shown in an error panel):\n\n- Room overlap \u2014 `rooms "bed1" and "bath" overlap by 0.40\xD72.60 m \u2014 move "bath" right-of "bed1" or shrink size`\n- Door between non-adjacent rooms \u2014 `door between "kitchen" and "bed2": rooms share no wall (gap 2 m on x-axis)`\n- Furniture outside its room \u2014 `furniture sofa #1 extends 1.7 m outside room "c" \u2014 move it or shrink size`\n\n**Warnings** (render anyway, listed under the plan):\n\n- Furniture collision \u2014 bounding boxes including **chair-ring envelopes**, so two banquet rounds whose chairs touch get flagged even when the table tops don\'t.\n- Opening clamped to fit its wall segment.\n\n---\n\n## 8. Grammar (EBNF)\n\n```text\nplan ::= "floorplan" string? ("unit" ("m"|"ft"))? NL statement*\nstatement ::= room | extend | north | door | window | opening | furniture | array\nroom ::= "room" id string? placement "size" dims ("fill" color)? ("nolabel")?\nextend ::= "extend" id placement "size" dims\nnorth ::= "north" num?\nplacement ::= "at" coord\n | ("right-of"|"left-of"|"above"|"below") id ("offset" num)?\n ("align" ("start"|"center"|"end"))?\ndoor ::= "door" (wallref | "between" id id) "at" pct\n ("width" num)? ("hinge" ("left"|"right"))? ("swing" ("in"|"out"))?\n ("type" ("single"|"double"|"sliding"|"pocket"|"bifold"))?\nwindow ::= "window" wallref "at" pct ("width" num)?\n ("type" ("fixed"|"sliding"|"casement"|"bay"))?\nopening ::= "opening" (wallref | "between" id id) "at" pct ("width" num)?\nfurniture ::= "furniture" type ("in" id) "at" coord ("size" dims)? ("rotate" num)? string?\narray ::= ("grid"|"row"|"arc") type "in" id\n ("rows" int)? ("cols" int)? ("count" int)?\n ("area" coord coord)? ("itemsize" dims)? ("rotate" num)?\n ("center" coord)? ("radius" num)? ("from" num "to" num)?\nwallref ::= id ("north"|"south"|"east"|"west")\ncoord ::= num "," num dims ::= num "x" num pct ::= num "%"?\n```\n\nComments run from `#` to end of line. CJK quotes (`\u201C\u201D`) are accepted as ASCII quotes.\n\n---\n\n## Related examples\n\n- [Two-bedroom apartment](/examples#floorplan) \u2014 relative placement, 7 doors, full furnishing\n- [27-desk classroom](/examples#floorplan) \u2014 `grid \u2026 count` truncation, `unit ft`\n- [Wedding reception for 120](/examples#floorplan) \u2014 auto-seated banquet rounds, dance floor'
4732
+ "content": '## 1. Your first floor plan\n\nA header, one room, a door, and a window:\n\n```\nfloorplan "Studio"\nroom main "Studio" at 0,0 size 4x3\ndoor main south at 20%\nwindow main north at 50%\n```\n\nThree rules cover most usage:\n\n1. Start with `floorplan`, an optional quoted title, and `unit m` (default) or `unit ft`. **All numbers are in this unit.**\n2. Rooms are rectangles: `room id "Label" at x,y size WxH`. The label and computed area render centered in the room.\n3. Openings hang on walls: a wall reference (`main south`) positions along that wall at a percentage; `between A B` finds the shared wall automatically.\n\n---\n\n## 2. Rooms and placement\n\nPlace the first room at `0,0` and chain the rest relatively \u2014 adjacent rooms share an edge exactly, and their walls merge into a single band:\n\n```\nroom living "Living Room" at 0,0 size 5.2x4.2\nroom kitchen "Kitchen" right-of living size 3.0x4.2\nroom hall "Hallway" below living size 2.0x2.6\nroom bed1 "Bedroom 1" right-of hall size 3.2x2.6\n```\n\n- `right-of` / `left-of` / `above` / `below` snap to the reference room\'s edge.\n- `align start|center|end` aligns the cross axis (default `start` = top/left edges flush); `offset n` shifts it.\n- `fill #e0f2fe` tints the floor; `nolabel` suppresses the name + area label (single-space plans like classrooms).\n- Coordinates are y-down: `at 0,0` is the top-left corner.\n\n**L/T/U-shaped rooms** use `extend` \u2014 declare the main rectangle, then grow it with edge-sharing rectangles. The walls merge along the seam, the area is summed into one number (exactly how professionals measure L-rooms), and the label centers on the largest part:\n\n```\nroom living "Living Room" at 0,0 size 5x4\nextend living at 5,2 size 2x2 # L-shape: notch at top-right\n```\n\nAn extension that doesn\'t touch the room, or overlaps it, is rejected with a quantified error. `north` (optionally `north 30` for rotated plans) adds the compass at the top right.\n\n---\n\n## 3. Doors, windows, openings\n\n```\ndoor hall west at 50% width 1.0 swing in # exterior door on a wall\ndoor between hall bed1 at 50% hinge right # interior door on the shared wall\ndoor between bed1 bath at 30% type sliding # sliding door \u2014 no arc\nopening between living kitchen at 35% width 1.2 # archway, no leaf\nwindow living north at 30% width 1.8\n```\n\n- `between A B` resolves the shared wall segment and positions at the percentage **along the overlap** \u2014 no coordinates needed. Non-adjacent rooms are rejected with the measured gap.\n- Doors default to 0.9 m wide on exterior walls, 0.8 m on `between` walls; windows default to 1.2 m.\n- `hinge left|right` picks the jamb; `swing in|out` flips the quarter-arc (default swings into the owning room \u2014 the first room named).\n- Door `type single|double|sliding|pocket|bifold`: double draws two mirrored arcs; sliding/pocket draw offset leaf lines without an arc; bifold draws the two closet-door tent peaks.\n- Window `type fixed|sliding|casement|bay`: sliding = two offset panels, casement adds the outward swing arc, bay projects a splayed trapezoid outside the wall.\n- Openings clamp to fit their wall segment (with a warning) rather than overflowing.\n\n---\n\n## 4. Furniture\n\nFurniture is placed **relative to its room\'s interior top-left corner**, with optional `size`, `rotate`, and a label:\n\n```\nfurniture sofa in living at 0.25,2.9\nfurniture desk "Teacher" in class at 2,1.5 size 5x2.5 rotate 20\nfurniture counter "Cubbies" in class at 6,24.4 size 10x1.2\n```\n\nThe catalog spans residential, commercial, and site work (sizes default to industry-standard footprints):\n\n| Cluster | Types |\n| --- | --- |\n| Residential | `bed-double` `bed-single` `bed-queen` `bed-king` `bunk-bed` `crib` `sofa` `loveseat` `sectional` `armchair` `ottoman` `coffee-table` `side-table` `tv` `tv-stand` `fireplace` `floor-lamp` `rug` `wardrobe` `dresser` `nightstand` `bookshelf` `plant` `piano` `piano-upright` `pool-table` `ceiling-fan` `dining-table` |\n| Kitchen / bath | `counter` `wall-cabinet` `kitchen-sink` `stove` `range-hood` `fridge` `dishwasher` `island` `bar-stool` `toilet` `sink` `vanity` `bidet` `urinal` `bathtub` `shower` `washer` `dryer` |\n| Classroom / office | `desk-chair` `desk` `desk-l` `chair` `whiteboard` `smartboard` `bookcase` `cubbies` `filing-cabinet` `lockers` `kidney-table` `round-table-4/6/8/10` `conference-table` |\n| Event / banquet | `banquet-table` `head-table` `stage` `dance-floor` `bar` `dj-booth` `cocktail-table` `podium` `row-chairs` |\n| Retail / warehouse | `shelving` `checkout` `clothing-rack` `fitting-room` `pallet-rack` `loading-dock` `forklift` |\n| Salon / gym | `salon-chair` `shampoo-bowl` `manicure-table` `treadmill` `weight-bench` `power-rack` `yoga-mat` |\n| Restaurant / commercial kitchen | `booth` `prep-table` `range` `walk-in` `commercial-sink` `fryer` |\n| Stairs / structural | `stairs` `stairs-l` `stairs-u` `spiral-stairs` `elevator` `column` |\n| Site / outdoor | `tree` `car` |\n\n**Auto-seating** is built in: `round-table-8` draws 8 chairs on its circumference (60\u2033 top; `round-table-10` uses 72\u2033), `dining-table` / `banquet-table` / `conference-table` seat both long edges at one chair per 0.65 m, `head-table` seats one side facing the room, `manicure-table` seats a client and technician chair, and `row-chairs` places a theater strip at 0.55 m pitch. `rug`, `dance-floor`, `yoga-mat`, `counter`, `island`, `wall-cabinet`, `range-hood`, and `ceiling-fan` are underlays/overheads \u2014 other furniture can overlap them without a collision warning.\n\n**Seating charts** \u2014 name the occupants of any auto-seating table with a `seats` clause, and the engine writes each name onto its chair (in placement order: round tables clockwise from the top; rectangular tables fill the top edge left-to-right, then the bottom edge). This turns a venue floor plan into the seating chart guests actually read:\n\n```\nfurniture round-table-8 "Table 3" in hall at 11,4 seats "Alice" "Bob" "Carol" "Dave"\nfurniture head-table "Head Table" in hall at 5,0.6 size 6x0.9 seats "Bride" "Groom"\n```\n\nExtra chairs without a name stay empty; extra names past the chair count are ignored. CJK-quoted names (`seats "\u5F20\u4F1F" "\u674E\u5A1C"`) work like every other label. Names read horizontally, so keep the table unrotated for a clean chart.\n\n`tree` and `car` are sized for the outdoors (canopy disc, parking-stall footprint), so a **site plan** is just zones tiled as adjacent rooms \u2014 front yard, house footprint, driveway, back yard \u2014 with trees and parked cars placed on top.\n\n**Stairs** follow the drafting conventions: tread lines at 0.28 m (11\u2033), a direction arrow starting at the lowest tread labeled `UP` (give the item a `"DN"` label for a descending run), and the 45\xB0 zigzag break line at the imaginary 4-ft cut plane, with dashed treads beyond. `stairs` is a straight run (orient with `size`/`rotate`), `stairs-l` turns 90\xB0 over a landing, `stairs-u` switches back 180\xB0, `spiral-stairs` is a circle with radial treads and a center pole.\n\n---\n\n## 5. Arrays \u2014 grid, row, arc\n\nRepeated furniture is one statement, not thirty:\n\n```\ngrid desk-chair in class rows 5 cols 6 count 27 area 5,8 25,24 itemsize 2x2.5\nrow round-table-8 in hall cols 3 area 8.8,13.4 15.2,13.4 itemsize 2.3x2.3\narc chair in hall count 13 center 12,8 radius 5 from 200 to 340\n```\n\n- `area x1,y1 x2,y2` gives the first and last item **centers**; items spread evenly between them.\n- `count` truncates **row-major** \u2014 27 desks in a 5\xD76 grid drops the last row\'s tail, exactly like a real classroom.\n- `arc` places items on a circular arc facing the center \u2014 semicircle classrooms, ceremony seating.\n\n---\n\n## 6. Units, areas, dimension lines\n\n- `unit ft` makes every number feet; dimension lines format as `32\'` / `15\'1"` and areas as `sq ft`. Internally everything is metric (1 ft = 0.3048 m).\n- Room areas are **computed by the engine** from the declared geometry, never typed by hand.\n- Dimension lines render outside the plan with architectural slash ticks: overall width + height always, plus per-room segments along the top and left exteriors.\n\n---\n\n## 7. Validation\n\nThe engine validates what LLMs (and humans) actually get wrong, with errors that name the offending elements and a fix direction:\n\n**Errors** (block rendering, shown in an error panel):\n\n- Room overlap \u2014 `rooms "bed1" and "bath" overlap by 0.40\xD72.60 m \u2014 move "bath" right-of "bed1" or shrink size`\n- Door between non-adjacent rooms \u2014 `door between "kitchen" and "bed2": rooms share no wall (gap 2 m on x-axis)`\n- Furniture outside its room \u2014 `furniture sofa #1 extends 1.7 m outside room "c" \u2014 move it or shrink size`\n\n**Warnings** (render anyway, listed under the plan):\n\n- Furniture collision \u2014 bounding boxes including **chair-ring envelopes**, so two banquet rounds whose chairs touch get flagged even when the table tops don\'t.\n- Opening clamped to fit its wall segment.\n\n---\n\n## 8. Grammar (EBNF)\n\n```text\nplan ::= "floorplan" string? ("unit" ("m"|"ft"))? NL statement*\nstatement ::= room | extend | north | door | window | opening | furniture | array\nroom ::= "room" id string? placement "size" dims ("fill" color)? ("nolabel")?\nextend ::= "extend" id placement "size" dims\nnorth ::= "north" num?\nplacement ::= "at" coord\n | ("right-of"|"left-of"|"above"|"below") id ("offset" num)?\n ("align" ("start"|"center"|"end"))?\ndoor ::= "door" (wallref | "between" id id) "at" pct\n ("width" num)? ("hinge" ("left"|"right"))? ("swing" ("in"|"out"))?\n ("type" ("single"|"double"|"sliding"|"pocket"|"bifold"))?\nwindow ::= "window" wallref "at" pct ("width" num)?\n ("type" ("fixed"|"sliding"|"casement"|"bay"))?\nopening ::= "opening" (wallref | "between" id id) "at" pct ("width" num)?\nfurniture ::= "furniture" type ("in" id) "at" coord ("size" dims)? ("rotate" num)? string? ("seats" string+)?\narray ::= ("grid"|"row"|"arc") type "in" id\n ("rows" int)? ("cols" int)? ("count" int)?\n ("area" coord coord)? ("itemsize" dims)? ("rotate" num)?\n ("center" coord)? ("radius" num)? ("from" num "to" num)?\nwallref ::= id ("north"|"south"|"east"|"west")\ncoord ::= num "," num dims ::= num "x" num pct ::= num "%"?\n```\n\nComments run from `#` to end of line. CJK quotes (`\u201C\u201D`) are accepted as ASCII quotes.\n\n---\n\n## Related examples\n\n- [Two-bedroom apartment](/examples#floorplan) \u2014 relative placement, 7 doors, full furnishing\n- [27-desk classroom](/examples#floorplan) \u2014 `grid \u2026 count` truncation, `unit ft`\n- [Wedding reception for 120](/examples#floorplan) \u2014 auto-seated banquet rounds, dance floor'
4606
4733
  },
4607
4734
  "playbook": {
4608
4735
  "title": "Sports playbook",
@@ -4611,6 +4738,10 @@ var SYNTAX = {
4611
4738
  "rbd": {
4612
4739
  "title": "Reliability Block Diagram",
4613
4740
  "content": '## 1. Your first diagram\n\nEvery document starts with the `rbd` keyword (alias `reliability`), an optional title, then nested success-logic groups around `block` leaves:\n\n```\nrbd "Two redundant pumps"\n parallel {\n block A "Pump A" R=0.9\n block B "Pump B" R=0.9\n }\n```\n\nThe engine draws the two pumps on parallel rails between a split node and a join node, computes the system reliability `1 \u2212 (1\u22120.9)(1\u22120.9) = 0.99`, and prints it as the headline. A bare top-level list of blocks (no outer group) is treated as a **series** chain.\n\n## 2. Blocks\n\nA `block` is one component on a success path:\n\n```\nblock ID "Label" R=0.99\n```\n\n- `ID` \u2014 a short identifier (shown when no label is given).\n- `"Label"` \u2014 an optional display name (CJK quotes welcome).\n- Reliability is given as **`R=0.99`** (reliability/availability), **`p=0.01`** (probability of *failure*, \u2192 R = 1\u2212p), or a percentage **`R=99%`**. A block with no reliability leaves the system figure symbolic (`n/a`).\n\n## 3. Success-logic groups\n\nGroups nest freely, so you can model redundant chains, voting banks, and standby pairs:\n\n| Group | Succeeds when | Reliability |\n|-------|---------------|-------------|\n| `series { \u2026 }` | **every** child works | \u220F R\u1D62 |\n| `parallel { \u2026 }` | **any** child works | 1 \u2212 \u220F(1 \u2212 R\u1D62) |\n| `kofn k/n { \u2026 }` | **\u2265 k of n** children work | exact state enumeration |\n\n```\nseries {\n block CTRL "Controller" R=0.995\n parallel {\n series { block P1 "Path 1 sensor" R=0.97\n block A1 "Path 1 actuator" R=0.98 }\n series { block P2 "Path 2 sensor" R=0.97\n block A2 "Path 2 actuator" R=0.98 }\n }\n}\n```\n\n## 4. Computed reliability, importance & SPOF\n\nAfter parsing, the engine computes:\n\n- **System reliability** \u2014 the headline figure, by recursive series/parallel/k-of-n reduction.\n- **Birnbaum importance** `I\u1D2E(i) = R_sys(R\u1D62=1) \u2212 R_sys(R\u1D62=0)` for every block; the highest-importance block (the improvement target) is accented.\n- **Criticality importance** `I_C(i) = I\u1D2E(i)\xB7(1\u2212R\u1D62)/(1\u2212R_sys)` \u2014 the probability block i is failed *and* critical, given the system is failed.\n- **Single points of failure** \u2014 any block where `R_sys(R\u1D62=0) = 0` (its failure alone fails the system) is drawn with a red border. A non-redundant block in series is always a SPOF.\n\n## 5. Time-dependent reliability \u2014 R(t)\n\nA static `R=` is the entry point; in practice reliability is a function of mission time. Set a **`mission: <t>`** and give blocks a failure distribution instead of a constant \u2014 the engine evaluates **R(t)** and rolls it up exactly as before. Use **consistent time units** across `mission` and the rates.\n\n| Block attribute | Model | R(t) |\n|-----------------|-------|------|\n| `rate=0.0001` | exponential (constant hazard \u03BB) | e^(\u2212\u03BBt) |\n| `mtbf=10000` | exponential (\u03BB = 1/MTBF) | e^(\u2212t/MTBF) |\n| `weibull=2,10000` | Weibull(\u03B2 shape, \u03B7 scale) | e^(\u2212(t/\u03B7)^\u03B2) |\n\n```\nrbd "Pump station \u2014 1-year mission"\n mission: 8760 # hours\n parallel {\n block A "Pump A" mtbf=10000\n block B "Pump B" weibull=1.5,12000\n }\n```\n\nThe headline becomes `R(t=8760) = \u2026`. A block with a distribution but no `mission:` warns and falls back to its constant `R=` (if any).\n\n## 6. Validation\n\nThe parser reports non-fatal warnings rather than failing:\n\n- a `kofn k/n` threshold with `k > n` is clamped to `n` (and `k < 1` to `1`);\n- a reliability outside `0..1` is clamped;\n- a duplicate block id is flagged.\n\n## 7. Theming\n\n`theme: default` uses the shared risk-reliability palette (neutral blocks, blue reliability numerals, red single-point-of-failure borders). `theme: monochrome` renders a black-and-white print version (SPOF by border weight); `theme: dark` is the Catppuccin dark variant.'
4741
+ },
4742
+ "comparison": {
4743
+ "title": "Comparison & Decision Matrix",
4744
+ "content": '## 1. Header and mode\n\nThe header keyword is `comparison` (aliases `compare`, `vs`). The header keywords `tchart` and `pugh` set the mode directly. Otherwise choose with the `mode:` directive:\n\n```\ncomparison "Title"\nmode: tchart | pros-cons | matrix | decision | double-bubble\nlegend: on | off\n```\n\nIf you omit `mode:`, it is inferred from the keywords you use \u2014 but generating it explicitly is more reliable.\n\n## 2. T-chart (and Y-chart)\n\nDeclare each `column`, then list its points with `-` bullets. Three columns reads as a Y-chart.\n\n```\ntchart "TCP vs UDP"\ncolumn "TCP"\n- Connection-oriented (handshake)\n- Guaranteed, ordered delivery\ncolumn "UDP"\n- Connectionless, fire-and-forget\n- Minimal header, low latency\n```\n\n## 3. Pros / cons\n\n```\ncomparison "Migrate to microservices?"\nmode: pros-cons\npro "Independent team deploys"\npro "Scale hot paths in isolation"\ncon "Distributed-systems complexity"\ncon "Operational + infra cost goes up"\n```\n\n`pro` lines fill the green column, `con` the red \u2014 order independent.\n\n## 4. Comparison matrix\n\nDeclare every `option` (the columns), then each `criterion` (a row) with one indented `OptionName: value` cell per option. Cell values: `yes` / `no` / `partial` render as \u2713 / \u2717 / ~, numbers are scores, quoted text is shown verbatim. The option name must match an `option` exactly (a typo is flagged, not dropped).\n\n```\ncomparison "Cloud provider \u2014 managed services"\nmode: matrix\noption "AWS"\noption "GCP"\noption "Azure"\ncriterion "Free tier"\n AWS: "12 months"\n GCP: "Always-free"\n Azure: "12 months"\ncriterion "Managed Postgres"\n AWS: yes\n GCP: yes\n Azure: partial\n```\n\nA compact pipe form is also accepted: `criterion "Free tier" | "12 months" | "Always-free" | "12 months"` (positional to option order).\n\n## 5. Decision matrix (computed)\n\nAdd a `weight:` to each criterion and a numeric score to each cell. The engine appends a **Weighted total** row, ranks the options (`#1`, `#2`, \u2026), and highlights the winner. Add `baseline: "Option"` for a Pugh datum \u2014 that column is shaded and a **vs datum** delta row is added.\n\n```\npugh "Database for the new service"\nbaseline: "PostgreSQL"\noption "PostgreSQL"\noption "MongoDB"\noption "DynamoDB"\ncriterion "Query flexibility" weight: 5\n PostgreSQL: 5\n MongoDB: 3\n DynamoDB: 2\ncriterion "Horizontal scaling" weight: 4\n PostgreSQL: 3\n MongoDB: 4\n DynamoDB: 5\ncriterion "Operational cost" weight: 3\n PostgreSQL: 4\n MongoDB: 3\n DynamoDB: 3\n```\n\nYou never write the totals \u2014 the engine computes \u03A3(weight \xD7 score), so getting a score wrong changes the computed winner.\n\n## 6. Double-bubble (compare & contrast)\n\n```\ncomparison "Plant cell vs Animal cell"\nmode: double-bubble\nleft "Plant cell"\nright "Animal cell"\nshared "Has a nucleus"\nshared "Mitochondria"\nleft-only "Cell wall"\nleft-only "Chloroplasts"\nright-only "Centrioles"\nright-only "Lysosomes"\n```\n\n`shared` traits sit in the middle, connected to both centres; `left-only` / `right-only` fan out to their own centre.\n\n## 7. Themes\n\n`default` is the house blue with green/red/amber valence; `monochrome` drops colour (valence rides on \u2713/\u2717/~, the winner on a heavy border) for B&W print; `dark` is Catppuccin.\n\n## Standard\n\nPugh, *Total Design* (1991) controlled convergence \xB7 ASQ decision matrix \xB7 Hyerle Thinking Maps (double-bubble) \xB7 K-12 graphic-organizer convention. See `docs/reference/51-COMPARISON-STANDARD.md`.'
4614
4745
  }
4615
4746
  };
4616
4747
 
@@ -5918,6 +6049,49 @@ var PROFILES = {
5918
6049
  "If system reliability shows 'n/a', a block is missing its `R=`/`p=`."
5919
6050
  ]
5920
6051
  },
6052
+ comparison: {
6053
+ type: "comparison",
6054
+ header: 'comparison "Title"',
6055
+ mode: "one DSL, five modes selected by `mode:` \u2014 pick the mode that matches the task",
6056
+ keywords: 'comparison "Title" (alias headers: tchart | pugh) \xB7 mode: tchart | pros-cons | matrix | decision | double-bubble \xB7 legend: on|off \xB7 tchart: column "X" then `- item` bullets \xB7 pros-cons: pro "\u2026" / con "\u2026" \xB7 matrix & decision: option "A" (columns) + criterion "X" [weight: N] (rows) with indented `A: value` cells (value = text | yes/no/partial | number) \xB7 decision adds numeric scores + optional baseline: "A" (Pugh datum) \u2192 engine computes weighted total, rank, winner \xB7 double-bubble: left "A" / right "B" / shared "\u2026" / left-only "\u2026" / right-only "\u2026"',
6057
+ forms: [
6058
+ 'comparison "Database choice"',
6059
+ "mode: decision",
6060
+ 'option "PostgreSQL"',
6061
+ 'option "MongoDB"',
6062
+ 'criterion "Query flexibility" weight: 5',
6063
+ " PostgreSQL: 5",
6064
+ " MongoDB: 3",
6065
+ 'criterion "Horizontal scaling" weight: 4',
6066
+ " PostgreSQL: 3",
6067
+ " MongoDB: 5",
6068
+ "# \u2014 or a simple T-chart \u2014",
6069
+ "mode: tchart",
6070
+ 'column "Remote"',
6071
+ "- No commute",
6072
+ 'column "Office"',
6073
+ "- Easier collaboration"
6074
+ ],
6075
+ prefer: [
6076
+ "Choose the mode by the job: 2\u2013N bullet columns \u2192 `tchart`; a green/red list \u2192 `pros-cons`; an options\xD7criteria table of facts \u2192 `matrix`; a *decision* with weighted scores \u2192 `decision` (alias `pugh`); a compare/contrast organizer \u2192 `double-bubble`.",
6077
+ "In `matrix`/`decision`, declare every `option` first, then each `criterion`, then indent the per-option cells as `OptionName: value` (the name must match an `option` exactly).",
6078
+ "Use `decision` whenever the user wants to *pick a winner*: give each criterion a `weight:` and each option a numeric score \u2014 the engine sums \u03A3(weight\xD7score), ranks, and highlights the winner. Don't compute the totals yourself.",
6079
+ "Cell marks: `yes`/`no`/`partial` render as \u2713/\u2717/~; numbers are scores; quoted text is shown verbatim.",
6080
+ 'For a Pugh datum, add `baseline: "OptionName"` \u2014 the engine shades that column and shows each option\'s delta versus it.'
6081
+ ],
6082
+ avoid: [
6083
+ "Don't reach for `comparison` to plot items on two axes (Eisenhower / BCG / impact-effort) \u2014 that's the `matrix` diagram. `comparison` is a table, not a quadrant.",
6084
+ "Don't write cell lines before declaring the options \u2014 an unknown `Name:` cell is dropped with a warning.",
6085
+ "Don't hand-write a 'Total' row in `decision` mode \u2014 the engine appends and ranks it.",
6086
+ "Don't mix modes in one document; set exactly one `mode:`."
6087
+ ],
6088
+ repair: [
6089
+ "'is not a declared option' -> add `option \"Name\"` or fix the cell's name to match an option.",
6090
+ "'needs at least one option/criterion' -> a matrix needs both `option` columns and `criterion` rows.",
6091
+ "'no numeric scores found' (decision) -> add `Option: <number>` cells, or switch to `mode: matrix`.",
6092
+ '\'needs both a left and a right\' (double-bubble) -> declare `left "A"` and `right "B"`.'
6093
+ ]
6094
+ },
5921
6095
  causalloop: {
5922
6096
  type: "causalloop",
5923
6097
  header: 'causalloop "Title"',
@@ -6387,5 +6561,5 @@ function matchRepair(repairs, message) {
6387
6561
  }
6388
6562
 
6389
6563
  export { DIAGRAM_REGISTRY, DIAGRAM_SINCE, getAllDiagramTypes, getDiagramMeta, getDiagramSince, getExamples, getSyntax, listDiagrams, renderDsl, resolveDiagramType, validateDsl };
6390
- //# sourceMappingURL=chunk-DVRB64CN.js.map
6391
- //# sourceMappingURL=chunk-DVRB64CN.js.map
6564
+ //# sourceMappingURL=chunk-RCR4UGKV.js.map
6565
+ //# sourceMappingURL=chunk-RCR4UGKV.js.map