@pascal-app/core 0.8.0 → 0.9.1

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 (272) hide show
  1. package/dist/events/bus.d.ts +39 -13
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/hooks/scene-registry/scene-registry.d.ts +6 -22
  4. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  5. package/dist/hooks/scene-registry/scene-registry.js +33 -26
  6. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +14 -0
  7. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -0
  8. package/dist/hooks/spatial-grid/floor-placed-elevation.js +51 -0
  9. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +2 -0
  10. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +1 -0
  11. package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +273 -0
  12. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +13 -2
  13. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  14. package/dist/hooks/spatial-grid/spatial-grid-manager.js +95 -9
  15. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +28 -1
  16. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  17. package/dist/hooks/spatial-grid/spatial-grid-sync.js +91 -18
  18. package/dist/index.d.ts +22 -4
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +19 -2
  21. package/dist/lib/polygon-relations.d.ts +10 -0
  22. package/dist/lib/polygon-relations.d.ts.map +1 -0
  23. package/dist/lib/polygon-relations.js +73 -0
  24. package/dist/lib/space-detection-pause.test.d.ts +2 -0
  25. package/dist/lib/space-detection-pause.test.d.ts.map +1 -0
  26. package/dist/lib/space-detection-pause.test.js +42 -0
  27. package/dist/lib/space-detection.d.ts +30 -1
  28. package/dist/lib/space-detection.d.ts.map +1 -1
  29. package/dist/lib/space-detection.js +215 -36
  30. package/dist/lib/space-detection.test.d.ts +2 -0
  31. package/dist/lib/space-detection.test.d.ts.map +1 -0
  32. package/dist/lib/space-detection.test.js +77 -0
  33. package/dist/material-library.d.ts +1 -1
  34. package/dist/material-library.d.ts.map +1 -1
  35. package/dist/material-library.js +1940 -143
  36. package/dist/registry/__bench__/relations-resolver.bench.d.ts +15 -0
  37. package/dist/registry/__bench__/relations-resolver.bench.d.ts.map +1 -0
  38. package/dist/registry/__bench__/relations-resolver.bench.js +170 -0
  39. package/dist/registry/handles.d.ts +321 -0
  40. package/dist/registry/handles.d.ts.map +1 -0
  41. package/dist/registry/handles.js +24 -0
  42. package/dist/registry/index.d.ts +7 -0
  43. package/dist/registry/index.d.ts.map +1 -0
  44. package/dist/registry/index.js +4 -0
  45. package/dist/registry/registry.d.ts +93 -0
  46. package/dist/registry/registry.d.ts.map +1 -0
  47. package/dist/registry/registry.js +201 -0
  48. package/dist/registry/registry.test.d.ts +2 -0
  49. package/dist/registry/registry.test.d.ts.map +1 -0
  50. package/dist/registry/registry.test.js +183 -0
  51. package/dist/registry/relations-resolver.d.ts +42 -0
  52. package/dist/registry/relations-resolver.d.ts.map +1 -0
  53. package/dist/registry/relations-resolver.js +77 -0
  54. package/dist/registry/relations-resolver.test.d.ts +2 -0
  55. package/dist/registry/relations-resolver.test.d.ts.map +1 -0
  56. package/dist/registry/relations-resolver.test.js +183 -0
  57. package/dist/registry/scene-api.d.ts +44 -0
  58. package/dist/registry/scene-api.d.ts.map +1 -0
  59. package/dist/registry/scene-api.js +111 -0
  60. package/dist/registry/scene-api.test.d.ts +2 -0
  61. package/dist/registry/scene-api.test.d.ts.map +1 -0
  62. package/dist/registry/scene-api.test.js +183 -0
  63. package/dist/registry/subtree.d.ts +67 -0
  64. package/dist/registry/subtree.d.ts.map +1 -0
  65. package/dist/registry/subtree.js +119 -0
  66. package/dist/registry/subtree.test.d.ts +2 -0
  67. package/dist/registry/subtree.test.d.ts.map +1 -0
  68. package/dist/registry/subtree.test.js +133 -0
  69. package/dist/registry/types.d.ts +1420 -0
  70. package/dist/registry/types.d.ts.map +1 -0
  71. package/dist/registry/types.js +1 -0
  72. package/dist/schema/index.d.ts +17 -2
  73. package/dist/schema/index.d.ts.map +1 -1
  74. package/dist/schema/index.js +17 -3
  75. package/dist/schema/material.d.ts +10 -0
  76. package/dist/schema/material.d.ts.map +1 -1
  77. package/dist/schema/material.js +10 -0
  78. package/dist/schema/nodes/box-vent.d.ts +74 -0
  79. package/dist/schema/nodes/box-vent.d.ts.map +1 -0
  80. package/dist/schema/nodes/box-vent.js +63 -0
  81. package/dist/schema/nodes/building.d.ts +1 -1
  82. package/dist/schema/nodes/building.d.ts.map +1 -1
  83. package/dist/schema/nodes/building.js +3 -2
  84. package/dist/schema/nodes/ceiling.d.ts +2 -0
  85. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  86. package/dist/schema/nodes/ceiling.js +1 -1
  87. package/dist/schema/nodes/chimney.d.ts +158 -0
  88. package/dist/schema/nodes/chimney.d.ts.map +1 -0
  89. package/dist/schema/nodes/chimney.js +67 -0
  90. package/dist/schema/nodes/column.d.ts +597 -5
  91. package/dist/schema/nodes/column.d.ts.map +1 -1
  92. package/dist/schema/nodes/column.js +586 -6
  93. package/dist/schema/nodes/cupola.d.ts +66 -0
  94. package/dist/schema/nodes/cupola.d.ts.map +1 -0
  95. package/dist/schema/nodes/cupola.js +28 -0
  96. package/dist/schema/nodes/dormer.d.ts +228 -0
  97. package/dist/schema/nodes/dormer.d.ts.map +1 -0
  98. package/dist/schema/nodes/dormer.js +119 -0
  99. package/dist/schema/nodes/downspout.d.ts +75 -0
  100. package/dist/schema/nodes/downspout.d.ts.map +1 -0
  101. package/dist/schema/nodes/downspout.js +63 -0
  102. package/dist/schema/nodes/elevator.d.ts +105 -0
  103. package/dist/schema/nodes/elevator.d.ts.map +1 -0
  104. package/dist/schema/nodes/elevator.js +54 -0
  105. package/dist/schema/nodes/eyebrow-vent.d.ts +68 -0
  106. package/dist/schema/nodes/eyebrow-vent.d.ts.map +1 -0
  107. package/dist/schema/nodes/eyebrow-vent.js +40 -0
  108. package/dist/schema/nodes/fence.d.ts +1 -0
  109. package/dist/schema/nodes/fence.d.ts.map +1 -1
  110. package/dist/schema/nodes/fence.js +2 -0
  111. package/dist/schema/nodes/gutter.d.ts +84 -0
  112. package/dist/schema/nodes/gutter.d.ts.map +1 -0
  113. package/dist/schema/nodes/gutter.js +76 -0
  114. package/dist/schema/nodes/item.d.ts +4 -0
  115. package/dist/schema/nodes/item.d.ts.map +1 -1
  116. package/dist/schema/nodes/item.js +9 -0
  117. package/dist/schema/nodes/level.d.ts +1 -1
  118. package/dist/schema/nodes/level.d.ts.map +1 -1
  119. package/dist/schema/nodes/level.js +2 -0
  120. package/dist/schema/nodes/ridge-vent.d.ts +67 -0
  121. package/dist/schema/nodes/ridge-vent.d.ts.map +1 -0
  122. package/dist/schema/nodes/ridge-vent.js +30 -0
  123. package/dist/schema/nodes/roof-segment.d.ts +195 -1
  124. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  125. package/dist/schema/nodes/roof-segment.js +254 -3
  126. package/dist/schema/nodes/roof.d.ts.map +1 -1
  127. package/dist/schema/nodes/roof.js +4 -16
  128. package/dist/schema/nodes/shelf.d.ts +105 -0
  129. package/dist/schema/nodes/shelf.d.ts.map +1 -0
  130. package/dist/schema/nodes/shelf.js +84 -0
  131. package/dist/schema/nodes/site.d.ts +1 -122
  132. package/dist/schema/nodes/site.d.ts.map +1 -1
  133. package/dist/schema/nodes/site.js +2 -6
  134. package/dist/schema/nodes/skylight.d.ts +279 -0
  135. package/dist/schema/nodes/skylight.d.ts.map +1 -0
  136. package/dist/schema/nodes/skylight.js +152 -0
  137. package/dist/schema/nodes/slab.d.ts +2 -0
  138. package/dist/schema/nodes/slab.d.ts.map +1 -1
  139. package/dist/schema/nodes/slab.js +1 -1
  140. package/dist/schema/nodes/solar-panel.d.ts +117 -0
  141. package/dist/schema/nodes/solar-panel.d.ts.map +1 -0
  142. package/dist/schema/nodes/solar-panel.js +47 -0
  143. package/dist/schema/nodes/surface-hole-metadata.d.ts +2 -0
  144. package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -1
  145. package/dist/schema/nodes/surface-hole-metadata.js +3 -1
  146. package/dist/schema/nodes/turbine-vent.d.ts +68 -0
  147. package/dist/schema/nodes/turbine-vent.d.ts.map +1 -0
  148. package/dist/schema/nodes/turbine-vent.js +41 -0
  149. package/dist/schema/types.d.ts +1325 -125
  150. package/dist/schema/types.d.ts.map +1 -1
  151. package/dist/schema/types.js +26 -0
  152. package/dist/services/alignment-anchors.d.ts +100 -0
  153. package/dist/services/alignment-anchors.d.ts.map +1 -0
  154. package/dist/services/alignment-anchors.js +283 -0
  155. package/dist/services/alignment-anchors.test.d.ts +2 -0
  156. package/dist/services/alignment-anchors.test.d.ts.map +1 -0
  157. package/dist/services/alignment-anchors.test.js +383 -0
  158. package/dist/services/alignment.d.ts +126 -0
  159. package/dist/services/alignment.d.ts.map +1 -0
  160. package/dist/services/alignment.js +169 -0
  161. package/dist/services/alignment.test.d.ts +2 -0
  162. package/dist/services/alignment.test.d.ts.map +1 -0
  163. package/dist/services/alignment.test.js +92 -0
  164. package/dist/services/drag-session.d.ts +47 -0
  165. package/dist/services/drag-session.d.ts.map +1 -0
  166. package/dist/services/drag-session.js +100 -0
  167. package/dist/services/drag-session.test.d.ts +2 -0
  168. package/dist/services/drag-session.test.d.ts.map +1 -0
  169. package/dist/services/drag-session.test.js +219 -0
  170. package/dist/services/hosting.d.ts +80 -0
  171. package/dist/services/hosting.d.ts.map +1 -0
  172. package/dist/services/hosting.js +122 -0
  173. package/dist/services/hosting.test.d.ts +2 -0
  174. package/dist/services/hosting.test.d.ts.map +1 -0
  175. package/dist/services/hosting.test.js +199 -0
  176. package/dist/services/index.d.ts +7 -0
  177. package/dist/services/index.d.ts.map +1 -0
  178. package/dist/services/index.js +6 -0
  179. package/dist/services/movement.d.ts +48 -0
  180. package/dist/services/movement.d.ts.map +1 -0
  181. package/dist/services/movement.js +65 -0
  182. package/dist/services/movement.test.d.ts +2 -0
  183. package/dist/services/movement.test.d.ts.map +1 -0
  184. package/dist/services/movement.test.js +133 -0
  185. package/dist/services/single-undo-dance.test.d.ts +2 -0
  186. package/dist/services/single-undo-dance.test.d.ts.map +1 -0
  187. package/dist/services/single-undo-dance.test.js +210 -0
  188. package/dist/services/snap.d.ts +72 -0
  189. package/dist/services/snap.d.ts.map +1 -0
  190. package/dist/services/snap.js +120 -0
  191. package/dist/services/snap.test.d.ts +2 -0
  192. package/dist/services/snap.test.d.ts.map +1 -0
  193. package/dist/services/snap.test.js +95 -0
  194. package/dist/solar-panel-presets.d.ts +17 -0
  195. package/dist/solar-panel-presets.d.ts.map +1 -0
  196. package/dist/solar-panel-presets.js +43 -0
  197. package/dist/store/actions/node-actions.d.ts +14 -2
  198. package/dist/store/actions/node-actions.d.ts.map +1 -1
  199. package/dist/store/actions/node-actions.js +492 -15
  200. package/dist/store/actions/node-mutation-sanitize.test.d.ts +2 -0
  201. package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +1 -0
  202. package/dist/store/actions/node-mutation-sanitize.test.js +147 -0
  203. package/dist/store/actions/reparent.test.d.ts +2 -0
  204. package/dist/store/actions/reparent.test.d.ts.map +1 -0
  205. package/dist/store/actions/reparent.test.js +212 -0
  206. package/dist/store/use-interactive.d.ts +39 -0
  207. package/dist/store/use-interactive.d.ts.map +1 -1
  208. package/dist/store/use-interactive.js +75 -0
  209. package/dist/store/use-live-node-overrides.d.ts +22 -0
  210. package/dist/store/use-live-node-overrides.d.ts.map +1 -0
  211. package/dist/store/use-live-node-overrides.js +59 -0
  212. package/dist/store/use-scene-elevator-migration.test.d.ts +2 -0
  213. package/dist/store/use-scene-elevator-migration.test.d.ts.map +1 -0
  214. package/dist/store/use-scene-elevator-migration.test.js +109 -0
  215. package/dist/store/use-scene.d.ts +11 -0
  216. package/dist/store/use-scene.d.ts.map +1 -1
  217. package/dist/store/use-scene.js +196 -6
  218. package/dist/systems/elevator/elevator-dispatch.d.ts +12 -0
  219. package/dist/systems/elevator/elevator-dispatch.d.ts.map +1 -0
  220. package/dist/systems/elevator/elevator-dispatch.js +57 -0
  221. package/dist/systems/elevator/elevator-geometry.d.ts +15 -0
  222. package/dist/systems/elevator/elevator-geometry.d.ts.map +1 -0
  223. package/dist/systems/elevator/elevator-geometry.js +50 -0
  224. package/dist/systems/elevator/elevator-opening-sync.d.ts +6 -0
  225. package/dist/systems/elevator/elevator-opening-sync.d.ts.map +1 -0
  226. package/dist/systems/elevator/elevator-opening-sync.js +218 -0
  227. package/dist/systems/elevator/elevator-opening-sync.test.d.ts +2 -0
  228. package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +1 -0
  229. package/dist/systems/elevator/elevator-opening-sync.test.js +146 -0
  230. package/dist/systems/elevator/elevator-opening-system.d.ts +2 -0
  231. package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -0
  232. package/dist/systems/elevator/elevator-opening-system.js +48 -0
  233. package/dist/systems/elevator/elevator-runtime-system.d.ts +2 -0
  234. package/dist/systems/elevator/elevator-runtime-system.d.ts.map +1 -0
  235. package/dist/systems/elevator/elevator-runtime-system.js +8 -0
  236. package/dist/systems/elevator/elevator-runtime.d.ts +18 -0
  237. package/dist/systems/elevator/elevator-runtime.d.ts.map +1 -0
  238. package/dist/systems/elevator/elevator-runtime.js +225 -0
  239. package/dist/systems/elevator/elevator-runtime.test.d.ts +2 -0
  240. package/dist/systems/elevator/elevator-runtime.test.d.ts.map +1 -0
  241. package/dist/systems/elevator/elevator-runtime.test.js +64 -0
  242. package/dist/systems/elevator/elevator-service.d.ts +19 -0
  243. package/dist/systems/elevator/elevator-service.d.ts.map +1 -0
  244. package/dist/systems/elevator/elevator-service.js +111 -0
  245. package/dist/systems/stair/stair-footprint.d.ts +44 -0
  246. package/dist/systems/stair/stair-footprint.d.ts.map +1 -0
  247. package/dist/systems/stair/stair-footprint.js +168 -0
  248. package/dist/systems/stair/stair-opening-preview.d.ts +1777 -0
  249. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -0
  250. package/dist/systems/stair/stair-opening-preview.js +93 -0
  251. package/dist/systems/stair/stair-opening-preview.test.d.ts +2 -0
  252. package/dist/systems/stair/stair-opening-preview.test.d.ts.map +1 -0
  253. package/dist/systems/stair/stair-opening-preview.test.js +80 -0
  254. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  255. package/dist/systems/stair/stair-opening-sync.js +172 -147
  256. package/dist/systems/stair/stair-opening-sync.test.js +385 -2
  257. package/dist/systems/stair/stair-opening-system.d.ts +2 -0
  258. package/dist/systems/stair/stair-opening-system.d.ts.map +1 -0
  259. package/dist/systems/stair/stair-opening-system.js +104 -0
  260. package/dist/systems/wall/wall-move.d.ts +48 -0
  261. package/dist/systems/wall/wall-move.d.ts.map +1 -0
  262. package/dist/systems/wall/wall-move.js +193 -0
  263. package/dist/utils/clone-scene-graph.d.ts +6 -4
  264. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  265. package/dist/utils/clone-scene-graph.js +6 -4
  266. package/dist/utils/clone-scene-graph.test.d.ts +2 -0
  267. package/dist/utils/clone-scene-graph.test.d.ts.map +1 -0
  268. package/dist/utils/clone-scene-graph.test.js +59 -0
  269. package/dist/validation/validate-build-json.d.ts +43 -0
  270. package/dist/validation/validate-build-json.d.ts.map +1 -0
  271. package/dist/validation/validate-build-json.js +227 -0
  272. package/package.json +9 -2
