@faicad/faijs 0.22.2 → 0.29.5

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 (488) hide show
  1. package/LICENSE +202 -28
  2. package/dist/api/api-namespace.d.ts +5 -5
  3. package/dist/api/api-namespace.d.ts.map +1 -1
  4. package/dist/api/api-namespace.js +4 -4
  5. package/dist/api/api-namespace.js.map +1 -1
  6. package/dist/api/appearance.d.ts +138 -0
  7. package/dist/api/appearance.d.ts.map +1 -0
  8. package/dist/api/appearance.js +230 -0
  9. package/dist/api/appearance.js.map +1 -0
  10. package/dist/api/assert.d.ts +2 -2
  11. package/dist/api/assert.js +8 -8
  12. package/dist/api/assert.js.map +1 -1
  13. package/dist/api/asset.d.ts +1 -1
  14. package/dist/api/asset.js +2 -2
  15. package/dist/api/asset.js.map +1 -1
  16. package/dist/api/boolean.d.ts +1 -1
  17. package/dist/api/boolean.d.ts.map +1 -1
  18. package/dist/api/boolean.js +128 -16
  19. package/dist/api/boolean.js.map +1 -1
  20. package/dist/api/cadquery-selectors/borrow-bridge.d.ts +14 -0
  21. package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -0
  22. package/dist/api/cadquery-selectors/borrow-bridge.js +52 -0
  23. package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -0
  24. package/dist/api/cadquery-selectors/edge.d.ts +40 -0
  25. package/dist/api/cadquery-selectors/edge.d.ts.map +1 -0
  26. package/dist/api/cadquery-selectors/edge.js +70 -0
  27. package/dist/api/cadquery-selectors/edge.js.map +1 -0
  28. package/dist/api/cadquery-selectors/entity.d.ts +121 -0
  29. package/dist/api/cadquery-selectors/entity.d.ts.map +1 -0
  30. package/dist/api/cadquery-selectors/entity.js +167 -0
  31. package/dist/api/cadquery-selectors/entity.js.map +1 -0
  32. package/dist/api/cadquery-selectors/face.d.ts +33 -0
  33. package/dist/api/cadquery-selectors/face.d.ts.map +1 -0
  34. package/dist/api/cadquery-selectors/face.js +353 -0
  35. package/dist/api/cadquery-selectors/face.js.map +1 -0
  36. package/dist/api/cadquery-selectors/grammar.d.ts +50 -0
  37. package/dist/api/cadquery-selectors/grammar.d.ts.map +1 -0
  38. package/dist/api/cadquery-selectors/grammar.js +345 -0
  39. package/dist/api/cadquery-selectors/grammar.js.map +1 -0
  40. package/dist/api/cadquery-selectors/index.d.ts +18 -0
  41. package/dist/api/cadquery-selectors/index.d.ts.map +1 -0
  42. package/dist/api/cadquery-selectors/index.js +17 -0
  43. package/dist/api/cadquery-selectors/index.js.map +1 -0
  44. package/dist/api/cadquery-selectors/predicates.d.ts +76 -0
  45. package/dist/api/cadquery-selectors/predicates.d.ts.map +1 -0
  46. package/dist/api/cadquery-selectors/predicates.js +85 -0
  47. package/dist/api/cadquery-selectors/predicates.js.map +1 -0
  48. package/dist/api/cadquery-selectors/resolve.d.ts +41 -0
  49. package/dist/api/cadquery-selectors/resolve.d.ts.map +1 -0
  50. package/dist/api/cadquery-selectors/resolve.js +243 -0
  51. package/dist/api/cadquery-selectors/resolve.js.map +1 -0
  52. package/dist/api/cadquery-selectors/types.d.ts +96 -0
  53. package/dist/api/cadquery-selectors/types.d.ts.map +1 -0
  54. package/dist/api/cadquery-selectors/types.js +11 -0
  55. package/dist/api/cadquery-selectors/types.js.map +1 -0
  56. package/dist/api/chamfer.d.ts +13 -5
  57. package/dist/api/chamfer.d.ts.map +1 -1
  58. package/dist/api/chamfer.js +63 -7
  59. package/dist/api/chamfer.js.map +1 -1
  60. package/dist/api/compound-geom.d.ts +1 -1
  61. package/dist/api/compound-geom.js +1 -1
  62. package/dist/api/compound-geom.js.map +1 -1
  63. package/dist/api/draft.d.ts +1 -1
  64. package/dist/api/draft.js +1 -1
  65. package/dist/api/draft.js.map +1 -1
  66. package/dist/api/edge-ref.d.ts +1 -1
  67. package/dist/api/edge-ref.d.ts.map +1 -1
  68. package/dist/api/edge-ref.js +11 -3
  69. package/dist/api/edge-ref.js.map +1 -1
  70. package/dist/api/engrave.d.ts +1 -1
  71. package/dist/api/engrave.js +7 -7
  72. package/dist/api/engrave.js.map +1 -1
  73. package/dist/api/extrude.d.ts +6 -1
  74. package/dist/api/extrude.d.ts.map +1 -1
  75. package/dist/api/extrude.js +59 -5
  76. package/dist/api/extrude.js.map +1 -1
  77. package/dist/api/face-ref.d.ts +1 -1
  78. package/dist/api/face-ref.js +1 -1
  79. package/dist/api/face-ref.js.map +1 -1
  80. package/dist/api/feature-repair.d.ts +1 -1
  81. package/dist/api/feature-repair.js +1 -1
  82. package/dist/api/feature-repair.js.map +1 -1
  83. package/dist/api/fillet-variable.d.ts +1 -1
  84. package/dist/api/fillet-variable.js +1 -1
  85. package/dist/api/fillet-variable.js.map +1 -1
  86. package/dist/api/fillet.d.ts +28 -8
  87. package/dist/api/fillet.d.ts.map +1 -1
  88. package/dist/api/fillet.js +64 -9
  89. package/dist/api/fillet.js.map +1 -1
  90. package/dist/api/geom.d.ts +1 -1
  91. package/dist/api/geom.js +1 -1
  92. package/dist/api/geom.js.map +1 -1
  93. package/dist/api/helix.d.ts +1 -1
  94. package/dist/api/helix.js +1 -1
  95. package/dist/api/helix.js.map +1 -1
  96. package/dist/api/import-brep.d.ts +20 -2
  97. package/dist/api/import-brep.d.ts.map +1 -1
  98. package/dist/api/import-brep.js +28 -3
  99. package/dist/api/import-brep.js.map +1 -1
  100. package/dist/api/import-step.d.ts +17 -2
  101. package/dist/api/import-step.d.ts.map +1 -1
  102. package/dist/api/import-step.js +51 -3
  103. package/dist/api/import-step.js.map +1 -1
  104. package/dist/api/index.d.ts +6 -1
  105. package/dist/api/index.d.ts.map +1 -1
  106. package/dist/api/index.js +7 -2
  107. package/dist/api/index.js.map +1 -1
  108. package/dist/api/internal/compat-op.js +1 -1
  109. package/dist/api/internal/compat-op.js.map +1 -1
  110. package/dist/api/internal/mesh-solid-op.d.ts +236 -0
  111. package/dist/api/internal/mesh-solid-op.d.ts.map +1 -0
  112. package/dist/api/internal/mesh-solid-op.js +352 -0
  113. package/dist/api/internal/mesh-solid-op.js.map +1 -0
  114. package/dist/api/internal/svg-asset-resolver.d.ts +1 -1
  115. package/dist/api/internal/svg-asset-resolver.js +1 -1
  116. package/dist/api/internal/svg-asset-resolver.js.map +1 -1
  117. package/dist/api/knurl.d.ts +1 -1
  118. package/dist/api/knurl.js +2 -2
  119. package/dist/api/knurl.js.map +1 -1
  120. package/dist/api/loft.d.ts +1 -1
  121. package/dist/api/loft.js +1 -1
  122. package/dist/api/loft.js.map +1 -1
  123. package/dist/api/measurement/index.d.ts +9 -5
  124. package/dist/api/measurement/index.d.ts.map +1 -1
  125. package/dist/api/measurement/index.js +47 -20
  126. package/dist/api/measurement/index.js.map +1 -1
  127. package/dist/api/meta.d.ts +93 -0
  128. package/dist/api/meta.d.ts.map +1 -0
  129. package/dist/api/meta.js +99 -0
  130. package/dist/api/meta.js.map +1 -0
  131. package/dist/api/pattern.d.ts +5 -3
  132. package/dist/api/pattern.d.ts.map +1 -1
  133. package/dist/api/pattern.js +32 -4
  134. package/dist/api/pattern.js.map +1 -1
  135. package/dist/api/place.d.ts +1 -1
  136. package/dist/api/place.js +1 -1
  137. package/dist/api/place.js.map +1 -1
  138. package/dist/api/primitives.d.ts +1 -1
  139. package/dist/api/primitives.d.ts.map +1 -1
  140. package/dist/api/primitives.js +119 -4
  141. package/dist/api/primitives.js.map +1 -1
  142. package/dist/api/profile.d.ts +39 -12
  143. package/dist/api/profile.d.ts.map +1 -1
  144. package/dist/api/profile.js +4 -4
  145. package/dist/api/profile.js.map +1 -1
  146. package/dist/api/reconcile.d.ts +1 -1
  147. package/dist/api/reconcile.js +1 -1
  148. package/dist/api/reconcile.js.map +1 -1
  149. package/dist/api/replicate.d.ts.map +1 -1
  150. package/dist/api/replicate.js +122 -1
  151. package/dist/api/replicate.js.map +1 -1
  152. package/dist/api/screw.d.ts +1 -1
  153. package/dist/api/screw.js +3 -3
  154. package/dist/api/screw.js.map +1 -1
  155. package/dist/api/sdf.d.ts +1 -1
  156. package/dist/api/sdf.js +2 -2
  157. package/dist/api/sdf.js.map +1 -1
  158. package/dist/api/section-by-plane.d.ts +1 -1
  159. package/dist/api/section-by-plane.d.ts.map +1 -1
  160. package/dist/api/section-by-plane.js +2 -1
  161. package/dist/api/section-by-plane.js.map +1 -1
  162. package/dist/api/shell.d.ts +11 -4
  163. package/dist/api/shell.d.ts.map +1 -1
  164. package/dist/api/shell.js +53 -7
  165. package/dist/api/shell.js.map +1 -1
  166. package/dist/api/sketch-on-face.d.ts +41 -0
  167. package/dist/api/sketch-on-face.d.ts.map +1 -1
  168. package/dist/api/sketch-on-face.js +100 -1
  169. package/dist/api/sketch-on-face.js.map +1 -1
  170. package/dist/api/sketch-on-plane.d.ts +7 -5
  171. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  172. package/dist/api/sketch-on-plane.js +6 -7
  173. package/dist/api/sketch-on-plane.js.map +1 -1
  174. package/dist/api/split-by-plane.d.ts +1 -1
  175. package/dist/api/split-by-plane.d.ts.map +1 -1
  176. package/dist/api/split-by-plane.js +2 -1
  177. package/dist/api/split-by-plane.js.map +1 -1
  178. package/dist/api/split.d.ts +1 -1
  179. package/dist/api/split.js +2 -2
  180. package/dist/api/split.js.map +1 -1
  181. package/dist/api/sweep.d.ts +1 -1
  182. package/dist/api/sweep.js +1 -1
  183. package/dist/api/sweep.js.map +1 -1
  184. package/dist/api/thicken.d.ts +1 -1
  185. package/dist/api/thicken.js +1 -1
  186. package/dist/api/thicken.js.map +1 -1
  187. package/dist/api/topo-resolve.d.ts +74 -1
  188. package/dist/api/topo-resolve.d.ts.map +1 -1
  189. package/dist/api/topo-resolve.js +180 -2
  190. package/dist/api/topo-resolve.js.map +1 -1
  191. package/dist/api/transform.d.ts +5 -1
  192. package/dist/api/transform.d.ts.map +1 -1
  193. package/dist/api/transform.js +62 -11
  194. package/dist/api/transform.js.map +1 -1
  195. package/dist/api/wire.d.ts +1 -1
  196. package/dist/api/wire.js +1 -1
  197. package/dist/api/wire.js.map +1 -1
  198. package/dist/brep/brep-ops.d.ts +9 -7
  199. package/dist/brep/brep-ops.d.ts.map +1 -1
  200. package/dist/brep/brep-ops.js +50 -26
  201. package/dist/brep/brep-ops.js.map +1 -1
  202. package/dist/brep/brep-topology.d.ts +5 -4
  203. package/dist/brep/brep-topology.d.ts.map +1 -1
  204. package/dist/brep/brep-topology.js +6 -5
  205. package/dist/brep/brep-topology.js.map +1 -1
  206. package/dist/brep/effective-deflection.d.ts +35 -0
  207. package/dist/brep/effective-deflection.d.ts.map +1 -0
  208. package/dist/brep/effective-deflection.js +49 -0
  209. package/dist/brep/effective-deflection.js.map +1 -0
  210. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  211. package/dist/brep/engine/adapters/brep-mock.js +27 -0
  212. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  213. package/dist/brep/engine/adapters/brepkit.d.ts +18 -0
  214. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  215. package/dist/brep/engine/adapters/brepkit.js +46 -1
  216. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  217. package/dist/brep/engine/adapters/occt.d.ts +1 -1
  218. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  219. package/dist/brep/engine/adapters/occt.js +4 -2
  220. package/dist/brep/engine/adapters/occt.js.map +1 -1
  221. package/dist/brep/engine/primitives.d.ts +29 -7
  222. package/dist/brep/engine/primitives.d.ts.map +1 -1
  223. package/dist/brep/engine/primitives.js.map +1 -1
  224. package/dist/brep/engine/registry.d.ts +24 -1
  225. package/dist/brep/engine/registry.d.ts.map +1 -1
  226. package/dist/brep/engine/registry.js +24 -0
  227. package/dist/brep/engine/registry.js.map +1 -1
  228. package/dist/brep/engine/types.d.ts +54 -3
  229. package/dist/brep/engine/types.d.ts.map +1 -1
  230. package/dist/brep/engine/types.js +10 -0
  231. package/dist/brep/engine/types.js.map +1 -1
  232. package/dist/brep/export/export-model.d.ts +40 -0
  233. package/dist/brep/export/export-model.d.ts.map +1 -1
  234. package/dist/brep/export/export-model.js +274 -30
  235. package/dist/brep/export/export-model.js.map +1 -1
  236. package/dist/brep/export/step-meta-header.d.ts +102 -0
  237. package/dist/brep/export/step-meta-header.d.ts.map +1 -0
  238. package/dist/brep/export/step-meta-header.js +225 -0
  239. package/dist/brep/export/step-meta-header.js.map +1 -0
  240. package/dist/brep/export/step.d.ts +5 -1
  241. package/dist/brep/export/step.d.ts.map +1 -1
  242. package/dist/brep/export/step.js +11 -2
  243. package/dist/brep/export/step.js.map +1 -1
  244. package/dist/brep/face-evolution.d.ts +1 -1
  245. package/dist/brep/face-evolution.d.ts.map +1 -1
  246. package/dist/brep/face-evolution.js +20 -1
  247. package/dist/brep/face-evolution.js.map +1 -1
  248. package/dist/brep/handle-bridge.d.ts +1 -1
  249. package/dist/brep/handle-bridge.js +1 -1
  250. package/dist/brep/handle-bridge.js.map +1 -1
  251. package/dist/brep/mesh-solid.d.ts +218 -0
  252. package/dist/brep/mesh-solid.d.ts.map +1 -0
  253. package/dist/brep/mesh-solid.js +229 -0
  254. package/dist/brep/mesh-solid.js.map +1 -0
  255. package/dist/brep/text/fontRegistry.d.ts +32 -1
  256. package/dist/brep/text/fontRegistry.d.ts.map +1 -1
  257. package/dist/brep/text/fontRegistry.js +51 -1
  258. package/dist/brep/text/fontRegistry.js.map +1 -1
  259. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  260. package/dist/brep/text/text-to-solid.js +8 -3
  261. package/dist/brep/text/text-to-solid.js.map +1 -1
  262. package/dist/brepkit-kernel/brepkitKernel.d.ts +18 -2
  263. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  264. package/dist/brepkit-kernel/brepkitKernel.js +449 -123
  265. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  266. package/dist/brepkit-kernel/brepkitWasm.d.ts +8 -0
  267. package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
  268. package/dist/brepkit-kernel/brepkitWasm.js +10 -0
  269. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  270. package/dist/browser-host/browser-font-provider.d.ts +12 -0
  271. package/dist/browser-host/browser-font-provider.d.ts.map +1 -1
  272. package/dist/browser-host/browser-font-provider.js +25 -0
  273. package/dist/browser-host/browser-font-provider.js.map +1 -1
  274. package/dist/browser.d.ts +6 -3
  275. package/dist/browser.d.ts.map +1 -1
  276. package/dist/browser.js +10 -3
  277. package/dist/browser.js.map +1 -1
  278. package/dist/cad-runtime/backend-dispatch.d.ts +28 -3
  279. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  280. package/dist/cad-runtime/backend-dispatch.js +119 -4
  281. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  282. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  283. package/dist/cad-runtime/direct-executor.d.ts +15 -3
  284. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  285. package/dist/cad-runtime/direct-executor.js +33 -1
  286. package/dist/cad-runtime/direct-executor.js.map +1 -1
  287. package/dist/cad-runtime/ports.d.ts +3 -3
  288. package/dist/cad-runtime/ports.d.ts.map +1 -1
  289. package/dist/cad-runtime/ports.js.map +1 -1
  290. package/dist/cad-runtime/preview-exec.d.ts +4 -4
  291. package/dist/cad-runtime/preview-exec.js +2 -2
  292. package/dist/cad-runtime/preview-exec.js.map +1 -1
  293. package/dist/cad-runtime/runtime.d.ts +42 -7
  294. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  295. package/dist/cad-runtime/runtime.js +68 -5
  296. package/dist/cad-runtime/runtime.js.map +1 -1
  297. package/dist/define-op.d.ts +15 -1
  298. package/dist/define-op.d.ts.map +1 -1
  299. package/dist/define-op.js +73 -2
  300. package/dist/define-op.js.map +1 -1
  301. package/dist/env-agnostic.d.ts +2 -2
  302. package/dist/env-agnostic.d.ts.map +1 -1
  303. package/dist/env-agnostic.js +1 -1
  304. package/dist/env-agnostic.js.map +1 -1
  305. package/dist/geometry2d/adapt.d.ts +39 -4
  306. package/dist/geometry2d/adapt.d.ts.map +1 -1
  307. package/dist/geometry2d/adapt.js +14 -3
  308. package/dist/geometry2d/adapt.js.map +1 -1
  309. package/dist/geometry2d/blueprint.d.ts +2 -2
  310. package/dist/geometry2d/blueprint.js +2 -2
  311. package/dist/geometry2d/blueprint.js.map +1 -1
  312. package/dist/geometry2d/bridge/lift-on-plane.d.ts +18 -8
  313. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  314. package/dist/geometry2d/bridge/lift-on-plane.js +65 -12
  315. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  316. package/dist/geometry2d/bridge/plane.d.ts +17 -0
  317. package/dist/geometry2d/bridge/plane.d.ts.map +1 -1
  318. package/dist/geometry2d/bridge/plane.js +22 -0
  319. package/dist/geometry2d/bridge/plane.js.map +1 -1
  320. package/dist/geometry2d/curve2d.d.ts +25 -0
  321. package/dist/geometry2d/curve2d.d.ts.map +1 -1
  322. package/dist/geometry2d/curve2d.js +41 -5
  323. package/dist/geometry2d/curve2d.js.map +1 -1
  324. package/dist/index.d.ts +6 -2
  325. package/dist/index.d.ts.map +1 -1
  326. package/dist/index.js +10 -3
  327. package/dist/index.js.map +1 -1
  328. package/dist/io/bytes-node.d.ts +11 -0
  329. package/dist/io/bytes-node.d.ts.map +1 -0
  330. package/dist/io/bytes-node.js +28 -0
  331. package/dist/io/bytes-node.js.map +1 -0
  332. package/dist/io/bytes.d.ts +33 -0
  333. package/dist/io/bytes.d.ts.map +1 -0
  334. package/dist/io/bytes.js +41 -0
  335. package/dist/io/bytes.js.map +1 -0
  336. package/dist/io/fai-zip/container-read.d.ts +102 -0
  337. package/dist/io/fai-zip/container-read.d.ts.map +1 -0
  338. package/dist/io/fai-zip/container-read.js +305 -0
  339. package/dist/io/fai-zip/container-read.js.map +1 -0
  340. package/dist/io/fai-zip/container-write.d.ts +70 -0
  341. package/dist/io/fai-zip/container-write.d.ts.map +1 -0
  342. package/dist/io/fai-zip/container-write.js +186 -0
  343. package/dist/io/fai-zip/container-write.js.map +1 -0
  344. package/dist/io/fai-zip/container.d.ts +107 -0
  345. package/dist/io/fai-zip/container.d.ts.map +1 -0
  346. package/dist/io/fai-zip/container.js +89 -0
  347. package/dist/io/fai-zip/container.js.map +1 -0
  348. package/dist/io/fai-zip/index.d.ts +18 -0
  349. package/dist/io/fai-zip/index.d.ts.map +1 -0
  350. package/dist/io/fai-zip/index.js +4 -0
  351. package/dist/io/fai-zip/index.js.map +1 -0
  352. package/dist/io/index.d.ts +10 -0
  353. package/dist/io/index.d.ts.map +1 -0
  354. package/dist/io/index.js +13 -0
  355. package/dist/io/index.js.map +1 -0
  356. package/dist/io/zip.d.ts +68 -0
  357. package/dist/io/zip.d.ts.map +1 -0
  358. package/dist/io/zip.js +147 -0
  359. package/dist/io/zip.js.map +1 -0
  360. package/dist/lang/code-to-args.d.ts +1 -1
  361. package/dist/lang/code-to-args.js +1 -1
  362. package/dist/lang/code-to-args.js.map +1 -1
  363. package/dist/lang/metadata-extractor.d.ts.map +1 -1
  364. package/dist/lang/metadata-extractor.js +2 -21
  365. package/dist/lang/metadata-extractor.js.map +1 -1
  366. package/dist/lang/statement-summary.d.ts +1 -1
  367. package/dist/lang/statement-summary.js +1 -1
  368. package/dist/lang/statement-summary.js.map +1 -1
  369. package/dist/lang/types.d.ts +6 -7
  370. package/dist/lang/types.d.ts.map +1 -1
  371. package/dist/lang/types.js +1 -1
  372. package/dist/lang/types.js.map +1 -1
  373. package/dist/mesh/index.d.ts +2 -1
  374. package/dist/mesh/index.d.ts.map +1 -1
  375. package/dist/mesh/index.js +2 -1
  376. package/dist/mesh/index.js.map +1 -1
  377. package/dist/mesh/io.d.ts +13 -0
  378. package/dist/mesh/io.d.ts.map +1 -1
  379. package/dist/mesh/io.js +38 -17
  380. package/dist/mesh/io.js.map +1 -1
  381. package/dist/mesh/primitives.d.ts.map +1 -1
  382. package/dist/mesh/primitives.js +41 -6
  383. package/dist/mesh/primitives.js.map +1 -1
  384. package/dist/mesh/reconcile.d.ts +1 -1
  385. package/dist/mesh/reconcile.js +1 -1
  386. package/dist/mesh/reconcile.js.map +1 -1
  387. package/dist/mesh/rigid-transform.d.ts +3 -3
  388. package/dist/mesh/rigid-transform.js +3 -3
  389. package/dist/mesh/rigid-transform.js.map +1 -1
  390. package/dist/mesh/stl-unit.d.ts +24 -0
  391. package/dist/mesh/stl-unit.d.ts.map +1 -0
  392. package/dist/mesh/stl-unit.js +17 -0
  393. package/dist/mesh/stl-unit.js.map +1 -0
  394. package/dist/mesh/threemf-bambu.d.ts +142 -0
  395. package/dist/mesh/threemf-bambu.d.ts.map +1 -0
  396. package/dist/mesh/threemf-bambu.js +334 -0
  397. package/dist/mesh/threemf-bambu.js.map +1 -0
  398. package/dist/mesh/threemf-loader.d.ts +65 -7
  399. package/dist/mesh/threemf-loader.d.ts.map +1 -1
  400. package/dist/mesh/threemf-loader.js +738 -99
  401. package/dist/mesh/threemf-loader.js.map +1 -1
  402. package/dist/mesh/threemf-view.d.ts +71 -0
  403. package/dist/mesh/threemf-view.d.ts.map +1 -0
  404. package/dist/mesh/threemf-view.js +100 -0
  405. package/dist/mesh/threemf-view.js.map +1 -0
  406. package/dist/mesh/types.d.ts +38 -0
  407. package/dist/mesh/types.d.ts.map +1 -1
  408. package/dist/mesh/types.js.map +1 -1
  409. package/dist/node-host/cli.d.ts +44 -6
  410. package/dist/node-host/cli.d.ts.map +1 -1
  411. package/dist/node-host/cli.js +76 -26
  412. package/dist/node-host/cli.js.map +1 -1
  413. package/dist/node-host/font-family-index.d.ts +93 -0
  414. package/dist/node-host/font-family-index.d.ts.map +1 -0
  415. package/dist/node-host/font-family-index.js +273 -0
  416. package/dist/node-host/font-family-index.js.map +1 -0
  417. package/dist/node-host/fs-asset-resolver.d.ts +8 -3
  418. package/dist/node-host/fs-asset-resolver.d.ts.map +1 -1
  419. package/dist/node-host/fs-asset-resolver.js +13 -5
  420. package/dist/node-host/fs-asset-resolver.js.map +1 -1
  421. package/dist/node-host/index.d.ts +8 -0
  422. package/dist/node-host/index.d.ts.map +1 -1
  423. package/dist/node-host/index.js +1 -0
  424. package/dist/node-host/index.js.map +1 -1
  425. package/dist/node-host/node-font-provider.d.ts +28 -0
  426. package/dist/node-host/node-font-provider.d.ts.map +1 -1
  427. package/dist/node-host/node-font-provider.js +49 -0
  428. package/dist/node-host/node-font-provider.js.map +1 -1
  429. package/dist/node.d.ts +1 -0
  430. package/dist/node.d.ts.map +1 -1
  431. package/dist/node.js +1 -0
  432. package/dist/node.js.map +1 -1
  433. package/dist/occt-kernel/highLevelApi.d.ts +4 -1
  434. package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
  435. package/dist/occt-kernel/highLevelApi.js +4 -2
  436. package/dist/occt-kernel/highLevelApi.js.map +1 -1
  437. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  438. package/dist/occt-kernel/occt-primitives.js +36 -3
  439. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  440. package/dist/occt-kernel/occtKernel.d.ts +19 -14
  441. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  442. package/dist/occt-kernel/occtKernel.js +19 -32
  443. package/dist/occt-kernel/occtKernel.js.map +1 -1
  444. package/dist/occt-kernel/stepColorParser.d.ts +18 -0
  445. package/dist/occt-kernel/stepColorParser.d.ts.map +1 -1
  446. package/dist/occt-kernel/stepColorParser.js +38 -0
  447. package/dist/occt-kernel/stepColorParser.js.map +1 -1
  448. package/dist/occt-kernel/stepMetaParser.d.ts +44 -0
  449. package/dist/occt-kernel/stepMetaParser.d.ts.map +1 -0
  450. package/dist/occt-kernel/stepMetaParser.js +166 -0
  451. package/dist/occt-kernel/stepMetaParser.js.map +1 -0
  452. package/dist/occt-kernel/topologyExt.d.ts +1 -1
  453. package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
  454. package/dist/occt-kernel/topologyExt.js +4 -5
  455. package/dist/occt-kernel/topologyExt.js.map +1 -1
  456. package/dist/primitives/text/cjk-font.d.ts +2 -15
  457. package/dist/primitives/text/cjk-font.d.ts.map +1 -1
  458. package/dist/primitives/text/cjk-font.js +13 -1
  459. package/dist/primitives/text/cjk-font.js.map +1 -1
  460. package/dist/runtime-state.d.ts +85 -9
  461. package/dist/runtime-state.d.ts.map +1 -1
  462. package/dist/runtime-state.js +72 -2
  463. package/dist/runtime-state.js.map +1 -1
  464. package/dist/sdk.d.ts +3 -3
  465. package/dist/sdk.d.ts.map +1 -1
  466. package/dist/sdk.js +5 -5
  467. package/dist/sdk.js.map +1 -1
  468. package/dist/shape.d.ts +108 -5
  469. package/dist/shape.d.ts.map +1 -1
  470. package/dist/shape.js +130 -3
  471. package/dist/shape.js.map +1 -1
  472. package/dist/step/stepMetaParser.d.ts +55 -0
  473. package/dist/step/stepMetaParser.d.ts.map +1 -0
  474. package/dist/step/stepMetaParser.js +177 -0
  475. package/dist/step/stepMetaParser.js.map +1 -0
  476. package/dist/topology/naming/lineage.d.ts +6 -0
  477. package/dist/topology/naming/lineage.d.ts.map +1 -1
  478. package/dist/topology/naming/lineage.js +8 -0
  479. package/dist/topology/naming/lineage.js.map +1 -1
  480. package/dist/topology/naming/resolve-edge.d.ts +20 -1
  481. package/dist/topology/naming/resolve-edge.d.ts.map +1 -1
  482. package/dist/topology/naming/resolve-edge.js +54 -20
  483. package/dist/topology/naming/resolve-edge.js.map +1 -1
  484. package/dist/weapp.d.ts +6 -2
  485. package/dist/weapp.d.ts.map +1 -1
  486. package/dist/weapp.js +7 -1
  487. package/dist/weapp.js.map +1 -1
  488. package/package.json +19 -3
