@pascal-app/core 0.9.2 → 1.0.0-beta.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 (339) hide show
  1. package/README.md +17 -10
  2. package/dist/events/bus.d.ts +21 -2
  3. package/dist/events/bus.d.ts.map +1 -1
  4. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +17 -1
  5. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
  6. package/dist/hooks/spatial-grid/floor-placed-elevation.js +61 -8
  7. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +116 -66
  8. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  9. package/dist/hooks/spatial-grid/spatial-grid-manager.js +316 -441
  10. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +46 -1
  11. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  12. package/dist/hooks/spatial-grid/spatial-grid-sync.js +193 -12
  13. package/dist/hooks/spatial-grid/support-host-id.d.ts +3 -0
  14. package/dist/hooks/spatial-grid/support-host-id.d.ts.map +1 -0
  15. package/dist/hooks/spatial-grid/support-host-id.js +2 -0
  16. package/dist/hooks/spatial-grid/support-host-patch.d.ts +51 -0
  17. package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -0
  18. package/dist/hooks/spatial-grid/support-host-patch.js +164 -0
  19. package/dist/index.d.ts +23 -11
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +22 -10
  22. package/dist/lib/measurement-geometry.d.ts +4 -0
  23. package/dist/lib/measurement-geometry.d.ts.map +1 -1
  24. package/dist/lib/measurement-geometry.js +27 -10
  25. package/dist/lib/slab-polygon.d.ts.map +1 -1
  26. package/dist/lib/slab-polygon.js +33 -1
  27. package/dist/lib/space-detection.d.ts +15 -4
  28. package/dist/lib/space-detection.d.ts.map +1 -1
  29. package/dist/lib/space-detection.js +174 -88
  30. package/dist/lib/terrain-brush.d.ts +163 -0
  31. package/dist/lib/terrain-brush.d.ts.map +1 -0
  32. package/dist/lib/terrain-brush.js +359 -0
  33. package/dist/lib/terrain-codec.d.ts +51 -0
  34. package/dist/lib/terrain-codec.d.ts.map +1 -0
  35. package/dist/lib/terrain-codec.js +167 -0
  36. package/dist/lib/terrain-field.d.ts +150 -0
  37. package/dist/lib/terrain-field.d.ts.map +1 -0
  38. package/dist/lib/terrain-field.js +248 -0
  39. package/dist/lib/terrain-raycast.d.ts +44 -0
  40. package/dist/lib/terrain-raycast.d.ts.map +1 -0
  41. package/dist/lib/terrain-raycast.js +188 -0
  42. package/dist/lib/terrain-source.d.ts +60 -0
  43. package/dist/lib/terrain-source.d.ts.map +1 -0
  44. package/dist/lib/terrain-source.js +90 -0
  45. package/dist/lib/terrain-support.d.ts +60 -0
  46. package/dist/lib/terrain-support.d.ts.map +1 -0
  47. package/dist/lib/terrain-support.js +150 -0
  48. package/dist/lib/zone-quantities.d.ts +1 -1
  49. package/dist/lib/zone-quantities.d.ts.map +1 -1
  50. package/dist/lib/zone-quantities.js +311 -66
  51. package/dist/material-library.d.ts +9 -1
  52. package/dist/material-library.d.ts.map +1 -1
  53. package/dist/material-library.js +56 -4
  54. package/dist/registry/handles.d.ts +16 -1
  55. package/dist/registry/handles.d.ts.map +1 -1
  56. package/dist/registry/index.d.ts +1 -1
  57. package/dist/registry/index.d.ts.map +1 -1
  58. package/dist/registry/subtree.d.ts.map +1 -1
  59. package/dist/registry/subtree.js +5 -2
  60. package/dist/registry/types.d.ts +64 -1
  61. package/dist/registry/types.d.ts.map +1 -1
  62. package/dist/schema/index.d.ts +6 -3
  63. package/dist/schema/index.d.ts.map +1 -1
  64. package/dist/schema/index.js +6 -3
  65. package/dist/schema/nodes/cabinet.d.ts +2 -0
  66. package/dist/schema/nodes/cabinet.d.ts.map +1 -1
  67. package/dist/schema/nodes/cabinet.js +4 -2
  68. package/dist/schema/nodes/ceiling.d.ts +1 -1
  69. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  70. package/dist/schema/nodes/ceiling.js +7 -1
  71. package/dist/schema/nodes/column.d.ts +1 -0
  72. package/dist/schema/nodes/column.d.ts.map +1 -1
  73. package/dist/schema/nodes/column.js +2 -0
  74. package/dist/schema/nodes/construction-dimension.d.ts +195 -0
  75. package/dist/schema/nodes/construction-dimension.d.ts.map +1 -0
  76. package/dist/schema/nodes/construction-dimension.js +151 -0
  77. package/dist/schema/nodes/door.d.ts +29 -0
  78. package/dist/schema/nodes/door.d.ts.map +1 -1
  79. package/dist/schema/nodes/door.js +20 -0
  80. package/dist/schema/nodes/duct-terminal.d.ts +1 -0
  81. package/dist/schema/nodes/duct-terminal.d.ts.map +1 -1
  82. package/dist/schema/nodes/duct-terminal.js +2 -0
  83. package/dist/schema/nodes/fence.d.ts +2 -0
  84. package/dist/schema/nodes/fence.d.ts.map +1 -1
  85. package/dist/schema/nodes/fence.js +8 -0
  86. package/dist/schema/nodes/hvac-equipment.d.ts +1 -0
  87. package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -1
  88. package/dist/schema/nodes/hvac-equipment.js +2 -0
  89. package/dist/schema/nodes/item.d.ts +1 -0
  90. package/dist/schema/nodes/item.d.ts.map +1 -1
  91. package/dist/schema/nodes/item.js +13 -0
  92. package/dist/schema/nodes/level.d.ts +2 -1
  93. package/dist/schema/nodes/level.d.ts.map +1 -1
  94. package/dist/schema/nodes/level.js +12 -33
  95. package/dist/schema/nodes/shelf.d.ts +1 -0
  96. package/dist/schema/nodes/shelf.d.ts.map +1 -1
  97. package/dist/schema/nodes/shelf.js +2 -0
  98. package/dist/schema/nodes/site.d.ts +9 -0
  99. package/dist/schema/nodes/site.d.ts.map +1 -1
  100. package/dist/schema/nodes/site.js +8 -6
  101. package/dist/schema/nodes/slab.d.ts +5 -0
  102. package/dist/schema/nodes/slab.d.ts.map +1 -1
  103. package/dist/schema/nodes/slab.js +14 -2
  104. package/dist/schema/nodes/spawn.d.ts +1 -0
  105. package/dist/schema/nodes/spawn.d.ts.map +1 -1
  106. package/dist/schema/nodes/spawn.js +2 -0
  107. package/dist/schema/nodes/stair.d.ts +3 -1
  108. package/dist/schema/nodes/stair.d.ts.map +1 -1
  109. package/dist/schema/nodes/stair.js +8 -1
  110. package/dist/schema/nodes/structural-grid.d.ts +27 -0
  111. package/dist/schema/nodes/structural-grid.d.ts.map +1 -0
  112. package/dist/schema/nodes/structural-grid.js +17 -0
  113. package/dist/schema/nodes/wall.d.ts +5 -2
  114. package/dist/schema/nodes/wall.d.ts.map +1 -1
  115. package/dist/schema/nodes/wall.js +13 -4
  116. package/dist/schema/nodes/window.d.ts +29 -0
  117. package/dist/schema/nodes/window.d.ts.map +1 -1
  118. package/dist/schema/nodes/window.js +18 -0
  119. package/dist/schema/nodes/zone.d.ts +20 -0
  120. package/dist/schema/nodes/zone.d.ts.map +1 -1
  121. package/dist/schema/nodes/zone.js +15 -0
  122. package/dist/schema/terrain.d.ts +28 -0
  123. package/dist/schema/terrain.d.ts.map +1 -0
  124. package/dist/schema/terrain.js +30 -0
  125. package/dist/schema/types.d.ts +211 -3
  126. package/dist/schema/types.d.ts.map +1 -1
  127. package/dist/schema/types.js +4 -0
  128. package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts +80 -0
  129. package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts.map +1 -0
  130. package/dist/services/__fixtures__/wall-plane-top-boundary-repro.js +89 -0
  131. package/dist/services/index.d.ts +2 -1
  132. package/dist/services/index.d.ts.map +1 -1
  133. package/dist/services/index.js +2 -1
  134. package/dist/services/level-height.d.ts +8 -9
  135. package/dist/services/level-height.d.ts.map +1 -1
  136. package/dist/services/level-height.js +48 -16
  137. package/dist/services/storey.d.ts +103 -0
  138. package/dist/services/storey.d.ts.map +1 -0
  139. package/dist/services/storey.js +296 -0
  140. package/dist/store/actions/node-actions.d.ts.map +1 -1
  141. package/dist/store/actions/node-actions.js +47 -3
  142. package/dist/store/history-control.d.ts +20 -0
  143. package/dist/store/history-control.d.ts.map +1 -1
  144. package/dist/store/history-control.js +110 -13
  145. package/dist/store/use-live-terrain.d.ts +65 -0
  146. package/dist/store/use-live-terrain.d.ts.map +1 -0
  147. package/dist/store/use-live-terrain.js +31 -0
  148. package/dist/store/use-live-transforms.d.ts +8 -0
  149. package/dist/store/use-live-transforms.d.ts.map +1 -1
  150. package/dist/store/use-scene.d.ts +31 -2
  151. package/dist/store/use-scene.d.ts.map +1 -1
  152. package/dist/store/use-scene.js +638 -8
  153. package/dist/systems/elevator/elevator-opening-system.d.ts +1 -0
  154. package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -1
  155. package/dist/systems/elevator/elevator-opening-system.js +27 -21
  156. package/dist/systems/elevator/elevator-service.d.ts +0 -2
  157. package/dist/systems/elevator/elevator-service.d.ts.map +1 -1
  158. package/dist/systems/elevator/elevator-service.js +2 -24
  159. package/dist/systems/slab/slab-placement.d.ts +11 -0
  160. package/dist/systems/slab/slab-placement.d.ts.map +1 -0
  161. package/dist/systems/slab/slab-placement.js +14 -0
  162. package/dist/systems/slab/slab-support.d.ts +137 -0
  163. package/dist/systems/slab/slab-support.d.ts.map +1 -0
  164. package/dist/systems/slab/slab-support.js +557 -0
  165. package/dist/systems/stair/stair-opening-preview.d.ts +1060 -935
  166. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
  167. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  168. package/dist/systems/stair/stair-opening-sync.js +18 -15
  169. package/dist/systems/stair/stair-opening-system.d.ts.map +1 -1
  170. package/dist/systems/stair/stair-opening-system.js +32 -4
  171. package/dist/systems/stair/stair-rise.d.ts +22 -0
  172. package/dist/systems/stair/stair-rise.d.ts.map +1 -0
  173. package/dist/systems/stair/stair-rise.js +79 -0
  174. package/dist/systems/wall/wall-curve.d.ts +10 -0
  175. package/dist/systems/wall/wall-curve.d.ts.map +1 -1
  176. package/dist/systems/wall/wall-curve.js +1 -1
  177. package/dist/systems/wall/wall-mitering.js +6 -6
  178. package/dist/systems/wall/wall-top.d.ts +40 -0
  179. package/dist/systems/wall/wall-top.d.ts.map +1 -0
  180. package/dist/systems/wall/wall-top.js +46 -0
  181. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  182. package/dist/utils/clone-scene-graph.js +34 -3
  183. package/dist/utils/heal-scene-graph.d.ts +1 -1
  184. package/dist/utils/heal-scene-graph.d.ts.map +1 -1
  185. package/dist/utils/heal-scene-graph.js +25 -9
  186. package/dist/validation/validate-build-json.d.ts +2 -0
  187. package/dist/validation/validate-build-json.d.ts.map +1 -1
  188. package/dist/validation/validate-build-json.js +59 -3
  189. package/package.json +2 -2
  190. package/dist/hooks/scene-registry/scene-registry.test.d.ts +0 -2
  191. package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +0 -1
  192. package/dist/hooks/scene-registry/scene-registry.test.js +0 -26
  193. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +0 -2
  194. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +0 -1
  195. package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +0 -366
  196. package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +0 -2
  197. package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +0 -1
  198. package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +0 -363
  199. package/dist/lib/measurement-geometry.test.d.ts +0 -2
  200. package/dist/lib/measurement-geometry.test.d.ts.map +0 -1
  201. package/dist/lib/measurement-geometry.test.js +0 -102
  202. package/dist/lib/slab-polygon.test.d.ts +0 -2
  203. package/dist/lib/slab-polygon.test.d.ts.map +0 -1
  204. package/dist/lib/slab-polygon.test.js +0 -635
  205. package/dist/lib/space-detection-pause.test.d.ts +0 -2
  206. package/dist/lib/space-detection-pause.test.d.ts.map +0 -1
  207. package/dist/lib/space-detection-pause.test.js +0 -42
  208. package/dist/lib/space-detection.test.d.ts +0 -2
  209. package/dist/lib/space-detection.test.d.ts.map +0 -1
  210. package/dist/lib/space-detection.test.js +0 -376
  211. package/dist/lib/zone-quantities.test.d.ts +0 -2
  212. package/dist/lib/zone-quantities.test.d.ts.map +0 -1
  213. package/dist/lib/zone-quantities.test.js +0 -82
  214. package/dist/registry/registry.test.d.ts +0 -2
  215. package/dist/registry/registry.test.d.ts.map +0 -1
  216. package/dist/registry/registry.test.js +0 -196
  217. package/dist/registry/relations-resolver.test.d.ts +0 -2
  218. package/dist/registry/relations-resolver.test.d.ts.map +0 -1
  219. package/dist/registry/relations-resolver.test.js +0 -183
  220. package/dist/registry/scene-api.test.d.ts +0 -2
  221. package/dist/registry/scene-api.test.d.ts.map +0 -1
  222. package/dist/registry/scene-api.test.js +0 -183
  223. package/dist/registry/subtree.test.d.ts +0 -2
  224. package/dist/registry/subtree.test.d.ts.map +0 -1
  225. package/dist/registry/subtree.test.js +0 -163
  226. package/dist/schema/asset-url.test.d.ts +0 -2
  227. package/dist/schema/asset-url.test.d.ts.map +0 -1
  228. package/dist/schema/asset-url.test.js +0 -134
  229. package/dist/schema/material.test.d.ts +0 -2
  230. package/dist/schema/material.test.d.ts.map +0 -1
  231. package/dist/schema/material.test.js +0 -43
  232. package/dist/schema/nodes/measurement.test.d.ts +0 -2
  233. package/dist/schema/nodes/measurement.test.d.ts.map +0 -1
  234. package/dist/schema/nodes/measurement.test.js +0 -139
  235. package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +0 -2
  236. package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +0 -1
  237. package/dist/schema/nodes/ridge-vent-defaults.test.js +0 -205
  238. package/dist/schema/nodes/roof-segment-shape.test.d.ts +0 -2
  239. package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +0 -1
  240. package/dist/schema/nodes/roof-segment-shape.test.js +0 -175
  241. package/dist/schema/nodes/roof-segment-surface.test.d.ts +0 -2
  242. package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +0 -1
  243. package/dist/schema/nodes/roof-segment-surface.test.js +0 -48
  244. package/dist/schema/nodes/roof-segment-trim.test.d.ts +0 -2
  245. package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +0 -1
  246. package/dist/schema/nodes/roof-segment-trim.test.js +0 -107
  247. package/dist/schema/nodes/roof-segment-walls.test.d.ts +0 -2
  248. package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +0 -1
  249. package/dist/schema/nodes/roof-segment-walls.test.js +0 -92
  250. package/dist/schema/nodes/wall.test.d.ts +0 -2
  251. package/dist/schema/nodes/wall.test.d.ts.map +0 -1
  252. package/dist/schema/nodes/wall.test.js +0 -208
  253. package/dist/services/alignment-anchors.test.d.ts +0 -2
  254. package/dist/services/alignment-anchors.test.d.ts.map +0 -1
  255. package/dist/services/alignment-anchors.test.js +0 -383
  256. package/dist/services/alignment.test.d.ts +0 -2
  257. package/dist/services/alignment.test.d.ts.map +0 -1
  258. package/dist/services/alignment.test.js +0 -92
  259. package/dist/services/drag-session.test.d.ts +0 -2
  260. package/dist/services/drag-session.test.d.ts.map +0 -1
  261. package/dist/services/drag-session.test.js +0 -219
  262. package/dist/services/hosting.test.d.ts +0 -2
  263. package/dist/services/hosting.test.d.ts.map +0 -1
  264. package/dist/services/hosting.test.js +0 -230
  265. package/dist/services/movement.test.d.ts +0 -2
  266. package/dist/services/movement.test.d.ts.map +0 -1
  267. package/dist/services/movement.test.js +0 -133
  268. package/dist/services/opening-guides.test.d.ts +0 -2
  269. package/dist/services/opening-guides.test.d.ts.map +0 -1
  270. package/dist/services/opening-guides.test.js +0 -208
  271. package/dist/services/port-connectivity.test.d.ts +0 -2
  272. package/dist/services/port-connectivity.test.d.ts.map +0 -1
  273. package/dist/services/port-connectivity.test.js +0 -297
  274. package/dist/services/riser-diagram.test.d.ts +0 -2
  275. package/dist/services/riser-diagram.test.d.ts.map +0 -1
  276. package/dist/services/riser-diagram.test.js +0 -66
  277. package/dist/services/single-undo-dance.test.d.ts +0 -2
  278. package/dist/services/single-undo-dance.test.d.ts.map +0 -1
  279. package/dist/services/single-undo-dance.test.js +0 -210
  280. package/dist/services/snap.test.d.ts +0 -2
  281. package/dist/services/snap.test.d.ts.map +0 -1
  282. package/dist/services/snap.test.js +0 -137
  283. package/dist/services/system-graph.test.d.ts +0 -2
  284. package/dist/services/system-graph.test.d.ts.map +0 -1
  285. package/dist/services/system-graph.test.js +0 -138
  286. package/dist/services/validate-dwv.test.d.ts +0 -2
  287. package/dist/services/validate-dwv.test.d.ts.map +0 -1
  288. package/dist/services/validate-dwv.test.js +0 -109
  289. package/dist/store/actions/node-mutation-sanitize.test.d.ts +0 -2
  290. package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +0 -1
  291. package/dist/store/actions/node-mutation-sanitize.test.js +0 -147
  292. package/dist/store/actions/reparent.test.d.ts +0 -2
  293. package/dist/store/actions/reparent.test.d.ts.map +0 -1
  294. package/dist/store/actions/reparent.test.js +0 -212
  295. package/dist/store/actions/ridge-vent-update.test.d.ts +0 -2
  296. package/dist/store/actions/ridge-vent-update.test.d.ts.map +0 -1
  297. package/dist/store/actions/ridge-vent-update.test.js +0 -264
  298. package/dist/store/use-scene-dirty-tracking.test.d.ts +0 -2
  299. package/dist/store/use-scene-dirty-tracking.test.d.ts.map +0 -1
  300. package/dist/store/use-scene-dirty-tracking.test.js +0 -68
  301. package/dist/store/use-scene-elevator-migration.test.d.ts +0 -2
  302. package/dist/store/use-scene-elevator-migration.test.d.ts.map +0 -1
  303. package/dist/store/use-scene-elevator-migration.test.js +0 -109
  304. package/dist/store/use-scene-measurement-roundtrip.test.d.ts +0 -2
  305. package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +0 -1
  306. package/dist/store/use-scene-measurement-roundtrip.test.js +0 -97
  307. package/dist/store/use-scene-plugins.test.d.ts +0 -2
  308. package/dist/store/use-scene-plugins.test.d.ts.map +0 -1
  309. package/dist/store/use-scene-plugins.test.js +0 -51
  310. package/dist/store/use-scene-wall-slot-migration.test.d.ts +0 -2
  311. package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +0 -1
  312. package/dist/store/use-scene-wall-slot-migration.test.js +0 -210
  313. package/dist/store/use-scene-window-migration.test.d.ts +0 -2
  314. package/dist/store/use-scene-window-migration.test.d.ts.map +0 -1
  315. package/dist/store/use-scene-window-migration.test.js +0 -85
  316. package/dist/systems/elevator/elevator-opening-sync.test.d.ts +0 -2
  317. package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +0 -1
  318. package/dist/systems/elevator/elevator-opening-sync.test.js +0 -146
  319. package/dist/systems/elevator/elevator-runtime.test.d.ts +0 -2
  320. package/dist/systems/elevator/elevator-runtime.test.d.ts.map +0 -1
  321. package/dist/systems/elevator/elevator-runtime.test.js +0 -64
  322. package/dist/systems/fence/fence-spline.test.d.ts +0 -2
  323. package/dist/systems/fence/fence-spline.test.d.ts.map +0 -1
  324. package/dist/systems/fence/fence-spline.test.js +0 -136
  325. package/dist/systems/stair/stair-opening-preview.test.d.ts +0 -2
  326. package/dist/systems/stair/stair-opening-preview.test.d.ts.map +0 -1
  327. package/dist/systems/stair/stair-opening-preview.test.js +0 -80
  328. package/dist/systems/stair/stair-opening-sync.test.d.ts +0 -2
  329. package/dist/systems/stair/stair-opening-sync.test.d.ts.map +0 -1
  330. package/dist/systems/stair/stair-opening-sync.test.js +0 -485
  331. package/dist/systems/wall/wall-mitering.test.d.ts +0 -2
  332. package/dist/systems/wall/wall-mitering.test.d.ts.map +0 -1
  333. package/dist/systems/wall/wall-mitering.test.js +0 -63
  334. package/dist/utils/clone-scene-graph.test.d.ts +0 -2
  335. package/dist/utils/clone-scene-graph.test.d.ts.map +0 -1
  336. package/dist/utils/clone-scene-graph.test.js +0 -62
  337. package/dist/utils/heal-scene-graph.test.d.ts +0 -2
  338. package/dist/utils/heal-scene-graph.test.d.ts.map +0 -1
  339. package/dist/utils/heal-scene-graph.test.js +0 -88
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Scene → `TerrainField`, cached.
3
+ *
4
+ * Every consumer that needs the ground — the mesh builder, the raycast, the
5
+ * placement predicate, the collider, the 2D view — starts here. It exists to
6
+ * solve one problem: the scene stores terrain as base64 (`site.terrain`), and
7
+ * decoding that per frame, or per pointer-move, would be absurd.
8
+ *
9
+ * The cache is a `WeakMap` keyed on the **`TerrainData` object identity**, which
10
+ * is a correct version key because the scene store is immutable-by-convention:
11
+ * `updateNode` produces a new node object with a new `terrain` object, so a
12
+ * changed terrain necessarily misses the cache and a stale entry is unreachable.
13
+ * No invalidation call, no version counter, nothing to forget to bump.
14
+ *
15
+ * `commitTerrainField` closes the loop: it encodes a field *and* primes the cache
16
+ * with the field it just encoded. That is what makes a sculpt stroke free — after
17
+ * the commit, the next read is a cache hit, so a stroke never decodes base64 even
18
+ * once, let alone per dab.
19
+ */
20
+ import type { SiteNode } from '../schema/nodes/site';
21
+ import type { TerrainData } from '../schema/terrain';
22
+ import { createTerrainField, type TerrainField } from './terrain-field';
23
+ /**
24
+ * The terrain field for a site, or `null` when the site has no sculpted terrain.
25
+ *
26
+ * `null` means flat ground at the datum. It is deliberately not "a flat field":
27
+ * callers use `null` to take their existing flat-ground fast path, which keeps
28
+ * every scene that has never touched terrain — the overwhelming majority —
29
+ * running exactly the code it ran before terrain existed. That property is worth
30
+ * more than the uniformity of always having a field.
31
+ *
32
+ * An in-flight sculpt stroke wins over the persisted data. Resolving that *here*
33
+ * rather than per caller is what makes a stroke consistent: the mesh, the pointer
34
+ * raycast, the placement predicate, the collider, and the 2D view all see the
35
+ * same ground mid-drag without any of them knowing a stroke exists. The
36
+ * alternative — each consumer checking the live store — is how a drag ends up
37
+ * showing a hill the raycast cannot hit.
38
+ */
39
+ export declare function terrainFieldOf(site: (Pick<SiteNode, 'terrain'> & {
40
+ id?: string;
41
+ }) | null | undefined): TerrainField | null;
42
+ /**
43
+ * The field a site *would* sculpt into: its existing terrain, or a fresh flat
44
+ * field sized to `options`.
45
+ *
46
+ * Separate from `terrainFieldOf` because the read path wants `null` for "no
47
+ * terrain" and the write path wants something to write into. Collapsing them
48
+ * would force every reader to allocate a field it does not need.
49
+ */
50
+ export declare function terrainFieldForEdit(site: Pick<SiteNode, 'terrain'> | null | undefined, options?: Parameters<typeof createTerrainField>[0]): TerrainField;
51
+ /**
52
+ * Encode a field for persistence and prime the read cache with it.
53
+ *
54
+ * Call this instead of `encodeTerrainField` whenever the result is going into the
55
+ * scene. The returned data is what to write to `site.terrain`; the cache priming
56
+ * means the very next `terrainFieldOf` on the updated node returns this exact
57
+ * field object without decoding.
58
+ */
59
+ export declare function commitTerrainField(field: TerrainField): TerrainData;
60
+ //# sourceMappingURL=terrain-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain-source.d.ts","sourceRoot":"","sources":["../../src/lib/terrain-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAGpD,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAUvE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GACrE,YAAY,GAAG,IAAI,CAkBrB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,EAClD,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,GACjD,YAAY,CAEd;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAInE"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Scene → `TerrainField`, cached.
3
+ *
4
+ * Every consumer that needs the ground — the mesh builder, the raycast, the
5
+ * placement predicate, the collider, the 2D view — starts here. It exists to
6
+ * solve one problem: the scene stores terrain as base64 (`site.terrain`), and
7
+ * decoding that per frame, or per pointer-move, would be absurd.
8
+ *
9
+ * The cache is a `WeakMap` keyed on the **`TerrainData` object identity**, which
10
+ * is a correct version key because the scene store is immutable-by-convention:
11
+ * `updateNode` produces a new node object with a new `terrain` object, so a
12
+ * changed terrain necessarily misses the cache and a stale entry is unreachable.
13
+ * No invalidation call, no version counter, nothing to forget to bump.
14
+ *
15
+ * `commitTerrainField` closes the loop: it encodes a field *and* primes the cache
16
+ * with the field it just encoded. That is what makes a sculpt stroke free — after
17
+ * the commit, the next read is a cache hit, so a stroke never decodes base64 even
18
+ * once, let alone per dab.
19
+ */
20
+ import useLiveTerrain from '../store/use-live-terrain';
21
+ import { decodeTerrainField, encodeTerrainField } from './terrain-codec';
22
+ import { createTerrainField } from './terrain-field';
23
+ const fieldCache = new WeakMap();
24
+ /**
25
+ * Sites whose `terrain` failed to decode. Prevents re-attempting a doomed decode
26
+ * on every frame — the corrupt-scene path must be cheap, not just survivable.
27
+ */
28
+ const failedDecodes = new WeakSet();
29
+ /**
30
+ * The terrain field for a site, or `null` when the site has no sculpted terrain.
31
+ *
32
+ * `null` means flat ground at the datum. It is deliberately not "a flat field":
33
+ * callers use `null` to take their existing flat-ground fast path, which keeps
34
+ * every scene that has never touched terrain — the overwhelming majority —
35
+ * running exactly the code it ran before terrain existed. That property is worth
36
+ * more than the uniformity of always having a field.
37
+ *
38
+ * An in-flight sculpt stroke wins over the persisted data. Resolving that *here*
39
+ * rather than per caller is what makes a stroke consistent: the mesh, the pointer
40
+ * raycast, the placement predicate, the collider, and the 2D view all see the
41
+ * same ground mid-drag without any of them knowing a stroke exists. The
42
+ * alternative — each consumer checking the live store — is how a drag ends up
43
+ * showing a hill the raycast cannot hit.
44
+ */
45
+ export function terrainFieldOf(site) {
46
+ if (site?.id) {
47
+ const live = useLiveTerrain.getState().fieldOf(site.id);
48
+ if (live)
49
+ return live;
50
+ }
51
+ const data = site?.terrain;
52
+ if (!data)
53
+ return null;
54
+ const cached = fieldCache.get(data);
55
+ if (cached)
56
+ return cached;
57
+ if (failedDecodes.has(data))
58
+ return null;
59
+ const field = decodeTerrainField(data);
60
+ if (!field) {
61
+ failedDecodes.add(data);
62
+ return null;
63
+ }
64
+ fieldCache.set(data, field);
65
+ return field;
66
+ }
67
+ /**
68
+ * The field a site *would* sculpt into: its existing terrain, or a fresh flat
69
+ * field sized to `options`.
70
+ *
71
+ * Separate from `terrainFieldOf` because the read path wants `null` for "no
72
+ * terrain" and the write path wants something to write into. Collapsing them
73
+ * would force every reader to allocate a field it does not need.
74
+ */
75
+ export function terrainFieldForEdit(site, options) {
76
+ return terrainFieldOf(site) ?? createTerrainField(options);
77
+ }
78
+ /**
79
+ * Encode a field for persistence and prime the read cache with it.
80
+ *
81
+ * Call this instead of `encodeTerrainField` whenever the result is going into the
82
+ * scene. The returned data is what to write to `site.terrain`; the cache priming
83
+ * means the very next `terrainFieldOf` on the updated node returns this exact
84
+ * field object without decoding.
85
+ */
86
+ export function commitTerrainField(field) {
87
+ const data = encodeTerrainField(field);
88
+ fieldCache.set(data, field);
89
+ return data;
90
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Terrain as the level base — the third and last place flat ground was assumed.
3
+ *
4
+ * `getFloorPlacedElevation` returns a *lift* added to a node's level-local Y, and
5
+ * two of its `0`-returns mean "supported by the level base". This module is what
6
+ * those two branches call so that "the level base" can mean the sculpted ground
7
+ * instead of the plane `y = 0`. The other `0`-returns are `+0` no-ops for
8
+ * wall/ceiling-attached items, non-`level` parents, and broken graphs; substituting
9
+ * terrain there would lift sconces off walls, so they stay `0` forever.
10
+ *
11
+ * The whole file is pure — nodes in, metres out — which is what lets the stacking
12
+ * matrix be tested per kind without a canvas.
13
+ */
14
+ import type { AnyNode } from '../schema';
15
+ /**
16
+ * World Y of the site datum — the plane terrain heights are measured from.
17
+ *
18
+ * Terrain vertices are absolute world coordinates (the site group renders at the
19
+ * origin and `terrain-geometry` writes `origin + col * spacing` straight into the
20
+ * buffer), so the datum is a constant rather than a site property. It is named
21
+ * because the *comparison* against it is load-bearing, not the value: it is what
22
+ * separates "the ground" from every other horizontal surface in the scene.
23
+ */
24
+ export declare const SITE_DATUM_Y = 0;
25
+ /**
26
+ * How close a surface must sit to the datum to count as the ground.
27
+ *
28
+ * Loose enough to absorb float drift through a level's world matrix, tight enough
29
+ * that a ground slab (5 cm) still reads as a built surface rather than as terrain.
30
+ */
31
+ export declare const SITE_DATUM_EPSILON = 0.0001;
32
+ /** True when a world-space height is the site datum — i.e. the terrain's plane. */
33
+ export declare function isSiteDatum(worldY: number): boolean;
34
+ /**
35
+ * Whether the sculpted ground is what a node on `levelId` stands on — i.e.
36
+ * whether moving the terrain moves that node.
37
+ *
38
+ * Split out of `terrainSupportLift` so the invalidation rule that re-elevates
39
+ * nodes after a sculpt (`markTerrainSupportDependents`) tests grade-ness with
40
+ * the *same* predicate the resolver does. Two copies of this test would drift,
41
+ * and the failure is silent: a level the resolver drapes but the dirty rule
42
+ * skips leaves its contents frozen at the height the ground used to be.
43
+ *
44
+ * Deliberately independent of whether a field exists. A stroke that clears the
45
+ * terrain has to re-elevate exactly the nodes a stroke that creates it does, and
46
+ * asking about the field here would mark none of them on the way back down.
47
+ */
48
+ export declare function isLevelAtSiteDatum(nodes: Record<string, AnyNode>, levelId: string): boolean;
49
+ /**
50
+ * The lift, in level-local metres, that the sculpted ground provides to a node on
51
+ * `levelId` at level-local `x`/`z`. Null when terrain does not support this node —
52
+ * no sculpted ground, an unresolvable level, or a storey whose floor is not at
53
+ * grade.
54
+ *
55
+ * Null rather than 0 so callers keep their existing flat-ground path verbatim.
56
+ * That is what makes this change invisible to every scene that never touched
57
+ * terrain, which is nearly all of them.
58
+ */
59
+ export declare function terrainSupportLift(nodes: Record<string, AnyNode>, levelId: string, x: number, z: number): number | null;
60
+ //# sourceMappingURL=terrain-support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain-support.d.ts","sourceRoot":"","sources":["../../src/lib/terrain-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,WAAW,CAAA;AAOnD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,IAAI,CAAA;AAE7B;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,SAAO,CAAA;AAEtC,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAqFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3F;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,MAAM,EACf,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,MAAM,GAAG,IAAI,CAYf"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Terrain as the level base — the third and last place flat ground was assumed.
3
+ *
4
+ * `getFloorPlacedElevation` returns a *lift* added to a node's level-local Y, and
5
+ * two of its `0`-returns mean "supported by the level base". This module is what
6
+ * those two branches call so that "the level base" can mean the sculpted ground
7
+ * instead of the plane `y = 0`. The other `0`-returns are `+0` no-ops for
8
+ * wall/ceiling-attached items, non-`level` parents, and broken graphs; substituting
9
+ * terrain there would lift sconces off walls, so they stay `0` forever.
10
+ *
11
+ * The whole file is pure — nodes in, metres out — which is what lets the stacking
12
+ * matrix be tested per kind without a canvas.
13
+ */
14
+ import { getLevelElevations } from '../services/storey';
15
+ import { heightAt } from './terrain-field';
16
+ import { terrainFieldOf } from './terrain-source';
17
+ /**
18
+ * World Y of the site datum — the plane terrain heights are measured from.
19
+ *
20
+ * Terrain vertices are absolute world coordinates (the site group renders at the
21
+ * origin and `terrain-geometry` writes `origin + col * spacing` straight into the
22
+ * buffer), so the datum is a constant rather than a site property. It is named
23
+ * because the *comparison* against it is load-bearing, not the value: it is what
24
+ * separates "the ground" from every other horizontal surface in the scene.
25
+ */
26
+ export const SITE_DATUM_Y = 0;
27
+ /**
28
+ * How close a surface must sit to the datum to count as the ground.
29
+ *
30
+ * Loose enough to absorb float drift through a level's world matrix, tight enough
31
+ * that a ground slab (5 cm) still reads as a built surface rather than as terrain.
32
+ */
33
+ export const SITE_DATUM_EPSILON = 1e-4;
34
+ /** True when a world-space height is the site datum — i.e. the terrain's plane. */
35
+ export function isSiteDatum(worldY) {
36
+ return Math.abs(worldY - SITE_DATUM_Y) < SITE_DATUM_EPSILON;
37
+ }
38
+ /**
39
+ * `getLevelElevations` memoized on the `nodes` record identity.
40
+ *
41
+ * Without this the stacking resolver is O(N) per node and therefore O(N²) per
42
+ * frame, since `FloorElevationSystem` calls it for every dirty floor-placed node.
43
+ * The scene store is immutable-by-convention, so the record identity is a correct
44
+ * version key — the same reasoning (and the same `WeakMap` shape) as
45
+ * `terrain-source`'s field cache and the spatial grid's `levelWallsCache`.
46
+ */
47
+ const levelElevationCache = new WeakMap();
48
+ function cachedLevelElevations(nodes) {
49
+ const cached = levelElevationCache.get(nodes);
50
+ if (cached)
51
+ return cached;
52
+ const elevations = getLevelElevations(nodes);
53
+ levelElevationCache.set(nodes, elevations);
54
+ return elevations;
55
+ }
56
+ function siteOf(nodes) {
57
+ for (const node of Object.values(nodes)) {
58
+ if (node?.type === 'site')
59
+ return node;
60
+ }
61
+ return null;
62
+ }
63
+ /**
64
+ * Level-local XZ → world XZ, through the building's transform.
65
+ *
66
+ * A level group carries only a Y offset (`LevelSystem` writes `position.y` and
67
+ * nothing else), so level-local XZ is building-local XZ; the building carries the
68
+ * site-space placement, and the site renders at the origin. Only the Y rotation
69
+ * matters — a building tipped in X or Z is not a thing the editor can produce.
70
+ */
71
+ function levelLocalToWorldXZ(building, x, z) {
72
+ if (!building)
73
+ return [x, z];
74
+ const angle = building.rotation?.[1] ?? 0;
75
+ const [px, , pz] = building.position ?? [0, 0, 0];
76
+ if (angle === 0)
77
+ return [x + px, z + pz];
78
+ const cos = Math.cos(angle);
79
+ const sin = Math.sin(angle);
80
+ return [cos * x + sin * z + px, -sin * x + cos * z + pz];
81
+ }
82
+ /**
83
+ * Where a level sits relative to the datum, for the levels terrain can support.
84
+ *
85
+ * **Only the storey the level stack puts at the datum follows terrain.** An upper
86
+ * storey has a real floor, and draping it would sink its contents into the
87
+ * hillside under the building. The test is that storey's own base height against
88
+ * the datum — deliberately asked of `getLevelElevations`, the same function the
89
+ * renderer positions level groups with, so placement can never hold a second
90
+ * opinion about which storey is on the ground.
91
+ *
92
+ * Which storey that is follows from the stack, not from the ordinal: today the
93
+ * lowest ordinal anchors at 0, so a building with an ordinal `-1` level has *that*
94
+ * level at grade and its ground floor a storey up. When genuine below-grade
95
+ * stacking lands, this rule tracks it with no change here — an excavated basement
96
+ * will stop being at the datum, and stop being draped, on its own.
97
+ */
98
+ function levelDatum(nodes, levelId) {
99
+ const elevation = cachedLevelElevations(nodes).get(levelId);
100
+ if (!elevation)
101
+ return null;
102
+ const building = elevation.buildingId
103
+ ? (nodes[elevation.buildingId] ?? null)
104
+ : null;
105
+ const datum = building?.position?.[1] ?? 0;
106
+ const baseWorldY = datum + elevation.baseY;
107
+ if (!isSiteDatum(baseWorldY))
108
+ return null;
109
+ return { building, baseWorldY };
110
+ }
111
+ /**
112
+ * Whether the sculpted ground is what a node on `levelId` stands on — i.e.
113
+ * whether moving the terrain moves that node.
114
+ *
115
+ * Split out of `terrainSupportLift` so the invalidation rule that re-elevates
116
+ * nodes after a sculpt (`markTerrainSupportDependents`) tests grade-ness with
117
+ * the *same* predicate the resolver does. Two copies of this test would drift,
118
+ * and the failure is silent: a level the resolver drapes but the dirty rule
119
+ * skips leaves its contents frozen at the height the ground used to be.
120
+ *
121
+ * Deliberately independent of whether a field exists. A stroke that clears the
122
+ * terrain has to re-elevate exactly the nodes a stroke that creates it does, and
123
+ * asking about the field here would mark none of them on the way back down.
124
+ */
125
+ export function isLevelAtSiteDatum(nodes, levelId) {
126
+ return levelDatum(nodes, levelId) !== null;
127
+ }
128
+ /**
129
+ * The lift, in level-local metres, that the sculpted ground provides to a node on
130
+ * `levelId` at level-local `x`/`z`. Null when terrain does not support this node —
131
+ * no sculpted ground, an unresolvable level, or a storey whose floor is not at
132
+ * grade.
133
+ *
134
+ * Null rather than 0 so callers keep their existing flat-ground path verbatim.
135
+ * That is what makes this change invisible to every scene that never touched
136
+ * terrain, which is nearly all of them.
137
+ */
138
+ export function terrainSupportLift(nodes, levelId, x, z) {
139
+ const site = siteOf(nodes);
140
+ const field = site ? terrainFieldOf(site) : null;
141
+ if (!field)
142
+ return null;
143
+ const datum = levelDatum(nodes, levelId);
144
+ if (!datum)
145
+ return null;
146
+ const [worldX, worldZ] = levelLocalToWorldXZ(datum.building, x, z);
147
+ // The lift is measured from the storey's own base, so a building sited on a
148
+ // datum other than 0 does not double-count it.
149
+ return heightAt(field, worldX, worldZ) - datum.baseWorldY;
150
+ }
@@ -17,5 +17,5 @@ export type ZoneQuantityReport = {
17
17
  floorSurface: ZoneQuantityValue;
18
18
  volume: ZoneQuantityValue;
19
19
  };
20
- export declare function deriveZoneQuantityReport(zone: ZoneNode, sceneNodes: Record<string, AnyNode>): ZoneQuantityReport;
20
+ export declare function deriveZoneQuantityReport(zone: ZoneNode, sceneNodes: Readonly<Record<string, AnyNode>>): ZoneQuantityReport;
21
21
  //# sourceMappingURL=zone-quantities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zone-quantities.d.ts","sourceRoot":"","sources":["../../src/lib/zone-quantities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAmC,QAAQ,EAAE,MAAM,WAAW,CAAA;AAOnF,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,cAAc,EAAE,WAAW,GAAG,eAAe,CAAA;IAC7C,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,WAAW,EAAE,iBAAiB,CAAA;IAC9B,YAAY,EAAE,iBAAiB,CAAA;IAC/B,MAAM,EAAE,iBAAiB,CAAA;CAC1B,CAAA;AA2HD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,kBAAkB,CA2GpB"}
1
+ {"version":3,"file":"zone-quantities.d.ts","sourceRoot":"","sources":["../../src/lib/zone-quantities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAmC,QAAQ,EAAE,MAAM,WAAW,CAAA;AAYnF,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,cAAc,EAAE,WAAW,GAAG,eAAe,CAAA;IAC7C,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,WAAW,EAAE,iBAAiB,CAAA;IAC9B,YAAY,EAAE,iBAAiB,CAAA;IAC/B,MAAM,EAAE,iBAAiB,CAAA;CAC1B,CAAA;AA8bD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC5C,kBAAkB,CAmGpB"}