@@ -0,0 +1,54 @@
1
+ import dedent from 'dedent';
2
+ import { z } from 'zod';
3
+ import { BaseNode, nodeType, objectId } from '../base';
4
+ import { MaterialSchema } from '../material';
5
+ export const ElevatorDoorStyle = z.enum(['center-opening', 'single-left', 'single-right']);
6
+ export const ElevatorDoorPanelStyle = z.enum(['glass-frame', 'solid-panel', 'segmented-panel']);
7
+ export const ElevatorShaftStyle = z.enum(['solid', 'glass']);
8
+ export const ElevatorNode = BaseNode.extend({
9
+ id: objectId('elevator'),
10
+ type: nodeType('elevator'),
11
+ material: MaterialSchema.optional(),
12
+ materialPreset: z.string().optional(),
13
+ position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
14
+ // Rotation around the Y axis in radians.
15
+ rotation: z.number().default(0),
16
+ width: z.number().default(1.84),
17
+ depth: z.number().default(1.84),
18
+ shaftWidth: z.number().optional(),
19
+ shaftDepth: z.number().optional(),
20
+ shaftWallThickness: z.number().default(0.09),
21
+ shaftStyle: ElevatorShaftStyle.default('solid'),
22
+ cabHeight: z.number().default(2.35),
23
+ doorWidth: z.number().default(0.95),
24
+ doorHeight: z.number().default(2.1),
25
+ doorStyle: ElevatorDoorStyle.default('center-opening'),
26
+ doorPanelStyle: ElevatorDoorPanelStyle.default('glass-frame'),
27
+ fromLevelId: z.string().nullable().default(null),
28
+ toLevelId: z.string().nullable().default(null),
29
+ servedLevelIds: z.array(z.string()).optional(),
30
+ disabledLevelIds: z.array(z.string()).default([]),
31
+ serviceOnlyLevelIds: z.array(z.string()).default([]),
32
+ defaultLevelId: z.string().nullable().default(null),
33
+ speed: z.number().default(2.2),
34
+ doorDurationMs: z.number().default(900),
35
+ dwellMs: z.number().default(1400),
36
+ }).describe(dedent `
37
+ Elevator node - a vertical transport core attached to a building.
38
+ - parentId: building that owns this elevator
39
+ - position: building-local shaft center on the X/Z plane
40
+ - rotation: rotation around the Y axis
41
+ - width/depth: cab footprint
42
+ - shaftWidth/shaftDepth: optional clear shaft footprint; falls back to cab footprint
43
+ - shaftWallThickness: visible shaft shell thickness
44
+ - shaftStyle: solid or glass shaft shell presentation
45
+ - cabHeight: visible elevator cab height
46
+ - doorWidth/doorHeight/doorStyle: landing and cab door movement/opening presentation
47
+ - doorPanelStyle: visual leaf style for glass-frame, solid-panel, or segmented-panel doors
48
+ - fromLevelId / toLevelId: source and destination levels used for service range and auto cutouts
49
+ - servedLevelIds: legacy optional explicit level list; used only when from/to are missing
50
+ - disabledLevelIds: stops visible in the service range but unavailable for public/cab requests
51
+ - serviceOnlyLevelIds: stops unavailable from landing calls but available from cab/admin controls
52
+ - defaultLevelId: starting/resting level, falling back to the lowest served level
53
+ - speed/doorDurationMs/dwellMs: runtime animation defaults
54
+ `);
@@ -0,0 +1,68 @@
1
+ import { z } from 'zod';
2
+ export declare const EyebrowVentNode: z.ZodObject<{
3
+ object: z.ZodDefault<z.ZodLiteral<"node">>;
4
+ name: z.ZodOptional<z.ZodString>;
5
+ parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
6
+ visible: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
7
+ camera: z.ZodOptional<z.ZodObject<{
8
+ position: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
9
+ target: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
10
+ mode: z.ZodDefault<z.ZodEnum<{
11
+ perspective: "perspective";
12
+ orthographic: "orthographic";
13
+ }>>;
14
+ fov: z.ZodOptional<z.ZodNumber>;
15
+ zoom: z.ZodOptional<z.ZodNumber>;
16
+ }, z.core.$strip>>;
17
+ metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
18
+ id: z.ZodDefault<z.ZodTemplateLiteral<`eyebrow-vent_${string}`>>;
19
+ type: z.ZodDefault<z.ZodLiteral<"eyebrow-vent">>;
20
+ material: z.ZodOptional<z.ZodObject<{
21
+ id: z.ZodOptional<z.ZodString>;
22
+ preset: z.ZodOptional<z.ZodEnum<{
23
+ custom: "custom";
24
+ white: "white";
25
+ brick: "brick";
26
+ concrete: "concrete";
27
+ wood: "wood";
28
+ glass: "glass";
29
+ metal: "metal";
30
+ plaster: "plaster";
31
+ tile: "tile";
32
+ marble: "marble";
33
+ }>>;
34
+ properties: z.ZodOptional<z.ZodObject<{
35
+ color: z.ZodDefault<z.ZodString>;
36
+ roughness: z.ZodDefault<z.ZodNumber>;
37
+ metalness: z.ZodDefault<z.ZodNumber>;
38
+ opacity: z.ZodDefault<z.ZodNumber>;
39
+ transparent: z.ZodDefault<z.ZodBoolean>;
40
+ side: z.ZodDefault<z.ZodEnum<{
41
+ front: "front";
42
+ back: "back";
43
+ double: "double";
44
+ }>>;
45
+ }, z.core.$strip>>;
46
+ texture: z.ZodOptional<z.ZodObject<{
47
+ url: z.ZodString;
48
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
49
+ scale: z.ZodOptional<z.ZodNumber>;
50
+ }, z.core.$strip>>;
51
+ }, z.core.$strip>>;
52
+ materialPreset: z.ZodDefault<z.ZodString>;
53
+ roofSegmentId: z.ZodOptional<z.ZodString>;
54
+ position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
55
+ rotation: z.ZodDefault<z.ZodNumber>;
56
+ width: z.ZodDefault<z.ZodNumber>;
57
+ depth: z.ZodDefault<z.ZodNumber>;
58
+ height: z.ZodDefault<z.ZodNumber>;
59
+ style: z.ZodDefault<z.ZodEnum<{
60
+ scoop: "scoop";
61
+ "half-round": "half-round";
62
+ "slant-box": "slant-box";
63
+ }>>;
64
+ louverCount: z.ZodDefault<z.ZodNumber>;
65
+ backRatio: z.ZodDefault<z.ZodNumber>;
66
+ }, z.core.$strip>;
67
+ export type EyebrowVentNode = z.infer<typeof EyebrowVentNode>;
68
+ //# sourceMappingURL=eyebrow-vent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eyebrow-vent.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/eyebrow-vent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2C3B,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA"}
@@ -0,0 +1,40 @@
1
+ import dedent from 'dedent';
2
+ import { z } from 'zod';
3
+ import { BaseNode, nodeType, objectId } from '../base';
4
+ import { MaterialSchema } from '../material';
5
+ export const EyebrowVentNode = BaseNode.extend({
6
+ id: objectId('eyebrow-vent'),
7
+ type: nodeType('eyebrow-vent'),
8
+ material: MaterialSchema.optional(),
9
+ // Default to the white preset so a freshly-placed vent reads as clean
10
+ // painted metal and the paint inspector shows "White" (matches box-vent).
11
+ materialPreset: z.string().default('preset-white'),
12
+ roofSegmentId: z.string().optional(),
13
+ position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
14
+ rotation: z.number().default(0),
15
+ // `width` is the opening width (left↔right across the louvered face),
16
+ // `depth` the front-to-back projection along the roof, `height` the rise.
17
+ width: z.number().default(0.5),
18
+ depth: z.number().default(0.6),
19
+ height: z.number().default(0.3),
20
+ // Body shape:
21
+ // - `scoop` : rounded louvered opening that sweeps back and tapers
22
+ // into the flashing plate (the classic dormer "eyebrow").
23
+ // - `half-round` : a D-shaped half-round louver vent (flat louvered face,
24
+ // semicircular curved top, short body).
25
+ // - `slant-box` : a low box with a slanted top and a screened front.
26
+ style: z.enum(['scoop', 'half-round', 'slant-box']).default('scoop'),
27
+ // Number of horizontal louver slats across the front opening (0 = open /
28
+ // screened only).
29
+ louverCount: z.number().int().min(0).max(8).default(3),
30
+ // `slant-box` only: the low rear edge as a fraction of the tall front edge.
31
+ // 1 = flat-topped box, lower = the top slopes down more steeply toward the
32
+ // back.
33
+ backRatio: z.number().min(0.15).max(1).default(0.5),
34
+ }).describe(dedent `
35
+ Eyebrow vent — a low roof ventilator with a rounded, louvered front that
36
+ sits on a flashing plate. Three styles: a swept "scoop" eyebrow, a D-shaped
37
+ "half-round" louver vent, and a "slant-box" hood. Parented to a roof-segment;
38
+ position is segment-local. Rotation is around the segment's vertical axis
39
+ (post-slope tilt).
40
+ `);
@@ -74,6 +74,7 @@ export declare const FenceNode: z.ZodObject<{
74
74
  floating: "floating";
75
75
  grounded: "grounded";
76
76
  }>>;