@@ -0,0 +1,353 @@
1
+ /**
2
+ * cadquery-selectors/face — CadQuery face 字符串选择器
3
+ *
4
+ * 等价搬运自 `packages/faijs-cadquery/src/workplane.ts` 的 `resolveFaceSelector`
5
+ * (含其私有 `NAMED_VIEW_TO_AXIS`、`bboxMax`/`bboxMin`、`cad` 单例)。仅 import
6
+ * 路径改为 core 内部相对路径,逻辑逐行不变,零功能增减。
7
+ *
8
+ * @platform occt — face 选择对 BREP 面做枚举/比较,经 `getKernel()` 与
9
+ * `getBrepApi()` 访问 occt 原生内核(getSubShapes / surface 查询等)。
10
+ */
11
+ import { createApiNamespace } from '../api-namespace.js';
12
+ import { getKernel } from '../../occt-kernel/occtKernel.js';
13
+ import { getBrepApi } from '../../brep/handle-bridge.js';
14
+ import { brepOf } from '../../shape.js';
15
+ import { asBrepShape } from './borrow-bridge.js';
16
+ // ── cad namespace singleton (created once at module load) ──────────────────
17
+ const cad = createApiNamespace();
18
+ /** core 直连 helpers(原 cq-compat 私有 helper,等价搬运)。 */
19
+ function kern() {
20
+ return getBrepApi();
21
+ }
22
+ function ownHandle(shape) {
23
+ return brepOf(shape);
24
+ }
25
+ /** Get bbox max of a shape (via cad.bboxMax — synchronous). */
26
+ function bboxMax(shape) {
27
+ return cad.bboxMax(shape);
28
+ }
29
+ /** Get bbox min of a shape. */
30
+ function bboxMin(shape) {
31
+ return cad.bboxMin(shape);
32
+ }
33
+ /**
34
+ * Resolve a face selector to a world-space point (face center) and normal.
35
+ *
36
+ * CadQuery semantics: `faces(">Z")` selects the face(s) at the extreme of the
37
+ * axis, and `workplane()` places the origin at the selected face's center —
38
+ * `centerOption: "CenterOfMass"` (default) uses the face's surface centroid,
39
+ * `"CenterOfBoundBox"` uses the face's bounding-box center.
40
+ *
41
+ * Supported forms: ">Z", "<Z", ">X", "<X", ">Y", "<Y", "+Z"/"-Z" aliases, each
42
+ * with an optional CadQuery-style index suffix like ">Z[-2]". The six CadQuery
43
+ * named views ("front"/"back"/"left"/"right"/"top"/"bottom") are accepted and
44
+ * normalised to their axis equivalent (front=>">Z", back=>"<Z", left=>"<X",
45
+ * right=>">X", top=>">Y", bottom=>"<Y"). This
46
+ * implementation enumerates the actual BREP faces and picks the one whose
47
+ * bbox-center is the extreme along the selector axis (ties broken by larger
48
+ * surface area, so a main face wins over a small coplanar boss face). When the
49
+ * shape has no BREP handle or the kernel is unavailable, it falls back to the
50
+ * whole-shape bounding-box approximation.
51
+ *
52
+ * Indexed selectors (`">Z[-2]"`) follow CadQuery's DirectionMinMaxSelector
53
+ * indexing, verified against the installed cadquery 2.8.0: `">A[k]"` lists all
54
+ * faces ASCENDING along axis A (`[0]` = lowest, `[-1]` = highest); `"<A[k]"`
55
+ * lists them DESCENDING (`[0]` = highest). The picked face's normal is the
56
+ * outward direction (away from the shape bbox center).
57
+ *
58
+ * @param shape - Shape whose BREP faces are enumerated for selection.
59
+ * @param sel - Selector string, e.g. ">Z", "<X", ">Z[-2]", or a named view
60
+ * ("front"/"back"/"left"/"right"/"top"/"bottom").
61
+ * @param centerOption - Optional center computation option forwarded to the
62
+ * face-center evaluation.
63
+ * @returns Promise resolving to the selected face's center point and outward
64
+ * normal.
65
+ */
66
+ /**
67
+ * CadQuery named views → axis selector (cadquery/selectors.py:687-694).
68
+ * Verified against installed cadquery 2.8.0 by evaluating
69
+ * `Workplane().rect(1,1).extrude(1).faces(n).val()` for each name.
70
+ */
71
+ const NAMED_VIEW_TO_AXIS = {
72
+ front: '>Z',
73
+ back: '<Z',
74
+ left: '<X',
75
+ right: '>X',
76
+ top: '>Y',
77
+ bottom: '<Y',
78
+ };
79
+ /**
80
+ * Resolve a CadQuery-style face selector string to the selected face's center
81
+ * point and outward normal.
82
+ *
83
+ * Supported forms: ">Z", "<Z", ">X", "<X", ">Y", "<Y", each with an optional
84
+ * CadQuery-style index suffix like ">Z[-2]", plus the six named views
85
+ * ("front"/"back"/"left"/"right"/"top"/"bottom") which are aliases for the
86
+ * corresponding axis selectors per cadquery/selectors.py:687-694.
87
+ * @param shape - Shape whose BREP faces are enumerated for selection.
88
+ * @param sel - Selector string, e.g. ">Z", "front", ">Z[-2]".
89
+ * @param centerOption - Optional center computation option forwarded to the
90
+ * face-center evaluation.
91
+ * @returns Promise resolving to the selected face's center point and outward
92
+ * normal.
93
+ * @throws Error when the selector matches no face or has unknown syntax
94
+ * (never falls back silently).
95
+ */
96
+ export async function resolveFaceSelector(shape, sel, centerOption) {
97
+ // compatOp 提升边界:实参可能是借用视图(见 asBrepShape 注释)——归一为真实
98
+ // Shape,否则 brepOf 为 undefined 会落到 bbox 兜底并在 cad.bboxMax 崩溃。
99
+ shape = asBrepShape(shape);
100
+ // CadQuery named views are aliases for an axis DirectionMinMaxSelector
101
+ // (cadquery/selectors.py:687-694):
102
+ // front=>(0,0,1,max) back=>(0,0,1,min) left=>(1,0,0,min)
103
+ // right=>(1,0,0,max) top=>(0,1,0,max) bottom=>(0,1,0,min)
104
+ // Normalise once so every branch below sees a plain axis selector; without
105
+ // this the lookup misses and the whole-shape bbox fallback silently returns
106
+ // the shape centre instead of the face plane (half-a-hole volume error).
107
+ sel = NAMED_VIEW_TO_AXIS[sel.trim().toLowerCase()] ?? sel;
108
+ // Strip index suffix like [-2]
109
+ const baseSel = sel.replace(/\[-?\d+\]$/, '');
110
+ const axisDir = {
111
+ '>Z': { axis: 2, sign: 1 }, '+Z': { axis: 2, sign: 1 },
112
+ '<Z': { axis: 2, sign: -1 }, '-Z': { axis: 2, sign: -1 },
113
+ '>X': { axis: 0, sign: 1 }, '+X': { axis: 0, sign: 1 },
114
+ '<X': { axis: 0, sign: -1 }, '-X': { axis: 0, sign: -1 },
115
+ '>Y': { axis: 1, sign: 1 }, '+Y': { axis: 1, sign: 1 },
116
+ '<Y': { axis: 1, sign: -1 }, '-Y': { axis: 1, sign: -1 },
117
+ };
118
+ const normals = {
119
+ '>Z': [0, 0, 1], '+Z': [0, 0, 1], '<Z': [0, 0, -1], '-Z': [0, 0, -1],
120
+ '>X': [1, 0, 0], '+X': [1, 0, 0], '<X': [-1, 0, 0], '-X': [-1, 0, 0],
121
+ '>Y': [0, 1, 0], '+Y': [0, 1, 0], '<Y': [0, -1, 0], '-Y': [0, -1, 0],
122
+ };
123
+ const dir = axisDir[baseSel];
124
+ const fallbackNormal = normals[baseSel] ?? [0, 0, 1];
125
+ // ── Multi-axis direction selectors ("+XY", ">XZ", "-YZ" … cadquery
126
+ // selectors.py:625 axes table XY=(1,1,0) XZ=(1,0,1) YZ=(0,1,1)) ──
127
+ // '+'/'-' → DirectionSelector: only faces whose outward normal is PARALLEL
128
+ // to the (±) direction (angle < 1e-4 rad, selectors.py:234). '>'/'<' →
129
+ // DirectionMinMaxSelector (selectors.py:399): the face whose center of MASS
130
+ // is farthest along the direction. Index suffixes mean DirectionNthSelector
131
+ // there — not supported, throw instead of silently approximating.
132
+ const multi = /^([<>+-])(XY|XZ|YZ)$/.exec(baseSel);
133
+ if (multi) {
134
+ if (/\[-?\d+\]$/.test(sel.trim())) {
135
+ throw new Error(`[cq-compat] selector "${sel}": indexed multi-axis selectors not supported`);
136
+ }
137
+ const axesTable = {
138
+ XY: [1, 1, 0],
139
+ XZ: [1, 0, 1],
140
+ YZ: [0, 1, 1],
141
+ };
142
+ let d = axesTable[multi[2]];
143
+ if (multi[1] === '-')
144
+ d = [-d[0], -d[1], -d[2]];
145
+ const dLen = Math.hypot(d[0], d[1], d[2]);
146
+ const dirV = [d[0] / dLen, d[1] / dLen, d[2] / dLen];
147
+ const handleM = brepOf(shape);
148
+ if (!handleM) {
149
+ throw new Error(`[cq-compat] selector "${sel}": BREP unavailable`);
150
+ }
151
+ const kernelM = getKernel();
152
+ const faceList = kernelM.getSubShapes(handleM, 'face');
153
+ if (faceList.length === 0) {
154
+ throw new Error(`[cq-compat] selector "${sel}": shape has no faces`);
155
+ }
156
+ const faceNormalOf = (f) => {
157
+ const uv = kernelM.uvBounds(f);
158
+ const n = kernelM.surfaceNormal(f, (uv.uMin + uv.uMax) / 2, (uv.vMin + uv.vMax) / 2);
159
+ return [n.x, n.y, n.z];
160
+ };
161
+ const comOf = (f) => {
162
+ const c = kernelM.getSurfaceCenterOfMass(f);
163
+ return [c.x, c.y, c.z];
164
+ };
165
+ const dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
166
+ if (multi[1] === '+' || multi[1] === '-') {
167
+ // DirectionSelector: angle(normal, dir) < 1e-4 rad (selectors.py:235).
168
+ const PAR_TOL = Math.cos(1e-4);
169
+ const found = faceList.find((f) => dot(faceNormalOf(f), dirV) > PAR_TOL);
170
+ if (!found) {
171
+ throw new Error(`[cq-compat] selector "${sel}": no face with normal parallel to the direction`);
172
+ }
173
+ return { center: comOf(found), normal: faceNormalOf(found) };
174
+ }
175
+ // '>'/'<': DirectionMinMaxSelector over center-of-mass projections.
176
+ let bestF = null;
177
+ let bestVal = 0;
178
+ for (const f of faceList) {
179
+ const val = dot(comOf(f), dirV);
180
+ if (!bestF || (multi[1] === '>' ? val > bestVal + 1e-9 : val < bestVal - 1e-9)) {
181
+ bestF = f;
182
+ bestVal = val;
183
+ }
184
+ }
185
+ return { center: comOf(bestF), normal: faceNormalOf(bestF) };
186
+ }
187
+ // ── Face-based selection (BREP kernel available) ──
188
+ try {
189
+ const handle = brepOf(shape);
190
+ const kernel = getKernel();
191
+ if (handle && dir) {
192
+ const faces = kernel.getSubShapes(handle, 'face');
193
+ const cands = [];
194
+ for (const f of faces) {
195
+ const bb = kernel.getBoundingBox(f);
196
+ cands.push({
197
+ handle: f,
198
+ center: [
199
+ (bb.xmin + bb.xmax) / 2,
200
+ (bb.ymin + bb.ymax) / 2,
201
+ (bb.zmin + bb.zmax) / 2,
202
+ ],
203
+ });
204
+ }
205
+ let best = null;
206
+ let normal = fallbackNormal;
207
+ // Extract the index suffix, if any.
208
+ const idxMatch = /\[(-?\d+)\]$/.exec(sel.trim());
209
+ if (idxMatch) {
210
+ // CadQuery face indexing (verified vs cadquery 2.8.0):
211
+ // '>A[k]' / '<A[k]' DirectionMinMaxSelector: '>' ascending, '<' descending
212
+ // '+A[k]' / '-A[k]' DirectionSelector: list the extreme face first, then
213
+ // inward — '-' ascending, '+' descending along A
214
+ // (faces("-Y")[1] is the 2nd -Y face from the -Y extreme,
215
+ // NOT the +Y extreme face).
216
+ // Only faces PERPENDICULAR to the axis participate (bbox thin along the axis).
217
+ // For '+'/'-' selectors we additionally keep only faces whose outward normal
218
+ // is parallel to the selector axis with the matching sign (CadQuery filters
219
+ // by exact normal direction), so a boss face and its base sibling don't
220
+ // collide in the index.
221
+ const sc = baseSel[0];
222
+ const isDirSelector = sc === '+' || sc === '-';
223
+ const perp = cands.filter((cd) => {
224
+ const bb = kernel.getBoundingBox(cd.handle);
225
+ const ext = [bb.xmax - bb.xmin, bb.ymax - bb.ymin, bb.zmax - bb.zmin][dir.axis];
226
+ if (ext > 0.1)
227
+ return false;
228
+ if (isDirSelector) {
229
+ const uv = kernel.uvBounds(cd.handle);
230
+ const n = kernel.surfaceNormal(cd.handle, (uv.uMin + uv.uMax) / 2, (uv.vMin + uv.vMax) / 2);
231
+ const nv = [n.x, n.y, n.z];
232
+ if (Math.abs(nv[dir.axis]) < 0.999)
233
+ return false;
234
+ if (Math.sign(nv[dir.axis]) !== dir.sign)
235
+ return false;
236
+ }
237
+ return true;
238
+ });
239
+ const idx = parseInt(idxMatch[1], 10);
240
+ const asc = sc === '>' || sc === '-';
241
+ const sorted = perp
242
+ .slice()
243
+ .sort((a, b) => (asc ? a.center[dir.axis] - b.center[dir.axis] : b.center[dir.axis] - a.center[dir.axis]));
244
+ const pick = idx < 0 ? sorted.length + idx : idx;
245
+ if (pick < 0 || pick >= sorted.length) {
246
+ throw new Error(`[cq-compat] selector "${sel}": index ${idx} out of range (${sorted.length} faces)`);
247
+ }
248
+ best = sorted[pick];
249
+ if (isDirSelector) {
250
+ // DirectionSelector: the outward normal is exactly the selector axis/sign.
251
+ normal = fallbackNormal;
252
+ }
253
+ else {
254
+ // DirectionMinMaxSelector: outward normal from face position vs shape centre.
255
+ const max = bboxMax(shape);
256
+ const min = bboxMin(shape);
257
+ const shapeCenter = [(max[0] + min[0]) / 2, (max[1] + min[1]) / 2, (max[2] + min[2]) / 2];
258
+ normal = [0, 0, 0];
259
+ normal[dir.axis] = best.center[dir.axis] >= shapeCenter[dir.axis] ? 1 : -1;
260
+ }
261
+ }
262
+ else {
263
+ for (const cd of cands) {
264
+ const val = cd.center[dir.axis];
265
+ if (!best) {
266
+ best = cd;
267
+ continue;
268
+ }
269
+ const bestVal = best.center[dir.axis];
270
+ if (dir.sign === 1 ? val > bestVal + 1e-6 : val < bestVal - 1e-6) {
271
+ best = cd;
272
+ }
273
+ else if (Math.abs(val - bestVal) <= 1e-6) {
274
+ // Tie (e.g. coplanar faces at the same extreme): prefer the larger face
275
+ const area = kernel.getSurfaceArea(cd.handle);
276
+ if (area > kernel.getSurfaceArea(best.handle))
277
+ best = cd;
278
+ }
279
+ }
280
+ }
281
+ if (best) {
282
+ let origin;
283
+ if (centerOption === 'CenterOfBoundBox') {
284
+ origin = best.center;
285
+ }
286
+ else {
287
+ // CenterOfMass: surface (area-weighted) centroid
288
+ const com = kernel.getSurfaceCenterOfMass(best.handle);
289
+ origin = [com.x, com.y, com.z];
290
+ }
291
+ return { center: origin, normal };
292
+ }
293
+ }
294
+ }
295
+ catch (e) {
296
+ if (e instanceof Error && e.message.includes('out of range'))
297
+ throw e;
298
+ // No BREP / kernel not ready — fall through to bbox approximation
299
+ }
300
+ // ── Fallback: whole-shape bbox (previous behavior) ──
301
+ const max = bboxMax(shape);
302
+ const min = bboxMin(shape);
303
+ const center = [
304
+ (max[0] + min[0]) / 2,
305
+ (max[1] + min[1]) / 2,
306
+ (max[2] + min[2]) / 2,
307
+ ];
308
+ const m = /^([<>+-])([XYZ])(?:\[(-?\d+)\])?$/.exec(sel.trim());
309
+ if (!m) {
310
+ // Default: return center
311
+ return { center, normal: [0, 0, 1] };
312
+ }
313
+ const [, sign, axisChar, idxStr] = m;
314
+ const axis = axisChar === 'X' ? 0 : axisChar === 'Y' ? 1 : 2;
315
+ // '>' and '+' select the max side; '<' and '-' select the min side.
316
+ const maxDir = sign === '>' || sign === '+';
317
+ const normal = [0, 0, 0];
318
+ normal[axis] = maxDir ? 1 : -1;
319
+ if (idxStr === undefined) {
320
+ const extreme = [center[0], center[1], center[2]];
321
+ extreme[axis] = maxDir ? max[axis] : min[axis];
322
+ return { center: extreme, normal };
323
+ }
324
+ // Indexed selector — enumerate real faces and sort by bbox center along axis.
325
+ // CadQuery semantics: '>A[k]' ascending, '<A[k]' descending (see doc above).
326
+ const idx = parseInt(idxStr, 10);
327
+ const faces = kern().getSubShapes(ownHandle(shape), 'face');
328
+ const entries = faces.map((f) => {
329
+ const b = kern().getBoundingBox(f);
330
+ return {
331
+ c: [(b.xmin + b.xmax) / 2, (b.ymin + b.ymax) / 2, (b.zmin + b.zmax) / 2],
332
+ bounds: b,
333
+ };
334
+ });
335
+ if (entries.length === 0) {
336
+ throw new Error(`[cq-compat] selector "${sel}": shape has no faces`);
337
+ }
338
+ entries.sort((a, b) => (maxDir ? a.c[axis] - b.c[axis] : b.c[axis] - a.c[axis]));
339
+ const pick = idx < 0 ? entries.length + idx : idx;
340
+ if (pick < 0 || pick >= entries.length) {
341
+ throw new Error(`[cq-compat] selector "${sel}": index ${idx} out of range (${entries.length} faces)`);
342
+ }
343
+ const fb = entries[pick].bounds;
344
+ const faceCenter = [
345
+ (fb.xmin + fb.xmax) / 2,
346
+ (fb.ymin + fb.ymax) / 2,
347
+ (fb.zmin + fb.zmax) / 2,
348
+ ];
349
+ // Outward normal: away from the shape bbox center along the axis.
350
+ normal[axis] = faceCenter[axis] >= center[axis] ? 1 : -1;
351
+ return { center: faceCenter, normal };
352
+ }
353
+ //# sourceMappingURL=face.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"face.js","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/face.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * cadquery-selectors/face — CadQuery face 字符串选择器\n *\n * 等价搬运自 `packages/faijs-cadquery/src/workplane.ts` 的 `resolveFaceSelector`\n * (含其私有 `NAMED_VIEW_TO_AXIS`、`bboxMax`/`bboxMin`、`cad` 单例)。仅 import\n * 路径改为 core 内部相对路径,逻辑逐行不变,零功能增减。\n *\n * @platform occt — face 选择对 BREP 面做枚举/比较,经 `getKernel()` 与\n * `getBrepApi()` 访问 occt 原生内核(getSubShapes / surface 查询等)。\n */\n\nimport { createApiNamespace } from '../api-namespace'\nimport { getKernel } from '../../occt-kernel/occtKernel'\nimport { getBrepApi } from '../../brep/handle-bridge'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport { brepOf } from '../../shape'\nimport type { OcctKernel, ShapeHandle } from 'occt-wasm'\nimport type { Shape } from '../../mesh/types'\nimport { asBrepShape } from './borrow-bridge'\n\n// ── cad namespace singleton (created once at module load) ──────────────────\nconst cad = createApiNamespace() as Record<string, (...args: unknown[]) => Promise<Shape>>\n\n/** core 直连 helpers(原 cq-compat 私有 helper,等价搬运)。 */\nfunction kern(): BrepEngineApi {\n return getBrepApi()\n}\nfunction ownHandle(shape: Shape): BrepHandle {\n return brepOf(shape) as BrepHandle\n}\n\n/** Get bbox max of a shape (via cad.bboxMax — synchronous). */\nfunction bboxMax(shape: Shape): [number, number, number] {\n return cad.bboxMax(shape) as unknown as [number, number, number]\n}\n\n/** Get bbox min of a shape. */\nfunction bboxMin(shape: Shape): [number, number, number] {\n return cad.bboxMin(shape) as unknown as [number, number, number]\n}\n\n/**\n * Resolve a face selector to a world-space point (face center) and normal.\n *\n * CadQuery semantics: `faces(\">Z\")` selects the face(s) at the extreme of the\n * axis, and `workplane()` places the origin at the selected face's center —\n * `centerOption: \"CenterOfMass\"` (default) uses the face's surface centroid,\n * `\"CenterOfBoundBox\"` uses the face's bounding-box center.\n *\n * Supported forms: \">Z\", \"<Z\", \">X\", \"<X\", \">Y\", \"<Y\", \"+Z\"/\"-Z\" aliases, each\n * with an optional CadQuery-style index suffix like \">Z[-2]\". The six CadQuery\n * named views (\"front\"/\"back\"/\"left\"/\"right\"/\"top\"/\"bottom\") are accepted and\n * normalised to their axis equivalent (front=>\">Z\", back=>\"<Z\", left=>\"<X\",\n * right=>\">X\", top=>\">Y\", bottom=>\"<Y\"). This\n * implementation enumerates the actual BREP faces and picks the one whose\n * bbox-center is the extreme along the selector axis (ties broken by larger\n * surface area, so a main face wins over a small coplanar boss face). When the\n * shape has no BREP handle or the kernel is unavailable, it falls back to the\n * whole-shape bounding-box approximation.\n *\n * Indexed selectors (`\">Z[-2]\"`) follow CadQuery's DirectionMinMaxSelector\n * indexing, verified against the installed cadquery 2.8.0: `\">A[k]\"` lists all\n * faces ASCENDING along axis A (`[0]` = lowest, `[-1]` = highest); `\"<A[k]\"`\n * lists them DESCENDING (`[0]` = highest). The picked face's normal is the\n * outward direction (away from the shape bbox center).\n *\n * @param shape - Shape whose BREP faces are enumerated for selection.\n * @param sel - Selector string, e.g. \">Z\", \"<X\", \">Z[-2]\", or a named view\n * (\"front\"/\"back\"/\"left\"/\"right\"/\"top\"/\"bottom\").\n * @param centerOption - Optional center computation option forwarded to the\n * face-center evaluation.\n * @returns Promise resolving to the selected face's center point and outward\n * normal.\n */\n/**\n * CadQuery named views → axis selector (cadquery/selectors.py:687-694).\n * Verified against installed cadquery 2.8.0 by evaluating\n * `Workplane().rect(1,1).extrude(1).faces(n).val()` for each name.\n */\nconst NAMED_VIEW_TO_AXIS: Record<string, string> = {\n front: '>Z',\n back: '<Z',\n left: '<X',\n right: '>X',\n top: '>Y',\n bottom: '<Y',\n}\n\n/**\n * Resolve a CadQuery-style face selector string to the selected face's center\n * point and outward normal.\n *\n * Supported forms: \">Z\", \"<Z\", \">X\", \"<X\", \">Y\", \"<Y\", each with an optional\n * CadQuery-style index suffix like \">Z[-2]\", plus the six named views\n * (\"front\"/\"back\"/\"left\"/\"right\"/\"top\"/\"bottom\") which are aliases for the\n * corresponding axis selectors per cadquery/selectors.py:687-694.\n * @param shape - Shape whose BREP faces are enumerated for selection.\n * @param sel - Selector string, e.g. \">Z\", \"front\", \">Z[-2]\".\n * @param centerOption - Optional center computation option forwarded to the\n * face-center evaluation.\n * @returns Promise resolving to the selected face's center point and outward\n * normal.\n * @throws Error when the selector matches no face or has unknown syntax\n * (never falls back silently).\n */\nexport async function resolveFaceSelector(\n shape: Shape,\n sel: string,\n centerOption?: string,\n): Promise<{ center: [number, number, number]; normal: [number, number, number] }> {\n // compatOp 提升边界:实参可能是借用视图(见 asBrepShape 注释)——归一为真实\n // Shape,否则 brepOf 为 undefined 会落到 bbox 兜底并在 cad.bboxMax 崩溃。\n shape = asBrepShape(shape)\n // CadQuery named views are aliases for an axis DirectionMinMaxSelector\n // (cadquery/selectors.py:687-694):\n // front=>(0,0,1,max) back=>(0,0,1,min) left=>(1,0,0,min)\n // right=>(1,0,0,max) top=>(0,1,0,max) bottom=>(0,1,0,min)\n // Normalise once so every branch below sees a plain axis selector; without\n // this the lookup misses and the whole-shape bbox fallback silently returns\n // the shape centre instead of the face plane (half-a-hole volume error).\n sel = NAMED_VIEW_TO_AXIS[sel.trim().toLowerCase()] ?? sel\n // Strip index suffix like [-2]\n const baseSel = sel.replace(/\\[-?\\d+\\]$/, '')\n const axisDir: Record<string, { axis: 0 | 1 | 2; sign: 1 | -1 }> = {\n '>Z': { axis: 2, sign: 1 }, '+Z': { axis: 2, sign: 1 },\n '<Z': { axis: 2, sign: -1 }, '-Z': { axis: 2, sign: -1 },\n '>X': { axis: 0, sign: 1 }, '+X': { axis: 0, sign: 1 },\n '<X': { axis: 0, sign: -1 }, '-X': { axis: 0, sign: -1 },\n '>Y': { axis: 1, sign: 1 }, '+Y': { axis: 1, sign: 1 },\n '<Y': { axis: 1, sign: -1 }, '-Y': { axis: 1, sign: -1 },\n }\n const normals: Record<string, [number, number, number]> = {\n '>Z': [0, 0, 1], '+Z': [0, 0, 1], '<Z': [0, 0, -1], '-Z': [0, 0, -1],\n '>X': [1, 0, 0], '+X': [1, 0, 0], '<X': [-1, 0, 0], '-X': [-1, 0, 0],\n '>Y': [0, 1, 0], '+Y': [0, 1, 0], '<Y': [0, -1, 0], '-Y': [0, -1, 0],\n }\n const dir = axisDir[baseSel]\n const fallbackNormal = normals[baseSel] ?? ([0, 0, 1] as [number, number, number])\n\n // ── Multi-axis direction selectors (\"+XY\", \">XZ\", \"-YZ\" … cadquery\n // selectors.py:625 axes table XY=(1,1,0) XZ=(1,0,1) YZ=(0,1,1)) ──\n // '+'/'-' → DirectionSelector: only faces whose outward normal is PARALLEL\n // to the (±) direction (angle < 1e-4 rad, selectors.py:234). '>'/'<' →\n // DirectionMinMaxSelector (selectors.py:399): the face whose center of MASS\n // is farthest along the direction. Index suffixes mean DirectionNthSelector\n // there — not supported, throw instead of silently approximating.\n const multi = /^([<>+-])(XY|XZ|YZ)$/.exec(baseSel)\n if (multi) {\n if (/\\[-?\\d+\\]$/.test(sel.trim())) {\n throw new Error(\n `[cq-compat] selector \"${sel}\": indexed multi-axis selectors not supported`,\n )\n }\n const axesTable: Record<string, [number, number, number]> = {\n XY: [1, 1, 0],\n XZ: [1, 0, 1],\n YZ: [0, 1, 1],\n }\n let d = axesTable[multi[2]]\n if (multi[1] === '-') d = [-d[0], -d[1], -d[2]]\n const dLen = Math.hypot(d[0], d[1], d[2])\n const dirV: [number, number, number] = [d[0] / dLen, d[1] / dLen, d[2] / dLen]\n const handleM = brepOf(shape)\n if (!handleM) {\n throw new Error(`[cq-compat] selector \"${sel}\": BREP unavailable`)\n }\n const kernelM = getKernel() as unknown as OcctKernel\n const faceList = kernelM.getSubShapes(handleM as unknown as ShapeHandle, 'face') as unknown as ShapeHandle[]\n if (faceList.length === 0) {\n throw new Error(`[cq-compat] selector \"${sel}\": shape has no faces`)\n }\n const faceNormalOf = (f: ShapeHandle): [number, number, number] => {\n const uv = kernelM.uvBounds(f)\n const n = kernelM.surfaceNormal(f, (uv.uMin + uv.uMax) / 2, (uv.vMin + uv.vMax) / 2)\n return [n.x, n.y, n.z]\n }\n const comOf = (f: ShapeHandle): [number, number, number] => {\n const c = kernelM.getSurfaceCenterOfMass(f)\n return [c.x, c.y, c.z]\n }\n const dot = (a: [number, number, number], b: [number, number, number]): number =>\n a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\n\n if (multi[1] === '+' || multi[1] === '-') {\n // DirectionSelector: angle(normal, dir) < 1e-4 rad (selectors.py:235).\n const PAR_TOL = Math.cos(1e-4)\n const found = faceList.find((f) => dot(faceNormalOf(f), dirV) > PAR_TOL)\n if (!found) {\n throw new Error(\n `[cq-compat] selector \"${sel}\": no face with normal parallel to the direction`,\n )\n }\n return { center: comOf(found), normal: faceNormalOf(found) }\n }\n // '>'/'<': DirectionMinMaxSelector over center-of-mass projections.\n let bestF: ShapeHandle | null = null\n let bestVal = 0\n for (const f of faceList) {\n const val = dot(comOf(f), dirV)\n if (!bestF || (multi[1] === '>' ? val > bestVal + 1e-9 : val < bestVal - 1e-9)) {\n bestF = f\n bestVal = val\n }\n }\n return { center: comOf(bestF!), normal: faceNormalOf(bestF!) }\n }\n\n // ── Face-based selection (BREP kernel available) ──\n try {\n const handle = brepOf(shape)\n const kernel = getKernel() as unknown as OcctKernel\n if (handle && dir) {\n const faces = kernel.getSubShapes(handle as unknown as ShapeHandle, 'face') as unknown as ShapeHandle[]\n const cands: { handle: ShapeHandle; center: [number, number, number] }[] = []\n for (const f of faces) {\n const bb = kernel.getBoundingBox(f)\n cands.push({\n handle: f,\n center: [\n (bb.xmin + bb.xmax) / 2,\n (bb.ymin + bb.ymax) / 2,\n (bb.zmin + bb.zmax) / 2,\n ],\n })\n }\n let best: { handle: ShapeHandle; center: [number, number, number] } | null = null\n let normal = fallbackNormal\n // Extract the index suffix, if any.\n const idxMatch = /\\[(-?\\d+)\\]$/.exec(sel.trim())\n if (idxMatch) {\n // CadQuery face indexing (verified vs cadquery 2.8.0):\n // '>A[k]' / '<A[k]' DirectionMinMaxSelector: '>' ascending, '<' descending\n // '+A[k]' / '-A[k]' DirectionSelector: list the extreme face first, then\n // inward — '-' ascending, '+' descending along A\n // (faces(\"-Y\")[1] is the 2nd -Y face from the -Y extreme,\n // NOT the +Y extreme face).\n // Only faces PERPENDICULAR to the axis participate (bbox thin along the axis).\n // For '+'/'-' selectors we additionally keep only faces whose outward normal\n // is parallel to the selector axis with the matching sign (CadQuery filters\n // by exact normal direction), so a boss face and its base sibling don't\n // collide in the index.\n const sc = baseSel[0]\n const isDirSelector = sc === '+' || sc === '-'\n const perp: typeof cands = cands.filter((cd) => {\n const bb = kernel.getBoundingBox(cd.handle)\n const ext = [bb.xmax - bb.xmin, bb.ymax - bb.ymin, bb.zmax - bb.zmin][dir.axis]\n if (ext > 0.1) return false\n if (isDirSelector) {\n const uv = kernel.uvBounds(cd.handle)\n const n = kernel.surfaceNormal(cd.handle, (uv.uMin + uv.uMax) / 2, (uv.vMin + uv.vMax) / 2)\n const nv: [number, number, number] = [n.x, n.y, n.z]\n if (Math.abs(nv[dir.axis]) < 0.999) return false\n if (Math.sign(nv[dir.axis]) !== dir.sign) return false\n }\n return true\n })\n const idx = parseInt(idxMatch[1], 10)\n const asc = sc === '>' || sc === '-'\n const sorted = perp\n .slice()\n .sort((a, b) => (asc ? a.center[dir.axis] - b.center[dir.axis] : b.center[dir.axis] - a.center[dir.axis]))\n const pick = idx < 0 ? sorted.length + idx : idx\n if (pick < 0 || pick >= sorted.length) {\n throw new Error(\n `[cq-compat] selector \"${sel}\": index ${idx} out of range (${sorted.length} faces)`,\n )\n }\n best = sorted[pick]\n if (isDirSelector) {\n // DirectionSelector: the outward normal is exactly the selector axis/sign.\n normal = fallbackNormal\n } else {\n // DirectionMinMaxSelector: outward normal from face position vs shape centre.\n const max = bboxMax(shape)\n const min = bboxMin(shape)\n const shapeCenter = [(max[0] + min[0]) / 2, (max[1] + min[1]) / 2, (max[2] + min[2]) / 2]\n normal = [0, 0, 0]\n normal[dir.axis] = best.center[dir.axis] >= shapeCenter[dir.axis] ? 1 : -1\n }\n } else {\n for (const cd of cands) {\n const val = cd.center[dir.axis]\n if (!best) {\n best = cd\n continue\n }\n const bestVal = best.center[dir.axis]\n if (dir.sign === 1 ? val > bestVal + 1e-6 : val < bestVal - 1e-6) {\n best = cd\n } else if (Math.abs(val - bestVal) <= 1e-6) {\n // Tie (e.g. coplanar faces at the same extreme): prefer the larger face\n const area = kernel.getSurfaceArea(cd.handle)\n if (area > kernel.getSurfaceArea(best.handle)) best = cd\n }\n }\n }\n if (best) {\n let origin: [number, number, number]\n if (centerOption === 'CenterOfBoundBox') {\n origin = best.center\n } else {\n // CenterOfMass: surface (area-weighted) centroid\n const com = kernel.getSurfaceCenterOfMass(best.handle)\n origin = [com.x, com.y, com.z]\n }\n return { center: origin, normal }\n }\n }\n } catch (e) {\n if (e instanceof Error && e.message.includes('out of range')) throw e\n // No BREP / kernel not ready — fall through to bbox approximation\n }\n\n // ── Fallback: whole-shape bbox (previous behavior) ──\n const max = bboxMax(shape)\n const min = bboxMin(shape)\n const center: [number, number, number] = [\n (max[0] + min[0]) / 2,\n (max[1] + min[1]) / 2,\n (max[2] + min[2]) / 2,\n ]\n\n const m = /^([<>+-])([XYZ])(?:\\[(-?\\d+)\\])?$/.exec(sel.trim())\n if (!m) {\n // Default: return center\n return { center, normal: [0, 0, 1] }\n }\n const [, sign, axisChar, idxStr] = m\n const axis = axisChar === 'X' ? 0 : axisChar === 'Y' ? 1 : 2\n // '>' and '+' select the max side; '<' and '-' select the min side.\n const maxDir = sign === '>' || sign === '+'\n const normal: [number, number, number] = [0, 0, 0]\n normal[axis] = maxDir ? 1 : -1\n\n if (idxStr === undefined) {\n const extreme: [number, number, number] = [center[0], center[1], center[2]]\n extreme[axis] = maxDir ? max[axis] : min[axis]\n return { center: extreme, normal }\n }\n\n // Indexed selector — enumerate real faces and sort by bbox center along axis.\n // CadQuery semantics: '>A[k]' ascending, '<A[k]' descending (see doc above).\n const idx = parseInt(idxStr, 10)\n const faces = kern().getSubShapes(ownHandle(shape), 'face') as unknown[]\n type Entry = { c: [number, number, number]; bounds: Record<string, number> }\n const entries: Entry[] = faces.map((f) => {\n const b = kern().getBoundingBox(f as BrepHandle) as unknown as Record<string, number>\n return {\n c: [(b.xmin + b.xmax) / 2, (b.ymin + b.ymax) / 2, (b.zmin + b.zmax) / 2],\n bounds: b,\n }\n })\n if (entries.length === 0) {\n throw new Error(`[cq-compat] selector \"${sel}\": shape has no faces`)\n }\n entries.sort((a, b) => (maxDir ? a.c[axis] - b.c[axis] : b.c[axis] - a.c[axis]))\n const pick = idx < 0 ? entries.length + idx : idx\n if (pick < 0 || pick >= entries.length) {\n throw new Error(\n `[cq-compat] selector \"${sel}\": index ${idx} out of range (${entries.length} faces)`,\n )\n }\n const fb = entries[pick].bounds\n const faceCenter: [number, number, number] = [\n (fb.xmin + fb.xmax) / 2,\n (fb.ymin + fb.ymax) / 2,\n (fb.zmin + fb.zmax) / 2,\n ]\n // Outward normal: away from the shape bbox center along the axis.\n normal[axis] = faceCenter[axis] >= center[axis] ? 1 : -1\n return { center: faceCenter, normal }\n}"]}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * cadquery-selectors/grammar — CadQuery string-syntax selector grammar.
3
+ *
4
+ * Hand-rolled recursive-descent parser mirroring the upstream grammar
5
+ * `cadquery/selectors.py::_makeGrammar` + `_makeExpressionGrammar`. No
6
+ * pyparsing dependency is introduced; this small grammar is hand-parsed.
7
+ *
8
+ * Precedence (pyparsing infix_notation lists operators lowest→highest):
9
+ * `and` (lowest) < `or` < `exc`/`except` < `not` (highest)
10
+ * so `not` binds tightest and `and` sits at the root of the tree.
11
+ *
12
+ * Atom forms (upstream `_makeGrammar`):
13
+ * * bare direction `X`|`Y`|`Z`|`XY`|`XZ`|`YZ`|`(x,y,z)` → DirectionSelector
14
+ * * named view `front`|`back`|`left`|`right`|`top`|`bottom` → DirectionMinMax
15
+ * * `%TYPE` type_op + caseless LUT member (upcased) → TypeSelector
16
+ * * `>A` / `>A[k]` direction_op + dir + optional index → DirectionNth
17
+ * * `>>A` / `<<A[k]` center_nth_op + dir + optional index → CenterNth
18
+ * * `|A`|`#A`|`+A`|`-A` other_op + direction → Parallel / Perp / Direction
19
+ *
20
+ * Binary operators fold their operands into a single n-ary node, matching the
21
+ * pyparsing odd-indexed reduce in the upstream callbacks.
22
+ */
23
+ import type { SelectorExpr, Vec3 } from './types.js';
24
+ /**
25
+ * The complete set of syntax features this grammar supports, in one place.
26
+ * The selector-parity plan drives its coverage gate off this list — adding a
27
+ * syntax feature without a coverage entry fails that gate.
28
+ */
29
+ export declare const SYNTAX_FEATURES: {
30
+ group: string;
31
+ name: string;
32
+ token: string;
33
+ }[];
34
+ /** Named views → (direction, max) — upstream `_SimpleStringSyntaxSelector.namedViews`. */
35
+ export declare const NAMED_VIEW: Record<string, {
36
+ vec: Vec3;
37
+ max: boolean;
38
+ }>;
39
+ /** Axes table — upstream `_SimpleStringSyntaxSelector.axes` (kept NON-unit). */
40
+ export declare const AXES: Record<string, Vec3>;
41
+ /** Valid `%type` names — union of upstream geom_LUT_EDGE ∪ geom_LUT_FACE values. */
42
+ export declare const TYPE_NAMES: ReadonlySet<string>;
43
+ /**
44
+ * Parse a raw CadQuery selector expression string into an AST.
45
+ *
46
+ * @param expr - The CadQuery selector string (e.g. `">Z and |X"`).
47
+ * @returns The parsed selector AST.
48
+ */
49
+ export declare function parseSelector(expr: string): SelectorExpr;
50
+ //# sourceMappingURL=grammar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/grammar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAY,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE3D;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EA+B3E,CAAA;AAED,0FAA0F;AAC1F,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAOlE,CAAA;AAED,gFAAgF;AAChF,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAOrC,CAAA;AAED,oFAAoF;AACpF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CAIzC,CAAA;AA+QF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAKxD"}