schematex 0.9.8 → 0.9.10

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.
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunk2LVU75P3_cjs = require('../chunk-2LVU75P3.cjs');
4
- require('../chunk-BEPVTFXK.cjs');
3
+ var chunkCA54ESRT_cjs = require('../chunk-CA54ESRT.cjs');
4
+ require('../chunk-OY2CXLVY.cjs');
5
5
  require('../chunk-UHRNFBWY.cjs');
6
6
  require('../chunk-TXWVJAMR.cjs');
7
7
  require('../chunk-T55OQILI.cjs');
@@ -31,7 +31,7 @@ var schematexTools = {
31
31
  listDiagrams: ai.tool({
32
32
  description: "List every Schematex diagram type with a tagline, 'use when' hint, domain cluster, and authoritative standard. Call this first to discover what's available.",
33
33
  inputSchema: zod.z.object({}),
34
- execute: async () => chunk2LVU75P3_cjs.listDiagrams()
34
+ execute: async () => chunkCA54ESRT_cjs.listDiagrams()
35
35
  }),
36
36
  getSyntax: ai.tool({
37
37
  description: "Return syntax for one diagram type. Default `detail: canonical` is the compact first-shot generation path: canonical header, preferred forms, rules, and repair checks. Request `detail: reference` only for advanced forms or imported adapters after choosing a type.",
@@ -46,7 +46,7 @@ var schematexTools = {
46
46
  execute: async ({
47
47
  type,
48
48
  detail
49
- }) => chunk2LVU75P3_cjs.getSyntax(type, { detail })
49
+ }) => chunkCA54ESRT_cjs.getSyntax(type, { detail })
50
50
  }),
51
51
  getExamples: ai.tool({
52
52
  description: "Return curated real-world DSL examples for a diagram type, each with scenario notes and tags. Use as few-shot context before generating DSL.",
@@ -56,7 +56,7 @@ var schematexTools = {
56
56
  preferFeatured: zod.z.boolean().optional().describe("Rank featured examples first."),
57
57
  maxComplexity: zod.z.number().int().min(1).max(5).optional().describe("Only return examples with complexity <= this value (1=simplest).")
58
58
  }),
59
- execute: async (args) => chunk2LVU75P3_cjs.getExamples(args.type, {
59
+ execute: async (args) => chunkCA54ESRT_cjs.getExamples(args.type, {
60
60
  limit: args.limit,
61
61
  preferFeatured: args.preferFeatured,
62
62
  maxComplexity: args.maxComplexity
@@ -70,7 +70,7 @@ var schematexTools = {
70
70
  ),
71
71
  dsl: zod.z.string().describe("The DSL source text to validate.")
72
72
  }),
73
- execute: async ({ type, dsl }) => chunk2LVU75P3_cjs.validateDsl(type, dsl)
73
+ execute: async ({ type, dsl }) => chunkCA54ESRT_cjs.validateDsl(type, dsl)
74
74
  }),
75
75
  renderDsl: ai.tool({
76
76
  description: "Render Schematex DSL to an SVG string. Returns { ok: true, svg } or { ok: false, errors }. Use when the caller needs the actual diagram output, not just validation.",
@@ -85,7 +85,7 @@ var schematexTools = {
85
85
  dsl,
86
86
  theme,
87
87
  padding
88
- }) => chunk2LVU75P3_cjs.renderDsl(type, dsl, { theme, padding })
88
+ }) => chunkCA54ESRT_cjs.renderDsl(type, dsl, { theme, padding })
89
89
  })
90
90
  };
91
91
 