77
+ showInfill: z.ZodDefault<z.ZodBoolean>;
77
78
  color: z.ZodDefault<z.ZodString>;
78
79
  style: z.ZodDefault<z.ZodEnum<{
79
80
  slat: "slat";
@@ -1 +1 @@
1
- {"version":3,"file":"fence.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/fence.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,UAAU;;;;EAAsC,CAAA;AAC7D,eAAO,MAAM,cAAc;;;EAAmC,CAAA;AAE9D,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA"}
1
+ {"version":3,"file":"fence.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/fence.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,UAAU;;;;EAAsC,CAAA;AAC7D,eAAO,MAAM,cAAc;;;EAAmC,CAAA;AAE9D,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA"}
@@ -21,6 +21,7 @@ export const FenceNode = BaseNode.extend({
21
21
  groundClearance: z.number().default(0),
22
22
  edgeInset: z.number().default(0.015),
23
23
  baseStyle: FenceBaseStyle.default('grounded'),
24
+ showInfill: z.boolean().default(true),
24
25
  color: z.string().default('#ffffff'),
25
26
  style: FenceStyle.default('slat'),
26
27
  }).describe(dedent `
@@ -30,5 +31,6 @@ export const FenceNode = BaseNode.extend({
30
31
  - curveOffset: midpoint sagitta offset used to bend the fence into an arc
31
32
  - baseHeight/postSpacing/postSize/topRailHeight: exact geometric controls from the plan3D fence model
32
33
  - groundClearance/edgeInset/baseStyle: fence support and inset configuration
34
+ - showInfill: whether to draw intermediate posts/slats between end posts
33
35
  - color/style: visual appearance options
34
36
  `);
@@ -0,0 +1,84 @@
1
+ import { z } from 'zod';
2
+ export declare const GutterOutlet: z.ZodObject<{
3
+ id: z.ZodString;
4
+ offset: z.ZodDefault<z.ZodNumber>;
5
+ diameter: z.ZodDefault<z.ZodNumber>;
6
+ }, z.core.$strip>;
7
+ export type GutterOutlet = z.infer<typeof GutterOutlet>;
8
+ export declare const GutterNode: z.ZodObject<{
9
+ object: z.ZodDefault<z.ZodLiteral<"node">>;
10
+ name: z.ZodOptional<z.ZodString>;
11
+ parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
12
+ visible: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
13
+ camera: z.ZodOptional<z.ZodObject<{
14
+ position: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
15
+ target: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
16
+ mode: z.ZodDefault<z.ZodEnum<{
17
+ perspective: "perspective";
18
+ orthographic: "orthographic";
19
+ }>>;
20
+ fov: z.ZodOptional<z.ZodNumber>;
21
+ zoom: z.ZodOptional<z.ZodNumber>;
22
+ }, z.core.$strip>>;
23
+ metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
24
+ id: z.ZodDefault<z.ZodTemplateLiteral<`gutter_${string}`>>;
25
+ type: z.ZodDefault<z.ZodLiteral<"gutter">>;
26
+ material: z.ZodOptional<z.ZodObject<{
27
+ id: z.ZodOptional<z.ZodString>;
28
+ preset: z.ZodOptional<z.ZodEnum<{
29
+ custom: "custom";
30
+ white: "white";
31
+ brick: "brick";
32
+ concrete: "concrete";
33
+ wood: "wood";
34
+ glass: "glass";
35
+ metal: "metal";
36
+ plaster: "plaster";
37
+ tile: "tile";
38
+ marble: "marble";
39
+ }>>;
40
+ properties: z.ZodOptional<z.ZodObject<{
41
+ color: z.ZodDefault<z.ZodString>;
42
+ roughness: z.ZodDefault<z.ZodNumber>;
43
+ metalness: z.ZodDefault<z.ZodNumber>;
44
+ opacity: z.ZodDefault<z.ZodNumber>;
45
+ transparent: z.ZodDefault<z.ZodBoolean>;
46
+ side: z.ZodDefault<z.ZodEnum<{
47
+ front: "front";
48
+ back: "back";
49
+ double: "double";
50
+ }>>;
51
+ }, z.core.$strip>>;
52
+ texture: z.ZodOptional<z.ZodObject<{
53
+ url: z.ZodString;
54
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
55
+ scale: z.ZodOptional<z.ZodNumber>;
56
+ }, z.core.$strip>>;
57
+ }, z.core.$strip>>;
58
+ materialPreset: z.ZodDefault<z.ZodString>;
59
+ roofSegmentId: z.ZodOptional<z.ZodString>;
60
+ position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
61
+ rotation: z.ZodDefault<z.ZodNumber>;
62
+ length: z.ZodDefault<z.ZodNumber>;
63
+ size: z.ZodDefault<z.ZodNumber>;
64
+ thickness: z.ZodDefault<z.ZodNumber>;
65
+ profile: z.ZodDefault<z.ZodEnum<{
66
+ box: "box";
67
+ "half-round": "half-round";
68
+ "k-style": "k-style";
69
+ }>>;
70
+ endCapLeft: z.ZodDefault<z.ZodBoolean>;
71
+ endCapRight: z.ZodDefault<z.ZodBoolean>;
72
+ hangerStyle: z.ZodDefault<z.ZodEnum<{
73
+ none: "none";
74
+ strap: "strap";
75
+ }>>;
76
+ hangerSpacing: z.ZodDefault<z.ZodNumber>;
77
+ outlets: z.ZodDefault<z.ZodArray<z.ZodObject<{
78
+ id: z.ZodString;
79
+ offset: z.ZodDefault<z.ZodNumber>;
80
+ diameter: z.ZodDefault<z.ZodNumber>;
81
+ }, z.core.$strip>>>;
82
+ }, z.core.$strip>;
83
+ export type GutterNode = z.infer<typeof GutterNode>;
84
+ //# sourceMappingURL=gutter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gutter.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/gutter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,eAAO,MAAM,YAAY;;;;iBAUvB,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkEtB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA"}
@@ -0,0 +1,76 @@
1
+ import dedent from 'dedent';
2
+ import { z } from 'zod';
3
+ import { BaseNode, nodeType, objectId } from '../base';
4
+ import { MaterialSchema } from '../material';
5
+ // A single drop outlet drilled in the gutter floor. A gutter can carry
6
+ // several so a long run can split between multiple downspouts (each
7
+ // downspout links to one outlet via its `outletId`).
8
+ export const GutterOutlet = z.object({
9
+ // Stable id the downspout references. Generated with `generateId('outlet')`.
10
+ id: z.string(),
11
+ // Position along the gutter length (gutter-local +X), signed from the
12
+ // CENTER. The geometry clamps it inside the end caps at build time, so
13
+ // a stored value that no longer fits just rides the nearest bound.
14
+ offset: z.number().default(0),
15
+ // Bore diameter of this drop. Default 0.07 m ≈ 3″. The cross-section
16
+ // SHAPE (round vs rectangular) follows the gutter's profile, not this.
17
+ diameter: z.number().default(0.07),
18
+ });
19
+ export const GutterNode = BaseNode.extend({
20
+ id: objectId('gutter'),
21
+ type: nodeType('gutter'),
22
+ material: MaterialSchema.optional(),
23
+ // White preset by default — matches the rest of the roof accessory
24
+ // family (box-vent / ridge-vent) so the paint inspector reads as
25
+ // "White" instead of "no material" on a freshly-placed gutter.
26
+ materialPreset: z.string().default('preset-white'),
27
+ roofSegmentId: z.string().optional(),
28
+ // Segment-local. The placement tool snaps to the eave line (Z =
29
+ // +depth/2, Y = wallHeight) of the segment under the cursor; X is
30
+ // wherever the user clicked. After placement the inspector + length
31
+ // handles can shift X along the eave.
32
+ position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
33
+ // Rotation around the gutter's own local Y. Kept at 0 by default
34
+ // because the gutter's length axis is constrained to the eave
35
+ // direction (segment-local +X) — but exposed in case the user wants
36
+ // to tilt for a custom run.
37
+ rotation: z.number().default(0),
38
+ // Length along the eave (gutter-local +X).
39
+ length: z.number().default(2.0),
40
+ // Profile size — the vertical drop of the U-channel below the eave
41
+ // line. 5″ (0.127 m) is the most common residential gutter size; 6″
42
+ // (0.152 m) is the common commercial / heavy-duty size. Default
43
+ // rounds the residential value to 0.13 m.
44
+ size: z.number().default(0.13),
45
+ // Wall thickness of the U-channel. Visible on the rim from above; too
46
+ // thin reads as a paper strip, too thick reads as a curb.
47
+ thickness: z.number().default(0.006),
48
+ profile: z.enum(['k-style', 'half-round', 'box']).default('k-style'),
49
+ // End caps close the open ends of the U-channel so water can't run
50
+ // out the sides. Independent per-end because a downspout typically
51
+ // joins the gutter at one end while the other stays capped. Default
52
+ // true on both — matches a freshly-installed residential gutter.
53
+ endCapLeft: z.boolean().default(true),
54
+ endCapRight: z.boolean().default(true),
55
+ // Hangers are the metal straps that hold the gutter onto the
56
+ // fascia. 'strap' renders periodic bars across the rim; 'none'
57
+ // hides them (some plastic gutters use hidden clips). Spacing is
58
+ // metres between hanger centers; real residential code is roughly
59
+ // 0.6 m for snow-load areas, 0.75 m elsewhere.
60
+ hangerStyle: z.enum(['strap', 'none']).default('strap'),
61
+ hangerSpacing: z.number().default(0.6),
62
+ // Downspout outlets — short drop tubes descending from the gutter
63
+ // floor where downspouts connect. Empty by default so existing
64
+ // gutters don't sprout outlets on schema upgrade. Each is drilled
65
+ // through the trough floor via CSG; a downspout links to one by id.
66
+ outlets: z.array(GutterOutlet).default([]),
67
+ }).describe(dedent `
68
+ Gutter — a rain-water channel running along the eave of a roof
69
+ segment. Parented to a roof-segment; position is segment-local.
70
+ - length: span along the eave (gutter-local +X)
71
+ - size: profile drop below the eave line (vertical extent)
72
+ - profile: k-style (ogee fascia), half-round, or square box
73
+ - endCapLeft / endCapRight: close the trough at gutter-local -X / +X
74
+ - hangerStyle / hangerSpacing: visible metal straps across the rim
75
+ - outlets: drop-tube outlets (id + along-length offset + bore diameter)
76
+ `);
@@ -157,7 +157,9 @@ declare const assetSchema: z.ZodObject<{
157
157
  ceiling: "ceiling";
158
158
  "wall-side": "wall-side";
159
159
  }>>;
160
+ recessed: z.ZodOptional<z.ZodBoolean>;
160
161
  tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
162
+ functionTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
161
163
  offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
162
164
  rotation: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
163
165
  scale: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
@@ -259,7 +261,9 @@ export declare const ItemNode: z.ZodObject<{
259
261
  ceiling: "ceiling";
260
262
  "wall-side": "wall-side";
261
263
  }>>;
264
+ recessed: z.ZodOptional<z.ZodBoolean>;
262
265
  tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
266
+ functionTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
263
267
  offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
264
268
  rotation: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
265
269
  scale: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
@@ -1 +1 @@
1
- {"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/item.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,QAAA,MAAM,mBAAmB;;;;iBAIvB,CAAA;AAEF,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;iBASvB,CAAA;AAEF,QAAA,MAAM,wBAAwB;;;;;;;;;;iBAO5B,CAAA;AAEF,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAIjB,CAAA;AAIF,QAAA,MAAM,qBAAqB;;;;;;;iBAOzB,CAAA;AAEF,QAAA,MAAM,iBAAiB;;;;;;iBAMrB,CAAA;AAEF,QAAA,MAAM,YAAY;;;;;;;;;;;;;2BAA2E,CAAA;AAI7F,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGrB,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA;AACzE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AACnD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACnE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAC3D,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AACjD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkCf,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AACpD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAE/C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BnB,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAE/C,eAAO,MAAM,mCAAmC,MAAM,CAAA;AAEtD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAM/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAI5E"}
1
+ {"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/item.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,QAAA,MAAM,mBAAmB;;;;iBAIvB,CAAA;AAEF,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;iBASvB,CAAA;AAEF,QAAA,MAAM,wBAAwB;;;;;;;;;;iBAO5B,CAAA;AAEF,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAIjB,CAAA;AAIF,QAAA,MAAM,qBAAqB;;;;;;;iBAOzB,CAAA;AAEF,QAAA,MAAM,iBAAiB;;;;;;iBAMrB,CAAA;AAEF,QAAA,MAAM,YAAY;;;;;;;;;;;;;2BAA2E,CAAA;AAI7F,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGrB,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA;AACzE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AACnD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACnE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAC3D,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AACjD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2Cf,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AACpD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAE/C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BnB,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAE/C,eAAO,MAAM,mCAAmC,MAAM,CAAA;AAEtD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAM/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAI5E"}
@@ -76,7 +76,16 @@ const assetSchema = z.object({
76
76
  src: AssetUrl,
77
77
  dimensions: z.tuple([z.number(), z.number(), z.number()]).default([1, 1, 1]), // [w, h, d]
78
78
  attachTo: z.enum(['wall', 'wall-side', 'ceiling']).optional(),
79
+ // Ceiling fixtures (e.g. recessed downlights) that embed *into* the ceiling
80
+ // rather than hang below it: the item seats flush with the ceiling plane
81
+ // (its body rising into the void above) and the ceiling is cut out around
82
+ // the item's footprint. Ignored unless `attachTo === 'ceiling'`.
83
+ recessed: z.boolean().optional(),
79
84
  tags: z.array(z.string()).optional(),
85
+ // Function-axis tag slugs from the taxonomy. Drives the hierarchical
86
+ // Items-tab browse: a tree node matches when any of its descendant slugs
87
+ // appears here. Absent for the seeded built-in catalog.
88
+ functionTags: z.array(z.string()).optional(),
80
89
  // These are "Corrective" transforms to normalize the GLB
81
90
  offset: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
82
91
  rotation: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
@@ -17,7 +17,7 @@ export declare const LevelNode: z.ZodObject<{
17
17
  metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
18
18
  id: z.ZodDefault<z.ZodTemplateLiteral<`level_${string}`>>;
19
19
  type: z.ZodDefault<z.ZodLiteral<"level">>;
20
- children: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodDefault<z.ZodTemplateLiteral<`wall_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`fence_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`column_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`zone_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`slab_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`ceiling_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`roof_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`stair_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`scan_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`guide_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`spawn_${string}`>>]>>>;
20
+ children: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodDefault<z.ZodTemplateLiteral<`wall_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`fence_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`column_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`zone_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`slab_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`ceiling_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`roof_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`stair_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`scan_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`guide_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`spawn_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`shelf_${string}`>>]>>>;
21
21
  level: z.ZodDefault<z.ZodNumber>;
22
22
  }, z.core.$strip>;
23
23
  export type LevelNode = z.infer<typeof LevelNode>;
@@ -1 +1 @@
1
- {"version":3,"file":"level.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/level.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAevB,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;iBA6BrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA"}
1
+ {"version":3,"file":"level.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/level.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAgBvB,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;iBA8BrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA"}
@@ -8,6 +8,7 @@ import { GuideNode } from './guide';
8
8
  import { ItemNode } from './item';
9
9
  import { RoofNode } from './roof';
10
10
  import { ScanNode } from './scan';
11
+ import { ShelfNode } from './shelf';
11
12
  import { SlabNode } from './slab';
12
13
  import { SpawnNode } from './spawn';
13
14
  import { StairNode } from './stair';
@@ -30,6 +31,7 @@ export const LevelNode = BaseNode.extend({
30
31
  ScanNode.shape.id,
31
32
  GuideNode.shape.id,
32
33
  SpawnNode.shape.id,
34
+ ShelfNode.shape.id,
33
35
  ]))
34
36
  .default([]),
35
37
  // Specific props
@@ -0,0 +1,67 @@
1
+ import { z } from 'zod';
2
+ export declare const RidgeVentNode: z.ZodObject<{
3
+ object: z.ZodDefault<z.ZodLiteral<"node">>;
4
+ name: z.ZodOptional<z.ZodString>;
5
+ parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
6
+ visible: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
7
+ camera: z.ZodOptional<z.ZodObject<{
8
+ position: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
9
+ target: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
10
+ mode: z.ZodDefault<z.ZodEnum<{
11
+ perspective: "perspective";
12
+ orthographic: "orthographic";
13
+ }>>;
14
+ fov: z.ZodOptional<z.ZodNumber>;
15
+ zoom: z.ZodOptional<z.ZodNumber>;
16
+ }, z.core.$strip>>;
17
+ metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
18
+ id: z.ZodDefault<z.ZodTemplateLiteral<`rvent_${string}`>>;
19
+ type: z.ZodDefault<z.ZodLiteral<"ridge-vent">>;
20
+ material: z.ZodOptional<z.ZodObject<{
21
+ id: z.ZodOptional<z.ZodString>;
22
+ preset: z.ZodOptional<z.ZodEnum<{
23
+ custom: "custom";
24
+ white: "white";
25
+ brick: "brick";
26
+ concrete: "concrete";
27
+ wood: "wood";
28
+ glass: "glass";
29
+ metal: "metal";
30
+ plaster: "plaster";
31
+ tile: "tile";
32
+ marble: "marble";
33
+ }>>;
34
+ properties: z.ZodOptional<z.ZodObject<{
35
+ color: z.ZodDefault<z.ZodString>;
36
+ roughness: z.ZodDefault<z.ZodNumber>;
37
+ metalness: z.ZodDefault<z.ZodNumber>;
38
+ opacity: z.ZodDefault<z.ZodNumber>;
39
+ transparent: z.ZodDefault<z.ZodBoolean>;
40
+ side: z.ZodDefault<z.ZodEnum<{
41
+ front: "front";
42
+ back: "back";
43
+ double: "double";
44
+ }>>;
45
+ }, z.core.$strip>>;
46
+ texture: z.ZodOptional<z.ZodObject<{
47
+ url: z.ZodString;
48
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
49
+ scale: z.ZodOptional<z.ZodNumber>;
50
+ }, z.core.$strip>>;
51
+ }, z.core.$strip>>;
52
+ materialPreset: z.ZodDefault<z.ZodString>;
53
+ roofSegmentId: z.ZodOptional<z.ZodString>;
54
+ position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
55
+ rotation: z.ZodDefault<z.ZodNumber>;
56
+ length: z.ZodDefault<z.ZodNumber>;
57
+ width: z.ZodDefault<z.ZodNumber>;
58
+ height: z.ZodDefault<z.ZodNumber>;
59
+ style: z.ZodDefault<z.ZodEnum<{
60
+ metal: "metal";
61
+ standard: "standard";
62
+ shingled: "shingled";
63
+ }>>;
64
+ endCaps: z.ZodDefault<z.ZodBoolean>;
65
+ }, z.core.$strip>;
66
+ export type RidgeVentNode = z.infer<typeof RidgeVentNode>;
67
+ //# sourceMappingURL=ridge-vent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ridge-vent.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/ridge-vent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA"}
@@ -0,0 +1,30 @@
1
+ import dedent from 'dedent';
2
+ import { z } from 'zod';
3
+ import { BaseNode, nodeType, objectId } from '../base';
4
+ import { MaterialSchema } from '../material';
5
+ export const RidgeVentNode = BaseNode.extend({
6
+ id: objectId('rvent'),
7
+ type: nodeType('ridge-vent'),
8
+ material: MaterialSchema.optional(),
9
+ // See note on box-vent: default to white so the paint inspector
10
+ // reflects the current visual state instead of "no material".
11
+ materialPreset: z.string().default('preset-white'),
12
+ roofSegmentId: z.string().optional(),
13
+ position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
14
+ rotation: z.number().default(0),
15
+ length: z.number().default(2.0),
16
+ width: z.number().default(0.3),
17
+ // Taller default than the old paper-thin shell so the solid body reads
18
+ // with real presence on the ridge; still adjustable down to 0.03.
19
+ height: z.number().default(0.1),
20
+ style: z.enum(['standard', 'shingled', 'metal']).default('standard'),
21
+ endCaps: z.boolean().default(true),
22
+ }).describe(dedent `
23
+ Ridge vent — a ventilation strip that sits along the ridge (peak) of a
24
+ roof segment. Parented to a roof-segment; position is segment-local.
25
+ - length: extent along the ridge
26
+ - width: vent width straddling the ridge center
27
+ - height: profile height above the ridge surface
28
+ - style: standard (curved cap) / shingled / metal
29
+ - endCaps: cap both ends or leave open
30
+ `);