@things-factory/figure-ui 10.1.75 → 10.1.77

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 (282) hide show
  1. package/client/figure-assistant.ts +3 -3
  2. package/client/graphql/{v3-store.ts → store.ts} +6 -6
  3. package/client/modeller/{v3-ai-proposal.ts → ai-proposal.ts} +8 -8
  4. package/client/modeller/{v3-align.ts → align.ts} +14 -14
  5. package/client/modeller/{v3-canvas.ts → canvas.ts} +13 -13
  6. package/client/modeller/{v3-clips.ts → clips.ts} +5 -5
  7. package/client/modeller/{v3-controls.ts → controls.ts} +2 -2
  8. package/client/modeller/{v3-editor.ts → editor.ts} +117 -117
  9. package/client/modeller/{figure-v3-capability.ts → figure-capability-panel.ts} +7 -7
  10. package/client/modeller/{figure-v3-clips.ts → figure-clips.ts} +10 -10
  11. package/client/modeller/{figure-v3-controls.ts → figure-controls.ts} +9 -9
  12. package/client/modeller/{v3-figure-facts.ts → figure-facts.ts} +11 -11
  13. package/client/modeller/{figure-v3-first-save.ts → figure-first-save.ts} +3 -3
  14. package/client/modeller/figure-history-panel.ts +1 -1
  15. package/client/modeller/{figure-v3-links.ts → figure-links.ts} +35 -35
  16. package/client/modeller/{figure-v3-material.ts → figure-material-panel.ts} +20 -20
  17. package/client/modeller/{figure-v3-parts.ts → figure-parts.ts} +15 -15
  18. package/client/modeller/{figure-v3-preview.ts → figure-preview.ts} +14 -14
  19. package/client/modeller/{figure-v3-properties.ts → figure-properties.ts} +25 -25
  20. package/client/modeller/{figure-v3-recipe-catalog.ts → figure-recipe-catalog.ts} +10 -10
  21. package/client/modeller/{figure-v3-verdict.ts → figure-verdict.ts} +24 -24
  22. package/client/modeller/gate-findings.ts +2 -2
  23. package/client/modeller/{v3-gizmo.ts → gizmo.ts} +11 -11
  24. package/client/modeller/{v3-joint-drag.ts → joint-drag.ts} +11 -11
  25. package/client/modeller/{v3-joint-fan.ts → joint-fan.ts} +13 -13
  26. package/client/modeller/{v3-links.ts → links.ts} +59 -59
  27. package/client/modeller/{v3-live.ts → live.ts} +9 -9
  28. package/client/modeller/{v3-maturity.ts → maturity.ts} +65 -65
  29. package/client/modeller/modeller-route.ts +1 -1
  30. package/client/modeller/{v3-occupancy.ts → occupancy.ts} +6 -6
  31. package/client/modeller/{v3-palette.ts → palette.ts} +3 -3
  32. package/client/modeller/{v3-preview-model.ts → preview-model.ts} +8 -8
  33. package/client/modeller/{v3-product-session.ts → product-session.ts} +25 -25
  34. package/client/modeller/{v3-recipe-source.ts → recipe-source.ts} +2 -2
  35. package/client/modeller/{v3-recipes.ts → recipes.ts} +9 -9
  36. package/client/modeller/{v3-renderer.ts → renderer.ts} +16 -16
  37. package/client/modeller/{v3-stage-model.ts → stage-model.ts} +15 -15
  38. package/client/modeller/{v3-thumbnail.ts → thumbnail.ts} +8 -8
  39. package/client/pages/figure-list-page.ts +4 -4
  40. package/client/pages/{figure-v3-modeller-page.ts → figure-modeller-page.ts} +37 -37
  41. package/client/route.ts +1 -5
  42. package/dist-client/figure-assistant.js +3 -3
  43. package/dist-client/figure-assistant.js.map +1 -1
  44. package/dist-client/graphql/store.d.ts +3 -0
  45. package/dist-client/graphql/{v3-store.js → store.js} +6 -6
  46. package/dist-client/graphql/store.js.map +1 -0
  47. package/dist-client/modeller/{v3-ai-proposal.d.ts → ai-proposal.d.ts} +7 -7
  48. package/dist-client/modeller/{v3-ai-proposal.js → ai-proposal.js} +1 -1
  49. package/dist-client/modeller/ai-proposal.js.map +1 -0
  50. package/dist-client/modeller/{v3-align.d.ts → align.d.ts} +8 -8
  51. package/dist-client/modeller/{v3-align.js → align.js} +6 -6
  52. package/dist-client/modeller/align.js.map +1 -0
  53. package/dist-client/modeller/{v3-canvas.d.ts → canvas.d.ts} +7 -7
  54. package/dist-client/modeller/{v3-canvas.js → canvas.js} +20 -20
  55. package/dist-client/modeller/canvas.js.map +1 -0
  56. package/dist-client/modeller/{v3-clips.d.ts → clips.d.ts} +4 -4
  57. package/dist-client/modeller/{v3-clips.js → clips.js} +1 -1
  58. package/dist-client/modeller/clips.js.map +1 -0
  59. package/dist-client/modeller/{v3-controls.d.ts → controls.d.ts} +2 -2
  60. package/dist-client/modeller/{v3-controls.js → controls.js} +1 -1
  61. package/dist-client/modeller/controls.js.map +1 -0
  62. package/dist-client/modeller/{v3-editor.d.ts → editor.d.ts} +19 -19
  63. package/dist-client/modeller/{v3-editor.js → editor.js} +103 -103
  64. package/dist-client/modeller/editor.js.map +1 -0
  65. package/dist-client/modeller/{v3-fields.js → fields.js} +1 -1
  66. package/dist-client/modeller/fields.js.map +1 -0
  67. package/dist-client/modeller/{figure-v3-capability.d.ts → figure-capability-panel.d.ts} +4 -4
  68. package/dist-client/modeller/{figure-v3-capability.js → figure-capability-panel.js} +12 -12
  69. package/dist-client/modeller/figure-capability-panel.js.map +1 -0
  70. package/dist-client/modeller/{figure-v3-clips.d.ts → figure-clips.d.ts} +4 -4
  71. package/dist-client/modeller/{figure-v3-clips.js → figure-clips.js} +16 -16
  72. package/dist-client/modeller/figure-clips.js.map +1 -0
  73. package/dist-client/modeller/{figure-v3-controls.d.ts → figure-controls.d.ts} +5 -5
  74. package/dist-client/modeller/{figure-v3-controls.js → figure-controls.js} +16 -16
  75. package/dist-client/modeller/figure-controls.js.map +1 -0
  76. package/dist-client/modeller/{v3-figure-facts.d.ts → figure-facts.d.ts} +5 -5
  77. package/dist-client/modeller/{v3-figure-facts.js → figure-facts.js} +5 -5
  78. package/dist-client/modeller/figure-facts.js.map +1 -0
  79. package/dist-client/modeller/{figure-v3-first-save.d.ts → figure-first-save.d.ts} +1 -1
  80. package/dist-client/modeller/{figure-v3-first-save.js → figure-first-save.js} +11 -11
  81. package/dist-client/modeller/figure-first-save.js.map +1 -0
  82. package/dist-client/modeller/figure-history-panel.d.ts +1 -1
  83. package/dist-client/modeller/figure-history-panel.js.map +1 -1
  84. package/dist-client/modeller/{figure-v3-links.d.ts → figure-links.d.ts} +5 -5
  85. package/dist-client/modeller/{figure-v3-links.js → figure-links.js} +24 -24
  86. package/dist-client/modeller/figure-links.js.map +1 -0
  87. package/dist-client/modeller/{figure-v3-material.d.ts → figure-material-panel.d.ts} +9 -9
  88. package/dist-client/modeller/{figure-v3-material.js → figure-material-panel.js} +19 -19
  89. package/dist-client/modeller/figure-material-panel.js.map +1 -0
  90. package/dist-client/modeller/{figure-v3-parts.d.ts → figure-parts.d.ts} +12 -12
  91. package/dist-client/modeller/{figure-v3-parts.js → figure-parts.js} +14 -14
  92. package/dist-client/modeller/figure-parts.js.map +1 -0
  93. package/dist-client/modeller/{figure-v3-preview.d.ts → figure-preview.d.ts} +4 -4
  94. package/dist-client/modeller/{figure-v3-preview.js → figure-preview.js} +21 -21
  95. package/dist-client/modeller/figure-preview.js.map +1 -0
  96. package/dist-client/modeller/{figure-v3-properties.d.ts → figure-properties.d.ts} +8 -8
  97. package/dist-client/modeller/{figure-v3-properties.js → figure-properties.js} +25 -25
  98. package/dist-client/modeller/figure-properties.js.map +1 -0
  99. package/dist-client/modeller/{figure-v3-recipe-catalog.d.ts → figure-recipe-catalog.d.ts} +4 -4
  100. package/dist-client/modeller/{figure-v3-recipe-catalog.js → figure-recipe-catalog.js} +21 -21
  101. package/dist-client/modeller/figure-recipe-catalog.js.map +1 -0
  102. package/dist-client/modeller/{figure-v3-verdict.d.ts → figure-verdict.d.ts} +2 -2
  103. package/dist-client/modeller/{figure-v3-verdict.js → figure-verdict.js} +26 -26
  104. package/dist-client/modeller/figure-verdict.js.map +1 -0
  105. package/dist-client/modeller/{v3-first-save.js → first-save.js} +1 -1
  106. package/dist-client/modeller/first-save.js.map +1 -0
  107. package/dist-client/modeller/gate-findings.d.ts +2 -2
  108. package/dist-client/modeller/gate-findings.js +2 -2
  109. package/dist-client/modeller/gate-findings.js.map +1 -1
  110. package/dist-client/modeller/{v3-gizmo.d.ts → gizmo.d.ts} +5 -5
  111. package/dist-client/modeller/{v3-gizmo.js → gizmo.js} +3 -3
  112. package/dist-client/modeller/gizmo.js.map +1 -0
  113. package/dist-client/modeller/{v3-help.js → help.js} +1 -1
  114. package/dist-client/modeller/help.js.map +1 -0
  115. package/dist-client/modeller/joint-drag.d.ts +19 -0
  116. package/dist-client/modeller/{v3-joint-drag.js → joint-drag.js} +4 -4
  117. package/dist-client/modeller/joint-drag.js.map +1 -0
  118. package/dist-client/modeller/{v3-joint-fan.d.ts → joint-fan.d.ts} +3 -3
  119. package/dist-client/modeller/{v3-joint-fan.js → joint-fan.js} +6 -6
  120. package/dist-client/modeller/joint-fan.js.map +1 -0
  121. package/dist-client/modeller/{v3-keys.js → keys.js} +1 -1
  122. package/dist-client/modeller/keys.js.map +1 -0
  123. package/dist-client/modeller/{v3-links.d.ts → links.d.ts} +48 -48
  124. package/dist-client/modeller/{v3-links.js → links.js} +15 -15
  125. package/dist-client/modeller/links.js.map +1 -0
  126. package/dist-client/modeller/{v3-live.d.ts → live.d.ts} +6 -6
  127. package/dist-client/modeller/{v3-live.js → live.js} +5 -5
  128. package/dist-client/modeller/live.js.map +1 -0
  129. package/dist-client/modeller/{v3-maturity.d.ts → maturity.d.ts} +26 -26
  130. package/dist-client/modeller/{v3-maturity.js → maturity.js} +28 -28
  131. package/dist-client/modeller/maturity.js.map +1 -0
  132. package/dist-client/modeller/modeller-route.d.ts +1 -1
  133. package/dist-client/modeller/modeller-route.js +1 -1
  134. package/dist-client/modeller/modeller-route.js.map +1 -1
  135. package/dist-client/modeller/{v3-occupancy.d.ts → occupancy.d.ts} +4 -4
  136. package/dist-client/modeller/{v3-occupancy.js → occupancy.js} +6 -6
  137. package/dist-client/modeller/occupancy.js.map +1 -0
  138. package/dist-client/modeller/palette.d.ts +7 -0
  139. package/dist-client/modeller/{v3-palette.js → palette.js} +1 -1
  140. package/dist-client/modeller/palette.js.map +1 -0
  141. package/dist-client/modeller/{v3-preview-model.d.ts → preview-model.d.ts} +3 -3
  142. package/dist-client/modeller/{v3-preview-model.js → preview-model.js} +6 -6
  143. package/dist-client/modeller/preview-model.js.map +1 -0
  144. package/dist-client/modeller/{v3-product-session.d.ts → product-session.d.ts} +56 -56
  145. package/dist-client/modeller/{v3-product-session.js → product-session.js} +7 -7
  146. package/dist-client/modeller/product-session.js.map +1 -0
  147. package/dist-client/modeller/{v3-recipe-source.d.ts → recipe-source.d.ts} +2 -2
  148. package/dist-client/modeller/{v3-recipe-source.js → recipe-source.js} +3 -3
  149. package/dist-client/modeller/recipe-source.js.map +1 -0
  150. package/dist-client/modeller/{v3-recipes.d.ts → recipes.d.ts} +7 -7
  151. package/dist-client/modeller/{v3-recipes.js → recipes.js} +4 -4
  152. package/dist-client/modeller/recipes.js.map +1 -0
  153. package/dist-client/modeller/{v3-refusals.js → refusals.js} +1 -1
  154. package/dist-client/modeller/refusals.js.map +1 -0
  155. package/dist-client/modeller/{v3-renderer.d.ts → renderer.d.ts} +6 -6
  156. package/dist-client/modeller/{v3-renderer.js → renderer.js} +13 -13
  157. package/dist-client/modeller/renderer.js.map +1 -0
  158. package/dist-client/modeller/{v3-stage-model.d.ts → stage-model.d.ts} +7 -7
  159. package/dist-client/modeller/{v3-stage-model.js → stage-model.js} +5 -5
  160. package/dist-client/modeller/stage-model.js.map +1 -0
  161. package/dist-client/modeller/thumbnail.d.ts +3 -0
  162. package/dist-client/modeller/{v3-thumbnail.js → thumbnail.js} +6 -6
  163. package/dist-client/modeller/thumbnail.js.map +1 -0
  164. package/dist-client/pages/figure-list-page.d.ts +1 -1
  165. package/dist-client/pages/figure-list-page.js +4 -4
  166. package/dist-client/pages/figure-list-page.js.map +1 -1
  167. package/dist-client/pages/{figure-v3-modeller-page.d.ts → figure-modeller-page.d.ts} +10 -10
  168. package/dist-client/pages/{figure-v3-modeller-page.js → figure-modeller-page.js} +42 -42
  169. package/dist-client/pages/figure-modeller-page.js.map +1 -0
  170. package/dist-client/route.d.ts +1 -1
  171. package/dist-client/route.js +1 -5
  172. package/dist-client/route.js.map +1 -1
  173. package/dist-client/tsconfig.tsbuildinfo +1 -1
  174. package/docs/product-cutover.md +25 -0
  175. package/package.json +5 -5
  176. package/test/{v3-ai-proposal.test.ts → ai-proposal.test.ts} +6 -6
  177. package/test/{v3-align.test.ts → align.test.ts} +8 -8
  178. package/test/browser/modeller-page.js +30 -30
  179. package/test/browser/modeller.check.mjs +14 -14
  180. package/test/browser/serve.mjs +1 -1
  181. package/test/browser/thumbnail-page.js +6 -6
  182. package/test/{v3-clips.test.ts → clips.test.ts} +18 -18
  183. package/test/{v3-controls.test.ts → controls.test.ts} +15 -15
  184. package/test/{v3-fields.test.ts → fields.test.ts} +13 -13
  185. package/test/figure-assistant-surface.test.ts +3 -3
  186. package/test/{v3-first-save.test.ts → first-save.test.ts} +10 -10
  187. package/test/fixtures/joint-column.json +2 -2
  188. package/test/fixtures/joint-roller.json +2 -2
  189. package/test/fixtures/robot-arm-6dof.json +2 -2
  190. package/test/{v3-gizmo.test.ts → gizmo.test.ts} +33 -33
  191. package/test/{v3-joint-drag.test.ts → joint-drag.test.ts} +17 -17
  192. package/test/{v3-joint-fan.test.ts → joint-fan.test.ts} +18 -18
  193. package/test/joints.ts +6 -6
  194. package/test/{v3-keys.test.ts → keys.test.ts} +2 -2
  195. package/test/{v3-layout.test.ts → layout.test.ts} +8 -8
  196. package/test/{v3-links.test.ts → links.test.ts} +201 -201
  197. package/test/{v3-live.test.ts → live.test.ts} +18 -18
  198. package/test/{v3-material.test.ts → material.test.ts} +12 -12
  199. package/test/{v3-maturity.test.ts → maturity.test.ts} +74 -74
  200. package/test/modeller-route.test.ts +5 -6
  201. package/test/{v3-palette-icons.test.ts → palette-icons.test.ts} +1 -1
  202. package/test/{v3-parts-wiring.test.ts → parts-wiring.test.ts} +5 -5
  203. package/test/{v3-preview.test.ts → preview.test.ts} +12 -12
  204. package/test/{v3-product-session.test.ts → product-session.test.ts} +17 -17
  205. package/test/{v3-product-write.test.ts → product-write.test.ts} +20 -20
  206. package/test/{v3-properties.test.ts → properties.test.ts} +24 -24
  207. package/test/{v3-recipes.test.ts → recipes.test.ts} +9 -9
  208. package/test/{v3-refusals.test.ts → refusals.test.ts} +43 -43
  209. package/test/{v3-release-panel.test.ts → release-panel.test.ts} +21 -21
  210. package/test/renderer.test.ts +24 -0
  211. package/test/resolve-ts-siblings.mjs +1 -1
  212. package/test/{v3-scene-canvas.test.ts → scene-canvas.test.ts} +6 -6
  213. package/test/{v3-stage-model.test.ts → stage-model.test.ts} +5 -5
  214. package/test/{v3-theme.test.ts → theme.test.ts} +4 -4
  215. package/test/{v3-thumbnail.test.ts → thumbnail.test.ts} +4 -4
  216. package/test/{v3-verdict.test.ts → verdict.test.ts} +17 -17
  217. package/test/{v3-view.test.ts → view.test.ts} +2 -2
  218. package/things-factory.config.js +2 -3
  219. package/translations/en.json +2 -2
  220. package/translations/ja.json +2 -2
  221. package/translations/ko.json +2 -2
  222. package/translations/ms.json +2 -2
  223. package/translations/zh.json +2 -2
  224. package/dist-client/graphql/v3-store.d.ts +0 -3
  225. package/dist-client/graphql/v3-store.js.map +0 -1
  226. package/dist-client/modeller/figure-v3-capability.js.map +0 -1
  227. package/dist-client/modeller/figure-v3-clips.js.map +0 -1
  228. package/dist-client/modeller/figure-v3-controls.js.map +0 -1
  229. package/dist-client/modeller/figure-v3-first-save.js.map +0 -1
  230. package/dist-client/modeller/figure-v3-links.js.map +0 -1
  231. package/dist-client/modeller/figure-v3-material.js.map +0 -1
  232. package/dist-client/modeller/figure-v3-parts.js.map +0 -1
  233. package/dist-client/modeller/figure-v3-preview.js.map +0 -1
  234. package/dist-client/modeller/figure-v3-properties.js.map +0 -1
  235. package/dist-client/modeller/figure-v3-recipe-catalog.js.map +0 -1
  236. package/dist-client/modeller/figure-v3-verdict.js.map +0 -1
  237. package/dist-client/modeller/v3-ai-proposal.js.map +0 -1
  238. package/dist-client/modeller/v3-align.js.map +0 -1
  239. package/dist-client/modeller/v3-canvas.js.map +0 -1
  240. package/dist-client/modeller/v3-clips.js.map +0 -1
  241. package/dist-client/modeller/v3-controls.js.map +0 -1
  242. package/dist-client/modeller/v3-editor.js.map +0 -1
  243. package/dist-client/modeller/v3-fields.js.map +0 -1
  244. package/dist-client/modeller/v3-figure-facts.js.map +0 -1
  245. package/dist-client/modeller/v3-first-save.js.map +0 -1
  246. package/dist-client/modeller/v3-gizmo.js.map +0 -1
  247. package/dist-client/modeller/v3-help.js.map +0 -1
  248. package/dist-client/modeller/v3-joint-drag.d.ts +0 -19
  249. package/dist-client/modeller/v3-joint-drag.js.map +0 -1
  250. package/dist-client/modeller/v3-joint-fan.js.map +0 -1
  251. package/dist-client/modeller/v3-keys.js.map +0 -1
  252. package/dist-client/modeller/v3-links.js.map +0 -1
  253. package/dist-client/modeller/v3-live.js.map +0 -1
  254. package/dist-client/modeller/v3-maturity.js.map +0 -1
  255. package/dist-client/modeller/v3-occupancy.js.map +0 -1
  256. package/dist-client/modeller/v3-palette.d.ts +0 -7
  257. package/dist-client/modeller/v3-palette.js.map +0 -1
  258. package/dist-client/modeller/v3-preview-model.js.map +0 -1
  259. package/dist-client/modeller/v3-product-session.js.map +0 -1
  260. package/dist-client/modeller/v3-recipe-source.js.map +0 -1
  261. package/dist-client/modeller/v3-recipes.js.map +0 -1
  262. package/dist-client/modeller/v3-refusals.js.map +0 -1
  263. package/dist-client/modeller/v3-renderer.js.map +0 -1
  264. package/dist-client/modeller/v3-stage-model.js.map +0 -1
  265. package/dist-client/modeller/v3-thumbnail.d.ts +0 -3
  266. package/dist-client/modeller/v3-thumbnail.js.map +0 -1
  267. package/dist-client/pages/figure-v3-modeller-page.js.map +0 -1
  268. package/dist-client/tsconfig.chk.tsbuildinfo +0 -1
  269. package/dist-client/tsconfig.fui.tsbuildinfo +0 -1
  270. package/dist-client/tsconfig.scratch-fm.tsbuildinfo +0 -1
  271. package/docs/v3-product-cutover.md +0 -25
  272. package/test/v3-renderer.test.ts +0 -24
  273. /package/client/modeller/{v3-fields.ts → fields.ts} +0 -0
  274. /package/client/modeller/{v3-first-save.ts → first-save.ts} +0 -0
  275. /package/client/modeller/{v3-help.ts → help.ts} +0 -0
  276. /package/client/modeller/{v3-keys.ts → keys.ts} +0 -0
  277. /package/client/modeller/{v3-refusals.ts → refusals.ts} +0 -0
  278. /package/dist-client/modeller/{v3-fields.d.ts → fields.d.ts} +0 -0
  279. /package/dist-client/modeller/{v3-first-save.d.ts → first-save.d.ts} +0 -0
  280. /package/dist-client/modeller/{v3-help.d.ts → help.d.ts} +0 -0
  281. /package/dist-client/modeller/{v3-keys.d.ts → keys.d.ts} +0 -0
  282. /package/dist-client/modeller/{v3-refusals.d.ts → refusals.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joint-fan.js","sourceRoot":"","sources":["../../client/modeller/joint-fan.ts"],"names":[],"mappings":"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","sourcesContent":["import { compileFigureAsset, compileFigureGraph, figureWorldBoxesOf, figureWritersOf } from '@hatiolab/figure-model'\nimport type { FigureAsset } from '@hatiolab/figure-model'\n\nimport type { FigureRenderPart } from './renderer.js'\n\n/*\n * Where the selected part turns, and how far -- a translucent fan on the editing board. An axis name says nothing about which way a part swings; on a six-axis arm the author went to the preview and\n * pushed each slider to its end to find out. The fan lies in the plane the part turns in, at the pivot, open from the\n * control's lowest value to its highest; the edge at the value the figure holds now is where the part is.\n *\n * It is found by evaluating, not by reading the graph's shape: the frame that carries the part is sampled across the\n * control's range, and a point at a fixed distance from the pivot traces the fan. So the direction is right whatever\n * the slope of the control, and a joint inside other joints is drawn where its parents put it.\n *\n * Two ways a part turns are read:\n * - a joint record (ADR-0093): at the joint's origin, about its axis;\n * - a joint written as values (`<joint>.motion` · `<joint>.chain`): the part is composed on the joint's\n * chain, the pivot is the joint's origin (`<joint>.frameOnParent`).\n * A slide has no fan. Nothing is drawn when the turn cannot be found -- a fan in some guessed plane would point the\n * wrong way.\n */\n\n/** The fan's name on the board. It is not a part: not in the list, not saved, not picked. */\nexport const JOINT_FAN = '__joint-fan'\n\n/** How thick the fan is: thin enough not to hide the part, thick enough to be seen edge-on. */\nconst THICKNESS = 6\n/** About one segment every six degrees, so a full turn reads as a circle. */\nconst STEP_DEG = 6\n\ntype Pose = { r: number[][]; t: number[] }\ninterface Node {\n id: string\n op: string\n args: string[]\n outputs: Record<string, string>\n params?: Record<string, string>\n}\n\nconst apply = (p: Pose, v: number[]) => [0, 1, 2].map(i => p.r[i]![0]! * v[0]! + p.r[i]![1]! * v[1]! + p.r[i]![2]! * v[2]! + p.t[i]!)\nconst sub = (a: number[], b: number[]) => a.map((v, i) => v - b[i]!)\nconst dot = (a: number[], b: number[]) => a.reduce((s, v, i) => s + v * b[i]!, 0)\nconst cross = (a: number[], b: number[]) => [a[1]! * b[2]! - a[2]! * b[1]!, a[2]! * b[0]! - a[0]! * b[2]!, a[0]! * b[1]! - a[1]! * b[0]!]\nconst norm = (a: number[]) => {\n const l = Math.hypot(...a)\n return l > 1e-9 ? a.map(v => v / l) : null\n}\n\n/** How far outside a part's box a pivot may lie and still be on the part: the kernel's contact skin. */\nconst SEAM = 1\n/** An origin this deep in a part's box (a share of its half-measure, on every axis) is housed by the part. */\nconst HOUSED = 0.5\nconst AXIS_NAMES = ['x', 'y', 'z'] as const\ntype WorldBox = { centre: Record<'x' | 'y' | 'z', number>; extent: Record<'x' | 'y' | 'z', number> }\n\ninterface Turn {\n /** The node whose value carries the moving frame into the figure's frame. */\n carrier: string\n /** The pivot, in the moving frame. */\n pivot: number[]\n /** The axis, in the moving frame. */\n axis: number[]\n /** Where the part sits, in the moving frame -- which way the fan's reference edge points. */\n toward: number[]\n /** The part the joint turns -- the fan is sized from it, so a joint shows one fan whichever part is selected. */\n turnedPart: string\n /** The state input that turns it. */\n control: { id: string; min: number; max: number }\n}\n\nfunction turnOf(asset: FigureAsset, part: string, values: Record<string, unknown>, box: WorldBox | undefined): Turn | null {\n const m = asset.document.model as unknown as { nodes: Node[]; constants: { id: string; value: number }[]; inputs: { id: string; role?: string; min?: number; max?: number }[] }\n const node = (id: string) => m.nodes.find(n => n.id === id)\n const constant = (ref: string) => m.constants.find(c => c.id === ref)?.value\n const valueOf = (n: Node | undefined) => (n ? values[Object.values(n.outputs)[0]!] : undefined) as Pose | undefined\n const controlOf = (ref: string | undefined, seen = new Set<string>()): Turn['control'] | null => {\n if (!ref || seen.has(ref)) return null\n seen.add(ref)\n const input = m.inputs.find(i => i.id === ref && i.role === 'state')\n if (input) return { id: input.id, min: input.min ?? 0, max: input.max ?? 0 }\n const writer = m.nodes.find(n => Object.values(n.outputs).includes(ref))\n for (const arg of writer?.args ?? []) {\n const found = controlOf(arg, seen)\n if (found) return found\n }\n return null\n }\n const axisOf = (motion: Node) => {\n const axis = motion.args.slice(0, 3).map(constant)\n return axis.every(v => typeof v === 'number') ? norm(axis as number[]) : null\n }\n\n /*\n A joint record (ADR-0093): the fan stands at the joint -- the point on the parent's face the child is fastened at --\n about the joint's axis. A part that does not turn itself shows the joint that sits on it, when there is one: the\n elbow block shows the elbow (user, 2026-09-24: 「elbow-housing itself is a axis」).\n */\n const turning = (asset.joints ?? []).filter(j => j.type === 'revolute')\n const record = turning.find(j => j.body1.part === part) ?? (() => {\n const on = turning.filter(j => 'part' in j.body0 && j.body0.part === part)\n return on.length === 1 && !(asset.joints ?? []).some(j => j.body1.part === part && j.type !== 'fixed') ? on[0] : undefined\n })()\n if (record) {\n const child = record.body1.part\n const carrier = node(`${child}.world`) ? `${child}.world` : `${child}.chain`\n const pose = valueOf(node(`${child}.pose`))\n const motion = node(`${child}.motion`)\n const control = controlOf(motion?.args[3])\n if (!node(carrier) || !pose || !control) return null\n /* In the child's own frame: the joint is where its pose puts the seat's origin, the axis turned back by its pose. */\n const back = (v: number[]) => [0, 1, 2].map(i => pose.r[0]![i]! * v[0]! + pose.r[1]![i]! * v[1]! + pose.r[2]![i]! * v[2]!)\n const pivot = back(pose.t.map(v => -v))\n const axis = norm(back(AXIS_NAMES.map(a => (a.toUpperCase() === record.axis ? 1 : 0))))\n if (!axis) return null\n return { carrier, pivot, axis, toward: [0, 0, 0], control, turnedPart: child }\n }\n\n /*\n A joint written as values (`<joint>.motion`, its origin `<joint>.frameOnParent`) carries its own part and\n everything fastened below it, through its chain (the first joint of a chain has only its attachment). A part shows\n the joint it is to that part of the mechanism (user, 2026-09-24: 「elbow-housing itself is a axis」 · 「please check\n all that logic and concept」), tested in this order on the joints as they stand now:\n 1. housing -- a joint's origin lies deep inside the part, which is centred on it: the shoulder housing shows the\n shoulder and the elbow housing the elbow, though another joint carries them;\n 2. turned -- the joint that carries the part, when its axis passes through the part: through its middle for a\n body that rolls on it (the wrist roll, the tool flange, the gripper body), through its root for a link (the\n upper arm, the forearm);\n 3. otherwise none: the pedestal (the base's axis runs through it but turns it not), the fingers.\n An axis passing through a part is not enough by itself: the wrist roll's axis runs the forearm's length and the\n tool roll's through the wrist pitch, and neither turns them (an earlier rule said so, and was wrong).\n */\n if (!box) return null\n const carrierOf = (joint: string) => (node(`${joint}.chain`) ? `${joint}.chain` : `${joint}.attach`)\n const mine = node(`${part}.moved`)?.args.find(arg => /\\.(chain|attach)\\.value$/.test(arg))?.replace(/\\.value$/, '')\n const centre = AXIS_NAMES.map(a => box.centre[a])\n const half = AXIS_NAMES.map(a => box.extent[a] / 2)\n const joints = m.nodes\n .filter(n => n.op === 'axis-turn@1' && n.id.endsWith('.motion') && node(n.id.replace(/\\.motion$/, '.frameOnParent')))\n .map(motion => {\n const joint = motion.id.replace(/\\.motion$/, '')\n const carrier = carrierOf(joint)\n const frame = valueOf(node(carrier))\n const origin = valueOf(node(`${joint}.frameOnParent`))\n const local = axisOf(motion)\n if (!frame || !origin || !local) return null\n const at = apply(frame, origin.t)\n const along = norm([0, 1, 2].map(i => dot(frame.r[i]!, local)))\n if (!along) return null\n const off = sub(centre, at)\n return {\n joint,\n motion,\n carrier,\n origin,\n /* How deep the origin lies: 0 at the centre, 1 on the box's face, on the axis where it is shallowest. */\n depth: Math.max(...[0, 1, 2].map(i => Math.abs(off[i]!) / (half[i]! + SEAM))),\n fromCentre: Math.hypot(...off),\n through: lineMeetsBox(at, along, centre, half)\n }\n })\n .filter((c): c is NonNullable<typeof c> => !!c)\n const housing = joints.filter(c => c.depth <= HOUSED).sort((a, b) => a.fromCentre - b.fromCentre)[0]\n const carrying = joints.find(c => c.carrier === mine)\n const chosen = housing ?? (carrying && carrying.through ? carrying : undefined)\n if (!chosen) return null\n const axis = axisOf(chosen.motion)\n const control = controlOf(chosen.motion.args[3])\n if (!axis || !control) return null\n /* The reference edge points at what the joint turns: of the parts it carries, the one farthest off its axis. */\n const flatOff = (t: number[]) => {\n const rel = sub(t, chosen.origin.t)\n return Math.hypot(...sub(rel, axis.map(v => v * dot(rel, axis))))\n }\n const turned = m.nodes\n .filter(n => n.id.endsWith('.moved') && n.args.includes(`${chosen.carrier}.value`))\n .map(n => ({ id: n.id.replace(/\\.moved$/, ''), t: valueOf(node(n.id.replace(/\\.moved$/, '.pose')))?.t }))\n .filter((one): one is { id: string; t: number[] } => !!one.t)\n .sort((a, b) => flatOff(b.t) - flatOff(a.t))[0]\n return { carrier: chosen.carrier, pivot: chosen.origin.t, axis, toward: turned?.t ?? chosen.origin.t, control, turnedPart: turned?.id ?? part }\n}\n\n/**\n * The fan for the part, as a body to stand on the board, or null when the part does not turn. `values` are the\n * inputs the figure is drawn with now (a pose in hand included), so the fan follows the arm as it is posed.\n */\nexport function jointFanOf(asset: FigureAsset, part: string, values: Record<string, number> = {}): FigureRenderPart | null {\n if (!part) return null\n let graph: ReturnType<typeof compileFigureGraph>\n try {\n graph = compileFigureGraph(asset.document.model as never)\n } catch {\n return null\n }\n const inputs = { ...asset.designInputs, ...asset.stateDefaults, ...values }\n const at = (over: Record<string, number>) => graph.evaluate({ ...inputs, ...over }).values as Record<string, unknown>\n let now: Record<string, unknown>\n try {\n now = at({})\n } catch {\n return null\n }\n let box: WorldBox | undefined\n try {\n box = figureWorldBoxesOf(\n compileFigureAsset({ ...asset, designInputs: { ...asset.designInputs, ...pick(values, asset.designInputs) }, stateDefaults: { ...asset.stateDefaults, ...pick(values, asset.stateDefaults) } })\n .evaluate()\n .geometry.filter(g => g.id === part),\n figureWritersOf(asset)\n )[0]\n } catch {\n box = undefined\n }\n const turn = turnOf(asset, part, now, box)\n if (!turn) return null\n const carrierRef = Object.values(asset.document.model.nodes.find(n => n.id === turn.carrier)!.outputs)[0]!\n const carrierNow = now[carrierRef] as Pose | undefined\n if (!carrierNow) return null\n\n /* The reference edge points from the pivot toward the part, in the plane it turns in; any perpendicular if it sits on the axis. */\n const rel = sub(turn.toward, turn.pivot)\n const inPlane = sub(rel, turn.axis.map(v => v * dot(rel, turn.axis)))\n const d = norm(inPlane) ?? norm(cross(turn.axis, Math.abs(turn.axis[0]!) < 0.9 ? [1, 0, 0] : [0, 1, 0]))!\n /*\n Sized from what the joint turns, not from the selected part: selecting the elbow housing or the forearm\n shows the elbow's one fan, not a smaller one for the smaller part (user, 2026-09-24).\n */\n const radius = Math.max(60, Math.round(Math.max(largestMeasureOf(asset, turn.turnedPart, inputs), Math.hypot(...inPlane)) * 0.6))\n const edge = turn.pivot.map((v, i) => v + d[i]! * radius)\n\n const { min, max } = turn.control\n if (!(max > min)) return null\n const steps = Math.max(2, Math.ceil((max - min) / STEP_DEG))\n const pivot = apply(carrierNow, turn.pivot)\n const traced: number[][] = []\n try {\n for (let i = 0; i <= steps; i++) {\n const s = min + ((max - min) * i) / steps\n traced.push(apply(at({ [turn.control.id]: s })[carrierRef] as Pose, edge))\n }\n } catch {\n return null\n }\n\n /* The fan's own frame: x toward the first traced point, y along the axis as it stands now, z completing them. */\n const axisNow = norm([0, 1, 2].map(i => dot(carrierNow.r[i]!, turn.axis)))\n const first = norm(sub(traced[0]!, pivot))\n if (!axisNow || !first) return null\n const zAxis = cross(first, axisNow)\n const r = [0, 1, 2].map(i => [first[i]!, axisNow[i]!, zAxis[i]!])\n const local = (p: number[]) => {\n const v = sub(p, pivot)\n return { x: dot(v, first), y: dot(v, zAxis) }\n }\n const full = max - min >= 359.999\n const profile = [...(full ? [] : [{ x: 0, y: 0 }]), ...traced.map(local)].map(p => ({ x: Math.round(p.x * 1000) / 1000, y: Math.round(p.y * 1000) / 1000 }))\n\n return {\n id: JOINT_FAN,\n shape: { provider: 'polygon', dimensions: { height: THICKNESS }, profile },\n pose: { t: pivot, r },\n material: { token: '__joint-fan', transparent: true },\n /** Which control turns it: the joint the fan shows. */\n turns: turn.control.id\n } as unknown as FigureRenderPart\n}\n\n/** The values in hand that belong to a record's keys (design inputs, or state defaults). */\nfunction pick(values: Record<string, number>, of: Record<string, number>): Record<string, number> {\n return Object.fromEntries(Object.entries(values).filter(([id]) => id in of))\n}\n\n/** A part's largest own measure (a box side, a diameter, a length) at the inputs given; 0 when it cannot be read. */\nfunction largestMeasureOf(asset: FigureAsset, part: string, inputs: Record<string, number>): number {\n try {\n const body = compileFigureAsset({ ...asset, designInputs: pick(inputs, asset.designInputs), stateDefaults: pick(inputs, asset.stateDefaults) })\n .evaluate()\n .geometry.find(g => g.id === part) as { shape?: { dimensions?: Record<string, number> } } | undefined\n const dims = Object.entries(body?.shape?.dimensions ?? {}).map(([k, v]) => (k.startsWith('radius') ? v * 2 : v))\n return dims.length ? Math.max(...dims) : 0\n } catch {\n return 0\n }\n}\n\n/** Whether the line through `at` along `along` passes through the box (centre, half-measures), within the skin. */\nfunction lineMeetsBox(at: number[], along: number[], centre: number[], half: number[]): boolean {\n let lo = -Infinity,\n hi = Infinity\n for (let i = 0; i < 3; i++) {\n const min = centre[i]! - half[i]! - SEAM,\n max = centre[i]! + half[i]! + SEAM\n if (Math.abs(along[i]!) < 1e-12) {\n if (at[i]! < min || at[i]! > max) return false\n continue\n }\n const t1 = (min - at[i]!) / along[i]!,\n t2 = (max - at[i]!) / along[i]!\n lo = Math.max(lo, Math.min(t1, t2))\n hi = Math.min(hi, Math.max(t1, t2))\n if (lo > hi) return false\n }\n return true\n}\n\n"]}
@@ -23,4 +23,4 @@ export function keyActionOf(e, selected) {
23
23
  return GIZMO_KEYS[key];
24
24
  return null;
25
25
  }
26
- //# sourceMappingURL=v3-keys.js.map
26
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../client/modeller/keys.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,GAA6B,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAA;AAkBxF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;AAEvD,MAAM,UAAU,WAAW,CAAC,CAAU,EAAE,QAAgB;IACtD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/G,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACzB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;IACtC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAA;IAC/B,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;IAC3D,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,MAAM,CAAA;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC1B,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,WAAW,CAAA;IAC1C,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,WAAW,CAAC;QAAE,OAAO,QAAQ,CAAA;IACtE,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAA;IAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAA;IAChF,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["/*\n * The modeller's keys: undo and redo on Ctrl+Z / Ctrl+Y, and what a person reaches for next. Read apart\n * from the element so the rule is tested without a browser.\n *\n * Typing is never taken: a key pressed in a field belongs to the field -- Backspace in a name box deletes a letter,\n * not the part.\n */\nexport type KeyAction = 'undo' | 'redo' | 'duplicate' | 'remove' | 'deselect' | GizmoKey\n\n/** The gizmo's modes on W, E and R, as the scene has them. */\nexport type GizmoKey = 'translate' | 'rotate' | 'scale'\nconst GIZMO_KEYS: Record<string, GizmoKey> = { w: 'translate', e: 'rotate', r: 'scale' }\n\nexport interface KeyLike {\n key: string\n ctrlKey?: boolean\n metaKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n /** The element the key was pressed in -- the first of the event's composed path. */\n target?: { tagName?: string; isContentEditable?: boolean } | null\n /**\n * Pressed with the canvas focused. The scene takes W, E and R there itself; they are passed on only from elsewhere\n * -- a part picked in the parts list left the focus there, and the gizmo could not be had at all (2026-09-25).\n * Passing a key the scene already took would toggle the gizmo off again.\n */\n inScene?: boolean\n}\n\nconst TYPING = new Set(['INPUT', 'SELECT', 'TEXTAREA'])\n\nexport function keyActionOf(e: KeyLike, selected: string): KeyAction | null {\n if (e.target && (TYPING.has(String(e.target.tagName).toUpperCase()) || e.target.isContentEditable)) return null\n if (e.altKey) return null\n const mod = !!(e.ctrlKey || e.metaKey)\n const key = e.key.toLowerCase()\n if (mod && key === 'z') return e.shiftKey ? 'redo' : 'undo'\n if (mod && key === 'y') return 'redo'\n if (!selected) return null\n if (mod && key === 'd') return 'duplicate'\n if (!mod && (key === 'delete' || key === 'backspace')) return 'remove'\n if (!mod && key === 'escape') return 'deselect'\n if (!mod && !e.shiftKey && !e.inScene && GIZMO_KEYS[key]) return GIZMO_KEYS[key]\n return null\n}\n"]}
@@ -1,61 +1,61 @@
1
- import type { V3Follow, V3SizeRange } from '@hatiolab/figure-model';
2
- import type { V3Asset, V3BindingPlace, V3Face, V3Joint } from '@hatiolab/figure-model';
1
+ import type { FigureFollow, FigureSizeRange } from '@hatiolab/figure-model';
2
+ import type { FigureAsset, FigureBindingPlace, FigureFace, FigureJoint } from '@hatiolab/figure-model';
3
3
  export type Axis = 'x' | 'y' | 'z';