@@ -7,13 +7,13 @@ declare const schematexTools: {
7
7
  readonly listDiagrams: ai.Tool<{}, DiagramListItem[]>;
8
8
  readonly getSyntax: ai.Tool<{
9
9
  type: string;
10
- detail?: "reference" | "canonical" | undefined;
10
+ detail?: "canonical" | "reference" | undefined;
11
11
  }, GetSyntaxResult>;
12
12
  readonly getExamples: ai.Tool<{
13
13
  type: string;
14
14
  limit?: number | undefined;
15
- maxComplexity?: number | undefined;
16
15
  preferFeatured?: boolean | undefined;
16
+ maxComplexity?: number | undefined;
17
17
  }, GetExamplesResult>;
18
18
  readonly validateDsl: ai.Tool<{
19
19
  dsl: string;
@@ -7,13 +7,13 @@ declare const schematexTools: {
7
7
  readonly listDiagrams: ai.Tool<{}, DiagramListItem[]>;
8
8
  readonly getSyntax: ai.Tool<{
9
9
  type: string;
10
- detail?: "reference" | "canonical" | undefined;
10
+ detail?: "canonical" | "reference" | undefined;
11
11
  }, GetSyntaxResult>;
12
12
  readonly getExamples: ai.Tool<{
13
13
  type: string;
14
14
  limit?: number | undefined;
15
- maxComplexity?: number | undefined;
16
15
  preferFeatured?: boolean | undefined;
16
+ maxComplexity?: number | undefined;
17
17
  }, GetExamplesResult>;
18
18
  readonly validateDsl: ai.Tool<{
19
19
  dsl: string;
package/dist/ai/ai-sdk.js CHANGED
@@ -1,5 +1,5 @@
1
- import { renderDsl, validateDsl, getExamples, getSyntax, listDiagrams } from '../chunk-33BFUEYU.js';
2
- import '../chunk-4QLIFOKH.js';
1
+ import { renderDsl, validateDsl, getExamples, getSyntax, listDiagrams } from '../chunk-CXA45HIT.js';
2
+ import '../chunk-T5QOVX2I.js';
3
3
  import '../chunk-EB7T5SEO.js';
4
4
  import '../chunk-IHX6J4HF.js';
5
5
  import '../chunk-P4U565XH.js';
package/dist/ai/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunk2LVU75P3_cjs = require('../chunk-2LVU75P3.cjs');
4
- require('../chunk-BEPVTFXK.cjs');
3
+ var chunkCA54ESRT_cjs = require('../chunk-CA54ESRT.cjs');
4
+ require('../chunk-OY2CXLVY.cjs');
5
5
  require('../chunk-UHRNFBWY.cjs');
6
6
  require('../chunk-TXWVJAMR.cjs');
7
7
  require('../chunk-T55OQILI.cjs');
@@ -27,10 +27,10 @@ require('../chunk-3WNW5Y7P.cjs');
27
27
 
28
28
  // src/ai/prompt-context.ts
29
29
  function buildPromptContext(type, opts = {}) {
30
- const resolved = chunk2LVU75P3_cjs.resolveDiagramType(type) ?? type;
30
+ const resolved = chunkCA54ESRT_cjs.resolveDiagramType(type) ?? type;
31
31
  const detail = opts.detail ?? "canonical";
32
32
  const limit = opts.examples ?? 2;
33
- const { type: canonical, name, standard, syntax } = chunk2LVU75P3_cjs.getSyntax(resolved, {
33
+ const { type: canonical, name, standard, syntax } = chunkCA54ESRT_cjs.getSyntax(resolved, {
34
34
  detail
35
35
  });
36
36
  const parts = [
@@ -41,7 +41,7 @@ function buildPromptContext(type, opts = {}) {
41
41
  ];
42
42
  let exampleCount = 0;
43
43
  if (limit > 0) {
44
- const examples = chunk2LVU75P3_cjs.getExamples(canonical, {
44
+ const examples = chunkCA54ESRT_cjs.getExamples(canonical, {
45
45
  preferFeatured: opts.preferFeatured ?? true,
46
46
  limit,
47
47
  maxComplexity: opts.maxComplexity
@@ -67,47 +67,47 @@ function buildPromptContext(type, opts = {}) {
67
67
 
68
68
  Object.defineProperty(exports, "DIAGRAM_REGISTRY", {
69
69
  enumerable: true,
70
- get: function () { return chunk2LVU75P3_cjs.DIAGRAM_REGISTRY; }
70
+ get: function () { return chunkCA54ESRT_cjs.DIAGRAM_REGISTRY; }
71
71
  });
72
72
  Object.defineProperty(exports, "DIAGRAM_SINCE", {
73
73
  enumerable: true,
74
- get: function () { return chunk2LVU75P3_cjs.DIAGRAM_SINCE; }
74
+ get: function () { return chunkCA54ESRT_cjs.DIAGRAM_SINCE; }
75
75
  });
76
76
  Object.defineProperty(exports, "getAllDiagramTypes", {
77
77
  enumerable: true,
78
- get: function () { return chunk2LVU75P3_cjs.getAllDiagramTypes; }
78
+ get: function () { return chunkCA54ESRT_cjs.getAllDiagramTypes; }
79
79
  });
80
80
  Object.defineProperty(exports, "getDiagramMeta", {
81
81
  enumerable: true,
82
- get: function () { return chunk2LVU75P3_cjs.getDiagramMeta; }
82
+ get: function () { return chunkCA54ESRT_cjs.getDiagramMeta; }
83
83
  });
84
84
  Object.defineProperty(exports, "getDiagramSince", {
85
85
  enumerable: true,
86
- get: function () { return chunk2LVU75P3_cjs.getDiagramSince; }
86
+ get: function () { return chunkCA54ESRT_cjs.getDiagramSince; }
87
87
  });
88
88
  Object.defineProperty(exports, "getExamples", {
89
89
  enumerable: true,
90
- get: function () { return chunk2LVU75P3_cjs.getExamples; }
90
+ get: function () { return chunkCA54ESRT_cjs.getExamples; }
91
91
  });
92
92
  Object.defineProperty(exports, "getSyntax", {
93
93
  enumerable: true,
94
- get: function () { return chunk2LVU75P3_cjs.getSyntax; }
94
+ get: function () { return chunkCA54ESRT_cjs.getSyntax; }
95
95
  });
96
96
  Object.defineProperty(exports, "listDiagrams", {
97
97
  enumerable: true,
98
- get: function () { return chunk2LVU75P3_cjs.listDiagrams; }
98
+ get: function () { return chunkCA54ESRT_cjs.listDiagrams; }
99
99
  });
100
100
  Object.defineProperty(exports, "renderDsl", {
101
101
  enumerable: true,
102
- get: function () { return chunk2LVU75P3_cjs.renderDsl; }
102
+ get: function () { return chunkCA54ESRT_cjs.renderDsl; }
103
103
  });
104
104
  Object.defineProperty(exports, "resolveDiagramType", {
105
105
  enumerable: true,
106
- get: function () { return chunk2LVU75P3_cjs.resolveDiagramType; }
106
+ get: function () { return chunkCA54ESRT_cjs.resolveDiagramType; }
107
107
  });
108
108
  Object.defineProperty(exports, "validateDsl", {
109
109
  enumerable: true,
110
- get: function () { return chunk2LVU75P3_cjs.validateDsl; }
110
+ get: function () { return chunkCA54ESRT_cjs.validateDsl; }
111
111
  });
112
112
  exports.buildPromptContext = buildPromptContext;
113
113
  //# sourceMappingURL=index.cjs.map
package/dist/ai/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { resolveDiagramType, getSyntax, getExamples } from '../chunk-33BFUEYU.js';
2
- export { DIAGRAM_REGISTRY, DIAGRAM_SINCE, getAllDiagramTypes, getDiagramMeta, getDiagramSince, getExamples, getSyntax, listDiagrams, renderDsl, resolveDiagramType, validateDsl } from '../chunk-33BFUEYU.js';
3
- import '../chunk-4QLIFOKH.js';
1
+ import { resolveDiagramType, getSyntax, getExamples } from '../chunk-CXA45HIT.js';
2
+ export { DIAGRAM_REGISTRY, DIAGRAM_SINCE, getAllDiagramTypes, getDiagramMeta, getDiagramSince, getExamples, getSyntax, listDiagrams, renderDsl, resolveDiagramType, validateDsl } from '../chunk-CXA45HIT.js';
3
+ import '../chunk-T5QOVX2I.js';
4
4
  import '../chunk-EB7T5SEO.js';
5
5
  import '../chunk-IHX6J4HF.js';
6
6
  import '../chunk-P4U565XH.js';
package/dist/browser.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkBEPVTFXK_cjs = require('./chunk-BEPVTFXK.cjs');
3
+ var chunkOY2CXLVY_cjs = require('./chunk-OY2CXLVY.cjs');
4
4
  require('./chunk-UHRNFBWY.cjs');
5
5
  require('./chunk-TXWVJAMR.cjs');
6
6
  require('./chunk-T55OQILI.cjs');
@@ -26,10 +26,10 @@ require('./chunk-3WNW5Y7P.cjs');
26
26
 
27
27
  // src/browser.ts
28
28
  function renderToElement(text, config) {
29
- return svgStringToElement(chunkBEPVTFXK_cjs.render(text, config));
29
+ return svgStringToElement(chunkOY2CXLVY_cjs.render(text, config));
30
30
  }
31
31
  function renderPreviewToElement(text, config) {
32
- return svgStringToElement(chunkBEPVTFXK_cjs.renderPreview(text, config));
32
+ return svgStringToElement(chunkOY2CXLVY_cjs.renderPreview(text, config));
33
33
  }
34
34
  function svgStringToElement(svgString) {
35
35
  const parser = new DOMParser();
@@ -42,23 +42,23 @@ function svgStringToElement(svgString) {
42
42
  return el;
43
43
  }
44
44
  function renderToContainer(text, container, config) {
45
- container.innerHTML = chunkBEPVTFXK_cjs.render(text, config);
45
+ container.innerHTML = chunkOY2CXLVY_cjs.render(text, config);
46
46
  }
47
47
  function renderPreviewToContainer(text, container, config) {
48
- container.innerHTML = chunkBEPVTFXK_cjs.renderPreview(text, config);
48
+ container.innerHTML = chunkOY2CXLVY_cjs.renderPreview(text, config);
49
49
  }
50
50
 
51
51
  Object.defineProperty(exports, "render", {
52
52
  enumerable: true,
53
- get: function () { return chunkBEPVTFXK_cjs.render; }
53
+ get: function () { return chunkOY2CXLVY_cjs.render; }
54
54
  });
55
55
  Object.defineProperty(exports, "renderPreview", {
56
56
  enumerable: true,
57
- get: function () { return chunkBEPVTFXK_cjs.renderPreview; }
57
+ get: function () { return chunkOY2CXLVY_cjs.renderPreview; }
58
58
  });
59
59
  Object.defineProperty(exports, "renderResult", {
60
60
  enumerable: true,
61
- get: function () { return chunkBEPVTFXK_cjs.renderResult; }
61
+ get: function () { return chunkOY2CXLVY_cjs.renderResult; }
62
62
  });
63
63
  exports.renderPreviewToContainer = renderPreviewToContainer;
64
64
  exports.renderPreviewToElement = renderPreviewToElement;
package/dist/browser.js CHANGED
@@ -1,5 +1,5 @@
1
- import { render, renderPreview } from './chunk-4QLIFOKH.js';
2
- export { render, renderPreview, renderResult } from './chunk-4QLIFOKH.js';
1
+ import { render, renderPreview } from './chunk-T5QOVX2I.js';
2
+ export { render, renderPreview, renderResult } from './chunk-T5QOVX2I.js';
3
3
  import './chunk-EB7T5SEO.js';
4
4
  import './chunk-IHX6J4HF.js';
5
5
  import './chunk-P4U565XH.js';
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkBEPVTFXK_cjs = require('./chunk-BEPVTFXK.cjs');
3
+ var chunkOY2CXLVY_cjs = require('./chunk-OY2CXLVY.cjs');
4
4
 
5
5
  // src/ai/registry.ts
6
6
  var DIAGRAM_REGISTRY = [
@@ -1990,6 +1990,23 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
1990
1990
  "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',
1991
1991
  "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."
1992
1992
  },
1993
+ {
1994
+ "slug": "floorplan-restaurant-kitchen",
1995
+ "diagram": "floorplan",
1996
+ "title": "Restaurant \u2014 dining room + commercial kitchen",
1997
+ "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.",
1998
+ "standard": "Architectural Graphic Standards \xB7 US NCS v6",
1999
+ "tags": [
2000
+ "floorplan",
2001
+ "restaurant",
2002
+ "commercial-kitchen",
2003
+ "hospitality"
2004
+ ],
2005
+ "complexity": 3,
2006
+ "featured": false,
2007
+ "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',
2008
+ "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."
2009
+ },
1993
2010
  {
1994
2011
  "slug": "floorplan-retail-boutique",
1995
2012
  "diagram": "floorplan",
@@ -2008,6 +2025,24 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
2008
2025
  "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',
2009
2026
  "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."
2010
2027
  },
2028
+ {
2029
+ "slug": "floorplan-seating-chart",
2030
+ "diagram": "floorplan",
2031
+ "title": "Wedding seating chart \u2014 named guests",
2032
+ "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.",
2033
+ "standard": "Architectural Graphic Standards \xB7 US NCS v6",
2034
+ "tags": [
2035
+ "floorplan",
2036
+ "wedding",
2037
+ "event",
2038
+ "seating",
2039
+ "seating-chart"
2040
+ ],
2041
+ "complexity": 3,
2042
+ "featured": true,
2043
+ "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',
2044
+ "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.'
2045
+ },
2011
2046
  {
2012
2047
  "slug": "floorplan-studio-office",
2013
2048
  "diagram": "floorplan",
@@ -2629,7 +2664,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
2629
2664
  "biology"
2630
2665
  ],
2631
2666
  "complexity": 1,
2632
- "featured": false,
2667
+ "featured": true,
2633
2668
  "dsl": 'matrix punnett "Eye color (Bb \xD7 Bb)"\ncross: Bb x Bb\ntrait B: "Brown eyes" / "Blue eyes"',
2634
2669
  "notes": "## What this shows\n\nThe **monohybrid cross** is where every genetics course starts: one gene, two heterozygous parents. Here both parents are `Bb` for eye colour \u2014 `B` (brown) is dominant, `b` (blue) recessive. You write only the cross; the engine does the Mendelian bookkeeping.\n\nEach `Bb` parent makes two gametes, `B` and `b`, so the grid is 2\xD72. The engine fills it \u2014 `BB`, `Bb`, `Bb`, `bb` \u2014 and computes the two ratios every student memorises: a **3:1 phenotype ratio** (3 brown-eyed : 1 blue-eyed) and a **1:2:1 genotype ratio** (1 `BB` : 2 `Bb` : 1 `bb`). The single recessive `bb` box is tinted apart from the three dominant boxes, and the `trait` line names the phenotypes so the legend reads in plain English. Allele case sets dominance \u2014 uppercase is dominant \u2014 so the notation is exactly what a textbook uses."
2635
2670
  },
@@ -2666,7 +2701,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
2666
2701
  "voice-of-customer"
2667
2702
  ],
2668
2703
  "complexity": 3,
2669
- "featured": false,
2704
+ "featured": true,
2670
2705
  "dsl": 'matrix qfd "Coffee maker"\nwhat: "Quiet operation" weight: 5\nwhat: "Brews fast" weight: 3\nwhat: "Energy efficient" weight: 4\nhow: "Fan RPM" dir: down\nhow: "Heater watts" dir: up\nhow: "Insulation" dir: up\nrel (0,0): 9\nrel (0,2): 3\nrel (1,1): 9\nrel (2,1): 3\nrel (2,2): 9\nroof (0,1): --\nroof (1,2): +',
2671
2706
  "notes": "## What this shows\n\nThe **House of Quality** \u2014 the core matrix of Akao's Quality Function Deployment \u2014 translates what customers want into the engineering characteristics that deliver it. Customer requirements (**WHATs**) are the rows, each with an importance weight; engineering characteristics (**HOWs**) are the columns; the body cells record how strongly each HOW serves each WHAT on the 9 / 3 / 1 strong-medium-weak scale.\n\nThe differentiator is the computed row at the foot of the house: each column's **technical importance** is the sum of `weight \xD7 strength` down that column, here **45 / 39 / 51** \u2014 so Insulation (51) is the highest-leverage characteristic to invest in and Heater watts (39) the lowest. (Add `normalize: true` to read these as 33% / 29% / 38% instead.) Above the columns, the **roof** is a half-matrix of diamond cells recording HOW-to-HOW correlations: `roof (0,1): --` flags that lowering Fan RPM while raising Heater watts is a trade-off, while `roof (1,2): +` flags that Heater watts and Insulation reinforce each other."
2672
2707
  },
@@ -2684,7 +2719,7 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
2684
2719
  "process-scoping"
2685
2720
  ],
2686
2721
  "complexity": 2,
2687
- "featured": false,
2722
+ "featured": true,
2688
2723
  "dsl": 'matrix sipoc "Order fulfilment"\nsuppliers: "Vendor", "Warehouse"\ninputs: "PO", "Stock levels"\nprocess: "Receive order", "Pick", "Pack", "Ship"\noutputs: "Shipped package", "Invoice"\ncustomers: "End customer", "Finance"',
2689
2724
  "notes": "## What this shows\n\nA **SIPOC** is the first artifact a Six Sigma team builds in the *Define* phase of DMAIC. It names \u2014 in five columns read left to right \u2014 everyone and everything the process touches: **S**uppliers hand in **I**nputs, the **P**rocess turns them into **O**utputs, and **C**ustomers receive them. Here the order-fulfilment process runs `Receive order \u2192 Pick \u2192 Pack \u2192 Ship`, fed by purchase orders and stock levels from the vendor and warehouse, and producing a shipped package for the end customer and an invoice for finance.\n\nThe point of a SIPOC is boundary-setting before measurement: it forces the team to agree where the process starts, where it ends, and who hands work in and out of it. The five columns always render in canonical S-I-P-O-C order, so the diagram reads correctly even when the blocks are authored out of sequence."
2690
2725
  },
@@ -4696,7 +4731,7 @@ var SYNTAX = {
4696
4731
  },
4697
4732
  "floorplan": {
4698
4733
  "title": "Floor plan",
4699
- "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'
4734
+ "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'
4700
4735
  },
4701
4736
  "playbook": {
4702
4737
  "title": "Sports playbook",
@@ -4902,7 +4937,7 @@ var PROFILES = {
4902
4937
  type: "timing",
4903
4938
  header: 'timing "Title"',
4904
4939
  mode: "WaveDrom signals, with clock/run-length shorthands",
4905
- keywords: 'timing "title" [hscale: N] \xB7 SIGNAME: wave_spec \xB7 wave chars 0 1 x z = . u d p P n N h H l L 2-9 \xB7 clock N [neg] \xB7 rle <state>*<count> \u2026 \xB7 data: ["a","b"] for = and digit segments \xB7 [GroupName] or group "name" { \u2026 } \xB7 --- spacer \xB7 phase: FLOAT (0.0\u20131.0)',
4940
+ keywords: 'timing "title" [hscale: N] \xB7 SIGNAME: wave_spec \xB7 wave chars 0 1 x z = . u d p P n N h H l L 2-9 \xB7 clock N [neg] \xB7 rle <state>*<count> \u2026 \xB7 data: ["a","b"] for = and digit segments \xB7 [GroupName] or group "name" { \u2026 } \xB7 --- spacer',
4906
4941
  forms: [
4907
4942
  'timing "Synchronous Bus Read"',
4908
4943
  "CLK: clock 8",
@@ -5254,7 +5289,7 @@ var PROFILES = {
5254
5289
  type: "matrix",
5255
5290
  header: 'matrix "Title"',
5256
5291
  mode: "quadrant scatter (default) | named templates | heatmap | sipoc | qfd | punnett",
5257
- keywords: 'header variants: matrix "Title" | matrix <template> "Title" | matrix heatmap NxM | matrix correlation | matrix sipoc | matrix qfd | matrix punnett \xB7 templates: eisenhower impact-effort rice bcg ansoff johari 9-box risk-matrix \xB7 quadrant: x-axis: Low -> High \xB7 y-axis: Low -> High \xB7 "Label" at (x,y) [size:N category:C shape:circle|square|triangle|diamond] \xB7 quadrant Q1..Q4 "name" \xB7 Q1:/"Q1: text" cell shortcuts \xB7 style: table \xB7 config: offChartPolicy=clamp-badge|drop bubbleScale=area|radius',
5292
+ keywords: 'header variants: matrix "Title" | matrix <template> "Title" | matrix heatmap NxM | matrix correlation | matrix sipoc | matrix qfd | matrix punnett \xB7 templates: eisenhower impact-effort rice bcg ansoff johari 9-box risk-matrix \xB7 quadrant: x-axis: Low -> High \xB7 y-axis: Low -> High \xB7 "Label" at (x,y) [size:N category:C shape:circle|square|triangle|diamond] \xB7 quadrant Q1..Q4 "name" \xB7 Q1:/"Q1: text" cell shortcuts \xB7 style: table \xB7 config: offChartPolicy=clamp-badge|drop bubbleScale=area|radius \xB7 QFD body (under `matrix qfd`): what: "Need" [weight: N] \xB7 how: "Spec" [dir: up|down|target] \xB7 rel (whatIdx, howIdx): 9|3|1 \xB7 roof (i, j): ++|+|-|-- \xB7 [normalize: percent] \u2014 engine computes the technical-importance row \xB7 SIPOC body (under `matrix sipoc`): suppliers:/inputs:/process:/outputs:/customers: "A", "B", \u2026 (each column one line) \xB7 Punnett body (under `matrix punnett`): cross: Bb x Bb (genotype pairs, separator x/\xD7/*) \xB7 trait B: "Brown" / "Blue" (dominant / recessive phenotype names) \u2014 engine computes the genotype + phenotype ratios',
5258
5293
  forms: [
5259
5294
  'matrix eisenhower "This Week"',
5260
5295
  "style: table",
@@ -5264,12 +5299,24 @@ var PROFILES = {
5264
5299
  "",
5265
5300
  'matrix bcg "Product Portfolio"',
5266
5301
  '"Platform SDK" at (0.8, 0.8) size: 5 category: star',
5267
- '"Legacy API" at (0.85, 0.15) size: 4 category: cashcow'
5302
+ '"Legacy API" at (0.85, 0.15) size: 4 category: cashcow',
5303
+ "",
5304
+ 'matrix qfd "House of Quality"',
5305
+ 'what: "Quiet operation" weight: 5',
5306
+ 'how: "Fan RPM" dir: down',
5307
+ "rel (1, 1): 9",
5308
+ "",
5309
+ 'matrix punnett "Monohybrid Cross"',
5310
+ "cross: Bb x Bb",
5311
+ 'trait B: "Brown" / "Blue"'
5268
5312
  ],
5269
5313
  prefer: [
5270
5314
  "Use a named template (`eisenhower`, `impact-effort`, `bcg`, `ansoff`, `johari`, `9-box`, `risk-matrix`, `rice`) for first-shot generation \u2014 it pre-fills axes and quadrant labels.",
5271
5315
  "Add `style: table` with `Q1:`/`Q2:`/`Q3:`/`Q4:` item lines for the four-cell list layout instead of a scatter.",
5272
- "Quadrant scatter coordinates are normalized `[0,1]` fractions; add `size: N` for a bubble chart and `category:` to drive legend color."
5316
+ "Quadrant scatter coordinates are normalized `[0,1]` fractions; add `size: N` for a bubble chart and `category:` to drive legend color.",
5317
+ 'For QFD / House of Quality, lead with the header `matrix qfd "\u2026"`, then list customer needs as `what: "\u2026" weight: N` and engineering specs as `how: "\u2026" dir: up|down`, then weight the cells with `rel (whatIdx, howIdx): 9|3|1` (1-based, in declaration order) \u2014 the engine computes the technical-importance row, so never type it yourself.',
5318
+ 'For SIPOC, header `matrix sipoc "\u2026"`, then one line per column: `suppliers:`, `inputs:`, `process:`, `outputs:`, `customers:`, each a comma-separated quoted list.',
5319
+ 'For a Punnett square, header `matrix punnett "\u2026"`, then `cross: <genotype> x <genotype>` (even-length allele pairs like `Bb` or `RrYy`) and optional `trait <Letter>: "Dominant" / "Recessive"` \u2014 the engine fills the grid and computes the genotype/phenotype ratios.'
5273
5320
  ],
5274
5321
  avoid: [
5275
5322
  "Don't mix `sipoc:`/`qfd:`/`punnett:` sub-keywords in plain quadrant mode \u2014 they activate only under the matching header mode (`matrix sipoc`).",
@@ -6302,7 +6349,7 @@ var PROFILES = {
6302
6349
  type: "floorplan",
6303
6350
  header: 'floorplan "Title" [unit m|ft]',
6304
6351
  mode: "explicit dimensions + relative room placement; furniture room-relative from each room's top-left",
6305
- keywords: 'room id "Label" at x,y | right-of/left-of/above/below ref [offset n] [align start|center|end] size WxH [fill #hex] [nolabel] \xB7 extend <room> at x,y | right-of ref size WxH (L/T/U rooms) \xB7 north [deg] \xB7 door <room> north|south|east|west | between A B at N% [width n] [hinge left|right] [swing in|out] [type single|double|sliding|pocket|bifold] \xB7 window <wallref> at N% [width n] [type fixed|sliding|casement|bay] \xB7 opening <wallref|between A B> at N% [width n] \xB7 furniture <type> in room at x,y [size WxH] [rotate deg] ["label"] \xB7 grid|row <type> in room rows R cols C [count N] area x1,y1 x2,y2 [itemsize WxH] \xB7 arc <type> in room count N center x,y radius r from deg to deg \xB7 types: bed-double/single/queen/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 counter wall-cabinet island kitchen-sink stove range-hood fridge dishwasher bar-stool toilet sink vanity bidet urinal bathtub shower washer dryer stairs stairs-l stairs-u spiral-stairs elevator column desk-chair desk desk-l chair whiteboard smartboard bookcase cubbies filing-cabinet lockers kidney-table round-table-4/6/8/10 conference-table banquet-table head-table stage dance-floor bar dj-booth cocktail-table podium row-chairs shelving checkout clothing-rack fitting-room pallet-rack loading-dock forklift salon-chair shampoo-bowl manicure-table treadmill weight-bench power-rack yoga-mat tree car',
6352
+ keywords: 'room id "Label" at x,y | right-of/left-of/above/below ref [offset n] [align start|center|end] size WxH [fill #hex] [nolabel] \xB7 extend <room> at x,y | right-of ref size WxH (L/T/U rooms) \xB7 north [deg] \xB7 door <room> north|south|east|west | between A B at N% [width n] [hinge left|right] [swing in|out] [type single|double|sliding|pocket|bifold] \xB7 window <wallref> at N% [width n] [type fixed|sliding|casement|bay] \xB7 opening <wallref|between A B> at N% [width n] \xB7 furniture <type> in room at x,y [size WxH] [rotate deg] ["label"] [seats "Name" "Name" \u2026] \xB7 grid|row <type> in room rows R cols C [count N] area x1,y1 x2,y2 [itemsize WxH] \xB7 arc <type> in room count N center x,y radius r from deg to deg \xB7 types: bed-double/single/queen/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 counter wall-cabinet island kitchen-sink stove range-hood fridge dishwasher bar-stool toilet sink vanity bidet urinal bathtub shower washer dryer stairs stairs-l stairs-u spiral-stairs elevator column desk-chair desk desk-l chair whiteboard smartboard bookcase cubbies filing-cabinet lockers kidney-table round-table-4/6/8/10 conference-table banquet-table head-table stage dance-floor bar dj-booth cocktail-table podium row-chairs shelving checkout clothing-rack fitting-room pallet-rack loading-dock forklift salon-chair shampoo-bowl manicure-table treadmill weight-bench power-rack yoga-mat tree car',
6306
6353
  forms: [
6307
6354
  'floorplan "Two-Bedroom Apartment" unit m',
6308
6355
  'room living "Living Room" at 0,0 size 5.2x4.2',
@@ -6318,6 +6365,7 @@ var PROFILES = {
6318
6365
  "Furniture `at x,y` is relative to its room's interior top-left corner, in the plan unit.",
6319
6366
  "Use `grid`/`row`/`arc` for repeated items (desks, banquet tables, ceremony chairs) instead of many `furniture` lines; `count` truncates row-major.",
6320
6367
  "Round tables auto-seat their chairs (round-table-8 = 8 chairs); dining/banquet/conference tables auto-seat both long edges; leave chair clearance \u2265 0.5 m around tables.",
6368
+ 'For a seating chart / plan de table / \u5E2D\u6B21\u8868 \u2014 who sits where, not just where the tables go \u2014 add `seats "Alice" "Bob" \u2026` to each table: the names are written onto the chairs in seating order (round tables clockwise from top, head/long tables along the seated edge). Fewer names than chairs is fine (extras stay empty); CJK names quote like any label.',
6321
6369
  "For L/T/U-shaped rooms, declare the main rectangle then `extend <room> at x,y size WxH` \u2014 the extension must share an edge; the engine merges walls and sums the area.",
6322
6370
  'Stairs are furniture: `furniture stairs in hall at x,y` (also stairs-l, stairs-u, spiral-stairs) \u2014 they draw treads, the UP arrow, and the cut-plane break line automatically; label "DN" for a descending run.',
6323
6371
  "Commercial & site symbols: retail uses shelving/checkout/clothing-rack/fitting-room; warehouse uses pallet-rack/loading-dock/forklift; salon uses salon-chair/shampoo-bowl/manicure-table; gym uses treadmill/weight-bench/power-rack/yoga-mat; `tree` and `car` are sized for site plans, landscaping, and parking stalls."
@@ -6450,7 +6498,7 @@ function getExamples(type, opts = {}) {
6450
6498
  function validateDsl(type, dsl) {
6451
6499
  const resolvedType = type ? resolveDiagramType(type) : void 0;
6452
6500
  const config = type ? { type: resolvedType ?? type } : void 0;
6453
- const result = chunkBEPVTFXK_cjs.parseResult(dsl, config);
6501
+ const result = chunkOY2CXLVY_cjs.parseResult(dsl, config);
6454
6502
  if (result.ok) {
6455
6503
  return {
6456
6504
  ok: true,
@@ -6476,7 +6524,7 @@ function renderDsl(type, dsl, options = {}) {
6476
6524
  ...options,
6477
6525
  ...type ? { type: resolvedType ?? type } : {}
6478
6526
  };
6479
- const result = chunkBEPVTFXK_cjs.renderResult(dsl, config);
6527
+ const result = chunkOY2CXLVY_cjs.renderResult(dsl, config);
6480
6528
  if (result.ok) {
6481
6529
  return {
6482
6530
  ok: true,
@@ -6538,5 +6586,5 @@ exports.listDiagrams = listDiagrams;
6538
6586
  exports.renderDsl = renderDsl;
6539
6587
  exports.resolveDiagramType = resolveDiagramType;
6540
6588
  exports.validateDsl = validateDsl;
6541
- //# sourceMappingURL=chunk-2LVU75P3.cjs.map
6542
- //# sourceMappingURL=chunk-2LVU75P3.cjs.map
6589
+ //# sourceMappingURL=chunk-CA54ESRT.cjs.map
6590
+ //# sourceMappingURL=chunk-CA54ESRT.cjs.map