@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
@@ -1,134 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
2
- import { ALLOWED_ORIGINS_ENV, AssetUrl } from './asset-url';
3
- function isValid(url) {
4
- return AssetUrl.safeParse(url).success;
5
- }
6
- describe('AssetUrl', () => {
7
- describe('allowed URLs', () => {
8
- const cases = [
9
- ['asset://abc', 'internal asset handle'],
10
- ['asset://catalog/items/chair-1', 'nested asset handle'],
11
- ['blob:http://example.com/uuid-1234', 'blob URL with http inner'],
12
- ['blob:https://example.com/uuid-5678', 'blob URL with https inner'],
13
- ['https://cdn.example.com/a.glb', 'https CDN URL'],
14
- ['https://cdn.example.com/models/chair.glb?v=2', 'https URL with query string'],
15
- ['http://localhost:3000/x', 'http localhost with port'],
16
- ['http://localhost/x', 'http localhost without port'],
17
- ['http://127.0.0.1:8080/texture.png', 'http 127.0.0.1 loopback'],
18
- ['/public/a.glb', 'app-relative path'],
19
- ['/material/wood1/albedoMap_basecolor.jpg', 'relative path deep'],
20
- ['data:image/png;base64,AAA', 'inline PNG data URL'],
21
- ['data:image/jpeg;base64,/9j/', 'inline JPEG data URL'],
22
- ['data:image/webp;base64,UklGR', 'inline WebP data URL'],
23
- ['data:image/svg+xml,%3Csvg%3E', 'inline SVG data URL'],
24
- ];
25
- for (const [url, label] of cases) {
26
- test(`accepts ${label}: ${url}`, () => {
27
- expect(isValid(url)).toBe(true);
28
- });
29
- }
30
- });
31
- describe('rejected URLs', () => {
32
- const cases = [
33
- ['javascript:alert(1)', 'javascript scheme'],
34
- ['JAVASCRIPT:alert(1)', 'javascript scheme uppercase'],
35
- ['file:///etc/passwd', 'file scheme'],
36
- ['file://C:/Windows/System32/config', 'file scheme Windows'],
37
- ['http://evil.com/', 'non-loopback http'],
38
- ['http://example.com:3000/x', 'http on non-loopback host'],
39
- ['http://169.254.169.254/latest/meta-data/', 'http on link-local (cloud metadata)'],
40
- ['data:text/html,<script>alert(1)</script>', 'data text/html'],
41
- ['data:application/javascript,alert(1)', 'data application/javascript'],
42
- ['data:text/plain,hi', 'data text/plain'],
43
- ['ftp://a.b.com', 'ftp scheme'],
44
- ['ws://example.com/', 'websocket scheme'],
45
- ['vbscript:msgbox', 'vbscript scheme'],
46
- ['', 'empty string'],
47
- ['not a url at all', 'non-url string'],
48
- ['://missing-scheme', 'malformed'],
49
- ];
50
- for (const [url, label] of cases) {
51
- test(`rejects ${label}: ${url}`, () => {
52
- expect(isValid(url)).toBe(false);
53
- });
54
- }
55
- });
56
- describe(`env allowlist via ${ALLOWED_ORIGINS_ENV}`, () => {
57
- const g = globalThis;
58
- const original = g.process?.env?.[ALLOWED_ORIGINS_ENV];
59
- beforeEach(() => {
60
- if (g.process?.env)
61
- delete g.process.env[ALLOWED_ORIGINS_ENV];
62
- });
63
- afterEach(() => {
64
- if (!g.process?.env)
65
- return;
66
- if (original === undefined) {
67
- delete g.process.env[ALLOWED_ORIGINS_ENV];
68
- }
69
- else {
70
- g.process.env[ALLOWED_ORIGINS_ENV] = original;
71
- }
72
- });
73
- test('single origin allowlist accepts matching https URL', () => {
74
- if (!g.process?.env)
75
- return; // browser-only runtime
76
- g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
77
- expect(isValid('https://cdn.pascal.app/a.glb')).toBe(true);
78
- expect(isValid('https://cdn.pascal.app/deep/path?q=1')).toBe(true);
79
- });
80
- test('single origin allowlist rejects non-matching https URL', () => {
81
- if (!g.process?.env)
82
- return;
83
- g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
84
- expect(isValid('https://cdn.other.com/a.glb')).toBe(false);
85
- expect(isValid('https://attacker.example.com/x')).toBe(false);
86
- });
87
- test('multi-origin allowlist accepts any listed origin', () => {
88
- if (!g.process?.env)
89
- return;
90
- g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app, https://assets.pascal.app';
91
- expect(isValid('https://cdn.pascal.app/a.glb')).toBe(true);
92
- expect(isValid('https://assets.pascal.app/tex.webp')).toBe(true);
93
- expect(isValid('https://third.example.com/x')).toBe(false);
94
- });
95
- test('allowlist ignores trailing / in URL path (origin match only)', () => {
96
- if (!g.process?.env)
97
- return;
98
- g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
99
- expect(isValid('https://cdn.pascal.app/')).toBe(true);
100
- expect(isValid('https://cdn.pascal.app')).toBe(true);
101
- });
102
- test('empty allowlist behaves like unset', () => {
103
- if (!g.process?.env)
104
- return;
105
- g.process.env[ALLOWED_ORIGINS_ENV] = '';
106
- expect(isValid('https://cdn.other.com/a.glb')).toBe(true);
107
- });
108
- test('allowlist does not restrict non-https schemes', () => {
109
- if (!g.process?.env)
110
- return;
111
- g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
112
- // these should still pass because they match earlier scheme-based branches
113
- expect(isValid('asset://x')).toBe(true);
114
- expect(isValid('blob:https://example.com/abc')).toBe(true);
115
- expect(isValid('data:image/png;base64,AAA')).toBe(true);
116
- expect(isValid('/public/a.glb')).toBe(true);
117
- expect(isValid('http://localhost:3000/x')).toBe(true);
118
- });
119
- test('allowlist rejects subdomain spoofing', () => {
120
- if (!g.process?.env)
121
- return;
122
- g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
123
- expect(isValid('https://cdn.pascal.app.evil.com/x')).toBe(false);
124
- expect(isValid('https://evil.com/cdn.pascal.app')).toBe(false);
125
- });
126
- test('allowlist respects ports', () => {
127
- if (!g.process?.env)
128
- return;
129
- g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app:8443';
130
- expect(isValid('https://cdn.pascal.app:8443/x')).toBe(true);
131
- expect(isValid('https://cdn.pascal.app/x')).toBe(false);
132
- });
133
- });
134
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=material.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"material.test.d.ts","sourceRoot":"","sources":["../../src/schema/material.test.ts"],"names":[],"mappings":""}
@@ -1,43 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { MaterialSchema } from './material';
3
- describe('MaterialSchema', () => {
4
- describe('preset', () => {
5
- test('valid preset passes through unchanged', () => {
6
- const result = MaterialSchema.parse({ preset: 'brick' });
7
- expect(result.preset).toBe('brick');
8
- });
9
- test('every enum preset is accepted', () => {
10
- const presets = [
11
- 'white',
12
- 'brick',
13
- 'concrete',
14
- 'wood',
15
- 'glass',
16
- 'metal',
17
- 'plaster',
18
- 'tile',
19
- 'marble',
20
- 'custom',
21
- ];
22
- for (const preset of presets) {
23
- expect(MaterialSchema.parse({ preset }).preset).toBe(preset);
24
- }
25
- });
26
- test("unknown preset coerces to 'custom' instead of throwing (Sentry MONOREPO-EDITOR-DB)", () => {
27
- const result = MaterialSchema.parse({ preset: 'stone' });
28
- expect(result.preset).toBe('custom');
29
- });
30
- test("non-string preset coerces to 'custom'", () => {
31
- const result = MaterialSchema.parse({ preset: 42 });
32
- expect(result.preset).toBe('custom');
33
- });
34
- test('missing preset stays undefined', () => {
35
- const result = MaterialSchema.parse({});
36
- expect(result.preset).toBeUndefined();
37
- });
38
- test('explicit undefined preset stays undefined', () => {
39
- const result = MaterialSchema.parse({ preset: undefined });
40
- expect(result.preset).toBeUndefined();
41
- });
42
- });
43
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=measurement.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"measurement.test.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/measurement.test.ts"],"names":[],"mappings":""}
@@ -1,139 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { MeasurementNode } from './measurement';
3
- const parseMeasurement = (measurement) => MeasurementNode.safeParse({
4
- id: 'measurement_test',
5
- type: 'measurement',
6
- measurement,
7
- });
8
- describe('MeasurementNode', () => {
9
- test('accepts exactly two finite distance points', () => {
10
- expect(parseMeasurement({
11
- kind: 'distance',
12
- points: [
13
- [0, 1, 2],
14
- [3, 4, 5],
15
- ],
16
- }).success).toBe(true);
17
- expect(parseMeasurement({
18
- kind: 'distance',
19
- points: [
20
- [0, 1, 2],
21
- [3, 4, 5],
22
- [6, 7, 8],
23
- ],
24
- }).success).toBe(false);
25
- expect(parseMeasurement({
26
- kind: 'distance',
27
- points: [
28
- [0, 1, 2],
29
- [Number.POSITIVE_INFINITY, 4, 5],
30
- ],
31
- }).success).toBe(false);
32
- });
33
- test('accepts semantic feature anchors with finite fallbacks', () => {
34
- expect(parseMeasurement({
35
- kind: 'distance',
36
- points: [
37
- {
38
- kind: 'feature',
39
- reference: {
40
- nodeId: 'wall_a',
41
- featureId: 'wall:centerline',
42
- parameters: { t: 0.25, side: 'center' },
43
- },
44
- fallback: [1, 0, 2],
45
- },
46
- [3, 0, 2],
47
- ],
48
- }).success).toBe(true);
49
- });
50
- test('accepts angle and perimeter measurements', () => {
51
- expect(parseMeasurement({
52
- kind: 'angle',
53
- points: [
54
- [1, 0, 0],
55
- [0, 0, 0],
56
- [0, 0, 1],
57
- ],
58
- }).success).toBe(true);
59
- expect(parseMeasurement({
60
- kind: 'perimeter',
61
- base: [
62
- [0, 0, 0],
63
- [1, 0, 0],
64
- [0, 0, 1],
65
- ],
66
- }).success).toBe(true);
67
- });
68
- test('requires at least three area base points', () => {
69
- expect(parseMeasurement({
70
- kind: 'area',
71
- base: [
72
- [0, 0, 0],
73
- [1, 0, 0],
74
- [0, 0, 1],
75
- ],
76
- }).success).toBe(true);
77
- expect(parseMeasurement({
78
- kind: 'area',
79
- base: [
80
- [0, 0, 0],
81
- [1, 0, 0],
82
- ],
83
- }).success).toBe(false);
84
- expect(parseMeasurement({
85
- kind: 'area',
86
- base: [
87
- [0, 0, 0],
88
- [1, 0, 0],
89
- [2, 0, 0],
90
- ],
91
- }).success).toBe(false);
92
- expect(parseMeasurement({
93
- kind: 'area',
94
- base: [
95
- [0, 0, 0],
96
- [1, 0, 0],
97
- [1, 0, 1],
98
- [0, 0.1, 1],
99
- ],
100
- }).success).toBe(false);
101
- });
102
- test('requires a finite extrusion and at least three volume base points', () => {
103
- expect(parseMeasurement({
104
- kind: 'volume',
105
- base: [
106
- [0, 0, 0],
107
- [1, 0, 0],
108
- [0, 0, 1],
109
- ],
110
- extrusion: [0, 2, 0],
111
- }).success).toBe(true);
112
- expect(parseMeasurement({
113
- kind: 'volume',
114
- base: [
115
- [0, 0, 0],
116
- [1, 0, 0],
117
- ],
118
- extrusion: [0, 2, 0],
119
- }).success).toBe(false);
120
- expect(parseMeasurement({
121
- kind: 'volume',
122
- base: [
123
- [0, 0, 0],
124
- [1, 0, 0],
125
- [0, 0, 1],
126
- ],
127
- extrusion: [0, Number.NaN, 0],
128
- }).success).toBe(false);
129
- expect(parseMeasurement({
130
- kind: 'volume',
131
- base: [
132
- [0, 0, 0],
133
- [1, 0, 0],
134
- [0, 0, 1],
135
- ],
136
- extrusion: [2, 0, 0],
137
- }).success).toBe(false);
138
- });
139
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ridge-vent-defaults.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ridge-vent-defaults.test.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/ridge-vent-defaults.test.ts"],"names":[],"mappings":""}
@@ -1,205 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { createDefaultRidgeVentsForSegment, getRidgeVentLinesForSegment, isAutoRidgeVentEnabled, isDefaultRidgeVentNode, RidgeVentNode, } from './ridge-vent';
3
- import { getDutchRoofMetrics, getRoofSegmentVisibleTopBounds, ROOF_SHAPE_DEFAULTS, RoofSegmentNode, } from './roof-segment';
4
- describe('createDefaultRidgeVentsForSegment', () => {
5
- test('creates one shingled default ridge vent for gable roofs', () => {
6
- const segment = RoofSegmentNode.parse({
7
- roofType: 'gable',
8
- width: 8,
9
- depth: 6,
10
- });
11
- const vents = createDefaultRidgeVentsForSegment(segment);
12
- expect(vents).toHaveLength(1);
13
- expect(vents[0]?.name).toBe('Ridge Vent');
14
- expect(vents[0]?.style).toBe('shingled');
15
- expect(vents[0]?.roofSegmentId).toBe(segment.id);
16
- expect(isDefaultRidgeVentNode(vents[0], segment.id)).toBe(true);
17
- });
18
- test('keeps generated gable ridge vents anchored to the untrimmed ridge', () => {
19
- const segment = RoofSegmentNode.parse({
20
- roofType: 'gable',
21
- width: 8,
22
- depth: 6,
23
- overhang: 0,
24
- wallThickness: 0,
25
- shingleThickness: 0,
26
- trim: { left: 1, right: 2, front: 0, back: 0 },
27
- });
28
- const vents = createDefaultRidgeVentsForSegment(segment);
29
- expect(vents).toHaveLength(1);
30
- expect(vents[0]?.length).toBeCloseTo(8);
31
- expect(vents[0]?.position[0]).toBeCloseTo(0);
32
- });
33
- test('creates top ridge plus four hip vents for rectangular hip roofs', () => {
34
- const segment = RoofSegmentNode.parse({
35
- roofType: 'hip',
36
- width: 8,
37
- depth: 6,
38
- });
39
- const vents = createDefaultRidgeVentsForSegment(segment);
40
- expect(vents).toHaveLength(5);
41
- expect(vents.filter((vent) => vent.name === 'Ridge Vent')).toHaveLength(1);
42
- expect(vents.filter((vent) => vent.name === 'Hip Ridge Vent')).toHaveLength(4);
43
- for (const vent of vents) {
44
- expect(vent.style).toBe('shingled');
45
- expect(vent.length).toBeGreaterThan(0.4);
46
- expect(isDefaultRidgeVentNode(vent, segment.id)).toBe(true);
47
- }
48
- });
49
- test('omits the collapsed top ridge on square hip roofs', () => {
50
- const segment = RoofSegmentNode.parse({
51
- roofType: 'hip',
52
- width: 6,
53
- depth: 6,
54
- });
55
- const vents = createDefaultRidgeVentsForSegment(segment);
56
- expect(vents).toHaveLength(4);
57
- expect(vents.every((vent) => vent.name === 'Hip Ridge Vent')).toBe(true);
58
- });
59
- test('creates a top ridge plus four hip vents for width-axis Dutch roofs', () => {
60
- const segment = RoofSegmentNode.parse({
61
- roofType: 'dutch',
62
- width: 8,
63
- depth: 6,
64
- overhang: 0,
65
- wallThickness: 0,
66
- shingleThickness: 0,
67
- });
68
- const vents = createDefaultRidgeVentsForSegment(segment);
69
- expect(vents.filter((vent) => vent.name === 'Ridge Vent')).toHaveLength(1);
70
- expect(vents.filter((vent) => vent.name === 'Hip Ridge Vent')).toHaveLength(4);
71
- // Width-axis Dutch ridge runs along X (constant Z = 0).
72
- const metrics = getDutchRoofMetrics(segment);
73
- const ridge = vents.find((vent) => vent.name === 'Ridge Vent');
74
- const frontRightHip = vents.find((vent) => vent.name === 'Hip Ridge Vent' &&
75
- (vent.position[0] ?? 0) > 0 &&
76
- (vent.position[2] ?? 0) > 0);
77
- const expectedRakeReach = Math.min(segment.dutchGabletRake, Math.max(0, segment.width / 2 - metrics.waistHalfX) * 0.98);
78
- expect(ridge?.position[2]).toBeCloseTo(0);
79
- expect(ridge?.length).toBeCloseTo((metrics.waistHalfX + expectedRakeReach) * 2, 2);
80
- expect(frontRightHip?.position[0]).toBeCloseTo((4 + 2.93) / 2, 2);
81
- expect(frontRightHip?.position[2]).toBeCloseTo((3 + 1.5) / 2, 2);
82
- for (const vent of vents) {
83
- expect(vent.style).toBe('shingled');
84
- expect(vent.length).toBeGreaterThan(0.4);
85
- expect(isDefaultRidgeVentNode(vent, segment.id)).toBe(true);
86
- }
87
- });
88
- test('treats legacy segments with generated ridge vents as auto-enabled', () => {
89
- const segment = RoofSegmentNode.parse({
90
- roofType: 'gable',
91
- width: 8,
92
- depth: 6,
93
- });
94
- const vents = createDefaultRidgeVentsForSegment(segment);
95
- const nodes = Object.fromEntries(vents.map((vent) => [vent.id, vent]));
96
- expect(isAutoRidgeVentEnabled({
97
- id: segment.id,
98
- children: vents.map((vent) => vent.id),
99
- metadata: {},
100
- }, nodes)).toBe(true);
101
- });
102
- test('treats legacy preset-white ridge vents as generated defaults', () => {
103
- const segment = RoofSegmentNode.parse({
104
- id: 'rseg_test',
105
- roofType: 'gable',
106
- width: 8,
107
- depth: 6,
108
- });
109
- const legacyVent = RidgeVentNode.parse({
110
- id: 'rvent_legacy',
111
- roofSegmentId: segment.id,
112
- name: 'Ridge Vent',
113
- style: 'shingled',
114
- materialPreset: 'preset-white',
115
- position: [0, 0, 0],
116
- length: 8,
117
- });
118
- expect(isDefaultRidgeVentNode(legacyVent, segment.id)).toBe(true);
119
- });
120
- test('creates a Z-oriented ridge plus four hip lines for depth-axis Dutch roofs', () => {
121
- const segment = RoofSegmentNode.parse({
122
- roofType: 'dutch',
123
- width: 6,
124
- depth: 8,
125
- overhang: 0,
126
- wallThickness: 0,
127
- shingleThickness: 0,
128
- });
129
- const lines = getRidgeVentLinesForSegment(segment);
130
- const metrics = getDutchRoofMetrics(segment);
131
- const expectedRakeReach = Math.min(segment.dutchGabletRake, Math.max(0, segment.depth / 2 - metrics.waistHalfZ) * 0.98);
132
- const ridges = lines.filter((line) => line.name === 'Ridge Vent');
133
- const hips = lines.filter((line) => line.name === 'Hip Ridge Vent');
134
- expect(ridges).toHaveLength(1);
135
- expect(hips).toHaveLength(4);
136
- // Depth-axis Dutch ridge runs along Z (constant X = 0).
137
- expect(ridges[0]?.start[0]).toBeCloseTo(0);
138
- expect(ridges[0]?.end[0]).toBeCloseTo(0);
139
- expect(Math.abs(ridges[0]?.start[1] ?? 0)).toBeCloseTo(metrics.waistHalfZ + expectedRakeReach, 2);
140
- });
141
- test('keeps Dutch hip lines on the rendered arris when the roof has overhang', () => {
142
- // Overhang + shingle thickness expand the rendered roof; the eave corners
143
- // and the waist must share that expanded frame, otherwise the hip lines
144
- // tilt off the arris and the vents sink into the slope.
145
- const segment = RoofSegmentNode.parse({
146
- roofType: 'dutch',
147
- width: 8,
148
- depth: 6,
149
- overhang: 0.5,
150
- wallThickness: 0.2,
151
- shingleThickness: 0.05,
152
- });
153
- const lines = getRidgeVentLinesForSegment(segment);
154
- const hips = lines.filter((line) => line.name === 'Hip Ridge Vent');
155
- const ridge = lines.find((line) => line.name === 'Ridge Vent');
156
- expect(hips).toHaveLength(4);
157
- expect(ridge).toBeDefined();
158
- const bounds = getRoofSegmentVisibleTopBounds(segment);
159
- const { axis, inset } = getDutchRoofMetrics(segment);
160
- const waistLengthRatio = segment.dutchWaistLengthRatio;
161
- // width 8 >= depth 6 -> axis 'x': the ridge runs along X (waist scaled by
162
- // waistLengthRatio), and Z is the clean hipped axis (inset exactly).
163
- expect(axis).toBe('x');
164
- const halfWExpanded = bounds.maxX;
165
- const halfDExpanded = bounds.maxZ;
166
- const expectedWaistX = (halfWExpanded - inset) * waistLengthRatio;
167
- const expectedWaistZ = halfDExpanded - inset;
168
- const expectedRakeReach = Math.min(segment.dutchGabletRake ?? ROOF_SHAPE_DEFAULTS.dutchGabletRake, Math.max(0, halfWExpanded - expectedWaistX) * 0.98);
169
- for (const hip of hips) {
170
- const [ex, ez] = hip.start;
171
- const [wx, wz] = hip.end;
172
- // Eave end on an expanded-bounds corner; upper end at the rendered rake
173
- // termination where the lower slope starts, derived from the SAME
174
- // expanded frame (not the base-dim inner waist).
175
- expect(Math.abs(ex)).toBeCloseTo(halfWExpanded);
176
- expect(Math.abs(ez)).toBeCloseTo(halfDExpanded);
177
- expect(Math.abs(wx)).toBeCloseTo(expectedWaistX + expectedRakeReach);
178
- expect(Math.abs(wz)).toBeCloseTo(expectedWaistZ);
179
- }
180
- });
181
- test('creates top ridge plus four upper hip vents plus four lower-slope vents for mansard roofs', () => {
182
- const segment = RoofSegmentNode.parse({
183
- roofType: 'mansard',
184
- width: 8,
185
- depth: 6,
186
- });
187
- const vents = createDefaultRidgeVentsForSegment(segment);
188
- expect(vents).toHaveLength(9);
189
- expect(vents.filter((vent) => vent.name === 'Ridge Vent')).toHaveLength(1);
190
- expect(vents.filter((vent) => vent.name === 'Hip Ridge Vent')).toHaveLength(4);
191
- expect(vents.filter((vent) => vent.name === 'Slope Ridge Vent')).toHaveLength(4);
192
- expect(vents.find((vent) => vent.name === 'Ridge Vent')?.length).toBeLessThan(segment.width);
193
- const slopeVents = vents.filter((vent) => vent.name === 'Slope Ridge Vent');
194
- const slopeRotations = slopeVents.map((vent) => Math.abs(vent.rotation));
195
- expect(slopeRotations.every((rotation) => rotation > 0.1)).toBe(true);
196
- expect(slopeRotations.every((rotation) => Math.abs(rotation - Math.PI / 2) > 0.1)).toBe(true);
197
- expect(slopeVents.every((vent) => Math.abs(vent.position[0]) > segment.width / 2 - 0.8 &&
198
- Math.abs(vent.position[2]) > segment.depth / 2 - 0.8)).toBe(true);
199
- expect(new Set(slopeVents.map((vent) => `${Math.sign(vent.position[0])},${Math.sign(vent.position[2])}`)).size).toBe(4);
200
- for (const vent of vents) {
201
- expect(vent.style).toBe('shingled');
202
- expect(isDefaultRidgeVentNode(vent, segment.id)).toBe(true);
203
- }
204
- });
205
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=roof-segment-shape.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"roof-segment-shape.test.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/roof-segment-shape.test.ts"],"names":[],"mappings":""}