@faicad/faijs 0.33.1 → 0.35.2

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 (392) hide show
  1. package/dist/api/api-namespace.d.ts +14 -14
  2. package/dist/api/api-namespace.d.ts.map +1 -1
  3. package/dist/api/api-namespace.js +40 -14
  4. package/dist/api/api-namespace.js.map +1 -1
  5. package/dist/api/appearance.d.ts +47 -6
  6. package/dist/api/appearance.d.ts.map +1 -1
  7. package/dist/api/appearance.js.map +1 -1
  8. package/dist/api/assembly/solve-tree.d.ts +1 -0
  9. package/dist/api/assembly/solve-tree.d.ts.map +1 -1
  10. package/dist/api/assembly/solve-tree.js +42 -17
  11. package/dist/api/assembly/solve-tree.js.map +1 -1
  12. package/dist/api/assembly/solve.d.ts +1 -0
  13. package/dist/api/assembly/solve.d.ts.map +1 -1
  14. package/dist/api/assembly/solve.js.map +1 -1
  15. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  16. package/dist/api/assembly/solvers/global-solver.js +130 -23
  17. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  18. package/dist/api/assembly/solvers/pose-from-delta.d.ts +9 -0
  19. package/dist/api/assembly/solvers/pose-from-delta.d.ts.map +1 -1
  20. package/dist/api/assembly/solvers/pose-from-delta.js +23 -0
  21. package/dist/api/assembly/solvers/pose-from-delta.js.map +1 -1
  22. package/dist/api/assembly/solvers/types.d.ts +20 -2
  23. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  24. package/dist/api/assembly/solvers/types.js.map +1 -1
  25. package/dist/api/chamfer.d.ts +7 -4
  26. package/dist/api/chamfer.d.ts.map +1 -1
  27. package/dist/api/chamfer.js +57 -13
  28. package/dist/api/chamfer.js.map +1 -1
  29. package/dist/api/draft.d.ts +7 -4
  30. package/dist/api/draft.d.ts.map +1 -1
  31. package/dist/api/draft.js +11 -6
  32. package/dist/api/draft.js.map +1 -1
  33. package/dist/api/edge-ref.d.ts +4 -4
  34. package/dist/api/edge-ref.js +4 -4
  35. package/dist/api/edge-ref.js.map +1 -1
  36. package/dist/api/extrude.d.ts +10 -6
  37. package/dist/api/extrude.d.ts.map +1 -1
  38. package/dist/api/extrude.js +50 -25
  39. package/dist/api/extrude.js.map +1 -1
  40. package/dist/api/face-ref.d.ts +4 -4
  41. package/dist/api/face-ref.js +4 -4
  42. package/dist/api/face-ref.js.map +1 -1
  43. package/dist/api/feature-repair.d.ts +6 -3
  44. package/dist/api/feature-repair.d.ts.map +1 -1
  45. package/dist/api/feature-repair.js +12 -7
  46. package/dist/api/feature-repair.js.map +1 -1
  47. package/dist/api/fillet-variable.d.ts +6 -2
  48. package/dist/api/fillet-variable.d.ts.map +1 -1
  49. package/dist/api/fillet-variable.js +24 -6
  50. package/dist/api/fillet-variable.js.map +1 -1
  51. package/dist/api/fillet.d.ts +7 -4
  52. package/dist/api/fillet.d.ts.map +1 -1
  53. package/dist/api/fillet.js +45 -12
  54. package/dist/api/fillet.js.map +1 -1
  55. package/dist/api/helix.d.ts +13 -13
  56. package/dist/api/helix.d.ts.map +1 -1
  57. package/dist/api/helix.js +19 -24
  58. package/dist/api/helix.js.map +1 -1
  59. package/dist/api/import-brep.d.ts +10 -18
  60. package/dist/api/import-brep.d.ts.map +1 -1
  61. package/dist/api/import-brep.js +17 -25
  62. package/dist/api/import-brep.js.map +1 -1
  63. package/dist/api/import-step.d.ts +10 -15
  64. package/dist/api/import-step.d.ts.map +1 -1
  65. package/dist/api/import-step.js +24 -29
  66. package/dist/api/import-step.js.map +1 -1
  67. package/dist/api/index.js +2 -2
  68. package/dist/api/index.js.map +1 -1
  69. package/dist/api/internal/export-members.js.map +1 -1
  70. package/dist/api/loft-advanced.d.ts +4 -0
  71. package/dist/api/loft-advanced.d.ts.map +1 -1
  72. package/dist/api/loft-advanced.js +4 -0
  73. package/dist/api/loft-advanced.js.map +1 -1
  74. package/dist/api/loft.d.ts +5 -3
  75. package/dist/api/loft.d.ts.map +1 -1
  76. package/dist/api/loft.js +5 -3
  77. package/dist/api/loft.js.map +1 -1
  78. package/dist/api/meta.d.ts +42 -6
  79. package/dist/api/meta.d.ts.map +1 -1
  80. package/dist/api/meta.js.map +1 -1
  81. package/dist/api/punch-hole.d.ts +5 -2
  82. package/dist/api/punch-hole.d.ts.map +1 -1
  83. package/dist/api/punch-hole.js +4 -1
  84. package/dist/api/punch-hole.js.map +1 -1
  85. package/dist/api/replicate.d.ts +4 -5
  86. package/dist/api/replicate.d.ts.map +1 -1
  87. package/dist/api/replicate.js +4 -5
  88. package/dist/api/replicate.js.map +1 -1
  89. package/dist/api/selectors-to-refs.d.ts +83 -0
  90. package/dist/api/selectors-to-refs.d.ts.map +1 -0
  91. package/dist/api/selectors-to-refs.js +211 -0
  92. package/dist/api/selectors-to-refs.js.map +1 -0
  93. package/dist/api/shell.d.ts +17 -8
  94. package/dist/api/shell.d.ts.map +1 -1
  95. package/dist/api/shell.js +45 -15
  96. package/dist/api/shell.js.map +1 -1
  97. package/dist/api/sketch-on-face.d.ts +12 -6
  98. package/dist/api/sketch-on-face.d.ts.map +1 -1
  99. package/dist/api/sketch-on-face.js +31 -4
  100. package/dist/api/sketch-on-face.js.map +1 -1
  101. package/dist/api/sketch-on-plane.d.ts +3 -0
  102. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  103. package/dist/api/sketch-on-plane.js +3 -0
  104. package/dist/api/sketch-on-plane.js.map +1 -1
  105. package/dist/api/sketch-on-surface.d.ts +4 -1
  106. package/dist/api/sketch-on-surface.d.ts.map +1 -1
  107. package/dist/api/sketch-on-surface.js +4 -1
  108. package/dist/api/sketch-on-surface.js.map +1 -1
  109. package/dist/api/view/view-projection.d.ts.map +1 -1
  110. package/dist/api/view/view-projection.js +9 -2
  111. package/dist/api/view/view-projection.js.map +1 -1
  112. package/dist/brep/brep-chain.js +2 -2
  113. package/dist/brep/brep-chain.js.map +1 -1
  114. package/dist/brep/brep-ops.d.ts +1 -1
  115. package/dist/brep/brep-ops.js +1 -1
  116. package/dist/brep/brep-ops.js.map +1 -1
  117. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  118. package/dist/brep/engine/adapters/brep-mock.js +45 -0
  119. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  120. package/dist/brep/engine/primitives.d.ts +87 -3
  121. package/dist/brep/engine/primitives.d.ts.map +1 -1
  122. package/dist/brep/engine/primitives.js +1 -1
  123. package/dist/brep/engine/primitives.js.map +1 -1
  124. package/dist/brep/engine/registry.d.ts +33 -7
  125. package/dist/brep/engine/registry.d.ts.map +1 -1
  126. package/dist/brep/engine/registry.js +47 -16
  127. package/dist/brep/engine/registry.js.map +1 -1
  128. package/dist/brep/handle-bridge.d.ts +14 -15
  129. package/dist/brep/handle-bridge.d.ts.map +1 -1
  130. package/dist/brep/handle-bridge.js +35 -15
  131. package/dist/brep/handle-bridge.js.map +1 -1
  132. package/dist/brep/primitives-brep.js +2 -2
  133. package/dist/brep/primitives-brep.js.map +1 -1
  134. package/dist/brep/text/text-to-solid.d.ts +40 -3
  135. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  136. package/dist/brep/text/text-to-solid.js +104 -24
  137. package/dist/brep/text/text-to-solid.js.map +1 -1
  138. package/dist/brepkit-kernel/brepkitKernel.d.ts +2 -2
  139. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  140. package/dist/brepkit-kernel/brepkitKernel.js +315 -36
  141. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  142. package/dist/brepkit-kernel/brepkitWasm.js +7 -7
  143. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  144. package/dist/brepkit-kernel/multi-version-test.d.ts +2 -2
  145. package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
  146. package/dist/brepkit-kernel/multi-version-test.js +6 -6
  147. package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
  148. package/dist/browser.d.ts +2 -3
  149. package/dist/browser.d.ts.map +1 -1
  150. package/dist/browser.js +1 -2
  151. package/dist/browser.js.map +1 -1
  152. package/dist/cad-runtime/admit-compat-lib.d.ts +9 -1
  153. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  154. package/dist/cad-runtime/admit-compat-lib.js +11 -1
  155. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  156. package/dist/cad-runtime/browser-lib-loader.d.ts +16 -11
  157. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  158. package/dist/cad-runtime/browser-lib-loader.js +16 -8
  159. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  160. package/dist/cad-runtime/direct-executor.d.ts +62 -5
  161. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  162. package/dist/cad-runtime/direct-executor.js +617 -42
  163. package/dist/cad-runtime/direct-executor.js.map +1 -1
  164. package/dist/cad-runtime/interp/closure.d.ts +3 -2
  165. package/dist/cad-runtime/interp/closure.d.ts.map +1 -1
  166. package/dist/cad-runtime/interp/closure.js.map +1 -1
  167. package/dist/cad-runtime/interp/env.d.ts +9 -6
  168. package/dist/cad-runtime/interp/env.d.ts.map +1 -1
  169. package/dist/cad-runtime/interp/env.js +4 -2
  170. package/dist/cad-runtime/interp/env.js.map +1 -1
  171. package/dist/cad-runtime/lib-decl.d.ts +121 -0
  172. package/dist/cad-runtime/lib-decl.d.ts.map +1 -0
  173. package/dist/cad-runtime/lib-decl.js +100 -0
  174. package/dist/cad-runtime/lib-decl.js.map +1 -0
  175. package/dist/cad-runtime/ports.d.ts +12 -0
  176. package/dist/cad-runtime/ports.d.ts.map +1 -1
  177. package/dist/cad-runtime/ports.js.map +1 -1
  178. package/dist/cad-runtime/runtime.d.ts +59 -5
  179. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  180. package/dist/cad-runtime/runtime.js +237 -18
  181. package/dist/cad-runtime/runtime.js.map +1 -1
  182. package/dist/extra/browser.d.ts +9 -0
  183. package/dist/extra/browser.d.ts.map +1 -0
  184. package/dist/extra/browser.js +9 -0
  185. package/dist/extra/browser.js.map +1 -0
  186. package/dist/extra/editor-ops.d.ts +22 -0
  187. package/dist/extra/editor-ops.d.ts.map +1 -0
  188. package/dist/extra/editor-ops.js +21 -0
  189. package/dist/extra/editor-ops.js.map +1 -0
  190. package/dist/extra/extras/svg-extrude.d.ts +45 -0
  191. package/dist/extra/extras/svg-extrude.d.ts.map +1 -0
  192. package/dist/extra/extras/svg-extrude.js +110 -0
  193. package/dist/extra/extras/svg-extrude.js.map +1 -0
  194. package/dist/extra/extras/text-cjk.d.ts +36 -0
  195. package/dist/extra/extras/text-cjk.d.ts.map +1 -0
  196. package/dist/extra/extras/text-cjk.js +86 -0
  197. package/dist/extra/extras/text-cjk.js.map +1 -0
  198. package/dist/extra/extras/text-geometry.d.ts +69 -0
  199. package/dist/extra/extras/text-geometry.d.ts.map +1 -0
  200. package/dist/extra/extras/text-geometry.js +188 -0
  201. package/dist/extra/extras/text-geometry.js.map +1 -0
  202. package/dist/extra/index.d.ts +40 -0
  203. package/dist/extra/index.d.ts.map +1 -0
  204. package/dist/extra/index.js +40 -0
  205. package/dist/extra/index.js.map +1 -0
  206. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts +94 -0
  207. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts.map +1 -0
  208. package/dist/extra/mesh/drill-hole/DrillHoleCore.js +282 -0
  209. package/dist/extra/mesh/drill-hole/DrillHoleCore.js.map +1 -0
  210. package/dist/extra/mesh/drill-hole/drill-types.d.ts +34 -0
  211. package/dist/extra/mesh/drill-hole/drill-types.d.ts.map +1 -0
  212. package/dist/extra/mesh/drill-hole/drill-types.js +7 -0
  213. package/dist/extra/mesh/drill-hole/drill-types.js.map +1 -0
  214. package/dist/extra/mesh/engrave-decoration.d.ts +42 -0
  215. package/dist/extra/mesh/engrave-decoration.d.ts.map +1 -0
  216. package/dist/extra/mesh/engrave-decoration.js +39 -0
  217. package/dist/extra/mesh/engrave-decoration.js.map +1 -0
  218. package/dist/extra/mesh/fai_drill.d.ts +21 -0
  219. package/dist/extra/mesh/fai_drill.d.ts.map +1 -0
  220. package/dist/extra/mesh/fai_drill.js +89 -0
  221. package/dist/extra/mesh/fai_drill.js.map +1 -0
  222. package/dist/extra/mesh/fai_extrude.d.ts +24 -0
  223. package/dist/extra/mesh/fai_extrude.d.ts.map +1 -0
  224. package/dist/extra/mesh/fai_extrude.js +42 -0
  225. package/dist/extra/mesh/fai_extrude.js.map +1 -0
  226. package/dist/extra/mesh/fai_split.d.ts +164 -0
  227. package/dist/extra/mesh/fai_split.d.ts.map +1 -0
  228. package/dist/extra/mesh/fai_split.js +269 -0
  229. package/dist/extra/mesh/fai_split.js.map +1 -0
  230. package/dist/extra/mesh/primitives.d.ts +29 -0
  231. package/dist/extra/mesh/primitives.d.ts.map +1 -0
  232. package/dist/extra/mesh/primitives.js +41 -0
  233. package/dist/extra/mesh/primitives.js.map +1 -0
  234. package/dist/extra/op-names.d.ts +37 -0
  235. package/dist/extra/op-names.d.ts.map +1 -0
  236. package/dist/extra/op-names.js +46 -0
  237. package/dist/extra/op-names.js.map +1 -0
  238. package/dist/extra/ops/compound.d.ts +140 -0
  239. package/dist/extra/ops/compound.d.ts.map +1 -0
  240. package/dist/extra/ops/compound.js +167 -0
  241. package/dist/extra/ops/compound.js.map +1 -0
  242. package/dist/extra/ops/copy.d.ts +40 -0
  243. package/dist/extra/ops/copy.d.ts.map +1 -0
  244. package/dist/extra/ops/copy.js +83 -0
  245. package/dist/extra/ops/copy.js.map +1 -0
  246. package/dist/extra/ops/fai_drill.d.ts +51 -0
  247. package/dist/extra/ops/fai_drill.d.ts.map +1 -0
  248. package/dist/extra/ops/fai_drill.js +233 -0
  249. package/dist/extra/ops/fai_drill.js.map +1 -0
  250. package/dist/extra/ops/fai_extrude.d.ts +36 -0
  251. package/dist/extra/ops/fai_extrude.d.ts.map +1 -0
  252. package/dist/extra/ops/fai_extrude.js +84 -0
  253. package/dist/extra/ops/fai_extrude.js.map +1 -0
  254. package/dist/extra/ops/fai_split.d.ts +46 -0
  255. package/dist/extra/ops/fai_split.d.ts.map +1 -0
  256. package/dist/extra/ops/fai_split.js +235 -0
  257. package/dist/extra/ops/fai_split.js.map +1 -0
  258. package/dist/extra/ops/load.d.ts +49 -0
  259. package/dist/extra/ops/load.d.ts.map +1 -0
  260. package/dist/extra/ops/load.js +385 -0
  261. package/dist/extra/ops/load.js.map +1 -0
  262. package/dist/extra/ops/svg-extrude.d.ts +32 -0
  263. package/dist/extra/ops/svg-extrude.d.ts.map +1 -0
  264. package/dist/extra/ops/svg-extrude.js +74 -0
  265. package/dist/extra/ops/svg-extrude.js.map +1 -0
  266. package/dist/extra/ops/text.d.ts +34 -0
  267. package/dist/extra/ops/text.d.ts.map +1 -0
  268. package/dist/extra/ops/text.js +100 -0
  269. package/dist/extra/ops/text.js.map +1 -0
  270. package/dist/geometry2d/bridge/lift-on-plane.d.ts +8 -5
  271. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  272. package/dist/geometry2d/bridge/lift-on-plane.js +8 -5
  273. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  274. package/dist/index.d.ts +6 -2
  275. package/dist/index.d.ts.map +1 -1
  276. package/dist/index.js +8 -2
  277. package/dist/index.js.map +1 -1
  278. package/dist/lang/symbol-table.d.ts +3 -3
  279. package/dist/lang/symbol-table.generated.d.ts +10 -0
  280. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  281. package/dist/lang/symbol-table.generated.js +10 -0
  282. package/dist/lang/symbol-table.generated.js.map +1 -1
  283. package/dist/lang/symbol-table.js +3 -3
  284. package/dist/lang/symbol-table.js.map +1 -1
  285. package/dist/math3d/index.d.ts +1 -1
  286. package/dist/math3d/index.js +1 -1
  287. package/dist/math3d/index.js.map +1 -1
  288. package/dist/mesh/engrave.d.ts +2 -3
  289. package/dist/mesh/engrave.d.ts.map +1 -1
  290. package/dist/mesh/engrave.js +4 -11
  291. package/dist/mesh/engrave.js.map +1 -1
  292. package/dist/mesh/index.d.ts +0 -2
  293. package/dist/mesh/index.d.ts.map +1 -1
  294. package/dist/mesh/index.js +0 -2
  295. package/dist/mesh/index.js.map +1 -1
  296. package/dist/mesh/primitives.d.ts +1 -1
  297. package/dist/mesh/primitives.js +1 -1
  298. package/dist/mesh/primitives.js.map +1 -1
  299. package/dist/node-host/cli.d.ts +20 -4
  300. package/dist/node-host/cli.d.ts.map +1 -1
  301. package/dist/node-host/cli.js +84 -35
  302. package/dist/node-host/cli.js.map +1 -1
  303. package/dist/node-host/execute-script.d.ts.map +1 -1
  304. package/dist/node-host/execute-script.js +3 -4
  305. package/dist/node-host/execute-script.js.map +1 -1
  306. package/dist/node-host/lib-package-json.d.ts +36 -0
  307. package/dist/node-host/lib-package-json.d.ts.map +1 -0
  308. package/dist/node-host/lib-package-json.js +73 -0
  309. package/dist/node-host/lib-package-json.js.map +1 -0
  310. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  311. package/dist/occt-kernel/occt-primitives.js +41 -0
  312. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  313. package/dist/occt-kernel/occtKernel.d.ts +1 -1
  314. package/dist/occt-kernel/occtKernel.js +1 -1
  315. package/dist/occt-kernel/occtKernel.js.map +1 -1
  316. package/dist/runtime-state.d.ts +28 -1
  317. package/dist/runtime-state.d.ts.map +1 -1
  318. package/dist/runtime-state.js +14 -1
  319. package/dist/runtime-state.js.map +1 -1
  320. package/dist/sdk.d.ts +2 -2
  321. package/dist/sdk.d.ts.map +1 -1
  322. package/dist/sdk.js +11 -2
  323. package/dist/sdk.js.map +1 -1
  324. package/dist/sketch/bspline.d.ts +58 -0
  325. package/dist/sketch/bspline.d.ts.map +1 -0
  326. package/dist/sketch/bspline.js +104 -0
  327. package/dist/sketch/bspline.js.map +1 -0
  328. package/dist/sketch/canonical.d.ts +239 -0
  329. package/dist/sketch/canonical.d.ts.map +1 -0
  330. package/dist/sketch/canonical.js +17 -0
  331. package/dist/sketch/canonical.js.map +1 -0
  332. package/dist/sketch/contour.d.ts +43 -0
  333. package/dist/sketch/contour.d.ts.map +1 -0
  334. package/dist/sketch/contour.js +202 -0
  335. package/dist/sketch/contour.js.map +1 -0
  336. package/dist/sketch/dim-spec.d.ts +32 -0
  337. package/dist/sketch/dim-spec.d.ts.map +1 -0
  338. package/dist/sketch/dim-spec.js +112 -0
  339. package/dist/sketch/dim-spec.js.map +1 -0
  340. package/dist/sketch/faces.d.ts +45 -0
  341. package/dist/sketch/faces.d.ts.map +1 -0
  342. package/dist/sketch/faces.js +108 -0
  343. package/dist/sketch/faces.js.map +1 -0
  344. package/dist/sketch/fcstd-types.d.ts +194 -0
  345. package/dist/sketch/fcstd-types.d.ts.map +1 -0
  346. package/dist/sketch/fcstd-types.js +67 -0
  347. package/dist/sketch/fcstd-types.js.map +1 -0
  348. package/dist/sketch/index.d.ts +46 -0
  349. package/dist/sketch/index.d.ts.map +1 -0
  350. package/dist/sketch/index.js +39 -0
  351. package/dist/sketch/index.js.map +1 -0
  352. package/dist/sketch/node.d.ts +14 -0
  353. package/dist/sketch/node.d.ts.map +1 -0
  354. package/dist/sketch/node.js +43 -0
  355. package/dist/sketch/node.js.map +1 -0
  356. package/dist/sketch/op.d.ts +111 -0
  357. package/dist/sketch/op.d.ts.map +1 -0
  358. package/dist/sketch/op.js +185 -0
  359. package/dist/sketch/op.js.map +1 -0
  360. package/dist/sketch/planegcs-backend.d.ts +69 -0
  361. package/dist/sketch/planegcs-backend.d.ts.map +1 -0
  362. package/dist/sketch/planegcs-backend.js +812 -0
  363. package/dist/sketch/planegcs-backend.js.map +1 -0
  364. package/dist/sketch/project.d.ts +176 -0
  365. package/dist/sketch/project.d.ts.map +1 -0
  366. package/dist/sketch/project.js +656 -0
  367. package/dist/sketch/project.js.map +1 -0
  368. package/dist/sketch/shapes.d.ts +370 -0
  369. package/dist/sketch/shapes.d.ts.map +1 -0
  370. package/dist/sketch/shapes.js +959 -0
  371. package/dist/sketch/shapes.js.map +1 -0
  372. package/dist/sketch/solve.d.ts +21 -0
  373. package/dist/sketch/solve.d.ts.map +1 -0
  374. package/dist/sketch/solve.js +144 -0
  375. package/dist/sketch/solve.js.map +1 -0
  376. package/dist/sketch/solver-loader.d.ts +47 -0
  377. package/dist/sketch/solver-loader.d.ts.map +1 -0
  378. package/dist/sketch/solver-loader.js +77 -0
  379. package/dist/sketch/solver-loader.js.map +1 -0
  380. package/dist/sketch/solver.d.ts +63 -0
  381. package/dist/sketch/solver.d.ts.map +1 -0
  382. package/dist/sketch/solver.js +28 -0
  383. package/dist/sketch/solver.js.map +1 -0
  384. package/dist/sketch/verify.d.ts +53 -0
  385. package/dist/sketch/verify.d.ts.map +1 -0
  386. package/dist/sketch/verify.js +71 -0
  387. package/dist/sketch/verify.js.map +1 -0
  388. package/dist/weapp.d.ts +1 -1
  389. package/dist/weapp.d.ts.map +1 -1
  390. package/dist/weapp.js +1 -1
  391. package/dist/weapp.js.map +1 -1
  392. package/package.json +43 -11
