@faicad/faijs 0.13.1 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/dist/api/api-namespace.d.ts.map +1 -1
  2. package/dist/api/api-namespace.js +30 -4
  3. package/dist/api/api-namespace.js.map +1 -1
  4. package/dist/api/boolean.d.ts +19 -0
  5. package/dist/api/boolean.d.ts.map +1 -1
  6. package/dist/api/boolean.js +51 -10
  7. package/dist/api/boolean.js.map +1 -1
  8. package/dist/api/chamfer.d.ts.map +1 -1
  9. package/dist/api/chamfer.js +8 -7
  10. package/dist/api/chamfer.js.map +1 -1
  11. package/dist/api/compound-geom.d.ts +45 -0
  12. package/dist/api/compound-geom.d.ts.map +1 -0
  13. package/dist/api/compound-geom.js +85 -0
  14. package/dist/api/compound-geom.js.map +1 -0
  15. package/dist/api/compound.d.ts +2 -0
  16. package/dist/api/compound.d.ts.map +1 -1
  17. package/dist/api/compound.js +2 -0
  18. package/dist/api/compound.js.map +1 -1
  19. package/dist/api/copy.d.ts +1 -0
  20. package/dist/api/copy.d.ts.map +1 -1
  21. package/dist/api/copy.js +4 -2
  22. package/dist/api/copy.js.map +1 -1
  23. package/dist/api/edge-ref.d.ts +3 -2
  24. package/dist/api/edge-ref.d.ts.map +1 -1
  25. package/dist/api/edge-ref.js +10 -6
  26. package/dist/api/edge-ref.js.map +1 -1
  27. package/dist/api/engrave.d.ts.map +1 -1
  28. package/dist/api/engrave.js +1 -0
  29. package/dist/api/engrave.js.map +1 -1
  30. package/dist/api/extrude.d.ts.map +1 -1
  31. package/dist/api/extrude.js +131 -3
  32. package/dist/api/extrude.js.map +1 -1
  33. package/dist/api/face-ref.d.ts.map +1 -1
  34. package/dist/api/face-ref.js +7 -4
  35. package/dist/api/face-ref.js.map +1 -1
  36. package/dist/api/fai_drill.d.ts +1 -1
  37. package/dist/api/fai_drill.d.ts.map +1 -1
  38. package/dist/api/fai_drill.js +31 -18
  39. package/dist/api/fai_drill.js.map +1 -1
  40. package/dist/api/fai_extrude.d.ts +1 -1
  41. package/dist/api/fai_extrude.d.ts.map +1 -1
  42. package/dist/api/fai_extrude.js +2 -1
  43. package/dist/api/fai_extrude.js.map +1 -1
  44. package/dist/api/fai_split.d.ts +1 -1
  45. package/dist/api/fai_split.d.ts.map +1 -1
  46. package/dist/api/fai_split.js +2 -1
  47. package/dist/api/fai_split.js.map +1 -1
  48. package/dist/api/fillet.d.ts.map +1 -1
  49. package/dist/api/fillet.js +6 -5
  50. package/dist/api/fillet.js.map +1 -1
  51. package/dist/api/generated/operations.js +16 -16
  52. package/dist/api/generated/operations.js.map +1 -1
  53. package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
  54. package/dist/api/generated/script-face-manifest.js +0 -1
  55. package/dist/api/generated/script-face-manifest.js.map +1 -1
  56. package/dist/api/generated/script-face.d.ts +1 -4
  57. package/dist/api/generated/script-face.d.ts.map +1 -1
  58. package/dist/api/generated/script-face.js +2 -3
  59. package/dist/api/generated/script-face.js.map +1 -1
  60. package/dist/api/generated/sketching.js +1 -1
  61. package/dist/api/generated/sketching.js.map +1 -1
  62. package/dist/api/generated/topology.d.ts +0 -48
  63. package/dist/api/generated/topology.d.ts.map +1 -1
  64. package/dist/api/generated/topology.js +20 -62
  65. package/dist/api/generated/topology.js.map +1 -1
  66. package/dist/api/import-brep.d.ts +36 -0
  67. package/dist/api/import-brep.d.ts.map +1 -0
  68. package/dist/api/import-brep.js +72 -0
  69. package/dist/api/import-brep.js.map +1 -0
  70. package/dist/api/import-step.d.ts +28 -0
  71. package/dist/api/import-step.d.ts.map +1 -0
  72. package/dist/api/import-step.js +57 -0
  73. package/dist/api/import-step.js.map +1 -0
  74. package/dist/api/index.d.ts +7 -2
  75. package/dist/api/index.d.ts.map +1 -1
  76. package/dist/api/index.js +19 -5
  77. package/dist/api/index.js.map +1 -1
  78. package/dist/api/internal/compat-op.d.ts +2 -0
  79. package/dist/api/internal/compat-op.d.ts.map +1 -1
  80. package/dist/api/internal/compat-op.js +10 -2
  81. package/dist/api/internal/compat-op.js.map +1 -1
  82. package/dist/api/knurl.d.ts.map +1 -1
  83. package/dist/api/knurl.js +1 -0
  84. package/dist/api/knurl.js.map +1 -1
  85. package/dist/api/load.d.ts +3 -1
  86. package/dist/api/load.d.ts.map +1 -1
  87. package/dist/api/load.js +3 -1
  88. package/dist/api/load.js.map +1 -1
  89. package/dist/api/pattern.d.ts +32 -0
  90. package/dist/api/pattern.d.ts.map +1 -0
  91. package/dist/api/pattern.js +121 -0
  92. package/dist/api/pattern.js.map +1 -0
  93. package/dist/api/place.d.ts +35 -0
  94. package/dist/api/place.d.ts.map +1 -0
  95. package/dist/api/place.js +113 -0
  96. package/dist/api/place.js.map +1 -0
  97. package/dist/api/primitives.d.ts.map +1 -1
  98. package/dist/api/primitives.js +10 -3
  99. package/dist/api/primitives.js.map +1 -1
  100. package/dist/api/screw.d.ts.map +1 -1
  101. package/dist/api/screw.js +1 -0
  102. package/dist/api/screw.js.map +1 -1
  103. package/dist/api/sdf.d.ts.map +1 -1
  104. package/dist/api/sdf.js +1 -0
  105. package/dist/api/sdf.js.map +1 -1
  106. package/dist/api/sketch.d.ts.map +1 -1
  107. package/dist/api/sketch.js +1 -0
  108. package/dist/api/sketch.js.map +1 -1
  109. package/dist/api/split.d.ts +31 -0
  110. package/dist/api/split.d.ts.map +1 -0
  111. package/dist/api/split.js +96 -0
  112. package/dist/api/split.js.map +1 -0
  113. package/dist/api/surface/arg-spec.d.ts +9 -0
  114. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  115. package/dist/api/surface/arg-spec.js +49 -30
  116. package/dist/api/surface/arg-spec.js.map +1 -1
  117. package/dist/api/svgExtrude.d.ts.map +1 -1
  118. package/dist/api/svgExtrude.js +1 -0
  119. package/dist/api/svgExtrude.js.map +1 -1
  120. package/dist/api/text.d.ts.map +1 -1
  121. package/dist/api/text.js +1 -0
  122. package/dist/api/text.js.map +1 -1
  123. package/dist/api/topo-resolve.d.ts.map +1 -1
  124. package/dist/api/topo-resolve.js +65 -3
  125. package/dist/api/topo-resolve.js.map +1 -1
  126. package/dist/api/transform.d.ts +4 -0
  127. package/dist/api/transform.d.ts.map +1 -1
  128. package/dist/api/transform.js +44 -12
  129. package/dist/api/transform.js.map +1 -1
  130. package/dist/brep/brep-ops.d.ts +34 -1
  131. package/dist/brep/brep-ops.d.ts.map +1 -1
  132. package/dist/brep/brep-ops.js +62 -22
  133. package/dist/brep/brep-ops.js.map +1 -1
  134. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  135. package/dist/brep/engine/adapters/brep-mock.js +8 -0
  136. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  137. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  138. package/dist/brep/engine/adapters/brepkit.js +6 -1
  139. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  140. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  141. package/dist/brep/engine/adapters/occt.js +24 -1
  142. package/dist/brep/engine/adapters/occt.js.map +1 -1
  143. package/dist/brep/engine/primitives.d.ts +17 -0
  144. package/dist/brep/engine/primitives.d.ts.map +1 -1
  145. package/dist/brep/engine/primitives.js.map +1 -1
  146. package/dist/brep/engine/types.d.ts +49 -6
  147. package/dist/brep/engine/types.d.ts.map +1 -1
  148. package/dist/brep/engine/types.js.map +1 -1
  149. package/dist/brep/export/step.d.ts.map +1 -1
  150. package/dist/brep/export/step.js +6 -1
  151. package/dist/brep/export/step.js.map +1 -1
  152. package/dist/brep/face-evolution.d.ts +78 -8
  153. package/dist/brep/face-evolution.d.ts.map +1 -1
  154. package/dist/brep/face-evolution.js +130 -17
  155. package/dist/brep/face-evolution.js.map +1 -1
  156. package/dist/brepkit-kernel/brepkitKernel.d.ts +1 -1
  157. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  158. package/dist/brepkit-kernel/brepkitKernel.js +27 -1
  159. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  160. package/dist/browser.d.ts +0 -2
  161. package/dist/browser.d.ts.map +1 -1
  162. package/dist/browser.js +2 -2
  163. package/dist/browser.js.map +1 -1
  164. package/dist/cad-runtime/admit-compat-lib.d.ts +19 -1
  165. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  166. package/dist/cad-runtime/admit-compat-lib.js +21 -1
  167. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  168. package/dist/cad-runtime/backend-dispatch.d.ts +44 -3
  169. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  170. package/dist/cad-runtime/backend-dispatch.js +46 -3
  171. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  172. package/dist/cad-runtime/browser-lib-loader.d.ts +2 -0
  173. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  174. package/dist/cad-runtime/browser-lib-loader.js +9 -1
  175. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  176. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  177. package/dist/cad-runtime/direct-executor.js +14 -4
  178. package/dist/cad-runtime/direct-executor.js.map +1 -1
  179. package/dist/cad-runtime/module-registry.d.ts +3 -1
  180. package/dist/cad-runtime/module-registry.d.ts.map +1 -1
  181. package/dist/cad-runtime/module-registry.js +13 -1
  182. package/dist/cad-runtime/module-registry.js.map +1 -1
  183. package/dist/cad-runtime/ports.d.ts +7 -0
  184. package/dist/cad-runtime/ports.d.ts.map +1 -1
  185. package/dist/cad-runtime/ports.js.map +1 -1
  186. package/dist/cad-runtime/runtime-concurrent-error.d.ts +38 -0
  187. package/dist/cad-runtime/runtime-concurrent-error.d.ts.map +1 -0
  188. package/dist/cad-runtime/runtime-concurrent-error.js +43 -0
  189. package/dist/cad-runtime/runtime-concurrent-error.js.map +1 -0
  190. package/dist/cad-runtime/runtime.d.ts +54 -2
  191. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  192. package/dist/cad-runtime/runtime.js +186 -10
  193. package/dist/cad-runtime/runtime.js.map +1 -1
  194. package/dist/define-op.d.ts +22 -0
  195. package/dist/define-op.d.ts.map +1 -1
  196. package/dist/define-op.js +82 -12
  197. package/dist/define-op.js.map +1 -1
  198. package/dist/fcstd/attachment.d.ts +72 -0
  199. package/dist/fcstd/attachment.d.ts.map +1 -0
  200. package/dist/fcstd/attachment.js +93 -0
  201. package/dist/fcstd/attachment.js.map +1 -0
  202. package/dist/fcstd/build-fai-zip.d.ts +11 -0
  203. package/dist/fcstd/build-fai-zip.d.ts.map +1 -1
  204. package/dist/fcstd/build-fai-zip.js +21 -8
  205. package/dist/fcstd/build-fai-zip.js.map +1 -1
  206. package/dist/fcstd/cli.d.ts +3 -0
  207. package/dist/fcstd/cli.d.ts.map +1 -0
  208. package/dist/fcstd/cli.js +37 -0
  209. package/dist/fcstd/cli.js.map +1 -0
  210. package/dist/fcstd/codegen.d.ts +23 -1
  211. package/dist/fcstd/codegen.d.ts.map +1 -1
  212. package/dist/fcstd/codegen.js +159 -48
  213. package/dist/fcstd/codegen.js.map +1 -1
  214. package/dist/fcstd/container.d.ts +16 -1
  215. package/dist/fcstd/container.d.ts.map +1 -1
  216. package/dist/fcstd/container.js +12 -1
  217. package/dist/fcstd/container.js.map +1 -1
  218. package/dist/fcstd/contour.d.ts +9 -1
  219. package/dist/fcstd/contour.d.ts.map +1 -1
  220. package/dist/fcstd/contour.js +28 -18
  221. package/dist/fcstd/contour.js.map +1 -1
  222. package/dist/fcstd/convert.d.ts +31 -2
  223. package/dist/fcstd/convert.d.ts.map +1 -1
  224. package/dist/fcstd/convert.js +73 -22
  225. package/dist/fcstd/convert.js.map +1 -1
  226. package/dist/fcstd/document.d.ts +8 -1
  227. package/dist/fcstd/document.d.ts.map +1 -1
  228. package/dist/fcstd/document.js +4 -1
  229. package/dist/fcstd/document.js.map +1 -1
  230. package/dist/fcstd/expressions.d.ts +14 -1
  231. package/dist/fcstd/expressions.d.ts.map +1 -1
  232. package/dist/fcstd/expressions.js +11 -1
  233. package/dist/fcstd/expressions.js.map +1 -1
  234. package/dist/fcstd/external-geo.d.ts +27 -2
  235. package/dist/fcstd/external-geo.d.ts.map +1 -1
  236. package/dist/fcstd/external-geo.js +23 -2
  237. package/dist/fcstd/external-geo.js.map +1 -1
  238. package/dist/fcstd/feature-translate.d.ts +85 -3
  239. package/dist/fcstd/feature-translate.d.ts.map +1 -1
  240. package/dist/fcstd/feature-translate.js +189 -9
  241. package/dist/fcstd/feature-translate.js.map +1 -1
  242. package/dist/fcstd/index.d.ts +23 -0
  243. package/dist/fcstd/index.d.ts.map +1 -0
  244. package/dist/fcstd/index.js +19 -0
  245. package/dist/fcstd/index.js.map +1 -0
  246. package/dist/fcstd/placement.d.ts +49 -6
  247. package/dist/fcstd/placement.d.ts.map +1 -1
  248. package/dist/fcstd/placement.js +46 -6
  249. package/dist/fcstd/placement.js.map +1 -1
  250. package/dist/fcstd/planegcs-backend.d.ts +16 -1
  251. package/dist/fcstd/planegcs-backend.d.ts.map +1 -1
  252. package/dist/fcstd/planegcs-backend.js +16 -1
  253. package/dist/fcstd/planegcs-backend.js.map +1 -1
  254. package/dist/fcstd/sketch-parse.d.ts +43 -0
  255. package/dist/fcstd/sketch-parse.d.ts.map +1 -1
  256. package/dist/fcstd/sketch-parse.js +26 -0
  257. package/dist/fcstd/sketch-parse.js.map +1 -1
  258. package/dist/fcstd/sketch-solver.d.ts +20 -2
  259. package/dist/fcstd/sketch-solver.d.ts.map +1 -1
  260. package/dist/fcstd/sketch-solver.js +6 -1
  261. package/dist/fcstd/sketch-solver.js.map +1 -1
  262. package/dist/fcstd/sketch-verify.d.ts +19 -1
  263. package/dist/fcstd/sketch-verify.d.ts.map +1 -1
  264. package/dist/fcstd/sketch-verify.js +14 -1
  265. package/dist/fcstd/sketch-verify.js.map +1 -1
  266. package/dist/fcstd/structural-types.d.ts +83 -0
  267. package/dist/fcstd/structural-types.d.ts.map +1 -0
  268. package/dist/fcstd/structural-types.js +116 -0
  269. package/dist/fcstd/structural-types.js.map +1 -0
  270. package/dist/fcstd/unpack.d.ts +21 -2
  271. package/dist/fcstd/unpack.d.ts.map +1 -1
  272. package/dist/fcstd/unpack.js +11 -2
  273. package/dist/fcstd/unpack.js.map +1 -1
  274. package/dist/fcstd-convert.d.ts +30 -0
  275. package/dist/fcstd-convert.d.ts.map +1 -0
  276. package/dist/fcstd-convert.js +27 -0
  277. package/dist/fcstd-convert.js.map +1 -0
  278. package/dist/index.d.ts +1 -0
  279. package/dist/index.d.ts.map +1 -1
  280. package/dist/index.js.map +1 -1
  281. package/dist/lang/determinism-scanner.d.ts +62 -0
  282. package/dist/lang/determinism-scanner.d.ts.map +1 -0
  283. package/dist/lang/determinism-scanner.js +619 -0
  284. package/dist/lang/determinism-scanner.js.map +1 -0
  285. package/dist/lang/symbol-table.generated.d.ts +7 -3
  286. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  287. package/dist/lang/symbol-table.generated.js +7 -3
  288. package/dist/lang/symbol-table.generated.js.map +1 -1
  289. package/dist/mesh/index.d.ts.map +1 -1
  290. package/dist/mesh/index.js +3 -2
  291. package/dist/mesh/index.js.map +1 -1
  292. package/dist/node-host/cli.d.ts.map +1 -1
  293. package/dist/node-host/cli.js +56 -2
  294. package/dist/node-host/cli.js.map +1 -1
  295. package/dist/runtime-state.d.ts +18 -6
  296. package/dist/runtime-state.d.ts.map +1 -1
  297. package/dist/runtime-state.js +9 -1
  298. package/dist/runtime-state.js.map +1 -1
  299. package/dist/shape.d.ts +15 -0
  300. package/dist/shape.d.ts.map +1 -1
  301. package/dist/shape.js +26 -3
  302. package/dist/shape.js.map +1 -1
  303. package/dist/topology/naming/build-naming.d.ts +14 -30
  304. package/dist/topology/naming/build-naming.d.ts.map +1 -1
  305. package/dist/topology/naming/build-naming.js +21 -54
  306. package/dist/topology/naming/build-naming.js.map +1 -1
  307. package/dist/topology/naming/capture-topo-ref.d.ts.map +1 -1
  308. package/dist/topology/naming/capture-topo-ref.js +5 -0
  309. package/dist/topology/naming/capture-topo-ref.js.map +1 -1
  310. package/dist/topology/naming/index.d.ts +3 -0
  311. package/dist/topology/naming/index.d.ts.map +1 -1
  312. package/dist/topology/naming/index.js +3 -0
  313. package/dist/topology/naming/index.js.map +1 -1
  314. package/dist/topology/naming/lineage-resolve.d.ts +80 -0
  315. package/dist/topology/naming/lineage-resolve.d.ts.map +1 -0
  316. package/dist/topology/naming/lineage-resolve.js +120 -0
  317. package/dist/topology/naming/lineage-resolve.js.map +1 -0
  318. package/dist/topology/naming/lineage.d.ts +349 -0
  319. package/dist/topology/naming/lineage.d.ts.map +1 -0
  320. package/dist/topology/naming/lineage.js +398 -0
  321. package/dist/topology/naming/lineage.js.map +1 -0
  322. package/dist/topology/naming/migrate.d.ts +41 -0
  323. package/dist/topology/naming/migrate.d.ts.map +1 -0
  324. package/dist/topology/naming/migrate.js +88 -0
  325. package/dist/topology/naming/migrate.js.map +1 -0
  326. package/dist/topology/naming/role-name.d.ts +176 -0
  327. package/dist/topology/naming/role-name.d.ts.map +1 -0
  328. package/dist/topology/naming/role-name.js +344 -0
  329. package/dist/topology/naming/role-name.js.map +1 -0
  330. package/dist/topology/naming/roles.d.ts +20 -22
  331. package/dist/topology/naming/roles.d.ts.map +1 -1
  332. package/dist/topology/naming/roles.js +51 -49
  333. package/dist/topology/naming/roles.js.map +1 -1
  334. package/dist/topology/naming/types.d.ts +65 -18
  335. package/dist/topology/naming/types.d.ts.map +1 -1
  336. package/dist/topology/naming/types.js.map +1 -1
  337. package/dist/weapp.d.ts +22 -0
  338. package/dist/weapp.d.ts.map +1 -0
  339. package/dist/weapp.js +23 -0
  340. package/dist/weapp.js.map +1 -0
  341. package/package.json +18 -5
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/fcstd/codegen.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M5 — code generation: object graph + M4 call plans → model/*.fai.js.\n *\n * M5.1 topological order: Body.Group order wins where present; otherwise\n * PropertyLink dependency order. Cycles / missing deps → baked (no fallback\n * heuristics — explicit downgrade per plan §12).\n * M5.2 lowering: params → JS constants; calls → `const partN = await cad.x(...)`;\n * statement ids sN. Sketch contours enter as blueprint literals.\n */\nimport type { FcstdDocument } from './document.js';\nimport type { CadCall, TranslateVerdict } from './feature-translate.js';\nimport { translateObject, isJsExpr, jsExpr } from './feature-translate.js';\nimport type { Contour } from './contour.js';\nimport { type Placement, isIdentityPlacement, quatToEulerXYZDeg } from './placement.js';\n\nexport interface GenObjectResult {\n name: string;\n type: string;\n /** variable name bound in generated code (partN) or undefined when baked */\n variable?: string;\n calls: CadCall[];\n disposition: 'translated' | 'baked' | 'preserved-only';\n reason?: string;\n /** M3 sketch verdict when the object is a sketch */\n sketch?: { level: 'L0' | 'L1' | 'L2'; reason?: string; loopCount?: number };\n}\n\nexport interface GenResult {\n /** ordered translated calls (dependency order) */\n calls: CadCall[];\n objects: GenObjectResult[];\n /** generated .fai.js source (single-file mode or the main/aggregate script) */\n code: string;\n /** M10.3: multi-file mode — one script per Body with translated geometry.\n * Empty in single-file mode. Paths are container-relative (model/<Name>.fai.js). */\n files: { path: string; code: string; body: string }[];\n /** M10.3: variable in main.fai.js holding the grouped result (multi-file mode) */\n rootVar?: string;\n}\n\ninterface Node {\n name: string;\n obj: ReturnType<FcstdDocument['objects'][number]['properties']['get']> extends never ? never : FcstdDocument['objects'][number];\n deps: Set<string>;\n verdict?: TranslateVerdict;\n variable?: string;\n}\n\n/** Extract link dependencies relevant for ordering. */\nfunction depsOf(obj: FcstdDocument['objects'][number]): string[] {\n const out: string[] = [];\n const linkProps = ['Base', 'Tool', 'Profile', 'BaseFeature', 'Originals'];\n for (const p of linkProps) {\n const el = obj.properties.get(p)?.children[0];\n const v = el?.attributes['value'];\n if (v) out.push(v);\n }\n const shapes = obj.properties.get('Shapes')?.children[0];\n if (shapes) {\n for (const link of shapes.children) {\n const v = link.attributes['value'];\n if (v) out.push(v);\n }\n }\n return out;\n}\n\n/**\n * GOTCHA (PadTest V6 failure): a `PartDesign::Body`'s feature list lives in\n * DIFFERENT properties depending on the FreeCAD version —\n * - modern (0.19+): `Model` (App::PropertyLinkList), ordered\n * - legacy: `Group` (App::PropertyLinkList)\n * The Tip is `Body.Tip`. Reading only `Group` on a modern document yields an\n * empty list → no same-Body chaining → features degrade to a loose\n * `cad.group` of overlapping siblings (PadTest rebuilt volume ≈ 5.2× the Tip's,\n * bboxDiag ≈ 2×). Prefer `Model`, fall back to `Group`.\n */\nfunction bodyFeatureNames(obj: FcstdDocument['objects'][number]): string[] {\n for (const prop of ['Model', 'Group']) {\n const list = obj.properties.get(prop)?.children[0];\n if (!list) continue;\n const names: string[] = [];\n for (const link of list.children) {\n const v = link.attributes['value'];\n if (v) names.push(v);\n }\n if (names.length > 0) return names;\n }\n return [];\n}\n\n/**\n * M5.1/M5.2 — translate every object in dependency order and lower to JS.\n * `sketchVerdict` supplies the M3 outcome per sketch object name; sketches\n * whose contour feeds a Pad/Pocket appear as inputs.\n */\nexport function generateModel(\n doc: FcstdDocument,\n sketchVerdict: Map<string, { level: 'L0' | 'L1' | 'L2'; reason?: string; loopCount?: number }>,\n sketchContours: Map<string, Contour[]>,\n baseName: string,\n /** M8.3: per-object Placement (sketches + features); missing → identity */\n placements?: Map<string, Placement>,\n): GenResult {\n const byName = new Map(doc.objects.map((o) => [o.name, o]));\n const nodes = new Map<string, Node>();\n for (const obj of doc.objects) {\n nodes.set(obj.name, { name: obj.name, obj, deps: new Set(depsOf(obj)) });\n }\n\n // Kahn topological sort; objects with unbuilt deps fall back to insertion\n // order iteration until progress stalls (remaining are baked with reason).\n // M10.1: iteration order is Body.Group sequence FIRST (features of a Body\n // process in Group order so the D-C chain follows PartDesign semantics),\n // then leftover objects in document order.\n const groupSeq: string[] = [];\n for (const obj of doc.objects) {\n if (obj.type !== 'PartDesign::Body') continue;\n for (const m of bodyFeatureNames(obj)) {\n if (byName.has(m) && !groupSeq.includes(m)) groupSeq.push(m);\n }\n }\n const iterationOrder = [\n ...groupSeq,\n ...doc.objects.map((o) => o.name).filter((n) => !groupSeq.includes(n)),\n ];\n const order: string[] = [];\n const built = new Set<string>();\n let progress = true;\n while (progress) {\n progress = false;\n for (const name of iterationOrder) {\n const node = nodes.get(name)!;\n if (built.has(node.name)) continue;\n if ([...node.deps].every((d) => built.has(d) || !byName.has(d))) {\n built.add(node.name);\n order.push(node.name);\n progress = true;\n }\n }\n }\n\n const variables = new Map<string, string>();\n const results: GenObjectResult[] = [];\n const calls: CadCall[] = [];\n let partCounter = 0;\n const newVar = (): string => `part${partCounter++}`;\n\n // D-C (M9.4): same-Body features fuse cumulatively in Body.Group order —\n // the first translated feature is the base, every later additive feature\n // (Pad/…) unions with the chain, every subtractive one (Pocket/Cut)\n // subtracts. cad.group is NOT used inside a Body (that is assembly\n // semantics); cross-Body grouping stays in lower()'s root handling (M10).\n const memberToBody = new Map<string, string>();\n for (const obj of doc.objects) {\n if (obj.type !== 'PartDesign::Body') continue;\n for (const m of bodyFeatureNames(obj)) {\n if (!memberToBody.has(m)) memberToBody.set(m, obj.name);\n }\n }\n const chainVar = new Map<string, string>(); // body name → accumulated var\n\n for (const name of order) {\n const node = nodes.get(name)!;\n const obj = node.obj;\n\n if (obj.type === 'Sketcher::SketchObject') {\n const verdict = sketchVerdict.get(name);\n const contours = sketchContours.get(name);\n const usable =\n !!verdict &&\n verdict.level !== 'L2' &&\n (verdict.loopCount ?? 0) > 0 &&\n !!contours &&\n contours.length > 0;\n if (usable) {\n // M6 wiring: emit a real `cad.sketch({contours})` creator so the\n // solved contour becomes a face variable the Pad/Pocket/Extrusion/\n // Revolution features below can consume.\n const v = newVar();\n variables.set(name, v);\n const sketchCall: CadCall = {\n out: v, op: 'cad.sketch', source: name, inputs: [], params: { contours },\n };\n calls.push(sketchCall);\n results.push({\n name, type: obj.type, variable: v, calls: [sketchCall], disposition: 'translated',\n sketch: verdict,\n });\n } else {\n results.push({\n name, type: obj.type, calls: [], disposition: 'baked',\n reason: verdict?.reason ?? (contours ? 'sketch-not-solved' : 'sketch-no-contours'), sketch: verdict,\n });\n }\n continue;\n }\n\n if (obj.type === 'App::Origin' || obj.type === 'App::Plane' || obj.type === 'App::Line') {\n results.push({ name, type: obj.type, calls: [], disposition: 'preserved-only', reason: 'datum' });\n continue;\n }\n\n // Sketches are now real face variables (see the Sketcher::SketchObject\n // branch above), so every dependency that resolves to one flows through.\n const verdict = translateObject(obj, (dep) => {\n const v = variables.get(dep);\n return v !== undefined ? v : undefined;\n }, doc.objects);\n node.verdict = verdict;\n if (verdict.kind === 'translated') {\n // rename output vars to partN sequence\n for (const call of verdict.calls) {\n const v = newVar();\n variables.set(call.out, v);\n // remap inputs that were intermediate (Pocket_cut) or named outputs\n call.inputs = call.inputs.map((i) => variables.get(i) ?? i);\n call.out = v;\n calls.push(call);\n }\n // M8.3: features build in sketch-local coordinates (cad.sketch lays the\n // face on local XY; extrude runs along local +Z). Re-orient the final\n // solid by the PROFILE SKETCH's Placement: rotate_euler then translate,\n // so the result lands where FreeCAD puts it. Identity placements emit\n // nothing.\n // GOTCHA (PadTest V6, relErr 3.20%): a PartDesign feature's geometry is\n // built in the SKETCH frame, but FreeCAD may store a DIFFERENT Placement\n // on the feature object itself (Pad001: sketch P=(10,0,0)\n // Q=(0,.7071,0,.7071) vs feature P=0 Q=(0,.7071,.7071,0)) — re-orienting\n // by the feature's own frame drops the sketch origin offset and rotates\n // the extrude axis into the wrong direction (−3.20% volume, centroid\n // off 1.67). The sketch's Placement is the authoritative frame for the\n // built geometry; fall back to the feature's own for sketchless features.\n const lastVar = verdict.calls.at(-1)?.out;\n const sketchLink = obj.properties.get('Sketch')?.children[0]?.attributes['value'];\n const pl = (sketchLink ? placements?.get(sketchLink) : undefined) ?? placements?.get(name);\n if (lastVar && pl && !isIdentityPlacement(pl)) {\n let cur = lastVar;\n const euler = quatToEulerXYZDeg(pl.q);\n const isRotation = Math.abs(euler[0]) > 1e-9 || Math.abs(euler[1]) > 1e-9 || Math.abs(euler[2]) > 1e-9;\n if (isRotation) {\n const rv = newVar();\n variables.set(cur, rv); // map old name → rotated var for consumers\n calls.push({ out: rv, op: 'cad.rotate_euler', source: name, inputs: [cur], params: { anglesDeg: euler } });\n cur = rv;\n }\n const needsTranslate = Math.abs(pl.p[0]) > 1e-9 || Math.abs(pl.p[1]) > 1e-9 || Math.abs(pl.p[2]) > 1e-9;\n if (needsTranslate) {\n const tv = newVar();\n variables.set(cur, tv);\n calls.push({ out: tv, op: 'cad.translate', source: name, inputs: [cur], params: { offset: [...pl.p] } });\n cur = tv;\n }\n // the object's variable is now the fully placed result\n variables.set(name, cur);\n }\n // M9.4 (D-C): fold the feature into its Body's chain — AFTER the placement\n // step so the chain accumulates the PLACED feature shape. Pocket/Cut\n // subtract from the chain; everything else unions onto it. The first\n // feature in the Body's feature list (Model/Group) order becomes the\n // chain base — no cad.group inside a Body; consumers (M10) read chainVar.\n // GOTCHA (PadTest V6): folding the UNPLACED feature var (the old order)\n // left the chain head in sketch-local space while each feature's Placement\n // was applied to a separate, unused variable → the exported body spanned\n // both the local and the placed copies (~2× bboxDiag, ~5× volume).\n const body = memberToBody.get(name);\n const isSubtractive = obj.type === 'PartDesign::Pocket' || obj.type === 'Part::Cut';\n if (body) {\n const prev = chainVar.get(body);\n // UpToLast/UpToFirst: FreeCAD's \"up to\" support is the Body's ACCUMULATED\n // shape, NOT only the immediate BaseFeature link — retarget the kernel\n // ref at the chain head (prev). GOTCHA (PadTest V6): truncating against\n // the immediate BaseFeature (a small Pad001 disc) left an 8.06% volume\n // deficit vs the Tip; against the accumulated chain it drops to 3.20%\n // (bbox already exact at delta 0).\n if (prev) {\n for (const c of verdict.calls) {\n if (c.op === 'cad.extrude' && c.params.baseFeature !== undefined) {\n // GOTCHA (PadTest V6 residual): the up-to extrude builds its\n // prism in the SKETCH-LOCAL frame, but the chain head (prev)\n // lives in the PLACED (global) frame. FreeCAD's boolean runs in\n // one frame — so transform prev back into the sketch frame\n // first: local = R^-1(global - p). Feeding the placed chain var\n // directly silently truncates at the wrong face (Pad002 truth\n // AddShape 48199 vs rebuilt deficit ~9108 mm^3 → 3.2% total).\n const needsInverse =\n pl !== undefined && !isIdentityPlacement(pl);\n if (needsInverse && pl) {\n const invQ: [number, number, number, number] = [\n -pl.q[0]!, -pl.q[1]!, -pl.q[2]!, pl.q[3]!,\n ];\n const invEuler = quatToEulerXYZDeg(invQ);\n const tv = newVar();\n const tvCall: CadCall = {\n out: tv, op: 'cad.translate', source: name,\n inputs: [prev], params: { offset: [-pl.p[0]!, -pl.p[1]!, -pl.p[2]!] },\n };\n const rv = newVar();\n const rvCall: CadCall = {\n out: rv, op: 'cad.rotate_euler', source: name,\n inputs: [tv], params: { anglesDeg: invEuler },\n };\n // insert BEFORE the extrude call: faijs is a statement\n // language — `baseFeature: partN` referencing a later\n // statement is E_REFERENCE (parser rejects forward refs).\n const at = calls.indexOf(c);\n calls.splice(at < 0 ? calls.length : at, 0, tvCall, rvCall);\n c.params.baseFeature = jsExpr(rv);\n } else {\n c.params.baseFeature = jsExpr(prev);\n }\n }\n }\n }\n const featureVar = variables.get(name) ?? verdict.calls.at(-1)!.out;\n if (!prev) {\n chainVar.set(body, featureVar); // base feature\n } else if (isSubtractive && verdict.calls.at(-1)!.op === 'cad.subtract' && verdict.calls.at(-1)!.inputs.includes(prev)) {\n // Pocket already subtracted from the chain var itself (BaseFeature\n // resolved to the chain) — its output IS the new chain head; no\n // extra subtract (would cut twice).\n chainVar.set(body, featureVar);\n } else if (isSubtractive) {\n const nv = newVar();\n calls.push({ out: nv, op: 'cad.subtract', source: name, inputs: [prev, featureVar], params: {} });\n chainVar.set(body, nv);\n } else {\n const nv = newVar();\n calls.push({ out: nv, op: 'cad.union', source: name, inputs: [prev, featureVar], params: {} });\n chainVar.set(body, nv);\n }\n }\n results.push({ name, type: obj.type, variable: verdict.calls.at(-1)?.out, calls: verdict.calls, disposition: 'translated', reason: verdict.reason });\n } else if (verdict.kind === 'baked') {\n results.push({ name, type: obj.type, calls: [], disposition: 'baked', reason: verdict.reason });\n } else {\n results.push({ name, type: obj.type, calls: [], disposition: 'preserved-only', reason: verdict.reason });\n }\n }\n\n // also mark unreachable (cycle) objects as baked\n for (const obj of doc.objects) {\n if (!results.some((r) => r.name === obj.name)) {\n results.push({ name: obj.name, type: obj.type, calls: [], disposition: 'baked', reason: 'dependency-cycle' });\n }\n }\n\n // M10.3/M10.5 — split by Body: calls whose source object belongs to a Body\n // (including the chain union/subtract calls emitted for it) go to\n // model/<BodyName>.fai.js; everything else (loose Part features) stays in\n // main.fai.js. When no Body has geometry, everything lands in main (the\n // single-file shape). Aggregate entry groups per-file roots via cad.group.\n const callBody = new Map<string, string>();\n for (const r of results) {\n const b = memberToBody.get(r.name);\n if (b) for (const c of r.calls) callBody.set(c.out, b);\n }\n const bodiesWithGeo = new Set<string>();\n for (const b of new Set(memberToBody.values())) {\n if (chainVar.has(b)) bodiesWithGeo.add(b);\n }\n const files: GenResult['files'] = [];\n let code: string;\n let rootVar: string | undefined;\n if (bodiesWithGeo.size > 0) {\n const mainCalls: CadCall[] = [];\n const perBody = new Map<string, CadCall[]>();\n // M10c partition in DEPENDENCY ORDER: `calls` is already topologically\n // sorted, so ONE forward pass assigns each call — to its own source's Body\n // when known (`callBody`), else to the Body its first body-owned input went\n // to. GOTCHA (PadTest V6): the previous implementation re-assigned such\n // calls by APPENDING them to the end of the Body file, which broke\n // dependency order — a Body file ended up referencing a variable declared\n // further down (`let` TDZ ReferenceError at run time: `part8` used `part6`).\n // Filtering `calls` in place preserves the topological order.\n const assigned = new Map<string, string>(); // call.out → Body file name\n for (const c of calls) {\n const own = callBody.get(c.out);\n const viaInput = c.inputs.map((inp) => assigned.get(inp)).find((b) => b !== undefined);\n const b = own !== undefined && bodiesWithGeo.has(own) ? own : viaInput;\n if (b !== undefined && bodiesWithGeo.has(b)) {\n if (!perBody.has(b)) perBody.set(b, []);\n perBody.get(b)!.push(c);\n assigned.set(c.out, b);\n } else {\n mainCalls.push(c);\n }\n }\n for (const b of bodiesWithGeo) {\n const bodyCalls = perBody.get(b) ?? [];\n // terminal: alias the chain head to <Body>_out so the aggregate entry\n // has a stable, name-independent reference to each Body's result.\n const head = chainVar.get(b)!;\n const withTerminal = [\n ...bodyCalls,\n { out: `${b}_out`, op: 'identity', source: b, inputs: [head], params: {} } as CadCall,\n ];\n files.push({ path: `model/${b}.fai.js`, code: lowerBody(withTerminal, `${baseName}/${b}`, b), body: b });\n }\n // main.fai.js: aggregate the per-Body terminals via cad.group. M10c:\n // cross-file references close through the standard relative-import\n // contract (module-registry D6) — each Body module's terminal alias\n // `<Body>_out` is its live shape, so a named import binds it.\n const lines: string[] = [];\n lines.push(`// Generated by faijs FCStd port — ${baseName} (aggregate entry)`);\n lines.push(`// Units: mm (faijs contract; FCStd internal units are mm)`);\n const members = [...bodiesWithGeo].map((b) => `${b}_out`);\n // Always import the per-Body terminals: the aggregate entry references\n // `<Body>_out` in BOTH the cad.group (multi-Body) and the single-Body alias\n // path, so a missing import is a SEC_FREE_IDENT parse error (GOTCHA: the\n // single-Body branch previously emitted `let part_out = <Body>_out;` with\n // no import). `mainCalls` may still be empty here.\n if (members.length >= 1) {\n for (const b of bodiesWithGeo) {\n lines.push(`import { ${b}_out } from './${b}.fai.js'; // module ${b}`);\n }\n }\n for (const c of mainCalls) {\n const id = `s${lines.length - 2}`;\n lines.push(`let ${c.out} = ${c.op}(${renderArgs(c)}); // ${id} ${c.source}`);\n }\n if (members.length > 1) {\n rootVar = 'part_out';\n lines.push(`let part_out = cad.group({ members: [${members.join(', ')}] });`);\n } else if (members.length === 1) {\n // single Body: the imported terminal IS the result — alias keeps a\n // stable root name for executors\n rootVar = members[0];\n lines.push(`let part_out = ${rootVar}; // single-Body aggregate`);\n rootVar = 'part_out';\n }\n code = lines.join('\\n') + '\\n';\n } else {\n code = lower(calls, baseName);\n }\n return { calls, objects: results, code, files, rootVar };\n}\n\n/** M10.3 — lower one Body's calls; the last entry is the terminal alias\n * `<Body>_out` (plain JS assignment — faijs has no identity op). */\nfunction lowerBody(calls: CadCall[], label: string, body: string): string {\n const lines: string[] = [];\n lines.push(`// Generated by faijs FCStd port — ${label}`);\n lines.push(`// Units: mm (faijs contract; FCStd internal units are mm)`);\n for (const call of calls) {\n if (call.op === 'identity') {\n // terminal alias: `let <Body>_out = <chain head>;`\n lines.push(`let ${call.out} = ${call.inputs[0]}; // s? ${body} terminal`);\n continue;\n }\n const id = `s${lines.length - 2}`;\n lines.push(`let ${call.out} = ${call.op}(${renderArgs(call)}); // ${id} ${call.source}`);\n }\n return lines.join('\\n') + '\\n';\n}\n\n/** M5.2 — lower the call plan to .fai.js source. faijs syntax: top-level\n * statement flow with `let partN = cad.x(...)`; no wrapper function. */\nfunction lower(calls: CadCall[], baseName: string): string {\n const lines: string[] = [];\n lines.push(`// Generated by faijs FCStd port — ${baseName}`);\n lines.push(`// Units: mm (faijs contract; FCStd internal units are mm)`);\n for (const call of calls) {\n const id = `s${lines.length - 2}`; // statement id sN\n const args = renderArgs(call);\n lines.push(`let ${call.out} = ${call.op}(${args}); // ${id} ${call.source}`);\n }\n // final shape: union of root calls that nobody consumes; faijs scripts\n // end with the output-producing statement (no return, per fixtures).\n const consumed = new Set(calls.flatMap((c) => c.inputs));\n const roots = calls.filter((c) => !consumed.has(c.out)).map((c) => c.out);\n if (roots.length > 1) {\n lines.push(`let part_out = cad.group({ members: [${roots.join(', ')}] });`);\n } else if (roots.length === 0) {\n lines.push(`// no translated geometry (all baked)`);\n }\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * M5.2 — render one IR value as JS. Plain values JSON-encode (byte-identical to\n * the pre-JsExpr output); a `JsExpr` marker renders verbatim, and a container\n * holding one renders element-wise so the expression survives into the source.\n */\nfunction renderValue(v: unknown): string {\n if (isJsExpr(v)) return v.__jsExpr;\n if (Array.isArray(v)) {\n if (v.some(isJsExpr)) return `[${v.map(renderValue).join(', ')}]`;\n return JSON.stringify(v);\n }\n if (v && typeof v === 'object') {\n const entries = Object.entries(v as Record<string, unknown>);\n if (entries.some(([, val]) => containsJsExpr(val))) {\n return `{ ${entries.map(([k, val]) => `${k}: ${renderValue(val)}`).join(', ')} }`;\n }\n return JSON.stringify(v);\n }\n return JSON.stringify(v);\n}\n\n/** True when a value is or (recursively) contains a `JsExpr` marker. */\nfunction containsJsExpr(v: unknown): boolean {\n if (isJsExpr(v)) return true;\n if (Array.isArray(v)) return v.some(containsJsExpr);\n if (v && typeof v === 'object') return Object.values(v as Record<string, unknown>).some(containsJsExpr);\n return false;\n}\n\nfunction renderArgs(call: CadCall): string {\n const positional: string[] = [\n ...call.inputs.map((i) => i),\n ...(call.literals ?? []).map((l) => renderValue(l)),\n ].filter((s) => s.length > 0); // M7.1: drop empty entries so we never emit `(, `\n const named: string[] = [];\n for (const [k, v] of Object.entries(call.params ?? {})) {\n if (v === undefined) continue;\n named.push(`${k}: ${renderValue(v)}`);\n }\n const namedBlock = named.length ? `{ ${named.join(', ')} }` : '';\n // M7.1: no leading comma when there are no positional args — a call with only\n // named params must render as `cad.sketch({ ... })`, never `cad.sketch(, {...})`.\n const rest = namedBlock ? (positional.length ? `, ${namedBlock}` : namedBlock) : '';\n return `${positional.join(', ')}${rest}`;\n}\n"]}
1
+ {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/fcstd/codegen.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M5 — code generation: object graph + M4 call plans → model/*.fai.js.\n *\n * M5.1 topological order: Body.Group order wins where present; otherwise\n * PropertyLink dependency order. Cycles / missing deps → baked (no fallback\n * heuristics — explicit downgrade per plan §12).\n * M5.2 lowering: params → JS constants; calls → `const partN = await cad.x(...)`;\n * statement ids sN. Sketch contours enter as blueprint literals.\n *\n * 本文件为 Placement 发射平台 `cad.place`(旋转四元数 + 平移,单点)、为产物聚合发射\n * 平台 `cad.compound`(几何复合体,内核 `makeCompound`,持 OCCT 句柄)。这两个是 faijs\n * 平台几何 op(H11,方案 §4),不再借用 `../3d_editor` 的 `cad.group` /\n * `cad.translate` / `cad.rotate_euler`(编辑器交互 op,JSDoc 已 @deprecated)。\n */\nimport type { FcstdDocument } from './document.js';\nimport type { CadCall, TranslateVerdict } from './feature-translate.js';\nimport { translateObject, isJsExpr, jsExpr, BODY_CHAIN_BASE } from './feature-translate.js';\nimport type { Contour } from './contour.js';\nimport { type Placement, isIdentityPlacement, invertApplyPlacement } from './placement.js';\nimport { isNonModelingType } from './structural-types.js';\n\n/** Per-object codegen outcome: what was emitted for one FCStd object. */\nexport interface GenObjectResult {\n /** FCStd object name */\n name: string;\n /** FCStd type id */\n type: string;\n /** variable name bound in generated code (partN) or undefined when baked */\n variable?: string;\n calls: CadCall[];\n disposition: 'translated' | 'baked' | 'preserved-only';\n reason?: string;\n /** M3 sketch verdict when the object is a sketch */\n sketch?: { level: 'L0' | 'L1' | 'L2'; reason?: string; loopCount?: number };\n}\n\n/** Full codegen output: lowered calls, per-object ledger and generated script(s). */\nexport interface GenResult {\n /** ordered translated calls (dependency order) */\n calls: CadCall[];\n objects: GenObjectResult[];\n /** generated .fai.js source (single-file mode or the main/aggregate script) */\n code: string;\n /** M10.3: multi-file mode — one script per Body with translated geometry.\n * Empty in single-file mode. Paths are container-relative (model/<Name>.fai.js). */\n files: { path: string; code: string; body: string }[];\n /** M10.3: variable in main.fai.js holding the grouped result (multi-file mode) */\n rootVar?: string;\n}\n\ninterface Node {\n name: string;\n obj: ReturnType<FcstdDocument['objects'][number]['properties']['get']> extends never ? never : FcstdDocument['objects'][number];\n deps: Set<string>;\n verdict?: TranslateVerdict;\n variable?: string;\n}\n\n/** Extract link dependencies relevant for ordering. */\nfunction depsOf(obj: FcstdDocument['objects'][number]): string[] {\n const out: string[] = [];\n const linkProps = ['Base', 'Tool', 'Profile', 'BaseFeature', 'Originals'];\n for (const p of linkProps) {\n const el = obj.properties.get(p)?.children[0];\n const v = el?.attributes['value'];\n if (v) out.push(v);\n }\n // GOTCHA (ArchDetail corpus, 2026-09-21): App::PropertyLinkList properties.\n // `Shapes` is the multi-input geometry list (Part::MultiFuse / MultiCommon);\n // `Links` is Part::Compound's member list. Neither is a single-value link\n // property, so missing it here left the Compound with NO dependency on its\n // members — Kahn then placed it at its document position, and ArchDetail's\n // compounds sit at doc index 10-14 while every member sits at 269+ (Draft\n // emits the wire first, the compound last, but the file order is sorted by\n // name). inputVar() found nothing yet → `compound-missing-members` for all\n // five compounds, for a pure ordering reason.\n const linkLists = ['Shapes', 'Links'];\n for (const p of linkLists) {\n const el = obj.properties.get(p)?.children[0];\n if (!el) continue;\n for (const link of el.children) {\n const v = link.attributes['value'];\n if (v) out.push(v);\n }\n }\n return out;\n}\n\n/**\n * GOTCHA (PadTest V6 failure): a `PartDesign::Body`'s feature list lives in\n * DIFFERENT properties depending on the FreeCAD version —\n * - modern (0.19+): `Model` (App::PropertyLinkList), ordered\n * - legacy: `Group` (App::PropertyLinkList)\n * The Tip is `Body.Tip`. Reading only `Group` on a modern document yields an\n * empty list → no same-Body chaining → features degrade to a loose\n * `cad.group` of overlapping siblings (PadTest rebuilt volume ≈ 5.2× the Tip's,\n * bboxDiag ≈ 2×). Prefer `Model`, fall back to `Group`.\n */\nfunction bodyFeatureNames(obj: FcstdDocument['objects'][number]): string[] {\n for (const prop of ['Model', 'Group']) {\n const list = obj.properties.get(prop)?.children[0];\n if (!list) continue;\n const names: string[] = [];\n for (const link of list.children) {\n const v = link.attributes['value'];\n if (v) names.push(v);\n }\n if (names.length > 0) return names;\n }\n return [];\n}\n\n/**\n * M5.1/M5.2 — translate every object in dependency order and lower to JS.\n * `sketchVerdict` supplies the M3 outcome per sketch object name; sketches\n * whose contour feeds a Pad/Pocket appear as inputs.\n *\n * @param doc parsed FCStd object graph to translate\n * @param sketchVerdict per-sketch M3 verdict keyed by object name\n * @param sketchContours solved contours per L0 sketch, keyed by object name\n * @param baseName source base name used in generated file headers/labels\n * @param placements per-object Placement used to re-orient placed geometry; missing → identity\n * @param shapeCarriers objects whose Shape is a ZIP .brp member (pure-Shape carriers → shape-asset)\n * @param brokenShapeAssets objects whose Shape `file` attribute points at a missing/empty member (explicit gap)\n * @returns the lowered call plan, per-object dispositions and generated code\n */\nexport function generateModel(\n doc: FcstdDocument,\n sketchVerdict: Map<string, { level: 'L0' | 'L1' | 'L2'; reason?: string; loopCount?: number }>,\n sketchContours: Map<string, Contour[]>,\n baseName: string,\n /** M8.3: per-object Placement (sketches + features); missing → identity */\n placements?: Map<string, Placement>,\n /** H7: objects whose Shape is a ZIP .brp member (pure-Shape carriers → shape-asset). */\n shapeCarriers?: ReadonlySet<string>,\n /** E4: objects whose Shape `file` attribute points at a missing/empty member (explicit gap). */\n brokenShapeAssets?: ReadonlySet<string>,\n): GenResult {\n const byName = new Map(doc.objects.map((o) => [o.name, o]));\n // GOTCHA (test_geomop corpus, 2026-09-20): a dependency on a Body\n // CONTAINER (Part::Cut with Tool→Body) really waits for the Body's\n // features to have built the chain — expand the dep to the member\n // features so Kahn orders the consumer AFTER the chain exists (and\n // chainVar.get(Body) resolves). Treating the container itself as\n // satisfiable instead let the Cut run before the chain was built.\n const nodes = new Map<string, Node>();\n for (const obj of doc.objects) {\n const deps = new Set<string>();\n for (const d of depsOf(obj)) {\n const target = byName.get(d);\n if (target?.type === 'PartDesign::Body') {\n for (const m of bodyFeatureNames(target)) if (byName.has(m)) deps.add(m);\n } else {\n deps.add(d);\n }\n }\n nodes.set(obj.name, { name: obj.name, obj, deps });\n }\n\n // Kahn topological sort; objects with unbuilt deps fall back to insertion\n // order iteration until progress stalls (remaining are baked with reason).\n // M10.1: iteration order is Body.Group sequence FIRST (features of a Body\n // process in Group order so the D-C chain follows PartDesign semantics),\n // then leftover objects in document order.\n const groupSeq: string[] = [];\n for (const obj of doc.objects) {\n if (obj.type !== 'PartDesign::Body') continue;\n for (const m of bodyFeatureNames(obj)) {\n if (byName.has(m) && !groupSeq.includes(m)) groupSeq.push(m);\n }\n }\n const iterationOrder = [\n ...groupSeq,\n ...doc.objects.map((o) => o.name).filter((n) => !groupSeq.includes(n)),\n ];\n const order: string[] = [];\n const built = new Set<string>();\n let progress = true;\n while (progress) {\n progress = false;\n for (const name of iterationOrder) {\n const node = nodes.get(name)!;\n if (built.has(node.name)) continue;\n if ([...node.deps].every((d) => built.has(d) || !byName.has(d) || byName.get(d)!.type === 'PartDesign::Body')) {\n built.add(node.name);\n order.push(node.name);\n progress = true;\n }\n }\n }\n\n const variables = new Map<string, string>();\n const results: GenObjectResult[] = [];\n const calls: CadCall[] = [];\n let partCounter = 0;\n const newVar = (): string => `part${partCounter++}`;\n\n // D-C (M9.4): same-Body features fuse cumulatively in Body.Group order —\n // the first translated feature is the base, every later additive feature\n // (Pad/…) unions with the chain, every subtractive one (Pocket/Cut)\n // subtracts. cad.group is NOT used inside a Body (that is assembly\n // semantics); cross-Body grouping stays in lower()'s root handling (M10).\n const memberToBody = new Map<string, string>();\n for (const obj of doc.objects) {\n if (obj.type !== 'PartDesign::Body') continue;\n for (const m of bodyFeatureNames(obj)) {\n if (!memberToBody.has(m)) memberToBody.set(m, obj.name);\n }\n }\n const chainVar = new Map<string, string>(); // body name → accumulated var\n\n for (const name of order) {\n const node = nodes.get(name)!;\n const obj = node.obj;\n\n if (obj.type === 'Sketcher::SketchObject') {\n const verdict = sketchVerdict.get(name);\n const contours = sketchContours.get(name);\n const usable =\n !!verdict &&\n verdict.level !== 'L2' &&\n (verdict.loopCount ?? 0) > 0 &&\n !!contours &&\n contours.length > 0;\n if (usable) {\n // M6 wiring: emit a real `cad.sketch({contours})` creator so the\n // solved contour becomes a face variable the Pad/Pocket/Extrusion/\n // Revolution features below can consume.\n const v = newVar();\n variables.set(name, v);\n const sketchCall: CadCall = {\n out: v, op: 'cad.sketch', source: name, inputs: [], params: { contours },\n };\n calls.push(sketchCall);\n results.push({\n name, type: obj.type, variable: v, calls: [sketchCall], disposition: 'translated',\n sketch: verdict,\n });\n } else {\n results.push({\n name, type: obj.type, calls: [], disposition: 'baked',\n reason: verdict?.reason ?? (contours ? 'sketch-not-solved' : 'sketch-no-contours'), sketch: verdict,\n });\n }\n continue;\n }\n\n // Non-modeling objects are preserved-only and MUST be short-circuited\n // BEFORE translation. GOTCHA (PadTest, 2026-09-21): this used to list only\n // `App::Origin/Plane/Line`, so a Body's `PartDesign::Plane` went through\n // the translator, matched the shape-asset rule (datum planes store a\n // `Shape` .brp — the plane face) and was folded into the Body's chain:\n // `cad.union(pad, datumPlane)`. That both corrupts the solid and fails at\n // run time (`cad.load` requires a solid; a plane face has none). The\n // predicate is shared with the C4 audit (`structural-types.ts`) so codegen\n // and the disposition ledger can never disagree about what is non-modeling.\n if (isNonModelingType(obj.type)) {\n results.push({ name, type: obj.type, calls: [], disposition: 'preserved-only', reason: 'structural' });\n continue;\n }\n\n // Sketches are now real face variables (see the Sketcher::SketchObject\n // branch above), so every dependency that resolves to one flows through.\n const verdict = translateObject(obj, (dep) => {\n // GOTCHA (test_geomop corpus, 2026-09-20): a dependency on a Body\n // CONTAINER (Part::Cut with Tool→Body) resolves against the Body's\n // accumulated chain head, not `variables` — the container name is\n // never registered there (its result lives in chainVar).\n return variables.get(dep) ?? chainVar.get(dep);\n }, doc.objects, shapeCarriers, brokenShapeAssets);\n node.verdict = verdict;\n if (verdict.kind === 'translated') {\n // rename output vars to partN sequence\n for (const call of verdict.calls) {\n const v = newVar();\n variables.set(call.out, v);\n // remap inputs that were intermediate (Pocket_cut) or named outputs\n call.inputs = call.inputs.map((i) => variables.get(i) ?? i);\n // GOTCHA (ArchDetail s444, 2026-09-21): `cad.compound` passes its\n // members as LEXICAL VARIABLE NAMES inside `params.members` — they\n // must be remapped like `inputs`, otherwise renderArgs emits them as\n // string literals and the op receives strings (no BREP handle) and\n // throws \"compound members are not all on the BREP chain\".\n const members = (call.params as { members?: unknown } | undefined)?.members;\n if (Array.isArray(members)) {\n call.params!.members = members.map((m) =>\n typeof m === 'string' ? (variables.get(m) ?? m) : m,\n );\n }\n call.out = v;\n calls.push(call);\n }\n // M8.3: features build in sketch-local coordinates (cad.sketch lays the\n // face on local XY; extrude runs along local +Z). Re-orient the final\n // solid by the PROFILE SKETCH's Placement: rotate_euler then translate,\n // so the result lands where FreeCAD puts it. Identity placements emit\n // nothing.\n // GOTCHA (PadTest V6, relErr 3.20%): a PartDesign feature's geometry is\n // built in the SKETCH frame, but FreeCAD may store a DIFFERENT Placement\n // on the feature object itself (Pad001: sketch P=(10,0,0)\n // Q=(0,.7071,0,.7071) vs feature P=0 Q=(0,.7071,.7071,0)) — re-orienting\n // by the feature's own frame drops the sketch origin offset and rotates\n // the extrude axis into the wrong direction (−3.20% volume, centroid\n // off 1.67). The sketch's Placement is the authoritative frame for the\n // built geometry; fall back to the feature's own for sketchless features.\n const lastVar = verdict.calls.at(-1)?.out;\n const sketchLink = obj.properties.get('Sketch')?.children[0]?.attributes['value'];\n const pl = (sketchLink ? placements?.get(sketchLink) : undefined) ?? placements?.get(name);\n if (lastVar && pl && !isIdentityPlacement(pl)) {\n // 单个刚性放置:旋转(四元数,绕局部原点)+ 平移 = FreeCAD Placement(P,Q)。\n // 直接发 cad.place,避免 euler 往返损失精度(方案 §4.7:两语句合一)。\n const cur = lastVar;\n const rv = newVar();\n variables.set(cur, rv); // map old name → placed var for consumers\n calls.push({\n out: rv, op: 'cad.place', source: name, inputs: [cur],\n params: { rotation: [...pl.q], position: [...pl.p] },\n });\n // the object's variable is now the fully placed result\n variables.set(name, rv);\n }\n // M9.4 (D-C): fold the feature into its Body's chain — AFTER the placement\n // step so the chain accumulates the PLACED feature shape. Pocket/Cut\n // subtract from the chain; everything else unions onto it. The first\n // feature in the Body's feature list (Model/Group) order becomes the\n // chain base — no cad.group inside a Body; consumers (M10) read chainVar.\n // GOTCHA (PadTest V6): folding the UNPLACED feature var (the old order)\n // left the chain head in sketch-local space while each feature's Placement\n // was applied to a separate, unused variable → the exported body spanned\n // both the local and the placed copies (~2× bboxDiag, ~5× volume).\n const body = memberToBody.get(name);\n const isSubtractive = obj.type === 'PartDesign::Pocket' || obj.type === 'Part::Cut';\n if (body) {\n const prev = chainVar.get(body);\n // UpToLast/UpToFirst: FreeCAD's \"up to\" support is the Body's ACCUMULATED\n // shape, NOT only the immediate BaseFeature link — retarget the kernel\n // ref at the chain head (prev). GOTCHA (PadTest V6): truncating against\n // the immediate BaseFeature (a small Pad001 disc) left an 8.06% volume\n // deficit vs the Tip; against the accumulated chain it drops to 3.20%\n // (bbox already exact at delta 0).\n if (prev) {\n for (const c of verdict.calls) {\n // H7 (hole_puzzle corpus): the Pocket had NO BaseFeature property —\n // the translator emitted BODY_CHAIN_BASE as the subtract's base\n // input; retarget it at the chain head here (after the earlier\n // inputs remap, which leaves the marker untouched since it is not\n // a variable name).\n if (c.inputs) {\n c.inputs = c.inputs.map((i) => (i === BODY_CHAIN_BASE ? prev : i));\n }\n if (c.op === 'cad.extrude' && c.params.baseFeature !== undefined) {\n // GOTCHA (PadTest V6 residual): the up-to extrude builds its\n // prism in the SKETCH-LOCAL frame, but the chain head (prev)\n // lives in the PLACED (global) frame. FreeCAD's boolean runs in\n // one frame — so transform prev back into the sketch frame\n // first: local = R^-1(global - p). Feeding the placed chain var\n // directly silently truncates at the wrong face (Pad002 truth\n // AddShape 48199 vs rebuilt deficit ~9108 mm^3 → 3.2% total).\n const needsInverse =\n pl !== undefined && !isIdentityPlacement(pl);\n if (needsInverse && pl) {\n // 逆向刚性放置(单点发射,方案 §4.7):rotation 取共轭四元数、\n // position 取 invertApplyPlacement(pl, 0) = -(invQ·p),合成为\n // 一个 cad.place,避免 euler 往返。语义 = invertApplyPlacement(pl, prev)。\n const invQ: [number, number, number, number] = [\n -pl.q[0]!, -pl.q[1]!, -pl.q[2]!, pl.q[3]!,\n ];\n const invPos = invertApplyPlacement(pl, [0, 0, 0]);\n const rv = newVar();\n const rvCall: CadCall = {\n out: rv, op: 'cad.place', source: name,\n inputs: [prev],\n params: { rotation: invQ, position: invPos },\n };\n // insert BEFORE the extrude call: faijs is a statement\n // language — `baseFeature: partN` referencing a later\n // statement is E_REFERENCE (parser rejects forward refs).\n const at = calls.indexOf(c);\n calls.splice(at < 0 ? calls.length : at, 0, rvCall);\n c.params.baseFeature = jsExpr(rv);\n } else {\n c.params.baseFeature = jsExpr(prev);\n }\n }\n }\n }\n const featureVar = variables.get(name) ?? verdict.calls.at(-1)!.out;\n if (!prev) {\n chainVar.set(body, featureVar); // base feature\n } else if (isSubtractive && verdict.calls.at(-1)!.op === 'cad.subtract' && verdict.calls.at(-1)!.inputs.includes(prev)) {\n // Pocket already subtracted from the chain var itself (BaseFeature\n // resolved to the chain) — its output IS the new chain head; no\n // extra subtract (would cut twice).\n chainVar.set(body, featureVar);\n } else if (isSubtractive) {\n const nv = newVar();\n calls.push({ out: nv, op: 'cad.subtract', source: name, inputs: [prev, featureVar], params: {} });\n chainVar.set(body, nv);\n } else {\n const nv = newVar();\n calls.push({ out: nv, op: 'cad.union', source: name, inputs: [prev, featureVar], params: {} });\n chainVar.set(body, nv);\n }\n }\n // H7 guard (motor_mount_inch corpus): a feature outside a Body (or with\n // no chain head yet) never gets its BODY_CHAIN_BASE retargeted — the\n // marker would leak into the generated JS as an illegal identifier\n // (parser kills the whole file). Downgrade to an explicit gap instead.\n if (verdict.calls.some((c) => c.inputs?.includes(BODY_CHAIN_BASE))) {\n results.push({ name, type: obj.type, calls: [], disposition: 'baked', reason: 'pocket-missing-dependency' });\n continue;\n }\n results.push({ name, type: obj.type, variable: verdict.calls.at(-1)?.out, calls: verdict.calls, disposition: 'translated', reason: verdict.reason });\n } else if (verdict.kind === 'baked') {\n results.push({ name, type: obj.type, calls: [], disposition: 'baked', reason: verdict.reason });\n } else {\n results.push({ name, type: obj.type, calls: [], disposition: 'preserved-only', reason: verdict.reason });\n }\n }\n\n // also mark unreachable (cycle) objects as baked\n for (const obj of doc.objects) {\n if (!results.some((r) => r.name === obj.name)) {\n results.push({ name: obj.name, type: obj.type, calls: [], disposition: 'baked', reason: 'dependency-cycle' });\n }\n }\n\n // M10.3/M10.5 — split by Body: calls whose source object belongs to a Body\n // (including the chain union/subtract calls emitted for it) go to\n // model/<BodyName>.fai.js; everything else (loose Part features) stays in\n // main.fai.js. When no Body has geometry, everything lands in main (the\n // single-file shape). Aggregate entry compounds per-file roots via cad.compound.\n const callBody = new Map<string, string>();\n for (const r of results) {\n const b = memberToBody.get(r.name);\n if (b) for (const c of r.calls) callBody.set(c.out, b);\n }\n const bodiesWithGeo = new Set<string>();\n for (const b of new Set(memberToBody.values())) {\n if (chainVar.has(b)) bodiesWithGeo.add(b);\n }\n const files: GenResult['files'] = [];\n let code: string;\n let rootVar: string | undefined;\n if (bodiesWithGeo.size > 0) {\n const mainCalls: CadCall[] = [];\n const perBody = new Map<string, CadCall[]>();\n // M10c partition in DEPENDENCY ORDER: `calls` is already topologically\n // sorted, so ONE forward pass assigns each call — to its own source's Body\n // when known (`callBody`), else to the Body its first body-owned input went\n // to. GOTCHA (PadTest V6): the previous implementation re-assigned such\n // calls by APPENDING them to the end of the Body file, which broke\n // dependency order — a Body file ended up referencing a variable declared\n // further down (`let` TDZ ReferenceError at run time: `part8` used `part6`).\n // Filtering `calls` in place preserves the topological order.\n const assigned = new Map<string, string>(); // call.out → Body file name\n // chain-head var → terminal alias (and owning Body) — needed DURING\n // routing: a foreign chain head is never in `assigned` (it is a Body's\n // accumulated var, not a call output), so input-body checks must consult\n // this map to detect cross-Body references.\n const headToTerminal = new Map<string, string>();\n const headToBody = new Map<string, string>();\n for (const b of bodiesWithGeo) {\n headToTerminal.set(chainVar.get(b)!, `${b}_out`);\n headToBody.set(chainVar.get(b)!, b);\n }\n const mainPending: CadCall[] = [];\n const mainOuts = new Set<string>();\n for (const c of calls) {\n const own = callBody.get(c.out);\n const inputBodies = c.inputs.map((inp) => assigned.get(inp) ?? headToBody.get(inp)).filter((b): b is string => b !== undefined);\n const viaInput = inputBodies[0];\n const b = own !== undefined && bodiesWithGeo.has(own) ? own : viaInput;\n // GOTCHA (test_geomop corpus, 2026-09-20): a call whose own Body\n // differs from an input's Body (Part::Cut with Base in another Body's\n // chain) must NOT be emitted into its own Body file — the input\n // variable lives in ANOTHER module and is not declared there\n // (SEC_FREE_IDENT at check time). Same for inputs that will live in\n // MAIN (loose Part boxes): routing is a forward pass over the\n // topologically sorted calls, so main outputs are already known.\n // NOTE: Body-chain fold calls (union/subtract emitted during folding)\n // are NOT in `results`, so `own` is undefined for them — the main-input\n // check must not depend on `own`.\n const mixed = inputBodies.some((ib) => ib !== b) || (own !== undefined && viaInput !== undefined && viaInput !== own);\n const touchesMain = c.inputs.some((i) => mainOuts.has(i));\n if (b !== undefined && bodiesWithGeo.has(b) && !mixed && !touchesMain && (own === undefined || own === b)) {\n if (!perBody.has(b)) perBody.set(b, []);\n perBody.get(b)!.push(c);\n assigned.set(c.out, b);\n } else {\n mainPending.push(c);\n mainOuts.add(c.out);\n }\n }\n for (const c of mainPending) {\n mainCalls.push({ ...c, inputs: c.inputs.map((i) => headToTerminal.get(i) ?? i) });\n }\n for (const b of bodiesWithGeo) {\n const bodyCalls = perBody.get(b) ?? [];\n // terminal: alias the chain head to <Body>_out so the aggregate entry\n // has a stable, name-independent reference to each Body's result.\n const head = chainVar.get(b)!;\n const withTerminal = [\n ...bodyCalls,\n { out: `${b}_out`, op: 'identity', source: b, inputs: [head], params: {} } as CadCall,\n ];\n files.push({ path: `model/${b}.fai.js`, code: lowerBody(withTerminal, `${baseName}/${b}`, b), body: b });\n }\n // main.fai.js: aggregate the per-Body terminals via cad.compound. M10c:\n // cross-file references close through the standard relative-import\n // contract (module-registry D6) — each Body module's terminal alias\n // `<Body>_out` is its live shape, so a named import binds it.\n const lines: string[] = [];\n lines.push(`// Generated by faijs FCStd port — ${baseName} (aggregate entry)`);\n lines.push(`// Units: mm (faijs contract; FCStd internal units are mm)`);\n const members = [...bodiesWithGeo].map((b) => `${b}_out`);\n // Always import the per-Body terminals: the aggregate entry references\n // `<Body>_out` in BOTH the cad.compound (multi-Body) and the single-Body alias\n // path, so a missing import is a SEC_FREE_IDENT parse error (GOTCHA: the\n // single-Body branch previously emitted `let part_out = <Body>_out;` with\n // no import). `mainCalls` may still be empty here.\n if (members.length >= 1) {\n for (const b of bodiesWithGeo) {\n lines.push(`import { ${b}_out } from './${b}.fai.js'; // module ${b}`);\n }\n }\n for (const c of mainCalls) {\n const id = `s${lines.length - 2}`;\n lines.push(`let ${c.out} = ${c.op}(${renderArgs(c)}); // ${id} ${c.source}`);\n }\n if (members.length > 1) {\n rootVar = 'part_out';\n lines.push(`let part_out = cad.compound({ members: [${members.join(', ')}] });`);\n } else if (members.length === 1) {\n // single Body: the imported terminal IS the result — alias keeps a\n // stable root name for executors\n rootVar = members[0];\n lines.push(`let part_out = ${rootVar}; // single-Body aggregate`);\n rootVar = 'part_out';\n }\n code = lines.join('\\n') + '\\n';\n } else {\n code = lower(calls, baseName);\n }\n return { calls, objects: results, code, files, rootVar };\n}\n\n/** M10.3 — lower one Body's calls; the last entry is the terminal alias\n * `<Body>_out` (plain JS assignment — faijs has no identity op). */\nfunction lowerBody(calls: CadCall[], label: string, body: string): string {\n const lines: string[] = [];\n lines.push(`// Generated by faijs FCStd port — ${label}`);\n lines.push(`// Units: mm (faijs contract; FCStd internal units are mm)`);\n for (const call of calls) {\n if (call.op === 'identity') {\n // terminal alias: `let <Body>_out = <chain head>;`\n lines.push(`let ${call.out} = ${call.inputs[0]}; // s? ${body} terminal`);\n continue;\n }\n const id = `s${lines.length - 2}`;\n lines.push(`let ${call.out} = ${call.op}(${renderArgs(call)}); // ${id} ${call.source}`);\n }\n return lines.join('\\n') + '\\n';\n}\n\n/** M5.2 — lower the call plan to .fai.js source. faijs syntax: top-level\n * statement flow with `let partN = cad.x(...)`; no wrapper function. */\nfunction lower(calls: CadCall[], baseName: string): string {\n const lines: string[] = [];\n lines.push(`// Generated by faijs FCStd port — ${baseName}`);\n lines.push(`// Units: mm (faijs contract; FCStd internal units are mm)`);\n for (const call of calls) {\n const id = `s${lines.length - 2}`; // statement id sN\n const args = renderArgs(call);\n lines.push(`let ${call.out} = ${call.op}(${args}); // ${id} ${call.source}`);\n }\n // final shape: union of root calls that nobody consumes; faijs scripts\n // end with the output-producing statement (no return, per fixtures).\n const consumed = new Set(calls.flatMap((c) => c.inputs));\n const roots = calls.filter((c) => !consumed.has(c.out)).map((c) => c.out);\n if (roots.length > 1) {\n lines.push(`let part_out = cad.compound({ members: [${roots.join(', ')}] });`);\n } else if (roots.length === 0) {\n lines.push(`// no translated geometry (all baked)`);\n }\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * M5.2 — render one IR value as JS. Plain values JSON-encode (byte-identical to\n * the pre-JsExpr output); a `JsExpr` marker renders verbatim, and a container\n * holding one renders element-wise so the expression survives into the source.\n */\nfunction renderValue(v: unknown): string {\n if (isJsExpr(v)) return v.__jsExpr;\n if (Array.isArray(v)) {\n if (v.some(isJsExpr)) return `[${v.map(renderValue).join(', ')}]`;\n return JSON.stringify(v);\n }\n if (v && typeof v === 'object') {\n const entries = Object.entries(v as Record<string, unknown>);\n if (entries.some(([, val]) => containsJsExpr(val))) {\n return `{ ${entries.map(([k, val]) => `${k}: ${renderValue(val)}`).join(', ')} }`;\n }\n return JSON.stringify(v);\n }\n return JSON.stringify(v);\n}\n\n/** True when a value is or (recursively) contains a `JsExpr` marker. */\nfunction containsJsExpr(v: unknown): boolean {\n if (isJsExpr(v)) return true;\n if (Array.isArray(v)) return v.some(containsJsExpr);\n if (v && typeof v === 'object') return Object.values(v as Record<string, unknown>).some(containsJsExpr);\n return false;\n}\n\nfunction renderArgs(call: CadCall): string {\n const positional: string[] = [\n ...(call.noPositionalArgs ? [] : call.inputs.map((i) => i)),\n ...(call.literals ?? []).map((l) => renderValue(l)),\n ].filter((s) => s.length > 0); // M7.1: drop empty entries so we never emit `(, `\n const named: string[] = [];\n for (const [k, v] of Object.entries(call.params ?? {})) {\n if (v === undefined) continue;\n // GOTCHA (ArchDetail s444, 2026-09-21): `cad.compound`'s `members` are\n // LEXICAL VARIABLE NAMES, not data strings — render them bare, like\n // positional inputs. renderValue would quote them and the op would\n // receive strings with no BREP handle\n // (\"compound members are not all on the BREP chain\").\n if (k === 'members' && Array.isArray(v)) {\n named.push(`members: [${v.join(', ')}]`);\n continue;\n }\n named.push(`${k}: ${renderValue(v)}`);\n }\n const namedBlock = named.length ? `{ ${named.join(', ')} }` : '';\n // M7.1: no leading comma when there are no positional args — a call with only\n // named params must render as `cad.sketch({ ... })`, never `cad.sketch(, {...})`.\n const rest = namedBlock ? (positional.length ? `, ${namedBlock}` : namedBlock) : '';\n return `${positional.join(', ')}${rest}`;\n}\n"]}
@@ -9,6 +9,7 @@
9
9
  * freecad/* — byte-exact shadow of the source ZIP members
10
10
  */
11
11
  import type { FcstdDocument, FcstdObject } from './document.js';
12
+ /** manifest.json schema: source provenance, units and entry point for the .fai.zip container. */
12
13
  export interface FaiManifest {
13
14
  /** container format version */
14
15
  format: 1;
@@ -31,6 +32,7 @@ export interface FaiManifest {
31
32
  * disposition: translated | baked | preserved-only (V3 zero-silent-loss).
32
33
  */
33
34
  export type ObjectDisposition = 'translated' | 'baked' | 'preserved-only';
35
+ /** One mapping.json entry: a single object's fidelity disposition, reason and produced artifacts. */
34
36
  export interface ObjectMappingEntry {
35
37
  /** FCStd object name */
36
38
  name: string;
@@ -48,11 +50,24 @@ export interface ObjectMappingEntry {
48
50
  gcs?: unknown;
49
51
  };
50
52
  }
53
+ /** mapping.json schema: the per-object fidelity ledger (zero silent loss, V3). */
51
54
  export interface FaiMapping {
55
+ /** one entry per <ObjectData> object */
52
56
  objects: ObjectMappingEntry[];
53
57
  }
58
+ /**
59
+ * Assemble the container manifest.json from the parsed document.
60
+ * @param doc parsed FCStd document (SchemaVersion read from meta)
61
+ * @param sourceFile original FCStd file name (not full path)
62
+ * @param programVersion FreeCAD program version that wrote the document
63
+ * @returns the manifest with format 1, mm units and the BREP-chain entry point
64
+ */
54
65
  export declare function buildManifest(doc: FcstdDocument, sourceFile: string, programVersion: string): FaiManifest;
55
- /** Default disposition for an object type before feature translation (M4). */
66
+ /**
67
+ * Default disposition for an object type before feature translation (M4).
68
+ * @param obj the FCStd object to classify
69
+ * @returns `baked` for sketches and non-datum objects, `preserved-only` for datum types
70
+ */
56
71
  export declare function initialDisposition(obj: FcstdObject): {
57
72
  disposition: ObjectDisposition;
58
73
  reason?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/fcstd/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,MAAM,EAAE,CAAC,CAAC;IACV,MAAM,EAAE;QACN,+CAA+C;QAC/C,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,sEAAsE;IACtE,KAAK,EAAE,IAAI,CAAC;IACZ;gEAC4D;IAC5D,YAAY,EAAE,IAAI,CAAC;IACnB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,OAAO,GAAG,gBAAgB,CAAC;AAE1E,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,iBAAiB,CAAC;IAC/B,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,QAAQ,GAAG,eAAe,GAAG,OAAO,CAAC;QAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,6DAA6D;QAC7D,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB,WAAW,CAYb;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG;IAAE,WAAW,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CASxG"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/fcstd/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEhE,iGAAiG;AACjG,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,MAAM,EAAE,CAAC,CAAC;IACV,MAAM,EAAE;QACN,+CAA+C;QAC/C,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,sEAAsE;IACtE,KAAK,EAAE,IAAI,CAAC;IACZ;gEAC4D;IAC5D,YAAY,EAAE,IAAI,CAAC;IACnB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,OAAO,GAAG,gBAAgB,CAAC;AAE1E,qGAAqG;AACrG,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,iBAAiB,CAAC;IAC/B,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,QAAQ,GAAG,eAAe,GAAG,OAAO,CAAC;QAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,6DAA6D;QAC7D,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC;CACH;AAED,kFAAkF;AAClF,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB,WAAW,CAYb;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG;IAAE,WAAW,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CASxG"}
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Assemble the container manifest.json from the parsed document.
3
+ * @param doc parsed FCStd document (SchemaVersion read from meta)
4
+ * @param sourceFile original FCStd file name (not full path)
5
+ * @param programVersion FreeCAD program version that wrote the document
6
+ * @returns the manifest with format 1, mm units and the BREP-chain entry point
7
+ */
1
8
  export function buildManifest(doc, sourceFile, programVersion) {
2
9
  return {
3
10
  format: 1,
@@ -11,7 +18,11 @@ export function buildManifest(doc, sourceFile, programVersion) {
11
18
  entry: 'model/main.fai.js',
12
19
  };
13
20
  }
14
- /** Default disposition for an object type before feature translation (M4). */
21
+ /**
22
+ * Default disposition for an object type before feature translation (M4).
23
+ * @param obj the FCStd object to classify
24
+ * @returns `baked` for sketches and non-datum objects, `preserved-only` for datum types
25
+ */
15
26
  export function initialDisposition(obj) {
16
27
  if (obj.type === 'Sketcher::SketchObject') {
17
28
  return { disposition: 'baked', reason: 'pending-sketch-channel' };
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/fcstd/container.ts"],"names":[],"mappings":"AA0DA,MAAM,UAAU,aAAa,CAC3B,GAAkB,EAClB,UAAkB,EAClB,cAAsB;IAEtB,OAAO;QACL,MAAM,EAAE,CAAC;QACT,MAAM,EAAE;YACN,IAAI,EAAE,UAAU;YAChB,cAAc;YACd,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;SACrE;QACD,KAAK,EAAE,IAAI;QACX,YAAY,EAAE,IAAI;QAClB,KAAK,EAAE,mBAAmB;KAC3B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAAC,GAAgB;IACjD,IAAI,GAAG,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;QAC1C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACpE,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACxF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC5D,CAAC;IACD,sEAAsE;IACtE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;AACzE,CAAC","sourcesContent":["/**\n * M2.1 — .fai.zip container schemas (manifest.json / mapping.json).\n *\n * Container layout (plan §2.1, 前文 A §6):\n * manifest.json — container manifest, entry point, units\n * mapping.json — per-object fidelity ledger; zero silent loss (R7)\n * model/*.fai.js — translated model scripts\n * assets/*.step — baked geometry fallback set\n * freecad/* — byte-exact shadow of the source ZIP members\n */\nimport type { FcstdDocument, FcstdObject } from './document.js';\n\nexport interface FaiManifest {\n /** container format version */\n format: 1;\n source: {\n /** original FCStd file name (not full path) */\n file: string;\n programVersion: string;\n schemaVersion: number;\n };\n /** unit normalization applied to all coordinates (D7); always \"mm\" */\n units: 'mm';\n /** D-A: FCStd port output is BREP-chain-only (sketch/extrude/... are brep\n * impls without mesh); execution must use `--mode brep`. */\n requiresBrep: true;\n /** entry script inside model/ */\n entry: string;\n}\n\n/**\n * Per-object fidelity ledger. Every <ObjectData> object must have exactly one\n * disposition: translated | baked | preserved-only (V3 zero-silent-loss).\n */\nexport type ObjectDisposition = 'translated' | 'baked' | 'preserved-only';\n\nexport interface ObjectMappingEntry {\n /** FCStd object name */\n name: string;\n type: string;\n disposition: ObjectDisposition;\n /** why not translated (required when disposition !== 'translated') */\n reason?: string;\n /** produced artifacts, container-relative paths */\n artifacts: string[];\n /** M3 sketch fidelity level (D3) */\n sketch?: {\n level: 'solved' | 'initial-value' | 'baked';\n reason?: string;\n /** GCS primitives for future editable-sketch upgrade (D1) */\n gcs?: unknown;\n };\n}\n\nexport interface FaiMapping {\n objects: ObjectMappingEntry[];\n}\n\nexport function buildManifest(\n doc: FcstdDocument,\n sourceFile: string,\n programVersion: string,\n): FaiManifest {\n return {\n format: 1,\n source: {\n file: sourceFile,\n programVersion,\n schemaVersion: Number(doc.meta.get('SchemaVersion')?.valueText ?? 4),\n },\n units: 'mm',\n requiresBrep: true,\n entry: 'model/main.fai.js',\n };\n}\n\n/** Default disposition for an object type before feature translation (M4). */\nexport function initialDisposition(obj: FcstdObject): { disposition: ObjectDisposition; reason?: string } {\n if (obj.type === 'Sketcher::SketchObject') {\n return { disposition: 'baked', reason: 'pending-sketch-channel' };\n }\n if (obj.type === 'App::Origin' || obj.type === 'App::Plane' || obj.type === 'App::Line') {\n return { disposition: 'preserved-only', reason: 'datum' };\n }\n // M2 stage: everything non-datum is baked from the ZIP's .brp members\n return { disposition: 'baked', reason: 'feature-translation-pending' };\n}\n"]}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/fcstd/container.ts"],"names":[],"mappings":"AA8DA;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,GAAkB,EAClB,UAAkB,EAClB,cAAsB;IAEtB,OAAO;QACL,MAAM,EAAE,CAAC;QACT,MAAM,EAAE;YACN,IAAI,EAAE,UAAU;YAChB,cAAc;YACd,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;SACrE;QACD,KAAK,EAAE,IAAI;QACX,YAAY,EAAE,IAAI;QAClB,KAAK,EAAE,mBAAmB;KAC3B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAgB;IACjD,IAAI,GAAG,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;QAC1C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACpE,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACxF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC5D,CAAC;IACD,sEAAsE;IACtE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;AACzE,CAAC","sourcesContent":["/**\n * M2.1 — .fai.zip container schemas (manifest.json / mapping.json).\n *\n * Container layout (plan §2.1, 前文 A §6):\n * manifest.json — container manifest, entry point, units\n * mapping.json — per-object fidelity ledger; zero silent loss (R7)\n * model/*.fai.js — translated model scripts\n * assets/*.step — baked geometry fallback set\n * freecad/* — byte-exact shadow of the source ZIP members\n */\nimport type { FcstdDocument, FcstdObject } from './document.js';\n\n/** manifest.json schema: source provenance, units and entry point for the .fai.zip container. */\nexport interface FaiManifest {\n /** container format version */\n format: 1;\n source: {\n /** original FCStd file name (not full path) */\n file: string;\n programVersion: string;\n schemaVersion: number;\n };\n /** unit normalization applied to all coordinates (D7); always \"mm\" */\n units: 'mm';\n /** D-A: FCStd port output is BREP-chain-only (sketch/extrude/... are brep\n * impls without mesh); execution must use `--mode brep`. */\n requiresBrep: true;\n /** entry script inside model/ */\n entry: string;\n}\n\n/**\n * Per-object fidelity ledger. Every <ObjectData> object must have exactly one\n * disposition: translated | baked | preserved-only (V3 zero-silent-loss).\n */\nexport type ObjectDisposition = 'translated' | 'baked' | 'preserved-only';\n\n/** One mapping.json entry: a single object's fidelity disposition, reason and produced artifacts. */\nexport interface ObjectMappingEntry {\n /** FCStd object name */\n name: string;\n type: string;\n disposition: ObjectDisposition;\n /** why not translated (required when disposition !== 'translated') */\n reason?: string;\n /** produced artifacts, container-relative paths */\n artifacts: string[];\n /** M3 sketch fidelity level (D3) */\n sketch?: {\n level: 'solved' | 'initial-value' | 'baked';\n reason?: string;\n /** GCS primitives for future editable-sketch upgrade (D1) */\n gcs?: unknown;\n };\n}\n\n/** mapping.json schema: the per-object fidelity ledger (zero silent loss, V3). */\nexport interface FaiMapping {\n /** one entry per <ObjectData> object */\n objects: ObjectMappingEntry[];\n}\n\n/**\n * Assemble the container manifest.json from the parsed document.\n * @param doc parsed FCStd document (SchemaVersion read from meta)\n * @param sourceFile original FCStd file name (not full path)\n * @param programVersion FreeCAD program version that wrote the document\n * @returns the manifest with format 1, mm units and the BREP-chain entry point\n */\nexport function buildManifest(\n doc: FcstdDocument,\n sourceFile: string,\n programVersion: string,\n): FaiManifest {\n return {\n format: 1,\n source: {\n file: sourceFile,\n programVersion,\n schemaVersion: Number(doc.meta.get('SchemaVersion')?.valueText ?? 4),\n },\n units: 'mm',\n requiresBrep: true,\n entry: 'model/main.fai.js',\n };\n}\n\n/**\n * Default disposition for an object type before feature translation (M4).\n * @param obj the FCStd object to classify\n * @returns `baked` for sketches and non-datum objects, `preserved-only` for datum types\n */\nexport function initialDisposition(obj: FcstdObject): { disposition: ObjectDisposition; reason?: string } {\n if (obj.type === 'Sketcher::SketchObject') {\n return { disposition: 'baked', reason: 'pending-sketch-channel' };\n }\n if (obj.type === 'App::Origin' || obj.type === 'App::Plane' || obj.type === 'App::Line') {\n return { disposition: 'preserved-only', reason: 'datum' };\n }\n // M2 stage: everything non-datum is baked from the ZIP's .brp members\n return { disposition: 'baked', reason: 'feature-translation-pending' };\n}\n"]}
@@ -7,6 +7,7 @@
7
7
  * segments sharing endpoints (tolerance-based), keep closed loops.
8
8
  */
9
9
  import type { SketchGeom } from './sketch-parse.js';
10
+ /** One segment of a 2D contour: either a straight line or a circular arc (planar, sketch-local coordinates). */
10
11
  export type ContourSeg = {
11
12
  kind: 'line';
12
13
  x1: number;
@@ -26,10 +27,17 @@ export type ContourSeg = {
26
27
  x2: number;
27
28
  y2: number;
28
29
  };
30
+ /** A chained run of segments; `closed` when the chain's ends meet (R6: pure data, no OCCT dependency). */
29
31
  export interface Contour {
32
+ /** chained segments in traversal order */
30
33
  segments: ContourSeg[];
34
+ /** true when the chain's endpoints meet within JOIN_TOL */
31
35
  closed: boolean;
32
36
  }
33
- /** Extract closed contours (chains of segments whose endpoints meet). */
37
+ /**
38
+ * Extract closed contours (chains of segments whose endpoints meet).
39
+ * @param geoms solved sketch geometry to chain (non-construction segments only)
40
+ * @returns closed loops plus self-closed circles (open chains are dropped)
41
+ */
34
42
  export declare function extractContours(geoms: SketchGeom[]): Contour[];
35
43
  //# sourceMappingURL=contour.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contour.d.ts","sourceRoot":"","sources":["../../src/fcstd/contour.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChE;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEN,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;CACjB;AA2BD,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAuD9D"}
1
+ {"version":3,"file":"contour.d.ts","sourceRoot":"","sources":["../../src/fcstd/contour.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,gHAAgH;AAChH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChE;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEN,0GAA0G;AAC1G,MAAM,WAAW,OAAO;IACtB,0CAA0C;IAC1C,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,2DAA2D;IAC3D,MAAM,EAAE,OAAO,CAAC;CACjB;AA2BD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CA0D9D"}
@@ -21,7 +21,11 @@ function segEnds(g) {
21
21
  return undefined; // circles are closed on their own; points don't join
22
22
  }
23
23
  }
24
- /** Extract closed contours (chains of segments whose endpoints meet). */
24
+ /**
25
+ * Extract closed contours (chains of segments whose endpoints meet).
26
+ * @param geoms solved sketch geometry to chain (non-construction segments only)
27
+ * @returns closed loops plus self-closed circles (open chains are dropped)
28
+ */
25
29
  export function extractContours(geoms) {
26
30
  const pool = [];
27
31
  for (const g of geoms) {
@@ -35,32 +39,38 @@ export function extractContours(geoms) {
35
39
  if (start.used)
36
40
  continue;
37
41
  start.used = true;
38
- const segments = [start.seg];
39
- let tail = start.b;
40
42
  const head = start.a;
41
- let extended = true;
42
- while (extended) {
43
- extended = false;
43
+ // GOTCHA (slittingsaw corpus, 2026-09-20): junction points with free
44
+ // branches (three+ segments sharing an endpoint) defeat first-come
45
+ // chaining — a branch to a dead end consumed the segments and the real
46
+ // loop never closed. DFS with backtracking: try each candidate
47
+ // continuation; the FIRST chain that closes at the head wins; a dead
48
+ // branch returns its segments to the pool. Closure-stop (tap GOTCHA) and
49
+ // pool-restart are both subsumed by the DFS ordering.
50
+ const dfs = (tail, walk) => {
51
+ if (walk.length > 0 && near(tail, head))
52
+ return walk;
44
53
  for (const cand of pool) {
45
54
  if (cand.used)
46
55
  continue;
56
+ cand.used = true;
47
57
  if (near(tail, cand.a)) {
48
- cand.used = true;
49
- segments.push(cand.seg);
50
- tail = cand.b;
51
- extended = true;
58
+ const r = dfs(cand.b, [...walk, cand.seg]);
59
+ if (r)
60
+ return r;
52
61
  }
53
62
  else if (near(tail, cand.b)) {
54
- cand.used = true;
55
- segments.push(reverseSeg(cand.seg));
56
- tail = cand.a;
57
- extended = true;
63
+ const r = dfs(cand.a, [...walk, reverseSeg(cand.seg)]);
64
+ if (r)
65
+ return r;
58
66
  }
67
+ cand.used = false; // dead branch — return the segment to the pool
59
68
  }
60
- }
61
- const closed = near(tail, head);
62
- if (segments.length > 0 && closed) {
63
- contours.push({ segments, closed: true });
69
+ return undefined;
70
+ };
71
+ const solved = dfs(start.b, [start.seg]);
72
+ if (solved && solved.length > 1) {
73
+ contours.push({ segments: solved, closed: true });
64
74
  }
65
75
  }
66
76
  // circles are self-closed contours
@@ -1 +1 @@
1
- {"version":3,"file":"contour.js","sourceRoot":"","sources":["../../src/fcstd/contour.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M3.6 — contour extraction: solved sketch geometry → closed loops → 2D\n * contour (R6: pure data, no OCCT dependency; the cad-face wiring that turns\n * contours into Blueprint/extrude inputs happens in M4.6/M5).\n *\n * Extraction: collect endpoints of every non-construction geometry, chain\n * segments sharing endpoints (tolerance-based), keep closed loops.\n */\nimport type { SketchGeom } from './sketch-parse.js';\n\nexport type ContourSeg =\n | { kind: 'line'; x1: number; y1: number; x2: number; y2: number }\n | {\n kind: 'arc';\n cx: number;\n cy: number;\n radius: number;\n startAngle: number;\n endAngle: number;\n ccw: boolean;\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n };\n\nexport interface Contour {\n segments: ContourSeg[];\n closed: boolean;\n}\n\nconst JOIN_TOL = 1e-7;\n\nfunction segEnds(g: SketchGeom): [ContourSeg, { x: number; y: number }, { x: number; y: number }] | undefined {\n switch (g.kind) {\n case 'line':\n return [\n { kind: 'line', x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2 },\n { x: g.x1, y: g.y1 },\n { x: g.x2, y: g.y2 },\n ];\n case 'arc':\n return [\n {\n kind: 'arc', cx: g.cx, cy: g.cy, radius: g.radius,\n startAngle: g.startAngle, endAngle: g.endAngle, ccw: true,\n x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2,\n },\n { x: g.x1, y: g.y1 },\n { x: g.x2, y: g.y2 },\n ];\n default:\n return undefined; // circles are closed on their own; points don't join\n }\n}\n\n/** Extract closed contours (chains of segments whose endpoints meet). */\nexport function extractContours(geoms: SketchGeom[]): Contour[] {\n const pool: { seg: ContourSeg; a: { x: number; y: number }; b: { x: number; y: number }; used: boolean }[] = [];\n for (const g of geoms) {\n const s = segEnds(g);\n if (s) pool.push({ seg: s[0], a: s[1], b: s[2], used: false });\n }\n\n const near = (p: { x: number; y: number }, q: { x: number; y: number }): boolean =>\n Math.hypot(p.x - q.x, p.y - q.y) <= JOIN_TOL;\n\n const contours: Contour[] = [];\n for (const start of pool) {\n if (start.used) continue;\n start.used = true;\n const segments: ContourSeg[] = [start.seg];\n let tail = start.b;\n const head = start.a;\n let extended = true;\n while (extended) {\n extended = false;\n for (const cand of pool) {\n if (cand.used) continue;\n if (near(tail, cand.a)) {\n cand.used = true;\n segments.push(cand.seg);\n tail = cand.b;\n extended = true;\n } else if (near(tail, cand.b)) {\n cand.used = true;\n segments.push(reverseSeg(cand.seg));\n tail = cand.a;\n extended = true;\n }\n }\n }\n const closed = near(tail, head);\n if (segments.length > 0 && closed) {\n contours.push({ segments, closed: true });\n }\n }\n\n // circles are self-closed contours\n for (const g of geoms) {\n if (g.kind === 'circle' && g.radius > 0) {\n contours.push({\n segments: [{\n kind: 'arc', cx: g.cx, cy: g.cy, radius: g.radius,\n startAngle: 0, endAngle: Math.PI * 2, ccw: true,\n x1: g.cx + g.radius, y1: g.cy, x2: g.cx + g.radius, y2: g.cy,\n }],\n closed: true,\n });\n }\n }\n return contours;\n}\n\nfunction reverseSeg(s: ContourSeg): ContourSeg {\n if (s.kind === 'line') return { kind: 'line', x1: s.x2, y1: s.y2, x2: s.x1, y2: s.y1 };\n return { ...s, startAngle: s.endAngle, endAngle: s.startAngle, ccw: !s.ccw, x1: s.x2, y1: s.y2, x2: s.x1, y2: s.y1 };\n}\n"]}
1
+ {"version":3,"file":"contour.js","sourceRoot":"","sources":["../../src/fcstd/contour.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M3.6 — contour extraction: solved sketch geometry → closed loops → 2D\n * contour (R6: pure data, no OCCT dependency; the cad-face wiring that turns\n * contours into Blueprint/extrude inputs happens in M4.6/M5).\n *\n * Extraction: collect endpoints of every non-construction geometry, chain\n * segments sharing endpoints (tolerance-based), keep closed loops.\n */\nimport type { SketchGeom } from './sketch-parse.js';\n\n/** One segment of a 2D contour: either a straight line or a circular arc (planar, sketch-local coordinates). */\nexport type ContourSeg =\n | { kind: 'line'; x1: number; y1: number; x2: number; y2: number }\n | {\n kind: 'arc';\n cx: number;\n cy: number;\n radius: number;\n startAngle: number;\n endAngle: number;\n ccw: boolean;\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n };\n\n/** A chained run of segments; `closed` when the chain's ends meet (R6: pure data, no OCCT dependency). */\nexport interface Contour {\n /** chained segments in traversal order */\n segments: ContourSeg[];\n /** true when the chain's endpoints meet within JOIN_TOL */\n closed: boolean;\n}\n\nconst JOIN_TOL = 1e-7;\n\nfunction segEnds(g: SketchGeom): [ContourSeg, { x: number; y: number }, { x: number; y: number }] | undefined {\n switch (g.kind) {\n case 'line':\n return [\n { kind: 'line', x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2 },\n { x: g.x1, y: g.y1 },\n { x: g.x2, y: g.y2 },\n ];\n case 'arc':\n return [\n {\n kind: 'arc', cx: g.cx, cy: g.cy, radius: g.radius,\n startAngle: g.startAngle, endAngle: g.endAngle, ccw: true,\n x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2,\n },\n { x: g.x1, y: g.y1 },\n { x: g.x2, y: g.y2 },\n ];\n default:\n return undefined; // circles are closed on their own; points don't join\n }\n}\n\n/**\n * Extract closed contours (chains of segments whose endpoints meet).\n * @param geoms solved sketch geometry to chain (non-construction segments only)\n * @returns closed loops plus self-closed circles (open chains are dropped)\n */\nexport function extractContours(geoms: SketchGeom[]): Contour[] {\n const pool: { seg: ContourSeg; a: { x: number; y: number }; b: { x: number; y: number }; used: boolean }[] = [];\n for (const g of geoms) {\n const s = segEnds(g);\n if (s) pool.push({ seg: s[0], a: s[1], b: s[2], used: false });\n }\n\n const near = (p: { x: number; y: number }, q: { x: number; y: number }): boolean =>\n Math.hypot(p.x - q.x, p.y - q.y) <= JOIN_TOL;\n\n const contours: Contour[] = [];\n for (const start of pool) {\n if (start.used) continue;\n start.used = true;\n const head = start.a;\n // GOTCHA (slittingsaw corpus, 2026-09-20): junction points with free\n // branches (three+ segments sharing an endpoint) defeat first-come\n // chaining — a branch to a dead end consumed the segments and the real\n // loop never closed. DFS with backtracking: try each candidate\n // continuation; the FIRST chain that closes at the head wins; a dead\n // branch returns its segments to the pool. Closure-stop (tap GOTCHA) and\n // pool-restart are both subsumed by the DFS ordering.\n const dfs = (tail: { x: number; y: number }, walk: ContourSeg[]): ContourSeg[] | undefined => {\n if (walk.length > 0 && near(tail, head)) return walk;\n for (const cand of pool) {\n if (cand.used) continue;\n cand.used = true;\n if (near(tail, cand.a)) {\n const r = dfs(cand.b, [...walk, cand.seg]);\n if (r) return r;\n } else if (near(tail, cand.b)) {\n const r = dfs(cand.a, [...walk, reverseSeg(cand.seg)]);\n if (r) return r;\n }\n cand.used = false; // dead branch — return the segment to the pool\n }\n return undefined;\n };\n const solved = dfs(start.b, [start.seg]);\n if (solved && solved.length > 1) {\n contours.push({ segments: solved, closed: true });\n }\n }\n\n // circles are self-closed contours\n for (const g of geoms) {\n if (g.kind === 'circle' && g.radius > 0) {\n contours.push({\n segments: [{\n kind: 'arc', cx: g.cx, cy: g.cy, radius: g.radius,\n startAngle: 0, endAngle: Math.PI * 2, ccw: true,\n x1: g.cx + g.radius, y1: g.cy, x2: g.cx + g.radius, y2: g.cy,\n }],\n closed: true,\n });\n }\n }\n return contours;\n}\n\nfunction reverseSeg(s: ContourSeg): ContourSeg {\n if (s.kind === 'line') return { kind: 'line', x1: s.x2, y1: s.y2, x2: s.x1, y2: s.y1 };\n return { ...s, startAngle: s.endAngle, endAngle: s.startAngle, ccw: !s.ccw, x1: s.x2, y1: s.y2, x2: s.x1, y2: s.y1 };\n}\n"]}
@@ -1,8 +1,30 @@
1
+ import { STRUCTURAL_TYPES, STRUCTURAL_TYPES_EXTENDED, isFemStructural } from './structural-types.js';
2
+ export { STRUCTURAL_TYPES, STRUCTURAL_TYPES_EXTENDED, isFemStructural };
1
3
  /** V2 tolerance: solver must reproduce stored geometry (single source). */
2
4
  export declare const SKETCH_T1 = 0.000001;
3
5
  /** Dispositions allowed in a conforming container (C4). */
4
6
  export declare const ALLOWED_DISPOSITIONS: Set<string>;
7
+ /**
8
+ * Optional knobs for `convertFcstdFile`.
9
+ */
10
+ export interface ConvertOptions {
11
+ /**
12
+ * Return the container bytes even when the mapping audit reports gaps.
13
+ *
14
+ * Diagnostics only. C4 requires that a gapped document produces **no
15
+ * product**, and the CLI never sets this — `ok` stays false and the exit
16
+ * code stays 2 regardless. It exists because everything the pipeline built
17
+ * before the audit is otherwise unobservable for exactly the documents that
18
+ * need triage: gaps and non-L0 sketches usually co-occur (a sketch the
19
+ * solver cannot handle usually starves the features built on it), so
20
+ * "which contour assets / mapping entries would this document have had"
21
+ * cannot be answered from `gaps[]` alone.
22
+ */
23
+ keepGappedContainer?: boolean;
24
+ }
25
+ /** Structured result of one FCStd → .fai.zip conversion; the caller decides exit codes and formatting. */
5
26
  export interface ConvertSummary {
27
+ /** input file path */
6
28
  file: string;
7
29
  /** conversion succeeded AND mapping final check passed */
8
30
  ok: boolean;
@@ -24,11 +46,18 @@ export interface ConvertSummary {
24
46
  l1: number;
25
47
  l2: number;
26
48
  };
27
- /** container bytes (undefined when ok=false: no zip produced) */
49
+ /** container bytes (undefined when ok=false, unless `keepGappedContainer`) */
28
50
  zip?: Uint8Array;
29
51
  /** human-readable failure when the pipeline itself failed */
30
52
  error?: string;
31
53
  elapsedMs: number;
32
54
  }
33
- export declare function convertFcstdFile(input: string): Promise<ConvertSummary>;
55
+ /**
56
+ * Convert one FCStd file through the full pipeline (unpack → parse → sketch
57
+ * solving → codegen → container build) and return a structured summary.
58
+ * @param input path to the .FCStd file to convert
59
+ * @param opts optional knobs (see {@link ConvertOptions}); defaults keep the C4 contract
60
+ * @returns a summary with ok=false (and no zip, unless `keepGappedContainer`) on any pipeline failure or translation gap
61
+ */
62
+ export declare function convertFcstdFile(input: string, opts?: ConvertOptions): Promise<ConvertSummary>;
34
63
  //# sourceMappingURL=convert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/fcstd/convert.ts"],"names":[],"mappings":"AAyBA,2EAA2E;AAC3E,eAAO,MAAM,SAAS,WAAO,CAAC;AAE9B,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,aAA4D,CAAC;AAE9F,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,EAAE,EAAE,OAAO,CAAC;IACZ,0DAA0D;IAC1D,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,iEAAiE;IACjE,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAsCD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAwJ7E"}
1
+ {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/fcstd/convert.ts"],"names":[],"mappings":"AA8BA,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,eAAe,EAEhB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,eAAe,EAAE,CAAC;AAExE,2EAA2E;AAC3E,eAAO,MAAM,SAAS,WAAO,CAAC;AAE9B,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,aAA4D,CAAC;AAE9F;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,0GAA0G;AAC1G,MAAM,WAAW,cAAc;IAC7B,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,EAAE,EAAE,OAAO,CAAC;IACZ,0DAA0D;IAC1D,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,8EAA8E;IAC9E,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AA8BD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAiMpG"}