4
4
  export declare const AXES: readonly Axis[];
5
- /** What one dimension of a part is worked out from (figure-model's `V3Follow`). */
6
- export type Follow = V3Follow;
5
+ /** What one dimension of a part is worked out from (figure-model's `FigureFollow`). */
6
+ export type Follow = FigureFollow;
7
7
  /**
8
8
  * `link-dimension` routes a part's dimension through `<part>.dimension.<axis>` and points its first argument at the
9
9
  * source, directly or through the nodes that scale it. Walking back through those nodes finds the source: the
10
10
  * instance size (`size.<axis>`), another part's dimension (`<part>.dimension.<axis>.value`) or a declared input.
11
11
  */
12
12
  /** What one measure of a part is worked out from, read back from the graph (figure-model's reader, one copy). */
13
- export declare function followOf(asset: V3Asset, part: string, axis: Axis): Follow;
13
+ export declare function followOf(asset: FigureAsset, part: string, axis: Axis): Follow;
14
14
  /** Whether the asset declares an instance size on an axis — only then can a dimension follow it. */
15
- export declare const hasInstanceSize: (asset: V3Asset, axis: Axis) => boolean;
15
+ export declare const hasInstanceSize: (asset: FigureAsset, axis: Axis) => boolean;
16
16
  /** The part this one is fastened to, or `null`. The mounting plane counts as fastened (the model names no part). */