@@ -0,0 +1,656 @@
1
+ /**
2
+ * project — single-point conversion between the canonical sketch model and the
3
+ * two downstream projection dialects (§4.5).
4
+ *
5
+ * canonical ⇄ FCStd (`fcstd-types`, integer ConstraintType + PointPos)
6
+ * canonical ⇄ CadQuery (tag + string constraint names, 0..1 positions)
7
+ *
8
+ * One implementation, two projections: the FCStd side feeds the planegcs solve
9
+ * pipeline; the CadQuery side feeds `cq-compat-sketch`. Constraints with no
10
+ * counterpart in a target dialect raise an explicit `E_SKETCHC_*` — never a
11
+ * silent downgrade.
12
+ */
13
+ import { PointPos, GeoId, CONSTRAINT_NAMES, ConstraintType } from './fcstd-types.js';
14
+ import { evalBSpline } from './bspline.js';
15
+ /** Projection error with a stable `E_SKETCHC_*` code. */
16
+ export class SketchProjectionError extends Error {
17
+ code;
18
+ constructor(code, message) {
19
+ super(`${code}: ${message}`);
20
+ this.code = code;
21
+ this.name = 'SketchProjectionError';
22
+ }
23
+ }
24
+ // ── at / Ref resolution ──
25
+ /**
26
+ * Map a canonical `At` to an FCStd `PointPos`. Throws `E_SKETCHC_UNMAPPED` when there is no counterpart.
27
+ *
28
+ * @param at - the canonical position.
29
+ * @returns the FCStd `PointPos` integer.
30
+ */
31
+ export function atToFreeCad(at) {
32
+ if (at === undefined)
33
+ return PointPos.none;
34
+ if (at === 'start')
35
+ return PointPos.start;
36
+ if (at === 'end')
37
+ return PointPos.end;
38
+ if (at === 'center')
39
+ return PointPos.mid;
40
+ if (at === 'mid') {
41
+ throw new SketchProjectionError('E_SKETCHC_UNMAPPED', 'at "mid" (arc/line midpoint) has no FCStd PointPos');
42
+ }
43
+ if (typeof at === 'number') {
44
+ if (at === 0)
45
+ return PointPos.start;
46
+ if (at === 1)
47
+ return PointPos.end;
48
+ throw new SketchProjectionError('E_SKETCHC_UNMAPPED', `parametric at ${at} has no FCStd PointPos`);
49
+ }
50
+ throw new SketchProjectionError('E_SKETCHC_UNMAPPED', `unsupported at ${String(at)}`);
51
+ }
52
+ /**
53
+ * Map an FCStd `PointPos` to a canonical `At` (`mid` FCStd means the centre).
54
+ *
55
+ * @param pos - the FCStd `PointPos` integer.
56
+ * @returns the canonical position, or `undefined` for `none`.
57
+ */
58
+ export function atFromFreeCad(pos) {
59
+ switch (pos) {
60
+ case PointPos.none: return undefined;
61
+ case PointPos.start: return 'start';
62
+ case PointPos.end: return 'end';
63
+ case PointPos.mid: return 'center';
64
+ default: return undefined;
65
+ }
66
+ }
67
+ /**
68
+ * Map a canonical `At` to a CadQuery 0..1 parameter (`null` = the arc-centre `None` argument).
69
+ *
70
+ * @param at - the canonical position.
71
+ * @returns the CadQuery 0..1 parameter, or `null` for centre.
72
+ */
73
+ export function atToCadQuery(at) {
74
+ if (at === undefined)
75
+ return null;
76
+ if (at === 'start')
77
+ return 0;
78
+ if (at === 'end')
79
+ return 1;
80
+ if (at === 'mid')
81
+ return 0.5;
82
+ if (at === 'center')
83
+ return null;
84
+ return at;
85
+ }
86
+ /**
87
+ * Map a CadQuery 0..1 parameter to a canonical `At`.
88
+ *
89
+ * @param v - the CadQuery parameter, or `null`/`undefined` for centre.
90
+ * @returns the canonical position, or `undefined` for `null`/`undefined`.
91
+ */
92
+ export function atFromCadQuery(v) {
93
+ if (v === null || v === undefined)
94
+ return undefined;
95
+ if (v === 0)
96
+ return 'start';
97
+ if (v === 1)
98
+ return 'end';
99
+ if (v === 0.5)
100
+ return 'mid';
101
+ return v;
102
+ }
103
+ /**
104
+ * Build the tag → index lookup for a geometry list in one pass.
105
+ *
106
+ * @param geoms - canonical geometry list.
107
+ * @returns tag → geometry index.
108
+ */
109
+ export function buildTagIndex(geoms) {
110
+ const index = new Map();
111
+ geoms.forEach((g, i) => {
112
+ if (g.tag !== undefined)
113
+ index.set(g.tag, i);
114
+ });
115
+ return index;
116
+ }
117
+ /**
118
+ * Resolve a canonical `Ref` to an FCStd `(geoId, pos)` pair.
119
+ *
120
+ * @param ref - the canonical reference (tag or index + at).
121
+ * @param tagIndex - tag → index map (from {@link buildTagIndex}).
122
+ * @param geoms - the geometry array (for bounds checking of index refs).
123
+ * @returns the FCStd `(geoId, pos)` pair.
124
+ * @throws SketchProjectionError `E_SKETCHC_BAD_REF` for unknown tag or out-of-range index.
125
+ */
126
+ export function refToFreeCad(ref, tagIndex, geoms) {
127
+ let geoId;
128
+ if ('tag' in ref) {
129
+ const found = tagIndex.get(ref.tag);
130
+ if (found === undefined) {
131
+ throw new SketchProjectionError('E_SKETCHC_BAD_REF', `unknown tag "${ref.tag}"`);
132
+ }
133
+ geoId = found;
134
+ }
135
+ else if (ref.index === -1 || ref.index === -2) {
136
+ // AXIS ANCHORS (IRON RULE patch, 2026-10-04): canonical Refs may carry the
137
+ // X axis (-1) / Y axis (-2) verbatim so FCStd axis refs round-trip through
138
+ // canonical. The planegcs backend resolves them (`pt()`: -1 → root point,
139
+ // -2 → VAxis point); anything else negative stays invalid.
140
+ geoId = ref.index;
141
+ }
142
+ else if (ref.index <= -3 && ref.index > -2000) {
143
+ // EXTERNAL ANCHORS (IRON RULE patch, 2026-10-04): canonical Refs may carry
144
+ // the external-geometry geoId verbatim; the emitted `cad.sketch` carries
145
+ // the resolved fixed polylines as its `external` param and the backend
146
+ // (`pt()` + `externalLines`) resolves every ref statically.
147
+ geoId = ref.index;
148
+ }
149
+ else {
150
+ if (!Number.isInteger(ref.index) || ref.index < 0 || ref.index >= geoms.length) {
151
+ throw new SketchProjectionError('E_SKETCHC_BAD_REF', `index ${ref.index} out of range [0, ${geoms.length})`);
152
+ }
153
+ geoId = ref.index;
154
+ }
155
+ return { geoId, pos: atToFreeCad(ref.at) };
156
+ }
157
+ // ── geometry projection ──
158
+ /**
159
+ * Spread the `construction` flag when present so reference geometry round-trips
160
+ * through the FCStd projection (canonical ⇄ FCStd). Returns an empty object when
161
+ * the flag is absent, so spreading is a no-op for ordinary geometry.
162
+ */
163
+ function con(g) {
164
+ return g.construction ? { construction: true } : {};
165
+ }
166
+ /**
167
+ * Project canonical geometry to the FCStd shape consumed by the solver.
168
+ *
169
+ * @param geoms - canonical geometry.
170
+ * @returns FCStd geometry records (same order/index).
171
+ * @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_GEOM` for reserved kinds.
172
+ */
173
+ export function toFreeCadGeoms(geoms) {
174
+ return geoms.map((g, index) => {
175
+ switch (g.kind) {
176
+ case 'line':
177
+ return { kind: 'line', index, x1: g.x1, y1: g.y1, z1: 0, x2: g.x2, y2: g.y2, z2: 0, ...con(g) };
178
+ case 'circle':
179
+ return { kind: 'circle', index, cx: g.cx, cy: g.cy, cz: 0, radius: g.r, ...con(g) };
180
+ case 'arc': {
181
+ // Pass the canonical signed span (a0, a1) through unchanged. planegcs builds
182
+ // the arc from the pinned start/end endpoints *and* the signed start/end
183
+ // angles, so a CW arc (a1 < a0) is drawn as the short clockwise arc.
184
+ // Normalising a1 into a CCW span would instead produce the long arc through
185
+ // those same endpoints. Arc orientation is carried back to the caller via
186
+ // solveSketch (input ccw preserved), not recovered here.
187
+ const a0 = g.a0;
188
+ const a1 = g.a1;
189
+ return {
190
+ kind: 'arc', index, cx: g.cx, cy: g.cy, cz: 0, radius: g.r,
191
+ startAngle: a0, endAngle: a1,
192
+ x1: g.cx + g.r * Math.cos(a0), y1: g.cy + g.r * Math.sin(a0), z1: 0,
193
+ x2: g.cx + g.r * Math.cos(a1), y2: g.cy + g.r * Math.sin(a1), z2: 0,
194
+ ...con(g),
195
+ };
196
+ }
197
+ case 'point':
198
+ // Reopened 2026-09-28: planegcs-backend pushes standalone points and
199
+ // pulls them back; contour extraction skips them (no profile use).
200
+ return { kind: 'point', index, x: g.x, y: g.y, z: 0, ...con(g) };
201
+ case 'bspline': {
202
+ // Reopened 2026-09-29 (fcstd-port A2): the entry used to reject this
203
+ // with E_SKETCHC_UNSUPPORTED_GEOM even though the whole downstream
204
+ // chain already consumed it — planegcs-backend.ts:233 pushes the exact
205
+ // endpoints as a line proxy (so coincident/dimension constraints on the
206
+ // curve ends still solve), planegcs-backend.ts:700 pulls them back,
207
+ // contour.ts:57 de Boor-samples the interior, and verify.ts:30 anchors
208
+ // on the endpoints. Rejecting here was entry-schema narrowness, not a
209
+ // solver capability gap.
210
+ //
211
+ // Endpoints are evaluated at the clamped domain ends rather than read
212
+ // off poles[0]/poles[last]: a periodic or non-clamped knot vector has
213
+ // poles that are NOT on the curve, and evalBSpline already clamps its
214
+ // argument into [knots[degree], knots[n]] (bspline.ts:39-40).
215
+ const d = { poles: g.poles, knots: g.knots, degree: g.degree, periodic: g.periodic ?? false };
216
+ const lo = d.knots[d.degree] ?? 0;
217
+ const hi = d.knots[d.knots.length - d.degree - 1] ?? lo;
218
+ const s = d.poles.length > 0 ? evalBSpline(d, lo) : { x: 0, y: 0 };
219
+ const e = d.poles.length > 0 ? evalBSpline(d, hi) : { x: 0, y: 0 };
220
+ return {
221
+ kind: 'bspline', index,
222
+ poles: g.poles, knots: g.knots, degree: g.degree, periodic: d.periodic,
223
+ x1: s.x, y1: s.y, z1: 0, x2: e.x, y2: e.y, z2: 0,
224
+ ...con(g),
225
+ };
226
+ }
227
+ case 'ellipse': {
228
+ // rx/ry ARE the major/minor radii (fromFreeCadGeoms maps them back
229
+ // positionally), `angle` is the major-axis rotation in radians — the
230
+ // same unit contour.ts and planegcs consume for angleXU.
231
+ const major = g.rx;
232
+ const minor = g.ry;
233
+ const angleXU = g.angle ?? 0;
234
+ // first focus pair (computed, mirroring FreeCAD's stored foci)
235
+ const c = Math.sqrt(Math.max(major * major - minor * minor, 0));
236
+ const ca = Math.cos(angleXU);
237
+ const sa = Math.sin(angleXU);
238
+ return {
239
+ kind: 'ellipse', index,
240
+ cx: g.cx, cy: g.cy, cz: 0,
241
+ majorRadius: major, minorRadius: minor, angleXU,
242
+ fx1: g.cx - c * ca, fy1: g.cy - c * sa,
243
+ fx2: g.cx + c * ca, fy2: g.cy + c * sa,
244
+ ...con(g),
245
+ };
246
+ }
247
+ }
248
+ });
249
+ }
250
+ /**
251
+ * Project FCStd geometry back to the canonical model (reserved kinds are reported).
252
+ *
253
+ * @param geoms - FCStd geometry records from the solver.
254
+ * @returns canonical geometry (same order/index).
255
+ */
256
+ export function fromFreeCadGeoms(geoms) {
257
+ return geoms.map((g) => {
258
+ switch (g.kind) {
259
+ case 'line':
260
+ return { kind: 'line', x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2, ...con(g) };
261
+ case 'circle':
262
+ return { kind: 'circle', cx: g.cx, cy: g.cy, r: g.radius, ...con(g) };
263
+ case 'arc': {
264
+ const ccw = normalizeArcCcw(g.startAngle, g.endAngle);
265
+ return { kind: 'arc', cx: g.cx, cy: g.cy, r: g.radius, a0: g.startAngle, a1: g.endAngle, ccw, ...con(g) };
266
+ }
267
+ case 'point':
268
+ return { kind: 'point', x: g.x, y: g.y, ...con(g) };
269
+ case 'ellipse':
270
+ return { kind: 'ellipse', cx: g.cx, cy: g.cy, rx: g.majorRadius, ry: g.minorRadius, angle: g.angleXU, ...con(g) };
271
+ case 'bspline':
272
+ return { kind: 'bspline', poles: g.poles, knots: g.knots, degree: g.degree, periodic: g.periodic, ...con(g) };
273
+ }
274
+ });
275
+ }
276
+ /** True when the arc span is counter-clockwise as stored. */
277
+ function normalizeArcCcw(startAngle, endAngle) {
278
+ let sweep = endAngle - startAngle;
279
+ while (sweep <= 0)
280
+ sweep += 2 * Math.PI;
281
+ while (sweep > 2 * Math.PI)
282
+ sweep -= 2 * Math.PI;
283
+ return sweep > 0;
284
+ }
285
+ function mapConstraint(c, tagIndex, geoms) {
286
+ const ref = (r) => refToFreeCad(r, tagIndex, geoms);
287
+ switch (c.kind) {
288
+ case 'fixed':
289
+ // FCStd has no explicit fixed constraint — the implicit fixed frame
290
+ // (RtPnt + H/V axes) absorbs the rigid-body DoF (§4.5).
291
+ return 'noop';
292
+ case 'coincident':
293
+ return { type: ConstraintType.Coincident, refs: [ref(c.a), ref(c.b)] };
294
+ case 'horizontal':
295
+ return { type: ConstraintType.Horizontal, refs: [ref(c.of)] };
296
+ case 'vertical':
297
+ return { type: ConstraintType.Vertical, refs: [ref(c.of)] };
298
+ case 'parallel':
299
+ return { type: ConstraintType.Parallel, refs: [ref(c.a), ref(c.b)] };
300
+ case 'perpendicular':
301
+ return { type: ConstraintType.Perpendicular, refs: [ref(c.a), ref(c.b)] };
302
+ case 'tangent':
303
+ return { type: ConstraintType.Tangent, refs: [ref(c.a), ref(c.b)] };
304
+ case 'distance':
305
+ return { type: ConstraintType.Distance, refs: [ref(c.a), ref(c.b)], value: c.value };
306
+ case 'distanceX':
307
+ return { type: ConstraintType.DistanceX, refs: [ref(c.a), ref(c.b)], value: c.value };
308
+ case 'distanceY':
309
+ return { type: ConstraintType.DistanceY, refs: [ref(c.a), ref(c.b)], value: c.value };
310
+ case 'length': {
311
+ // Length is expressed as a point-to-point Distance over the element ends.
312
+ const base = ref(c.of);
313
+ const start = { geoId: base.geoId, pos: PointPos.start };
314
+ const end = { geoId: base.geoId, pos: PointPos.end };
315
+ return { type: ConstraintType.Distance, refs: [start, end], value: c.value };
316
+ }
317
+ case 'angle':
318
+ return { type: ConstraintType.Angle, refs: [ref(c.a), ref(c.b)], value: c.value };
319
+ case 'orientation':
320
+ // Reverse of the 1-ref Angle projection: emit a single-reference FCStd
321
+ // Angle (absolute line orientation, radians). The planegcs backend lowers a
322
+ // 1-ref Angle to `p2p_angle` on the line's own endpoints.
323
+ return { type: ConstraintType.Angle, refs: [ref(c.of)], value: Math.atan2(c.dir[1], c.dir[0]) };
324
+ case 'radius':
325
+ return { type: ConstraintType.Radius, refs: [ref(c.of)], value: c.value };
326
+ case 'diameter':
327
+ return { type: ConstraintType.Diameter, refs: [ref(c.of)], value: c.value };
328
+ case 'arcAngle':
329
+ throw new SketchProjectionError('E_SKETCHC_UNMAPPED', 'constraint "arcAngle" has no FCStd counterpart');
330
+ case 'equal':
331
+ return { type: ConstraintType.Equal, refs: [ref(c.a), ref(c.b)] };
332
+ case 'pointOnObject':
333
+ return { type: ConstraintType.PointOnObject, refs: [ref(c.p), ref(c.on)] };
334
+ case 'symmetric':
335
+ return { type: ConstraintType.Symmetric, refs: [ref(c.p1), ref(c.p2), ref(c.about)] };
336
+ }
337
+ }
338
+ /**
339
+ * Project canonical constraints to the FCStd shape the solver consumes.
340
+ *
341
+ * @param constraints - canonical constraints.
342
+ * @param geoms - canonical geometry (for tag/index resolution).
343
+ * @returns FCStd constraints plus the no-op (`fixed`) indices.
344
+ */
345
+ export function toFreeCadConstraints(constraints, geoms) {
346
+ const tagIndex = buildTagIndex(geoms);
347
+ const out = [];
348
+ const noops = [];
349
+ constraints.forEach((c, index) => {
350
+ const mapped = mapConstraint(c, tagIndex, geoms);
351
+ if (mapped === 'noop') {
352
+ noops.push(index);
353
+ return;
354
+ }
355
+ out.push({ index, type: mapped.type, refs: mapped.refs, value: mapped.value ?? 0, isDriving: true, name: '' });
356
+ });
357
+ return { constraints: out, noops };
358
+ }
359
+ /**
360
+ * Minimum number of refs each FCStd constraint type must carry before
361
+ * {@link fromFreeCadConstraints} can express it.
362
+ *
363
+ * GOTCHA (2026-09-28, `Bathroom_cabinet_sink.FCStd` Sketch259): FreeCAD stores
364
+ * an implicit axis/origin as GeoUndef, so a "vertical distance from the X axis"
365
+ * arrives as a **1-ref** `DistanceY`. `two()`/`ref()` then dereferenced the
366
+ * absent second ref and threw `Cannot read properties of undefined (reading
367
+ * 'pos')`, which the converter reports as `solver-throw` and which failed
368
+ * 436/900 corpus files. Only types the projection switch actually handles are
369
+ * listed here: anything absent (InternalAlignment, Block, Weight …) keeps
370
+ * flowing to the `default:` branch and is still reported as `unsupported-type`.
371
+ */
372
+ const REFS_REQUIRED = {
373
+ [ConstraintType.Horizontal]: 1,
374
+ [ConstraintType.Vertical]: 1,
375
+ [ConstraintType.Distance]: 1, // 1-ref Distance is a length (see the case below)
376
+ [ConstraintType.Angle]: 1, // the case below flags a 1-ref Angle as ambiguous
377
+ [ConstraintType.Radius]: 1,
378
+ [ConstraintType.Diameter]: 1,
379
+ [ConstraintType.Coincident]: 2,
380
+ [ConstraintType.Parallel]: 2,
381
+ [ConstraintType.Tangent]: 2,
382
+ [ConstraintType.DistanceX]: 1,
383
+ [ConstraintType.DistanceY]: 1,
384
+ [ConstraintType.Perpendicular]: 2,
385
+ [ConstraintType.Equal]: 2,
386
+ [ConstraintType.PointOnObject]: 2,
387
+ [ConstraintType.Symmetric]: 3,
388
+ };
389
+ /**
390
+ * Project FCStd sketch constraints back to the canonical model — the reverse of
391
+ * {@link toFreeCadConstraints} / `mapConstraint`. This is the bridge the fcstd
392
+ * converter uses to emit `cad.sketch({ geoms, constraints })` from a parsed
393
+ * `Sketcher::SketchObject` (2026-09-28 plan A1).
394
+ *
395
+ * Mapping notes / GOTCHAs (validated against `mapConstraint` + the planegcs
396
+ * backend):
397
+ * - `length` is stored FCStd-side as a point-to-point Distance over the line's
398
+ * own start/end — a 1-ref Distance projects back to `length` (GOTCHA: a
399
+ * genuine 2-ref Distance between two distinct points is NOT a length).
400
+ * - `fixed` has no FCStd counterpart (the implicit frame absorbs it), so it can
401
+ * never appear in FCStd input — nothing to project back.
402
+ * - Angle values pass through UNCHANGED in both directions: FreeCAD serializes
403
+ * Angle constraint `Value` in radians in the XML, and the planegcs backend
404
+ * forwards it verbatim. Consumers wanting canonical degrees must convert at
405
+ * the boundary that knows the file unit (GOTCHA 2026-09-28: forward
406
+ * projection also passes through, so roundtrips are unit-consistent).
407
+ * - Constraints referencing the axes (geoId -1/-2) or external geometry
408
+ * (geoId <= -3) have no canonical Ref (canonical refs are own-geometry
409
+ * indices only) — reported in `unmapped` with reason
410
+ * `external-or-axis-ref` instead of being silently dropped.
411
+ * - `isDriving === false` (reference/driven) constraints carry no solve
412
+ * information — reported with reason `reference-driven`.
413
+ * - A constraint with fewer refs than its type requires (e.g. a 1-ref
414
+ * `DistanceY`, which FreeCAD writes when the axis is implicit) is reported
415
+ * with reason `ambiguous-refs`; see `REFS_REQUIRED`. This projection never
416
+ * throws on such input.
417
+ *
418
+ * @param cons - FCStd constraints (e.g. from `parseSketchObject`).
419
+ * @param _geoms - unused; kept for signature symmetry with the projection pipeline.
420
+ * @returns canonical constraints plus the unmapped ledger.
421
+ */
422
+ export function fromFreeCadConstraints(cons, _geoms) {
423
+ const ref = (r) => {
424
+ const at = atFromFreeCad(r.pos);
425
+ return (at === undefined ? { index: r.geoId } : { index: r.geoId, at });
426
+ };
427
+ const constraints = [];
428
+ const unmapped = [];
429
+ const pushUnmapped = (index, type, reason) => {
430
+ unmapped.push({ index, type, typeName: CONSTRAINT_NAMES[type] ?? `type#${type}`, reason });
431
+ };
432
+ cons.forEach((c, index) => {
433
+ if (!c.isDriving) {
434
+ // Reference/driven constraint carries no solve information — canonical has
435
+ // no field for it. Drop it silently instead of reporting a gap.
436
+ return;
437
+ }
438
+ // External geometry refs (geoId <= -3, down to just above GeoUndef) ride
439
+ // into canonical as negative Ref indices verbatim — the converter resolves
440
+ // the referenced external geometry to fixed polylines at convert time and
441
+ // the emitted `cad.sketch` carries them as its `external` param, so the
442
+ // planegcs backend (`pt()` + `externalLines`) resolves every ref
443
+ // statically (IRON RULE patch, 2026-10-04: no run-time attempt — a ref the
444
+ // converter could NOT resolve never enters sketchInputs).
445
+ // GOTCHA (2026-10-04, taperedballnose): old-format constraint triples pad
446
+ // unused slots with GeoUndef = -2000 (sketch-parse.ts skips them when
447
+ // building externalGeoIds for the same reason) — a real axis/external ref
448
+ // never reaches -2000. The old `geoId < 0` blanket check here used to
449
+ // reject ~every constraint in such files (20 of 21 in the sample) as
450
+ // `external-or-axis-ref`, mass-gapping otherwise-clean sketches.
451
+ // Ref-count guard (see REFS_REQUIRED) — runs BEFORE any ref dereference so
452
+ // an under-specified constraint is recorded rather than thrown out of the
453
+ // whole projection. Types the switch does not handle (InternalAlignment,
454
+ // Block, Weight …) are absent from the map and stay on the `default:` path,
455
+ // so they keep reporting `unsupported-type`.
456
+ const required = REFS_REQUIRED[c.type];
457
+ if (required !== undefined && c.refs.length < required) {
458
+ pushUnmapped(index, c.type, 'ambiguous-refs');
459
+ return;
460
+ }
461
+ const two = () => [ref(c.refs[0]), ref(c.refs[1])];
462
+ switch (c.type) {
463
+ case ConstraintType.Coincident: {
464
+ const [a, b] = two();
465
+ constraints.push({ kind: 'coincident', a, b });
466
+ break;
467
+ }
468
+ case ConstraintType.Horizontal:
469
+ // GOTCHA (IRON RULE patch, 2026-10-04, Chair Sketch255): FreeCAD's
470
+ // Horizontal has a TWO-POINT form (refs[1] may be an external point):
471
+ // "these two points are level". The canonical `horizontal` kind only
472
+ // takes one line ref — projecting the 2-ref form to it SILENTLY DROPPED
473
+ // the second point and changed the constraint set (solver DoF mismatch
474
+ // → E_SKETCHC_CONFLICTING at run time). Static equivalent instead:
475
+ // two points level ⟺ distanceY(a, b, 0).
476
+ if (c.refs.length >= 2 && c.refs[1].pos !== PointPos.none && c.refs[1].geoId !== c.refs[0].geoId) {
477
+ constraints.push({ kind: 'distanceY', a: ref(c.refs[0]), b: ref(c.refs[1]), value: 0 });
478
+ }
479
+ else {
480
+ constraints.push({ kind: 'horizontal', of: ref(c.refs[0]) });
481
+ }
482
+ break;
483
+ case ConstraintType.Vertical:
484
+ // symmetric case to Horizontal: two points aligned ⟺ distanceX(a, b, 0)
485
+ if (c.refs.length >= 2 && c.refs[1].pos !== PointPos.none && c.refs[1].geoId !== c.refs[0].geoId) {
486
+ constraints.push({ kind: 'distanceX', a: ref(c.refs[0]), b: ref(c.refs[1]), value: 0 });
487
+ }
488
+ else {
489
+ constraints.push({ kind: 'vertical', of: ref(c.refs[0]) });
490
+ }
491
+ break;
492
+ case ConstraintType.Parallel: {
493
+ const [a, b] = two();
494
+ constraints.push({ kind: 'parallel', a, b });
495
+ break;
496
+ }
497
+ case ConstraintType.Perpendicular: {
498
+ const [a, b] = two();
499
+ constraints.push({ kind: 'perpendicular', a, b });
500
+ break;
501
+ }
502
+ case ConstraintType.Tangent: {
503
+ const [a, b] = two();
504
+ constraints.push({ kind: 'tangent', a, b });
505
+ break;
506
+ }
507
+ case ConstraintType.Distance:
508
+ if (c.refs.length >= 2 &&
509
+ // GOTCHA: mapConstraint encodes canonical `length` as a Distance over
510
+ // the SAME geometry's start/end points — a same-geoId start/end pair
511
+ // is a length, not a genuine point-to-point distance.
512
+ !(c.refs[0].geoId === c.refs[1].geoId && c.refs[0].pos === PointPos.start && c.refs[1].pos === PointPos.end)) {
513
+ const [a, b] = two();
514
+ constraints.push({ kind: 'distance', a, b, value: c.value });
515
+ }
516
+ else {
517
+ // point-to-point Distance over one element's own ends = length
518
+ // (canonical `length` refs the whole element, no `at`)
519
+ constraints.push({ kind: 'length', of: { index: c.refs[0].geoId }, value: c.value });
520
+ }
521
+ break;
522
+ case ConstraintType.DistanceX: {
523
+ if (c.refs.length >= 2) {
524
+ const [a, b] = two();
525
+ constraints.push({ kind: 'distanceX', a, b, value: c.value });
526
+ }
527
+ else {
528
+ // 1-ref DistanceX = absolute X coordinate of the point/line w.r.t. the
529
+ // Y-axis (VAxis, geoId -2). The planegcs backend special-cases an
530
+ // axis-edge second ref as `coordinate_x` (absolute, not a difference),
531
+ // matching FreeCAD's single-reference DistanceX semantics.
532
+ constraints.push({ kind: 'distanceX', a: ref(c.refs[0]), b: { index: GeoId.VAxis }, value: c.value });
533
+ }
534
+ break;
535
+ }
536
+ case ConstraintType.DistanceY: {
537
+ if (c.refs.length >= 2) {
538
+ const [a, b] = two();
539
+ constraints.push({ kind: 'distanceY', a, b, value: c.value });
540
+ }
541
+ else {
542
+ // 1-ref DistanceY = absolute Y coordinate w.r.t. the X-axis (HAxis=-1).
543
+ constraints.push({ kind: 'distanceY', a: ref(c.refs[0]), b: { index: GeoId.HAxis }, value: c.value });
544
+ }
545
+ break;
546
+ }
547
+ case ConstraintType.Angle:
548
+ if (c.refs.length >= 2) {
549
+ const [a, b] = two();
550
+ constraints.push({ kind: 'angle', a, b, value: c.value });
551
+ }
552
+ else {
553
+ // 1-ref Angle = absolute orientation of a single line w.r.t. the X-axis.
554
+ // Canonical models this as `orientation` (dir = [cos, sin]); the
555
+ // planegcs backend lowers a 1-ref FCStd Angle to `p2p_angle` on the
556
+ // line's own endpoints, and `mapConstraint` re-emits it as a 1-ref
557
+ // Angle on the reverse path.
558
+ constraints.push({ kind: 'orientation', of: ref(c.refs[0]), dir: [Math.cos(c.value), Math.sin(c.value)] });
559
+ }
560
+ break;
561
+ case ConstraintType.Radius:
562
+ constraints.push({ kind: 'radius', of: ref(c.refs[0]), value: c.value });
563
+ break;
564
+ case ConstraintType.Diameter:
565
+ constraints.push({ kind: 'diameter', of: ref(c.refs[0]), value: c.value });
566
+ break;
567
+ case ConstraintType.Equal: {
568
+ const [a, b] = two();
569
+ constraints.push({ kind: 'equal', a, b });
570
+ break;
571
+ }
572
+ case ConstraintType.PointOnObject:
573
+ constraints.push({ kind: 'pointOnObject', p: ref(c.refs[0]), on: ref(c.refs[1]) });
574
+ break;
575
+ case ConstraintType.Symmetric:
576
+ constraints.push({
577
+ kind: 'symmetric',
578
+ p1: ref(c.refs[0]),
579
+ p2: ref(c.refs[1]),
580
+ about: ref(c.refs[2]),
581
+ });
582
+ break;
583
+ case ConstraintType.Weight:
584
+ // Weight is a solver soft-penalty hint, not a geometric constraint —
585
+ // canonical has no field for it. Drop it (no gap, no constraint).
586
+ break;
587
+ case ConstraintType.Block: {
588
+ // Block freezes its referenced geometry. Canonical `fixed` is the closest
589
+ // existing kind; `mapConstraint` lowers `fixed` to a no-op because the
590
+ // implicit fixed frame already pins the rigid body.
591
+ for (const r of c.refs)
592
+ constraints.push({ kind: 'fixed', of: ref(r) });
593
+ break;
594
+ }
595
+ default:
596
+ // InternalAlignment / SnellsLaw / Group / Text / …
597
+ pushUnmapped(index, c.type, 'unsupported-type');
598
+ }
599
+ });
600
+ return { constraints, unmapped };
601
+ }
602
+ // ── CadQuery projection (constraint type names) ──
603
+ /** CadQuery constraint names for the canonical kinds it supports (the other 8). */
604
+ export const CONSTRAINT_KIND_TO_CADQUERY = {
605
+ fixed: 'FixedPoint',
606
+ coincident: 'Coincident',
607
+ angle: 'Angle',
608
+ length: 'Length',
609
+ distance: 'Distance',
610
+ radius: 'Radius',
611
+ orientation: 'Orientation',
612
+ arcAngle: 'ArcAngle',
613
+ };
614
+ /**
615
+ * CadQuery constraint name → canonical kind.
616
+ *
617
+ * Beyond the one-name-per-kind reverse of {@link CONSTRAINT_KIND_TO_CADQUERY},
618
+ * CadQuery spells the fixed constraint **two** ways — `Fixed` (whole entity) and
619
+ * `FixedPoint` (a point) — and both mean canonical `fixed` here. The forward
620
+ * direction emits `FixedPoint`; the reverse direction must accept either, or a
621
+ * caller that reads upstream CadQuery scripts (`s.constrain(f, "Fixed")`) gets
622
+ * `E_SKETCHC_UNSUPPORTED_CONSTRAINT` on a name upstream accepts.
623
+ */
624
+ export const CADQUERY_TO_CONSTRAINT_KIND = {
625
+ ...Object.fromEntries(Object.entries(CONSTRAINT_KIND_TO_CADQUERY).map(([kind, name]) => [name, kind])),
626
+ Fixed: 'fixed',
627
+ };
628
+ /**
629
+ * Map a canonical constraint kind to its CadQuery name.
630
+ *
631
+ * @param kind - canonical constraint kind.
632
+ * @returns the CadQuery constraint name.
633
+ * @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_BY_CQ` when CQ has no counterpart.
634
+ */
635
+ export function constraintKindToCadQuery(kind) {
636
+ const name = CONSTRAINT_KIND_TO_CADQUERY[kind];
637
+ if (!name) {
638
+ throw new SketchProjectionError('E_SKETCHC_UNSUPPORTED_BY_CQ', `constraint "${kind}" is not supported by CadQuery`);
639
+ }
640
+ return name;
641
+ }
642
+ /**
643
+ * Map a CadQuery constraint name to its canonical kind.
644
+ *
645
+ * @param name - CadQuery constraint name.
646
+ * @returns the canonical kind.
647
+ * @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_CONSTRAINT` for unknown names.
648
+ */
649
+ export function constraintKindFromCadQuery(name) {
650
+ const kind = CADQUERY_TO_CONSTRAINT_KIND[name];
651
+ if (!kind) {
652
+ throw new SketchProjectionError('E_SKETCHC_UNSUPPORTED_CONSTRAINT', `unknown CadQuery constraint "${name}"`);
653
+ }
654
+ return kind;
655
+ }
656
+ //# sourceMappingURL=project.js.map