17
- export declare function fastenedTo(asset: V3Asset, part: string): string | null;
17
+ export declare function fastenedTo(asset: FigureAsset, part: string): string | null;
18
18
  /**
19
19
  * What holds a part: the part it is fastened to, the plane the figure is mounted on, or nothing. The joint record says
20
20
  * it; a part standing on the plane had read as fastened to nothing, so the form offered no way to move it and sent
21
21
  * no replace -- the fastening was refused as already made (the door's post, 2026-09-25).
22
22
  */
23
- export declare function heldBy(asset: V3Asset, part: string): {
23
+ export declare function heldBy(asset: FigureAsset, part: string): {
24
24
  part: string;
25
25
  } | {
26
26
  plane: true;
27
27
  } | null;
28
28
  /** Whether a dimension of this part can follow something — box-shaped, whose three sizes are X, Y and Z. */
29
- export declare function canFollow(asset: V3Asset, part: string): boolean;
29
+ export declare function canFollow(asset: FigureAsset, part: string): boolean;
30
30
  /**
31
31
  * The axes whose size can follow something, by the shape's own measures: a box's X · Y · Z; a cylinder's radius (read
32
32
  * as X) and length (Y) -- its shape takes those two, so it has no Z of its own.
33
33
  */
34
- export declare function followableAxes(asset: V3Asset, part: string): Axis[];
34
+ export declare function followableAxes(asset: FigureAsset, part: string): Axis[];
35
35
  /** What a part's own measure on an axis is now (a box's side, a cylinder's radius or length), at the design as it stands. */
36
- export declare function dimensionNow(asset: V3Asset, part: string, axis: Axis): number | undefined;
36
+ export declare function dimensionNow(asset: FigureAsset, part: string, axis: Axis): number | undefined;
37
37
  /**
38
38
  * The flat faces a part's shape declares, by name -- figure-model's shape definitions are the one place they are
39
39
  * written (a portal's opening sides as well as its outer faces). A sphere has none.
40
40
  */
41
- export declare function facesOf(asset: V3Asset, part: string): string[];
41
+ export declare function facesOf(asset: FigureAsset, part: string): string[];
42
42
  /** The axis a face of a part faces along, from the same definitions. */
43
- export declare function faceAxisOf(asset: V3Asset, part: string, face: string): Axis | undefined;
43
+ export declare function faceAxisOf(asset: FigureAsset, part: string, face: string): Axis | undefined;
44
44
  /** Whether `attach` can take this part: any part whose shape has a flat face. */
45
- export declare function canFasten(asset: V3Asset, part: string): boolean;
45
+ export declare function canFasten(asset: FigureAsset, part: string): boolean;
46
46
  /**
47
47
  * The axes a part can be made a row along (r3 §8, figure-model `make-repeat`): across the face it is fastened by, when
48
48
  * it is fastened fixed to another part and holds nothing. None for a part that is loose, moves, stands on the floor or
49
49
  * already repeats -- the command would refuse those, so they are not offered.
50
50
  */
51
- export declare function rowAxesOf(asset: V3Asset, part: string): Axis[];
51
+ export declare function rowAxesOf(asset: FigureAsset, part: string): Axis[];
52
52
  /** The row a part is made into, as its fastening's record keeps it. */
53
- export declare const rowOf: (asset: V3Asset, part: string) => {
54
- axis: import("@hatiolab/figure-model").V3JointAxis;
55
- pitch: import("@hatiolab/figure-model").V3Measure;
53
+ export declare const rowOf: (asset: FigureAsset, part: string) => {
54
+ axis: import("@hatiolab/figure-model").FigureJointAxis;
55
+ pitch: import("@hatiolab/figure-model").FigureMeasure;
56
56
  count?: number;
57
57
  rise?: {
58
- axis: import("@hatiolab/figure-model").V3JointAxis;
58
+ axis: import("@hatiolab/figure-model").FigureJointAxis;
59
59
  mm: number;
60
60
  };
61
61
  } | undefined;
@@ -71,11 +71,11 @@ export type Alignment = 'centre' | 'min' | 'max' | 'mm' | 'share';
71
71
  * The mounting plane of this figure, by its placement (ADR-0093): the floor or the ceiling is Y = 0 and a part stands
72
72
  * on it by its bottom or hangs from it by its top; a wall is Z = 0 and a part is fastened to it by its back.
73
73
  */
74
- export declare function mountingPlaneOf(asset: V3Asset): {
74
+ export declare function mountingPlaneOf(asset: FigureAsset): {
75
75
  normal: Axis;
76
- faces: V3Face[];
76
+ faces: FigureFace[];
77
77
  };
78
- export declare function alignAxesOf(asset: V3Asset, part: string, target: {
78
+ export declare function alignAxesOf(asset: FigureAsset, part: string, target: {
79
79
  part: string;
80
80
  face: string;
81
81
  } | 'plane', twisted?: boolean): {
@@ -83,7 +83,7 @@ export declare function alignAxesOf(asset: V3Asset, part: string, target: {
83
83
  edges: boolean;
84
84
  }[];
85
85
  /** The controls a part's showing can follow: the figure's state inputs, with their range and label. */
86
- export declare function visibilityControlsOf(asset: V3Asset): Array<{
86
+ export declare function visibilityControlsOf(asset: FigureAsset): Array<{
87
87
  id: string;
88
88
  unit: string;
89
89
  min: number;
@@ -91,19 +91,19 @@ export declare function visibilityControlsOf(asset: V3Asset): Array<{
91
91
  label: string;
92
92
  }>;
93
93
  /** When the part is drawn (figure-model `set-visibility`): always (null), or while a control is at least a value. */
94
- export declare function shownWhenOf(asset: V3Asset, part: string): {
94
+ export declare function shownWhenOf(asset: FigureAsset, part: string): {
95
95
  input: string;
96
96
  atLeast: number;
97
97
  } | null;
98
98
  /** Whether `part` hangs from `from`, through any number of fastenings. */
99
- export declare function hangsFrom(asset: V3Asset, part: string, from: string): boolean;
99
+ export declare function hangsFrom(asset: FigureAsset, part: string, from: string): boolean;
100
100
  /**
101
101
  * The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the face, including
102
102
  * \`centre\`, the target and its face, the gap, the twist and where across the face) and a change is a change to that.
103
103
  * Opening it on the defaults showed a roller fastened by its centre as fastened by its bottom, and fastening again
104
104
  * from there broke its turning in place (walk 1, 2026-09-26). Null for a part fastened to nothing.
105
105
  */
106
- export declare function fasteningOf(asset: V3Asset, part: string): {
106
+ export declare function fasteningOf(asset: FigureAsset, part: string): {
107
107
  face: string;
108
108
  toPlane: boolean;
109
109
  target: string;
@@ -119,7 +119,7 @@ export declare function fasteningOf(asset: V3Asset, part: string): {
119
119
  * from the target's centre (the plane's is the origin). Fastening used to centre it -- a door set 100 mm in front of
120
120
  * its frame slid into it (2026-09-26). Left centred where it already is, and where the target stands turned.
121
121
  */
122
- export declare function placeKeptOf(asset: V3Asset, part: string, target: {
122
+ export declare function placeKeptOf(asset: FigureAsset, part: string, target: {
123
123
  part: string;
124
124
  face: string;
125
125
  } | 'plane', twisted?: boolean): {
@@ -127,7 +127,7 @@ export declare function placeKeptOf(asset: V3Asset, part: string, target: {
127
127
  alignMm: Partial<Record<Axis, number>>;
128
128
  };
129
129
  /** The `align` of an attach command from the form's choices: only the axes across that face, and centred ones left out. */
130
- export declare function alignOf(asset: V3Asset, part: string, target: {
130
+ export declare function alignOf(asset: FigureAsset, part: string, target: {
131
131
  part: string;
132
132
  face: string;
133
133
  } | 'plane', how: Partial<Record<Axis, Alignment>>, mm: Partial<Record<Axis, number>>, twisted?: boolean): Partial<Record<Axis, "min" | "max" | {
@@ -142,12 +142,12 @@ export declare function alignOf(asset: V3Asset, part: string, target: {
142
142
  /**
143
143
  * The axes on which the part's position is worked out from other values rather than being its own number. `fix-position` makes one its own number where it is now.
144
144
  */
145
- export declare function positionsWorkedOut(asset: V3Asset, part: string): Axis[];
145
+ export declare function positionsWorkedOut(asset: FigureAsset, part: string): Axis[];
146
146
  /**
147
147
  * Whether the part's position on an axis is a share of the instance size (`scale-position`): `size.<axis> × share`.
148
148
  * Such a position is worked out too, but it already grows with the figure, so it is not offered again.
149
149
  */
150
- export declare function positionIsShare(asset: V3Asset, part: string, axis: Axis): boolean;
150
+ export declare function positionIsShare(asset: FigureAsset, part: string, axis: Axis): boolean;
151
151
  /** How a part moves, if it does: slide or turn, along which axis, driven by which control. */
152
152
  export interface Motion {
153
153
  kind: 'slide' | 'turn' | 'continuous';
@@ -171,7 +171,7 @@ export interface Motion {
171
171
  plus?: number;
172
172
  };
173
173
  }
174
- export declare function motionOf(asset: V3Asset, part: string): Motion | undefined;
174
+ export declare function motionOf(asset: FigureAsset, part: string): Motion | undefined;
175
175
  /** What the motion form holds: how the part moves, and either its own control or the joint it moves with. */
176
176
  export interface MotionForm {
177
177
  kind: 'slide' | 'turn' | 'continuous';
@@ -195,31 +195,31 @@ export interface MotionForm {
195
195
  * travels by, what it follows -- rather than taken away and made again. Taking it away is refused while another joint
196
196
  * follows it, which left a leader's stroke fixed for good (the telescopic conveyor, 2026-09-25).
197
197
  */
198
- export declare function motionFormOf(joint: V3Joint): MotionForm;
198
+ export declare function motionFormOf(joint: FigureJoint): MotionForm;
199
199
  /**
200
200
  * The joints a part's joint can move with (URDF's mimic): a joint that moves the same way — a slide follows a slide, a
201
201
  * turn a turn — and has a control of its own, since a follower follows the joint that is driven.
202
202
  */
203
- export declare function leadersFor(asset: V3Asset, part: string, kind: MotionForm['kind']): V3Joint[];
203
+ export declare function leadersFor(asset: FigureAsset, part: string, kind: MotionForm['kind']): FigureJoint[];
204
204
  /**
205
205
  * The joint record the motion form writes for a part fastened by `joint`. A joint of its own gets its limits (none for
206
206
  * a turn without end, as in USD) and a control; a follower gets the leader, the multiplier and the offset, and no
207
207
  * control or limits of its own — its range is the leader's times the multiplier.
208
208
  */
209
- export declare function motionJoint(joint: V3Joint, m: MotionForm, part: string): V3Joint;
209
+ export declare function motionJoint(joint: FigureJoint, m: MotionForm, part: string): FigureJoint;
210
210
  /** The select's value for what a dimension follows now. */
211
211
  export declare function choiceOf(follow: Follow): string;
212
212
  /** The faces a place can sit on for this part: a box's six, a rounded box's top and bottom, none for a round body. */
213
- export declare function placeFacesOf(asset: V3Asset, part: string): V3Face[];
213
+ export declare function placeFacesOf(asset: FigureAsset, part: string): FigureFace[];
214
214
  /** The places things are held that sit on this part. */
215
- export declare function placesOn(asset: V3Asset, part: string): V3BindingPlace[];
215
+ export declare function placesOn(asset: FigureAsset, part: string): FigureBindingPlace[];
216
216
  /** An id for a new place on this part, not yet taken: `<part>-<role>`, then `-2`, `-3`. */
217
- export declare function placeIdFor(asset: V3Asset, part: string, role: 'seat' | 'grip'): string;
217
+ export declare function placeIdFor(asset: FigureAsset, part: string, role: 'seat' | 'grip'): string;
218
218
  /**
219
219
  * Whether a board will hand this figure anything: a place is a slot only on a figure that declares it holds things
220
220
  * (`Capacity`, or `FlowNode`, which includes it). Without it the places are declared and nothing arrives.
221
221
  */
222
- export declare const holdsThings: (asset: V3Asset) => boolean;
222
+ export declare const holdsThings: (asset: FigureAsset) => boolean;
223
223
  /** What `accepts` a person typed: names split on commas, trimmed, blanks and repeats dropped. */
224
224
  export declare const acceptsOf: (typed: string) => string[];
225
225
  /**
@@ -228,9 +228,9 @@ export declare const acceptsOf: (typed: string) => string[];
228
228
  * A range measured when a part filled what the others left (ROBOT_ARM: Y from 1,854 mm) stays narrow after the part is
229
229
  * made to grow with the figure; measuring again gives the figure its whole range back. Nothing when no size is declared.
230
230
  */
231
- export declare function instanceRangeOf(asset: V3Asset): {
232
- declared: V3SizeRange;
233
- measured: V3SizeRange;
231
+ export declare function instanceRangeOf(asset: FigureAsset): {
232
+ declared: FigureSizeRange;
233
+ measured: FigureSizeRange;
234
234
  } | undefined;
235
235
  /**
236
236
  * The size range to declare for a figure that has none yet: its parts' extent now as the size it is authored at, and
@@ -238,8 +238,8 @@ export declare function instanceRangeOf(asset: V3Asset): {
238
238
  * size or has nothing to measure. Without a declared size a board cannot resize the figure, and no part is offered
239
239
  * to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).
240
240
  */
241
- export declare function instanceRangeToDeclare(asset: V3Asset): {
242
- range: V3SizeRange;
241
+ export declare function instanceRangeToDeclare(asset: FigureAsset): {
242
+ range: FigureSizeRange;
243
243
  at: Record<Axis, number>;
244
244
  } | undefined;
245
245
  /** Whether measuring again would change the declared range (to a micrometre). */
@@ -248,20 +248,20 @@ export declare function instanceRangeToDeclare(asset: V3Asset): {
248
248
  * product (a gantry spans metres, not 30 cm to 29 m), and measuring only ever widens them. Nothing when the typed
249
249
  * value is not a number; whether the figure holds there is the command's to say.
250
250
  */
251
- export declare function rangeWith(declared: V3SizeRange, axis: Axis, bound: 'min' | 'max', value: number): V3SizeRange | undefined;
251
+ export declare function rangeWith(declared: FigureSizeRange, axis: Axis, bound: 'min' | 'max', value: number): FigureSizeRange | undefined;
252
252
  /**
253
253
  * For a figure that grows by one ratio: how many of its lengths would follow the ratio, and which it leaves with their
254
254
  * own number (not those that follow another length -- they grow with it). Nothing for a figure of another sizing.
255
255
  */
256
- export declare function proportionToFollow(asset: V3Asset): {
256
+ export declare function proportionToFollow(asset: FigureAsset): {
257
257
  count: number;
258
258
  kept: string[];
259
259
  } | undefined;
260
260
  /** A value of the figure as it stands, by its graph reference. */
261
- export declare function valueNow(asset: V3Asset, ref: string | undefined): number | undefined;
262
- export declare function rangeDiffers(a: V3SizeRange, b: V3SizeRange): boolean;
261
+ export declare function valueNow(asset: FigureAsset, ref: string | undefined): number | undefined;
262
+ export declare function rangeDiffers(a: FigureSizeRange, b: FigureSizeRange): boolean;
263
263
  /**
264
264
  * Whether the figure is a mechanism -- a part turns about a joint. Such a figure should grow by one ratio (chief
265
265
  * architect's ruling 2026-09-24); the modeller proposes it, the author declares it.
266
266
  */
267
- export declare function turnsAboutAJoint(asset: V3Asset): boolean;
267
+ export declare function turnsAboutAJoint(asset: FigureAsset): boolean;
@@ -1,4 +1,4 @@
1
- import { V3_FACES, v3ShapeFaces, v3PartsExtentOf, compileV3Asset, compileV3Graph, v3FollowOf, proposeV3Proportion, defaultInstanceSizeRange, foldInstanceSizeRange, v3AttachmentsOf, v3BindingsOf, v3InstanceSizeLimitsOf } from '@hatiolab/figure-model';
1
+ import { FIGURE_FACES, figureShapeFaces, figurePartsExtentOf, compileFigureAsset, compileFigureGraph, figureFollowOf, proposeFigureProportion, defaultInstanceSizeRange, foldInstanceSizeRange, figureAttachmentsOf, figureBindingsOf, figureInstanceSizeLimitsOf } from '@hatiolab/figure-model';
2
2
  export const AXES = ['x', 'y', 'z'];
3
3
  const modelOf = (asset) => asset.document.model;
4
4
  /**
@@ -8,13 +8,13 @@ const modelOf = (asset) => asset.document.model;
8
8
  */
9
9
  /** What one measure of a part is worked out from, read back from the graph (figure-model's reader, one copy). */
10
10
  export function followOf(asset, part, axis) {
11
- return v3FollowOf(asset, part, axis);
11
+ return figureFollowOf(asset, part, axis);
12
12
  }
13
13
  /** Whether the asset declares an instance size on an axis — only then can a dimension follow it. */
14
14
  export const hasInstanceSize = (asset, axis) => modelOf(asset).inputs.some(i => i.id === `size.${axis}` && i.role === 'design');
15
15
  /** The part this one is fastened to, or `null`. The mounting plane counts as fastened (the model names no part). */
16
16
  export function fastenedTo(asset, part) {
17
- return v3AttachmentsOf(asset)[part] ?? null;
17
+ return figureAttachmentsOf(asset)[part] ?? null;
18
18
  }
19
19
  /**
20
20
  * What holds a part: the part it is fastened to, the plane the figure is mounted on, or nothing. The joint record says
@@ -54,7 +54,7 @@ export function dimensionNow(asset, part, axis) {
54
54
  if (!ref)
55
55
  return undefined;
56
56
  try {
57
- const values = compileV3Graph(asset.document.model).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values;
57
+ const values = compileFigureGraph(asset.document.model).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values;
58
58
  const value = values[ref];
59
59
  return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
60
60
  }
@@ -68,12 +68,12 @@ export function dimensionNow(asset, part, axis) {
68
68
  */
69
69
  export function facesOf(asset, part) {
70
70
  const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`);
71
- return Object.keys((shape && v3ShapeFaces(shape.op)) ?? {});
71
+ return Object.keys((shape && figureShapeFaces(shape.op)) ?? {});
72
72
  }
73
73
  /** The axis a face of a part faces along, from the same definitions. */
74
74
  export function faceAxisOf(asset, part, face) {
75
75
  const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`);
76
- return (shape && v3ShapeFaces(shape.op)?.[face]?.axis);
76
+ return (shape && figureShapeFaces(shape.op)?.[face]?.axis);
77
77
  }
78
78
  /** Whether `attach` can take this part: any part whose shape has a flat face. */
79
79
  export function canFasten(asset, part) {
@@ -92,7 +92,7 @@ export function rowAxesOf(asset, part) {
92
92
  return [];
93
93
  if (joints.some(o => 'part' in o.body0 && o.body0.part === part))
94
94
  return [];
95
- return AXES.filter(axis => axis !== V3_FACES[j.body1.face]);
95
+ return AXES.filter(axis => axis !== FIGURE_FACES[j.body1.face]);
96
96
  }
97
97
  /** The row a part is made into, as its fastening's record keeps it. */
98
98
  export const rowOf = (asset, part) => asset.joints?.find(o => o.body1.part === part)?.repeat;
@@ -197,7 +197,7 @@ export function placeKeptOf(asset, part, target, twisted = false) {
197
197
  const kept = { align: {}, alignMm: {} };
198
198
  let geometry;
199
199
  try {
200
- geometry = compileV3Asset(asset).evaluate().geometry;
200
+ geometry = compileFigureAsset(asset).evaluate().geometry;
201
201
  }
202
202
  catch {
203
203
  return kept;
@@ -368,7 +368,7 @@ export function placeFacesOf(asset, part) {
368
368
  }
369
369
  /** The places things are held that sit on this part. */
370
370
  export function placesOn(asset, part) {
371
- return v3BindingsOf(asset).filter(one => one.part === part);
371
+ return figureBindingsOf(asset).filter(one => one.part === part);
372
372
  }
373
373
  /** An id for a new place on this part, not yet taken: `<part>-<role>`, then `-2`, `-3`. */
374
374
  export function placeIdFor(asset, part, role) {
@@ -407,7 +407,7 @@ export function instanceRangeOf(asset) {
407
407
  authored[axis] = at;
408
408
  }
409
409
  const start = defaultInstanceSizeRange(authored);
410
- const measured = foldInstanceSizeRange(start, v3InstanceSizeLimitsOf(asset, start)).range;
410
+ const measured = foldInstanceSizeRange(start, figureInstanceSizeLimitsOf(asset, start)).range;
411
411
  return { declared, measured };
412
412
  }
413
413
  /**
@@ -420,11 +420,11 @@ export function instanceRangeToDeclare(asset) {
420
420
  if (instanceRangeOf(asset) || !asset.appearance.length)
421
421
  return undefined;
422
422
  /* The parts as they rest -- not the room their joints swing them through, which declared a door 8208 mm every way. */
423
- const at = v3PartsExtentOf(asset);
423
+ const at = figurePartsExtentOf(asset);
424
424
  if (AXES.some(axis => !(at[axis] > 0)))
425
425
  return undefined;
426
426
  const start = defaultInstanceSizeRange(at);
427
- return { range: foldInstanceSizeRange(start, v3InstanceSizeLimitsOf(asset, start)).range, at };
427
+ return { range: foldInstanceSizeRange(start, figureInstanceSizeLimitsOf(asset, start)).range, at };
428
428
  }
429
429
  /** Whether measuring again would change the declared range (to a micrometre). */
430
430
  /**
@@ -447,7 +447,7 @@ export function proportionToFollow(asset) {
447
447
  if (asset.sizing !== 'uniform')
448
448
  return undefined;
449
449
  try {
450
- const plan = proposeV3Proportion(asset);
450
+ const plan = proposeFigureProportion(asset);
451
451
  return { count: plan.dimensions.length + plan.lengths.length, kept: plan.skipped.filter(s => !s.follows).map(s => s.what) };
452
452
  }
453
453
  catch {
@@ -459,7 +459,7 @@ export function valueNow(asset, ref) {
459
459
  if (!ref)
460
460
  return undefined;
461
461
  try {
462
- const values = compileV3Graph(asset.document.model).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values;
462
+ const values = compileFigureGraph(asset.document.model).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values;
463
463
  const value = values[ref];
464
464
  return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
465
465
  }
@@ -477,4 +477,4 @@ export function rangeDiffers(a, b) {
477
477
  export function turnsAboutAJoint(asset) {
478
478
  return modelOf(asset).nodes.some(n => n.op === 'axis-turn@1');
479
479
  }
480
- //# sourceMappingURL=v3-links.js.map
480
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../client/modeller/links.ts"],"names":[],"mappings":"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","sourcesContent":["import { FIGURE_FACES, figureShapeFaces, figurePartsExtentOf, compileFigureAsset, compileFigureGraph, figureFollowOf, proposeFigureProportion, defaultInstanceSizeRange, foldInstanceSizeRange, figureAttachmentsOf, figureBindingsOf, figureInstanceSizeLimitsOf } from '@hatiolab/figure-model'\nimport type { FigureFollow, FigureSizeRange } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureBindingPlace, FigureFace, FigureJoint } from '@hatiolab/figure-model'\n\n/*\n * What a part is tied to — the readers behind the parts' size response, fastening and motion sections. Kept apart from the element so they can be tested without a browser.\n */\n\nexport type Axis = 'x' | 'y' | 'z'\nexport const AXES: readonly Axis[] = ['x', 'y', 'z']\n\ninterface Node {\n id: string\n op: string\n args: string[]\n outputs: Record<string, string>\n}\nconst modelOf = (asset: FigureAsset) =>\n asset.document.model as unknown as { nodes: Node[]; inputs: Array<{ id: string; role?: string; unit?: string; min?: number; max?: number }>; constants: Array<{ id: string; value: number }> }\n\n/** What one dimension of a part is worked out from (figure-model's `FigureFollow`). */\nexport type Follow = FigureFollow\n\n/**\n * `link-dimension` routes a part's dimension through `<part>.dimension.<axis>` and points its first argument at the\n * source, directly or through the nodes that scale it. Walking back through those nodes finds the source: the\n * instance size (`size.<axis>`), another part's dimension (`<part>.dimension.<axis>.value`) or a declared input.\n */\n/** What one measure of a part is worked out from, read back from the graph (figure-model's reader, one copy). */\nexport function followOf(asset: FigureAsset, part: string, axis: Axis): Follow {\n return figureFollowOf(asset, part, axis)\n}\n\n/** Whether the asset declares an instance size on an axis — only then can a dimension follow it. */\nexport const hasInstanceSize = (asset: FigureAsset, axis: Axis) => modelOf(asset).inputs.some(i => i.id === `size.${axis}` && i.role === 'design')\n\n/** The part this one is fastened to, or `null`. The mounting plane counts as fastened (the model names no part). */\nexport function fastenedTo(asset: FigureAsset, part: string): string | null {\n return figureAttachmentsOf(asset)[part] ?? null\n}\n\n/**\n * What holds a part: the part it is fastened to, the plane the figure is mounted on, or nothing. The joint record says\n * it; a part standing on the plane had read as fastened to nothing, so the form offered no way to move it and sent\n * no replace -- the fastening was refused as already made (the door's post, 2026-09-25).\n */\nexport function heldBy(asset: FigureAsset, part: string): { part: string } | { plane: true } | null {\n const record = asset.joints?.find(j => j.body1.part === part)\n if (record) return 'plane' in record.body0 ? { plane: true } : { part: record.body0.part }\n const to = fastenedTo(asset, part)\n return to ? { part: to } : null\n}\n\n/** Whether a dimension of this part can follow something — box-shaped, whose three sizes are X, Y and Z. */\nexport function canFollow(asset: FigureAsset, part: string): boolean {\n return followableAxes(asset, part).length > 0\n}\n\n/**\n * The axes whose size can follow something, by the shape's own measures: a box's X · Y · Z; a cylinder's radius (read\n * as X) and length (Y) -- its shape takes those two, so it has no Z of its own.\n */\nexport function followableAxes(asset: FigureAsset, part: string): Axis[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n if (!shape) return []\n /* A door frame's first three measures are its width, height and depth, as a box's (figure-model portal-profile@2). */\n if (shape.op === 'box-shape@1' || shape.op === 'rounded-box@1' || shape.op === 'portal-profile@2' || shape.op === 'hollow-box@2') return [...AXES]\n if (shape.op === 'cylinder-shape@1') return ['x', 'y']\n return []\n}\n\n/** What a part's own measure on an axis is now (a box's side, a cylinder's radius or length), at the design as it stands. */\nexport function dimensionNow(asset: FigureAsset, part: string, axis: Axis): number | undefined {\n const m = modelOf(asset)\n const ref = m.nodes.find(n => n.id === `${part}.shape`)?.args[AXES.indexOf(axis)]\n if (!ref) return undefined\n try {\n const values = compileFigureGraph(asset.document.model as never).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values as Record<string, number>\n const value = values[ref]\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * The flat faces a part's shape declares, by name -- figure-model's shape definitions are the one place they are\n * written (a portal's opening sides as well as its outer faces). A sphere has none.\n */\nexport function facesOf(asset: FigureAsset, part: string): string[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n return Object.keys((shape && figureShapeFaces(shape.op)) ?? {})\n}\n\n/** The axis a face of a part faces along, from the same definitions. */\nexport function faceAxisOf(asset: FigureAsset, part: string, face: string): Axis | undefined {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n return (shape && figureShapeFaces(shape.op)?.[face]?.axis) as Axis | undefined\n}\n\n/** Whether `attach` can take this part: any part whose shape has a flat face. */\nexport function canFasten(asset: FigureAsset, part: string): boolean {\n return facesOf(asset, part).length > 0\n}\n\nconst OUTER: Record<Axis, [string, string]> = { x: ['left', 'right'], y: ['bottom', 'top'], z: ['back', 'front'] }\n\n/**\n * The axes a part can be made a row along (r3 §8, figure-model `make-repeat`): across the face it is fastened by, when\n * it is fastened fixed to another part and holds nothing. None for a part that is loose, moves, stands on the floor or\n * already repeats -- the command would refuse those, so they are not offered.\n */\nexport function rowAxesOf(asset: FigureAsset, part: string): Axis[] {\n const joints = asset.joints ?? []\n const j = joints.find(o => o.body1.part === part)\n if (!j || j.type !== 'fixed' || j.repeat || !('part' in j.body0)) return []\n if (joints.some(o => 'part' in o.body0 && o.body0.part === part)) return []\n return AXES.filter(axis => axis !== FIGURE_FACES[j.body1.face])\n}\n\n/** The row a part is made into, as its fastening's record keeps it. */\nexport const rowOf = (asset: FigureAsset, part: string) => asset.joints?.find(o => o.body1.part === part)?.repeat\n\n/** Where a part sits across the face it is fastened to, on one axis: centred, level with an edge, or a distance off centre. */\n/** `share`: the distance as a share of the figure's size on that axis, so it keeps its place when the figure is resized. */\nexport type Alignment = 'centre' | 'min' | 'max' | 'mm' | 'share'\n\n/**\n * The axes across the face a part is fastened to — the two a fastening does not set by itself. Edges to line up with\n * are offered where both parts have their two outer faces on that axis; the plane the figure is mounted on has none,\n * so on it (X and Z) only centred or a distance is offered.\n */\n/**\n * The mounting plane of this figure, by its placement (ADR-0093): the floor or the ceiling is Y = 0 and a part stands\n * on it by its bottom or hangs from it by its top; a wall is Z = 0 and a part is fastened to it by its back.\n */\nexport function mountingPlaneOf(asset: FigureAsset): { normal: Axis; faces: FigureFace[] } {\n return asset.occupancy?.placement === 'wall' ? { normal: 'z', faces: ['back'] } : { normal: 'y', faces: ['bottom', 'top'] }\n}\n\nexport function alignAxesOf(asset: FigureAsset, part: string, target: { part: string; face: string } | 'plane', twisted = false): { axis: Axis; edges: boolean }[] {\n /* The plane has no edges, but a figure that declares its size has sides on it (figure-model 0.1.64). */\n if (target === 'plane') {\n const { normal } = mountingPlaneOf(asset)\n return AXES.filter(axis => axis !== normal).map(axis => ({ axis, edges: !twisted && hasInstanceSize(asset, axis) }))\n }\n const along = faceAxisOf(asset, target.part, target.face)\n if (!along) return []\n const theirs = new Set(facesOf(asset, target.part)),\n mine = new Set(facesOf(asset, part))\n /* A part twisted about the face's normal has no side level with the target's edges. */\n return AXES.filter(axis => axis !== along).map(axis => ({ axis, edges: !twisted && OUTER[axis].every(f => theirs.has(f) && mine.has(f)) }))\n}\n\n/** The controls a part's showing can follow: the figure's state inputs, with their range and label. */\nexport function visibilityControlsOf(asset: FigureAsset): Array<{ id: string; unit: string; min: number; max: number; label: string }> {\n const labels = (asset as unknown as { stateInputs?: Record<string, { label?: string }> }).stateInputs ?? {}\n return modelOf(asset)\n .inputs.filter(input => input.role === 'state')\n .map(input => ({ id: input.id, unit: input.unit ?? '', min: input.min ?? 0, max: input.max ?? 1, label: labels[input.id]?.label || input.id }))\n}\n\n/** When the part is drawn (figure-model `set-visibility`): always (null), or while a control is at least a value. */\nexport function shownWhenOf(asset: FigureAsset, part: string): { input: string; atLeast: number } | null {\n const look = asset.appearance.find(one => one.target === part) as { visibility?: string } | undefined\n if (!look?.visibility) return null\n const m = modelOf(asset)\n const node = m.nodes.find(n => n.op === 'at-least@1' && Object.values(n.outputs).includes(look.visibility!))\n const at = node && m.constants.find(c => c.id === node.args[1])\n return node && at ? { input: node.args[0]!, atLeast: at.value } : null\n}\n\n/** Whether `part` hangs from `from`, through any number of fastenings. */\nexport function hangsFrom(asset: FigureAsset, part: string, from: string): boolean {\n const seen = new Set<string>()\n for (let at: string | undefined = part; at && !seen.has(at); ) {\n seen.add(at)\n const j = ((asset.joints ?? []) as FigureJoint[]).find(o => o.body1.part === at)\n at = j && 'part' in j.body0 ? (j.body0 as { part: string }).part : undefined\n if (at === from) return true\n }\n return false\n}\n\n/**\n * The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the face, including\n * \\`centre\\`, the target and its face, the gap, the twist and where across the face) and a change is a change to that.\n * Opening it on the defaults showed a roller fastened by its centre as fastened by its bottom, and fastening again\n * from there broke its turning in place (walk 1, 2026-09-26). Null for a part fastened to nothing.\n */\nexport function fasteningOf(\n asset: FigureAsset,\n part: string\n): {\n face: string\n toPlane: boolean\n target: string\n targetFace: string\n facing: 'meet' | 'flush'\n gap: number\n twist: number\n align: Partial<Record<Axis, Alignment>>\n alignMm: Partial<Record<Axis, number>>\n} | null {\n const record = asset.joints?.find(j => j.body1.part === part)\n if (!record) return null\n const toPlane = 'plane' in record.body0\n const target = 'part' in record.body0 ? record.body0.part : ''\n const targetFace = 'part' in record.body0 ? record.body0.face : 'top'\n const twist = record.origin?.twist ?? 0\n /* Where across the face: as the record says it, and where it says nothing, where the part stands now. */\n const kept = placeKeptOf(asset, part, toPlane ? 'plane' : { part: target, face: targetFace }, !!twist)\n for (const [axis, how] of Object.entries(record.origin?.align ?? {}) as Array<[Axis, unknown]>) {\n if (how === 'min' || how === 'max' || how === 'centre') {\n kept.align[axis] = how\n delete kept.alignMm[axis]\n } else if (how && typeof how === 'object' && typeof (how as { mm?: unknown }).mm === 'number') {\n kept.align[axis] = 'mm'\n kept.alignMm[axis] = (how as { mm: number }).mm\n }\n }\n const gap = record.origin?.gap\n return {\n face: record.body1.face,\n toPlane,\n target,\n targetFace,\n facing: record.origin?.facing ?? 'meet',\n gap: typeof gap === 'number' ? gap : 0,\n twist,\n ...kept\n }\n}\n\n/**\n * The alignment that keeps the part where it stands when it is fastened: on each axis across the face, its distance\n * from the target's centre (the plane's is the origin). Fastening used to centre it -- a door set 100 mm in front of\n * its frame slid into it (2026-09-26). Left centred where it already is, and where the target stands turned.\n */\nexport function placeKeptOf(\n asset: FigureAsset,\n part: string,\n target: { part: string; face: string } | 'plane',\n twisted = false\n): { align: Partial<Record<Axis, Alignment>>; alignMm: Partial<Record<Axis, number>> } {\n const kept = { align: {} as Partial<Record<Axis, Alignment>>, alignMm: {} as Partial<Record<Axis, number>> }\n let geometry\n try {\n geometry = compileFigureAsset(asset).evaluate().geometry as unknown as Array<{ id: string; pose?: { r: number[][]; t: number[] } }>\n } catch {\n return kept\n }\n const poseOf = (id: string) => geometry.find(g => g.id === id)?.pose\n const mine = poseOf(part)\n if (!mine) return kept\n let centre = [0, 0, 0]\n if (target !== 'plane') {\n const theirs = poseOf(target.part)\n const upright = theirs?.r.every((row, i) => row.every((v, j) => Math.abs(v - (i === j ? 1 : 0)) < 1e-9))\n if (!theirs || !upright) return kept\n centre = theirs.t\n }\n for (const { axis } of alignAxesOf(asset, part, target, twisted)) {\n const k = AXES.indexOf(axis)\n const off = Math.round((mine.t[k]! - centre[k]!) * 10) / 10\n if (Math.abs(off) < 0.5) continue\n kept.align[axis] = 'mm'\n kept.alignMm[axis] = off\n }\n return kept\n}\n\n/** The `align` of an attach command from the form's choices: only the axes across that face, and centred ones left out. */\nexport function alignOf(\n asset: FigureAsset,\n part: string,\n target: { part: string; face: string } | 'plane',\n how: Partial<Record<Axis, Alignment>>,\n mm: Partial<Record<Axis, number>>,\n twisted = false\n) {\n const align: Partial<Record<Axis, 'min' | 'max' | { mm: number | { from: { of: 'instance'; axis: Axis }; times: number } }>> = {}\n for (const { axis, edges } of alignAxesOf(asset, part, target, twisted)) {\n const one = how[axis] ?? 'centre'\n const size = asset.designInputs[`size.${axis}`]\n if (one === 'share' && mm[axis] && hasInstanceSize(asset, axis) && size)\n align[axis] = { mm: { from: { of: 'instance', axis }, times: Math.round((mm[axis]! / size) * 1e6) / 1e6 } }\n else if (one === 'mm' && mm[axis]) align[axis] = { mm: mm[axis]! }\n else if ((one === 'min' || one === 'max') && edges) align[axis] = one\n }\n return Object.keys(align).length ? align : undefined\n}\n\n/**\n * The axes on which the part's position is worked out from other values rather than being its own number. `fix-position` makes one its own number where it is now.\n */\nexport function positionsWorkedOut(asset: FigureAsset, part: string): Axis[] {\n const m = modelOf(asset)\n const pose = m.nodes.find(n => n.id === `${part}.pose`)\n if (!pose || pose.op !== 'rigid@1' || fastenedTo(asset, part)) return []\n const own = (ref: string) => ref.startsWith(`${part}.`) && m.inputs.some(i => i.id === ref && i.role === 'design')\n const constant = (ref: string) => m.constants.some(c => c.id === ref)\n return AXES.filter((_axis, i) => !own(pose.args[i]!) && !constant(pose.args[i]!))\n}\n\n/**\n * Whether the part's position on an axis is a share of the instance size (`scale-position`): `size.<axis> × share`.\n * Such a position is worked out too, but it already grows with the figure, so it is not offered again.\n */\nexport function positionIsShare(asset: FigureAsset, part: string, axis: Axis): boolean {\n const m = modelOf(asset)\n const ref = m.nodes.find(n => n.id === `${part}.pose`)?.args[AXES.indexOf(axis)]\n const writer = ref ? m.nodes.find(n => Object.values(n.outputs).includes(ref)) : undefined\n return !!writer && writer.op === 'mul@1' && writer.args[0] === `size.${axis}` && m.constants.some(c => c.id === writer.args[1])\n}\n\n/** How a part moves, if it does: slide or turn, along which axis, driven by which control. */\nexport interface Motion {\n kind: 'slide' | 'turn' | 'continuous'\n axis: Axis | '?'\n control?: { id: string; unit?: string; min?: number; max?: number }\n /** A joint that moves with another (URDF's mimic): the leader's value times `multiplier`, plus `offset`. */\n follows?: { joint: string; multiplier: number; offset?: number }\n /** A slide whose distance is a part's length (plus a difference): the control is its share. */\n travel?: { part: string; axis: string; plus?: number }\n}\n\nexport function motionOf(asset: FigureAsset, part: string): Motion | undefined {\n const m = modelOf(asset)\n const node = m.nodes.find(n => n.id === `${part}.motion`)\n if (!node) return undefined\n const record = asset.joints?.find(j => j.body1.part === part)\n const endless = record?.type === 'revolute' && record.lowerLimit === undefined && record.upperLimit === undefined\n const kind = endless ? 'continuous' : node.op === 'axis-turn@1' ? 'turn' : 'slide'\n const unit = node.args.slice(0, 3).map(ref => m.constants.find(c => c.id === ref)?.value)\n const axis = AXES[unit.findIndex(v => v !== undefined && v !== 0)] ?? '?'\n /* The quantity is the fourth argument, a state input directly or through the nodes that scale it. */\n const quantity = node.args[3]\n const seen = new Set<string>()\n const control = (ref?: string): Motion['control'] => {\n if (!ref || seen.has(ref)) return undefined\n seen.add(ref)\n const input = m.inputs.find(i => i.id === ref && i.role === 'state')\n if (input) return { id: input.id, unit: input.unit, min: input.min, max: input.max }\n const writer = m.nodes.find(n => Object.values(n.outputs).includes(ref))\n for (const arg of writer?.args ?? []) {\n const found = control(arg)\n if (found) return found\n }\n return undefined\n }\n const travel = record?.travel?.source && 'part' in record.travel.source ? { part: record.travel.source.part, axis: record.travel.source.axis, ...(record.travel.plus ? { plus: record.travel.plus } : {}) } : undefined\n return { kind, axis, control: control(quantity), ...(record?.mimic ? { follows: record.mimic } : {}), ...(travel ? { travel } : {}) }\n}\n\n/** What the motion form holds: how the part moves, and either its own control or the joint it moves with. */\nexport interface MotionForm {\n kind: 'slide' | 'turn' | 'continuous'\n axis: Axis\n id: string\n min: number\n max: number\n /** The joint this one moves with; empty for a joint with its own control. */\n follow: string\n multiplier: number\n offset: number\n /**\n * A slide whose distance follows a part's length (figure-model `travel`): `<part>:<axis>`, empty for a distance in\n * millimetres. The control is then the share of that length, 0..1, and the stroke grows when the part does.\n */\n travel?: string\n travelPlus?: number\n}\n\n/**\n * The motion form filled from a joint as it is, so a motion can be changed where it is -- its range, the length it\n * travels by, what it follows -- rather than taken away and made again. Taking it away is refused while another joint\n * follows it, which left a leader's stroke fixed for good (the telescopic conveyor, 2026-09-25).\n */\nexport function motionFormOf(joint: FigureJoint): MotionForm {\n const kind: MotionForm['kind'] = joint.type === 'prismatic' ? 'slide' : joint.lowerLimit === undefined && joint.upperLimit === undefined && !joint.mimic ? 'continuous' : 'turn'\n const travel = joint.travel?.source && 'part' in joint.travel.source ? `${joint.travel.source.part}:${joint.travel.source.axis}` : ''\n return {\n kind,\n axis: (joint.axis ?? 'X').toLowerCase() as Axis,\n id: joint.state?.id ?? '',\n min: travel ? 0 : (joint.lowerLimit ?? (kind === 'slide' ? 0 : -90)),\n max: travel ? 500 : (joint.upperLimit ?? (kind === 'slide' ? 500 : 90)),\n follow: joint.mimic?.joint ?? '',\n multiplier: joint.mimic?.multiplier ?? 1,\n offset: joint.mimic?.offset ?? 0,\n travel,\n travelPlus: joint.travel?.plus ?? 0\n }\n}\n\n/**\n * The joints a part's joint can move with (URDF's mimic): a joint that moves the same way — a slide follows a slide, a\n * turn a turn — and has a control of its own, since a follower follows the joint that is driven.\n */\nexport function leadersFor(asset: FigureAsset, part: string, kind: MotionForm['kind']): FigureJoint[] {\n return (asset.joints ?? []).filter(j => j.body1.part !== part && j.type !== 'fixed' && !j.mimic && (j.type === 'prismatic') === (kind === 'slide'))\n}\n\n/**\n * The joint record the motion form writes for a part fastened by `joint`. A joint of its own gets its limits (none for\n * a turn without end, as in USD) and a control; a follower gets the leader, the multiplier and the offset, and no\n * control or limits of its own — its range is the leader's times the multiplier.\n */\nexport function motionJoint(joint: FigureJoint, m: MotionForm, part: string): FigureJoint {\n const moving = {\n id: joint.id,\n body0: joint.body0,\n body1: joint.body1,\n ...(joint.origin ? { origin: joint.origin } : {}),\n type: m.kind === 'slide' ? ('prismatic' as const) : ('revolute' as const),\n axis: m.axis.toUpperCase() as 'X' | 'Y' | 'Z'\n }\n if (m.follow) return { ...moving, mimic: { joint: m.follow, multiplier: m.multiplier, ...(m.offset ? { offset: m.offset } : {}) } }\n if (m.kind === 'slide' && m.travel) {\n const [of, axis] = m.travel.split(':')\n return { ...moving, travel: { source: { of: 'part', part: of!, axis: axis as Axis }, ...(m.travelPlus ? { plus: m.travelPlus } : {}) }, state: { id: m.id || `${part}-${m.kind}` } }\n }\n return { ...moving, ...(m.kind === 'continuous' ? {} : { lowerLimit: m.min, upperLimit: m.max }), state: { id: m.id || `${part}-${m.kind}` } }\n}\n\n/** The select's value for what a dimension follows now. */\nexport function choiceOf(follow: Follow): string {\n switch (follow.of) {\n case 'own':\n return 'own'\n case 'instance':\n return follow.times === 1 ? `instance:${follow.axis}` : `share:${follow.axis}`\n case 'part':\n return `part:${follow.part}:${follow.axis}`\n case 'input':\n return `input:${follow.input}`\n case 'expression':\n return 'expression'\n }\n}\n\n/** The faces a place can sit on for this part: a box's six, a rounded box's top and bottom, none for a round body. */\nexport function placeFacesOf(asset: FigureAsset, part: string): FigureFace[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n if (shape?.op === 'box-shape@1') return ['left', 'right', 'bottom', 'top', 'back', 'front']\n if (shape?.op === 'rounded-box@1') return ['bottom', 'top']\n return []\n}\n\n/** The places things are held that sit on this part. */\nexport function placesOn(asset: FigureAsset, part: string): FigureBindingPlace[] {\n return figureBindingsOf(asset).filter(one => one.part === part)\n}\n\n/** An id for a new place on this part, not yet taken: `<part>-<role>`, then `-2`, `-3`. */\nexport function placeIdFor(asset: FigureAsset, part: string, role: 'seat' | 'grip'): string {\n const taken = new Set(asset.document.capabilities.bindings.map(b => b.id))\n const base = `${part}-${role}`\n if (!taken.has(base)) return base\n let n = 2\n while (taken.has(`${base}-${n}`)) n++\n return `${base}-${n}`\n}\n\n/**\n * Whether a board will hand this figure anything: a place is a slot only on a figure that declares it holds things\n * (`Capacity`, or `FlowNode`, which includes it). Without it the places are declared and nothing arrives.\n */\nexport const holdsThings = (asset: FigureAsset) => (asset.document.capabilities.names ?? []).some(n => n === 'Capacity' || n === 'FlowNode')\n\n/** What `accepts` a person typed: names split on commas, trimmed, blanks and repeats dropped. */\nexport const acceptsOf = (typed: string) => [...new Set(typed.split(',').map(one => one.trim()).filter(Boolean))]\n\n/**\n * The sizes a board may give this figure: the range it declares now, and the range measured afresh -- the default\n * (1 mm to ten times the authored size) narrowed only where the figure cannot follow, by figure-model's own functions.\n * A range measured when a part filled what the others left (ROBOT_ARM: Y from 1,854 mm) stays narrow after the part is\n * made to grow with the figure; measuring again gives the figure its whole range back. Nothing when no size is declared.\n */\nexport function instanceRangeOf(asset: FigureAsset): { declared: FigureSizeRange; measured: FigureSizeRange } | undefined {\n const inputs = modelOf(asset).inputs\n const declared = {} as FigureSizeRange\n const authored = {} as Record<Axis, number>\n for (const axis of AXES) {\n const input = inputs.find(i => i.id === `size.${axis}` && i.role === 'design')\n const at = asset.designInputs[`size.${axis}`]\n if (!input || typeof at !== 'number') return undefined\n declared[axis] = { min: input.min ?? 0, max: input.max ?? Infinity }\n authored[axis] = at\n }\n const start = defaultInstanceSizeRange(authored)\n const measured = foldInstanceSizeRange(start, figureInstanceSizeLimitsOf(asset, start)).range\n return { declared, measured }\n}\n\n/**\n * The size range to declare for a figure that has none yet: its parts' extent now as the size it is authored at, and\n * as wide as its parts allow around it (the same measure 「다시 재기」 uses). Undefined when the figure already has a\n * size or has nothing to measure. Without a declared size a board cannot resize the figure, and no part is offered\n * to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).\n */\nexport function instanceRangeToDeclare(asset: FigureAsset): { range: FigureSizeRange; at: Record<Axis, number> } | undefined {\n if (instanceRangeOf(asset) || !asset.appearance.length) return undefined\n /* The parts as they rest -- not the room their joints swing them through, which declared a door 8208 mm every way. */\n const at = figurePartsExtentOf(asset) as Record<Axis, number>\n if (AXES.some(axis => !(at[axis] > 0))) return undefined\n const start = defaultInstanceSizeRange(at)\n return { range: foldInstanceSizeRange(start, figureInstanceSizeLimitsOf(asset, start)).range, at }\n}\n\n/** Whether measuring again would change the declared range (to a micrometre). */\n/**\n * The declared range with one end typed by the author: the sizes a figure may be placed at are a claim about the\n * product (a gantry spans metres, not 30 cm to 29 m), and measuring only ever widens them. Nothing when the typed\n * value is not a number; whether the figure holds there is the command's to say.\n */\nexport function rangeWith(declared: FigureSizeRange, axis: Axis, bound: 'min' | 'max', value: number): FigureSizeRange | undefined {\n if (!Number.isFinite(value)) return undefined\n const next = structuredClone(declared)\n next[axis][bound] = value\n return next\n}\n\n/**\n * For a figure that grows by one ratio: how many of its lengths would follow the ratio, and which it leaves with their\n * own number (not those that follow another length -- they grow with it). Nothing for a figure of another sizing.\n */\nexport function proportionToFollow(asset: FigureAsset): { count: number; kept: string[] } | undefined {\n if (asset.sizing !== 'uniform') return undefined\n try {\n const plan = proposeFigureProportion(asset)\n return { count: plan.dimensions.length + plan.lengths.length, kept: plan.skipped.filter(s => !s.follows).map(s => s.what) }\n } catch {\n return undefined\n }\n}\n\n/** A value of the figure as it stands, by its graph reference. */\nexport function valueNow(asset: FigureAsset, ref: string | undefined): number | undefined {\n if (!ref) return undefined\n try {\n const values = compileFigureGraph(asset.document.model as never).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values as Record<string, number>\n const value = values[ref]\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n } catch {\n return undefined\n }\n}\n\nexport function rangeDiffers(a: FigureSizeRange, b: FigureSizeRange): boolean {\n return AXES.some(axis => Math.abs(a[axis].min - b[axis].min) > 1e-3 || Math.abs(a[axis].max - b[axis].max) > 1e-3)\n}\n\n/**\n * Whether the figure is a mechanism -- a part turns about a joint. Such a figure should grow by one ratio (chief\n * architect's ruling 2026-09-24); the modeller proposes it, the author declares it.\n */\nexport function turnsAboutAJoint(asset: FigureAsset): boolean {\n return modelOf(asset).nodes.some(n => n.op === 'axis-turn@1')\n}\n\n"]}