@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
@@ -1,11 +1,11 @@
1
- import { type V3InputChange, type V3PrimitiveCreation, type V3PartEdit, type V3AuthoringAction, type V3ProposalStep } from '@hatiolab/figure-model';
2
- export interface V3ProductRecord {
1
+ import { type FigureInputChange, type FigurePrimitiveCreation, type FigurePartEdit, type FigureAuthoringAction, type FigureProposalStep } from '@hatiolab/figure-model';
2
+ export interface FigureProductRecord {
3
3
  id: string;
4
4
  source: string;
5
5
  }
6
6
  /** Persistence is injected; neither the model engine nor the renderer owns the product ID. */
7
- export interface V3ProductStore {
8
- load(id: string): Promise<V3ProductRecord>;
7
+ export interface FigureProductStore {
8
+ load(id: string): Promise<FigureProductRecord>;
9
9
  save(request: {
10
10
  id?: string;
11
11
  source: string;
@@ -15,10 +15,10 @@ export interface V3ProductStore {
15
15
  thumbnail?: string;
16
16
  /** The type name a new figure is created under (the first save asks for it). Not sent for an existing one. */
17
17
  type?: string;
18
- }): Promise<V3ProductRecord>;
18
+ }): Promise<FigureProductRecord>;
19
19
  }
20
20
  /** Product lifecycle boundary. A late response can never change another editor's asset or ID. */
21
- export declare function createV3ProductSession(store: V3ProductStore): {
21
+ export declare function createFigureProductSession(store: FigureProductStore): {
22
22
  read: () => {
23
23
  id: string | undefined;
24
24
  loading: boolean;
@@ -48,13 +48,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
48
48
  fields: {
49
49
  value: number;
50
50
  id: string;
51
- unit: import("@hatiolab/figure-model").V3Unit;
51
+ unit: import("@hatiolab/figure-model").FigureUnit;
52
52
  min: number;
53
53
  max: number;
54
54
  role?: "design" | "state";
55
55
  }[];
56
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
57
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
56
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
57
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
58
58
  palette: Record<string, string>;
59
59
  };
60
60
  startNew({ discard }?: {
@@ -88,13 +88,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
88
88
  fields: {
89
89
  value: number;
90
90
  id: string;
91
- unit: import("@hatiolab/figure-model").V3Unit;
91
+ unit: import("@hatiolab/figure-model").FigureUnit;
92
92
  min: number;
93
93
  max: number;
94
94
  role?: "design" | "state";
95
95
  }[];
96
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
97
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
96
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
97
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
98
98
  palette: Record<string, string>;
99
99
  };
100
100
  open(nextId: string, { discard }?: {
@@ -128,13 +128,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
128
128
  fields: {
129
129
  value: number;
130
130
  id: string;
131
- unit: import("@hatiolab/figure-model").V3Unit;
131
+ unit: import("@hatiolab/figure-model").FigureUnit;
132
132
  min: number;
133
133
  max: number;
134
134
  role?: "design" | "state";
135
135
  }[];
136
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
137
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
136
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
137
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
138
138
  palette: Record<string, string>;
139
139
  }>;
140
140
  close({ discard }?: {
@@ -168,16 +168,16 @@ export declare function createV3ProductSession(store: V3ProductStore): {
168
168
  fields: {
169
169
  value: number;
170
170
  id: string;
171
- unit: import("@hatiolab/figure-model").V3Unit;
171
+ unit: import("@hatiolab/figure-model").FigureUnit;
172
172
  min: number;
173
173
  max: number;
174
174
  role?: "design" | "state";
175
175
  }[];
176
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
177
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
176
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
177
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
178
178
  palette: Record<string, string>;
179
179
  };
180
- apply(changes: V3InputChange[], origin?: "ui" | "ai", expectedRevision?: number, context?: string): {
180
+ apply(changes: FigureInputChange[], origin?: "ui" | "ai", expectedRevision?: number, context?: string): {
181
181
  context: null;
182
182
  name: null;
183
183
  fields: never[];
@@ -198,20 +198,20 @@ export declare function createV3ProductSession(store: V3ProductStore): {
198
198
  fields: {
199
199
  value: number;
200
200
  id: string;
201
- unit: import("@hatiolab/figure-model").V3Unit;
201
+ unit: import("@hatiolab/figure-model").FigureUnit;
202
202
  min: number;
203
203
  max: number;
204
204
  role?: "design" | "state";
205
205
  }[];
206
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
207
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
206
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
207
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
208
208
  palette: Record<string, string>;
209
209
  };
210
210
  /**
211
211
  * An AI proposal (ADR-0094): the modeller's commands, as one step of the history, on the version the model saw.
212
212
  * Never on the current one instead -- a person's edit in between makes the proposal stale, and it is refused.
213
213
  */
214
- applyProposal(steps: readonly V3ProposalStep[], expectedRevision: number, context: string): {
214
+ applyProposal(steps: readonly FigureProposalStep[], expectedRevision: number, context: string): {
215
215
  context: null;
216
216
  name: null;
217
217
  fields: never[];
@@ -232,20 +232,20 @@ export declare function createV3ProductSession(store: V3ProductStore): {
232
232
  fields: {
233
233
  value: number;
234
234
  id: string;
235
- unit: import("@hatiolab/figure-model").V3Unit;
235
+ unit: import("@hatiolab/figure-model").FigureUnit;
236
236
  min: number;
237
237
  max: number;
238
238
  role?: "design" | "state";
239
239
  }[];
240
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
241
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
240
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
241
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
242
242
  palette: Record<string, string>;
243
243
  };
244
244
  /**
245
245
  * A recipe put in by the person (ADR-0095): its resolved commands, as one step of the history, on the version open
246
246
  * now. The same path as a proposal; the person is its origin.
247
247
  */
248
- applyRecipe(steps: readonly V3ProposalStep[]): {
248
+ applyRecipe(steps: readonly FigureProposalStep[]): {
249
249
  context: null;
250
250
  name: null;
251
251
  fields: never[];
@@ -266,16 +266,16 @@ export declare function createV3ProductSession(store: V3ProductStore): {
266
266
  fields: {
267
267
  value: number;
268
268
  id: string;
269
- unit: import("@hatiolab/figure-model").V3Unit;
269
+ unit: import("@hatiolab/figure-model").FigureUnit;
270
270
  min: number;
271
271
  max: number;
272
272
  role?: "design" | "state";
273
273
  }[];
274
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
275
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
274
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
275
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
276
276
  palette: Record<string, string>;
277
277
  };
278
- add(part: V3PrimitiveCreation): {
278
+ add(part: FigurePrimitiveCreation): {
279
279
  context: null;
280
280
  name: null;
281
281
  fields: never[];
@@ -296,16 +296,16 @@ export declare function createV3ProductSession(store: V3ProductStore): {
296
296
  fields: {
297
297
  value: number;
298
298
  id: string;
299
- unit: import("@hatiolab/figure-model").V3Unit;
299
+ unit: import("@hatiolab/figure-model").FigureUnit;
300
300
  min: number;
301
301
  max: number;
302
302
  role?: "design" | "state";
303
303
  }[];
304
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
305
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
304
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
305
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
306
306
  palette: Record<string, string>;
307
307
  };
308
- edit(edit: V3PartEdit): {
308
+ edit(edit: FigurePartEdit): {
309
309
  context: null;
310
310
  name: null;
311
311
  fields: never[];
@@ -326,13 +326,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
326
326
  fields: {
327
327
  value: number;
328
328
  id: string;
329
- unit: import("@hatiolab/figure-model").V3Unit;
329
+ unit: import("@hatiolab/figure-model").FigureUnit;
330
330
  min: number;
331
331
  max: number;
332
332
  role?: "design" | "state";
333
333
  }[];
334
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
335
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
334
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
335
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
336
336
  palette: Record<string, string>;
337
337
  } | {
338
338
  removal: import("@hatiolab/figure-model").RemovalNotice;
@@ -357,17 +357,17 @@ export declare function createV3ProductSession(store: V3ProductStore): {
357
357
  fields: {
358
358
  value: number;
359
359
  id: string;
360
- unit: import("@hatiolab/figure-model").V3Unit;
360
+ unit: import("@hatiolab/figure-model").FigureUnit;
361
361
  min: number;
362
362
  max: number;
363
363
  role?: "design" | "state";
364
364
  }[];
365
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
366
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
365
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
366
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
367
367
  palette: Record<string, string>;
368
368
  };
369
369
  /** One authoring command — what a person means, not a graph edit — as one step of the same history. */
370
- command(action: V3AuthoringAction): {
370
+ command(action: FigureAuthoringAction): {
371
371
  context: null;
372
372
  name: null;
373
373
  fields: never[];
@@ -388,13 +388,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
388
388
  fields: {
389
389
  value: number;
390
390
  id: string;
391
- unit: import("@hatiolab/figure-model").V3Unit;
391
+ unit: import("@hatiolab/figure-model").FigureUnit;
392
392
  min: number;
393
393
  max: number;
394
394
  role?: "design" | "state";
395
395
  }[];
396
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
397
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
396
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
397
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
398
398
  palette: Record<string, string>;
399
399
  };
400
400
  undo(): {
@@ -418,13 +418,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
418
418
  fields: {
419
419
  value: number;
420
420
  id: string;
421
- unit: import("@hatiolab/figure-model").V3Unit;
421
+ unit: import("@hatiolab/figure-model").FigureUnit;
422
422
  min: number;
423
423
  max: number;
424
424
  role?: "design" | "state";
425
425
  }[];
426
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
427
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
426
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
427
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
428
428
  palette: Record<string, string>;
429
429
  };
430
430
  redo(): {
@@ -448,13 +448,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
448
448
  fields: {
449
449
  value: number;
450
450
  id: string;
451
- unit: import("@hatiolab/figure-model").V3Unit;
451
+ unit: import("@hatiolab/figure-model").FigureUnit;
452
452
  min: number;
453
453
  max: number;
454
454
  role?: "design" | "state";
455
455
  }[];
456
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
457
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
456
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
457
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
458
458
  palette: Record<string, string>;
459
459
  };
460
460
  source(): string;
@@ -463,7 +463,7 @@ export declare function createV3ProductSession(store: V3ProductStore): {
463
463
  *
464
464
  * The picture is the caller's because taking it needs a canvas, and this session is the place that knows
465
465
  * nothing about drawing. A save with no picture is a save: a tab in the background cannot draw, and the
466
- * source matters more than the card (see `v3-thumbnail.ts`).
466
+ * source matters more than the card (see `thumbnail.ts`).
467
467
  */
468
468
  save({ thumbnail, type }?: {
469
469
  thumbnail?: string;
@@ -497,14 +497,14 @@ export declare function createV3ProductSession(store: V3ProductStore): {
497
497
  fields: {
498
498
  value: number;
499
499
  id: string;
500
- unit: import("@hatiolab/figure-model").V3Unit;
500
+ unit: import("@hatiolab/figure-model").FigureUnit;
501
501
  min: number;
502
502
  max: number;
503
503
  role?: "design" | "state";
504
504
  }[];
505
- geometry: import("@hatiolab/figure-model").V3AssetGeometry[];
506
- bindings: import("@hatiolab/figure-model").V3EvaluatedBinding[];
505
+ geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
506
+ bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
507
507
  palette: Record<string, string>;
508
508
  }>;
509
509
  };
510
- export type V3ProductSession = ReturnType<typeof createV3ProductSession>;
510
+ export type FigureProductSession = ReturnType<typeof createFigureProductSession>;
@@ -1,7 +1,7 @@
1
- import { createV3Asset, createV3EditorWorkspace, serializeV3Asset, parseV3Asset } from '@hatiolab/figure-model';
1
+ import { createFigureAsset, createFigureEditorWorkspace, serializeFigureAsset, parseFigureAsset } from '@hatiolab/figure-model';
2
2
  /** Product lifecycle boundary. A late response can never change another editor's asset or ID. */
3
- export function createV3ProductSession(store) {
4
- const workspace = createV3EditorWorkspace();
3
+ export function createFigureProductSession(store) {
4
+ const workspace = createFigureEditorWorkspace();
5
5
  let epoch = 0, id, baseline;
6
6
  let loading = false, saving = false, error;
7
7
  let creationId;
@@ -38,7 +38,7 @@ export function createV3ProductSession(store) {
38
38
  ++epoch;
39
39
  clear();
40
40
  loading = false;
41
- workspace.open(serializeV3Asset(createV3Asset('새 Figure')));
41
+ workspace.open(serializeFigureAsset(createFigureAsset('새 Figure')));
42
42
  creationId = crypto.randomUUID();
43
43
  return read();
44
44
  },
@@ -128,7 +128,7 @@ export function createV3ProductSession(store) {
128
128
  *
129
129
  * The picture is the caller's because taking it needs a canvas, and this session is the place that knows
130
130
  * nothing about drawing. A save with no picture is a save: a tab in the background cannot draw, and the
131
- * source matters more than the card (see `v3-thumbnail.ts`).
131
+ * source matters more than the card (see `thumbnail.ts`).
132
132
  */
133
133
  async save({ thumbnail, type } = {}) {
134
134
  const control = writable(), requestEpoch = epoch;
@@ -140,7 +140,7 @@ export function createV3ProductSession(store) {
140
140
  return read();
141
141
  if (!record.id || (id !== undefined && record.id !== id))
142
142
  throw Error('저장 응답의 Figure 대상이 다릅니다.');
143
- if (serializeV3Asset(parseV3Asset(record.source)) !== exported.text)
143
+ if (serializeFigureAsset(parseFigureAsset(record.source)) !== exported.text)
144
144
  throw Error('저장 응답이 보낸 모델과 다릅니다. 저장 상태를 다시 확인해 주세요.');
145
145
  workspace.acknowledgeSaved(exported);
146
146
  id = record.id;
@@ -154,4 +154,4 @@ export function createV3ProductSession(store) {
154
154
  }
155
155
  };
156
156
  }
157
- //# sourceMappingURL=v3-product-session.js.map
157
+ //# sourceMappingURL=product-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-session.js","sourceRoot":"","sources":["../../client/modeller/product-session.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createFigureAsset,\n createFigureEditorWorkspace,\n serializeFigureAsset,\n parseFigureAsset,\n type FigureInputChange,\n type FigurePrimitiveCreation,\n type FigurePartEdit,\n type FigureAuthoringAction,\n type FigureProposalStep\n} from '@hatiolab/figure-model'\n\nexport interface FigureProductRecord {\n id: string\n source: string\n}\n\n/** Persistence is injected; neither the model engine nor the renderer owns the product ID. */\nexport interface FigureProductStore {\n load(id: string): Promise<FigureProductRecord>\n save(request: {\n id?: string\n source: string\n expectedSource?: string\n creationId?: string\n /** The card's picture. Absent when the browser could not draw one; the source is saved either way. */\n thumbnail?: string\n /** The type name a new figure is created under (the first save asks for it). Not sent for an existing one. */\n type?: string\n }): Promise<FigureProductRecord>\n}\n\n/** Product lifecycle boundary. A late response can never change another editor's asset or ID. */\nexport function createFigureProductSession(store: FigureProductStore) {\n const workspace = createFigureEditorWorkspace()\n let epoch = 0,\n id: string | undefined,\n baseline: string | undefined\n let loading = false,\n saving = false,\n error: string | undefined\n let creationId: string | undefined\n function read() {\n return { ...workspace.read(), id, loading, saving, error }\n }\n function writable() {\n const view = workspace.read()\n if (loading || error || !view.context || view.revision === null) throw Error('먼저 모델을 정상적으로 열어 주세요.')\n // Serializing writes also makes create retries safe: no second create while the first is pending.\n if (saving) throw Error('저장이 끝난 뒤 편집해 주세요.')\n return { context: view.context, expectedRevision: view.revision, origin: 'ui' as const }\n }\n function clear() {\n workspace.close({ discardDesignChanges: true })\n id = undefined\n baseline = undefined\n error = undefined\n saving = false\n creationId = undefined\n }\n function canLeave(discard: boolean) {\n if (saving) throw Error('저장이 끝난 뒤 모델을 전환해 주세요.')\n if (workspace.read().dirty && !discard) throw Error('저장하지 않은 변경이 있습니다.')\n }\n return {\n read,\n startNew({ discard = false } = {}) {\n canLeave(discard)\n ++epoch\n clear()\n loading = false\n workspace.open(serializeFigureAsset(createFigureAsset('새 Figure')))\n creationId = crypto.randomUUID()\n return read()\n },\n async open(nextId: string, { discard = false } = {}) {\n canLeave(discard)\n const requestEpoch = ++epoch\n clear()\n loading = true\n try {\n const record = await store.load(nextId)\n if (requestEpoch !== epoch) return read()\n if (record.id !== nextId) throw Error('요청한 Figure와 응답의 대상이 다릅니다.')\n workspace.open(record.source)\n id = nextId\n baseline = record.source\n } catch (cause) {\n if (requestEpoch === epoch) error = cause instanceof Error ? cause.message : String(cause)\n } finally {\n if (requestEpoch === epoch) loading = false\n }\n return read()\n },\n close({ discard = false } = {}) {\n canLeave(discard)\n ++epoch\n clear()\n loading = false\n return read()\n },\n apply(changes: FigureInputChange[], origin: 'ui' | 'ai' = 'ui', expectedRevision?: number, context?: string) {\n const control = writable()\n // AI must supply the context AND revision captured when it started. Never substitute current values.\n if (origin === 'ai' && (context === undefined || expectedRevision === undefined))\n throw Error('AI 편집에는 요청 당시의 모델 문맥과 리비전이 필요합니다.')\n return workspace.apply({\n ...control,\n origin,\n context: context ?? control.context,\n expectedRevision: expectedRevision ?? control.expectedRevision,\n changes\n })\n },\n /**\n * An AI proposal (ADR-0094): the modeller's commands, as one step of the history, on the version the model saw.\n * Never on the current one instead -- a person's edit in between makes the proposal stale, and it is refused.\n */\n applyProposal(steps: readonly FigureProposalStep[], expectedRevision: number, context: string) {\n writable()\n return workspace.applyProposal({ origin: 'ai', context, expectedRevision, steps })\n },\n /**\n * A recipe put in by the person (ADR-0095): its resolved commands, as one step of the history, on the version open\n * now. The same path as a proposal; the person is its origin.\n */\n applyRecipe(steps: readonly FigureProposalStep[]) {\n const at = writable()\n return workspace.applyProposal({ origin: 'ui', context: at.context, expectedRevision: at.expectedRevision, steps })\n },\n add(part: FigurePrimitiveCreation) {\n return workspace.addPrimitive({ ...writable(), part })\n },\n edit(edit: FigurePartEdit) {\n return workspace.editPart({ ...writable(), edit })\n },\n /** One authoring command — what a person means, not a graph edit — as one step of the same history. */\n command(action: FigureAuthoringAction) {\n return workspace.command({ ...writable(), action })\n },\n undo() {\n return workspace.undo(writable())\n },\n redo() {\n return workspace.redo(writable())\n },\n source() {\n const { context } = writable()\n return workspace.export({ context }).text\n },\n /**\n * Saves the model, and the card's picture when the caller managed to take one.\n *\n * The picture is the caller's because taking it needs a canvas, and this session is the place that knows\n * nothing about drawing. A save with no picture is a save: a tab in the background cannot draw, and the\n * source matters more than the card (see `thumbnail.ts`).\n */\n async save({ thumbnail, type }: { thumbnail?: string; type?: string } = {}) {\n const control = writable(),\n requestEpoch = epoch\n const exported = workspace.export(control)\n saving = true\n try {\n const record = await store.save({ id, source: exported.text, expectedSource: baseline, creationId, thumbnail, ...(id || !type ? {} : { type }) })\n if (requestEpoch !== epoch) return read()\n if (!record.id || (id !== undefined && record.id !== id)) throw Error('저장 응답의 Figure 대상이 다릅니다.')\n if (serializeFigureAsset(parseFigureAsset(record.source)) !== exported.text)\n throw Error('저장 응답이 보낸 모델과 다릅니다. 저장 상태를 다시 확인해 주세요.')\n workspace.acknowledgeSaved(exported)\n id = record.id\n baseline = record.source\n } finally {\n if (requestEpoch === epoch) saving = false\n }\n return read()\n }\n }\n}\nexport type FigureProductSession = ReturnType<typeof createFigureProductSession>\n"]}
@@ -1,7 +1,7 @@
1
- import { type RecipeTemplate } from './v3-recipes.js';
1
+ import { type RecipeTemplate } from './recipes.js';
2
2
  /**
3
3
  * Where the modeller gets its recipe templates: the server's static files (ADR-0095, amended 2026-09-26). The one place
4
- * they are read -- the rules in `v3-recipes.ts` stay free of the network so they are tested without it.
4
+ * they are read -- the rules in `recipes.ts` stay free of the network so they are tested without it.
5
5
  */
6
6
  export declare function availableRecipes(lang: string): Promise<RecipeTemplate[]>;
7
7
  /** One template's guide, or '' while none is written -- the screen then shows no guide and no word about one. */
@@ -1,8 +1,8 @@
1
1
  import { fetchRecipeGuide, fetchRecipeTemplates } from '../graphql/index.js';
2
- import { templatesOf } from './v3-recipes.js';
2
+ import { templatesOf } from './recipes.js';
3
3
  /**
4
4
  * Where the modeller gets its recipe templates: the server's static files (ADR-0095, amended 2026-09-26). The one place
5
- * they are read -- the rules in `v3-recipes.ts` stay free of the network so they are tested without it.
5
+ * they are read -- the rules in `recipes.ts` stay free of the network so they are tested without it.
6
6
  */
7
7
  export async function availableRecipes(lang) {
8
8
  return templatesOf(await fetchRecipeTemplates(lang));
@@ -11,4 +11,4 @@ export async function availableRecipes(lang) {
11
11
  export function recipeGuide(name, lang) {
12
12
  return fetchRecipeGuide(name, lang);
13
13
  }
14
- //# sourceMappingURL=v3-recipe-source.js.map
14
+ //# sourceMappingURL=recipe-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipe-source.js","sourceRoot":"","sources":["../../client/modeller/recipe-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAuB,MAAM,cAAc,CAAA;AAE/D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY;IACjD,OAAO,WAAW,CAAC,MAAM,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,IAAY;IACpD,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACrC,CAAC","sourcesContent":["import { fetchRecipeGuide, fetchRecipeTemplates } from '../graphql/index.js'\nimport { templatesOf, type RecipeTemplate } from './recipes.js'\n\n/**\n * Where the modeller gets its recipe templates: the server's static files (ADR-0095, amended 2026-09-26). The one place\n * they are read -- the rules in `recipes.ts` stay free of the network so they are tested without it.\n */\nexport async function availableRecipes(lang: string): Promise<RecipeTemplate[]> {\n return templatesOf(await fetchRecipeTemplates(lang))\n}\n\n/** One template's guide, or '' while none is written -- the screen then shows no guide and no word about one. */\nexport function recipeGuide(name: string, lang: string): Promise<string> {\n return fetchRecipeGuide(name, lang)\n}\n"]}
@@ -1,32 +1,32 @@
1
- import type { V3Recipe, V3RecipeParam, V3RecipeValue } from '@hatiolab/figure-model';
1
+ import type { FigureRecipe, FigureRecipeParam, FigureRecipeValue } from '@hatiolab/figure-model';
2
2
  import type { RecipeTemplateRow } from '../graphql/index.js';
3
3
  /** A template in the catalog: the server's row, its recipe parsed. */
4
4
  export interface RecipeTemplate extends Omit<RecipeTemplateRow, 'source'> {
5
- recipe: V3Recipe;
5
+ recipe: FigureRecipe;
6
6
  }
7
7
  /** The server's rows as templates. A row that is not a recipe is left out rather than breaking the catalog. */
8
8
  export declare function templatesOf(rows: ReadonlyArray<RecipeTemplateRow>): RecipeTemplate[];
9
9
  /** A part the recipe makes, as the catalog names it: its own name, the placeholder left off. */
10
10
  export declare const recipePartName: (part: string) => string;
11
11
  /**
12
- * How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeV3Recipe`), each
12
+ * How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeFigureRecipe`), each
13
13
  * a translation key and its words.
14
14
  */
15
- export declare function recipeWorkings(recipe: V3Recipe): Array<{
15
+ export declare function recipeWorkings(recipe: FigureRecipe): Array<{
16
16
  key: string;
17
17
  words: Record<string, string | number>;
18
18
  }>;
19
19
  /** A recipe's words in the language on screen: that language, else English, else the first it has. */
20
20
  export declare function recipeWord(words: Record<string, string> | undefined, language: string): string;
21
21
  /** Whether a recipe can be put in now: one for a part needs a part chosen. */
22
- export declare function recipeReady(recipe: Pick<V3Recipe, 'target'>, selected: string): boolean;
22
+ export declare function recipeReady(recipe: Pick<FigureRecipe, 'target'>, selected: string): boolean;
23
23
  /**
24
24
  * A field's value as the recipe takes it. A ratio is shown and typed as a percentage (35 for 0.35), since that is how a
25
25
  * person says a share; the rest are taken as they are. A number field left empty or not a number keeps the default.
26
26
  */
27
- export declare function recipeValueOf(param: V3RecipeParam, typed: string | boolean): V3RecipeValue;
27
+ export declare function recipeValueOf(param: FigureRecipeParam, typed: string | boolean): FigureRecipeValue;
28
28
  /** What a field shows for a value: a ratio as a percentage. */
29
- export declare function recipeFieldOf(param: V3RecipeParam, value: V3RecipeValue): string;
29
+ export declare function recipeFieldOf(param: FigureRecipeParam, value: FigureRecipeValue): string;
30
30
  /** The templates a category and words find: a word matches the title, the description, the name or a tag. */
31
31
  export declare function recipesMatching<T extends {
32
32
  category: string;
@@ -1,4 +1,4 @@
1
- import { describeV3Recipe } from '@hatiolab/figure-model';
1
+ import { describeFigureRecipe } from '@hatiolab/figure-model';
2
2
  /*
3
3
  * The recipe section's rules (ADR-0095), kept apart from the element so they can be tested without a browser.
4
4
  */
@@ -20,11 +20,11 @@ export function templatesOf(rows) {
20
20
  /** A part the recipe makes, as the catalog names it: its own name, the placeholder left off. */
21
21
  export const recipePartName = (part) => part.replace(/^\{id\}-/, '');
22
22
  /**
23
- * How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeV3Recipe`), each
23
+ * How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeFigureRecipe`), each
24
24
  * a translation key and its words.
25
25
  */
26
26
  export function recipeWorkings(recipe) {
27
- const d = describeV3Recipe(recipe);
27
+ const d = describeFigureRecipe(recipe);
28
28
  const lines = [];
29
29
  for (const m of d.moves)
30
30
  lines.push(m.follows
@@ -100,4 +100,4 @@ export function recipesMatching(templates, category, query) {
100
100
  };
101
101
  return found.map((t, i) => ({ t, i, r: rank(t) })).sort((a, b) => a.r - b.r || a.i - b.i).map(x => x.t);
102
102
  }
103
- //# sourceMappingURL=v3-recipes.js.map
103
+ //# sourceMappingURL=recipes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../client/modeller/recipes.ts"],"names":[],"mappings":"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","sourcesContent":["import { describeFigureRecipe } from '@hatiolab/figure-model'\nimport type { FigureRecipe, FigureRecipeParam, FigureRecipeValue } from '@hatiolab/figure-model'\n\nimport type { RecipeTemplateRow } from '../graphql/index.js'\n\n/** A template in the catalog: the server's row, its recipe parsed. */\nexport interface RecipeTemplate extends Omit<RecipeTemplateRow, 'source'> {\n recipe: FigureRecipe\n}\n\n/*\n * The recipe section's rules (ADR-0095), kept apart from the element so they can be tested without a browser.\n */\n\n/** The server's rows as templates. A row that is not a recipe is left out rather than breaking the catalog. */\nexport function templatesOf(rows: ReadonlyArray<RecipeTemplateRow>): RecipeTemplate[] {\n const out: RecipeTemplate[] = []\n for (const { source, ...row } of rows) {\n try {\n const recipe = JSON.parse(source)\n if (recipe && typeof recipe.name === 'string' && Array.isArray(recipe.steps)) out.push({ ...row, recipe })\n } catch {\n /* not a recipe */\n }\n }\n return out\n}\n\n/** A part the recipe makes, as the catalog names it: its own name, the placeholder left off. */\nexport const recipePartName = (part: string) => part.replace(/^\\{id\\}-/, '')\n\n/**\n * How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeFigureRecipe`), each\n * a translation key and its words.\n */\nexport function recipeWorkings(recipe: FigureRecipe): Array<{ key: string; words: Record<string, string | number> }> {\n const d = describeFigureRecipe(recipe)\n const lines: Array<{ key: string; words: Record<string, string | number> }> = []\n for (const m of d.moves)\n lines.push(\n m.follows\n ? { key: 'figure.text.recipe-moves-with', words: { part: recipePartName(m.part), leader: recipePartName(m.follows) } }\n : { key: m.kind === 'slide' ? 'figure.text.recipe-slides' : 'figure.text.recipe-turns', words: { part: recipePartName(m.part) } }\n )\n if (d.controls.length) lines.push({ key: 'figure.text.recipe-controls', words: { count: d.controls.length } })\n if (d.shownByControl.length) lines.push({ key: 'figure.text.recipe-shown-by-control', words: { parts: d.shownByControl.map(recipePartName).join(', ') } })\n for (const row of d.rows) lines.push({ key: 'figure.text.recipe-row', words: { part: recipePartName(row) } })\n return lines\n}\n\n/** A recipe's words in the language on screen: that language, else English, else the first it has. */\nexport function recipeWord(words: Record<string, string> | undefined, language: string): string {\n if (!words) return ''\n return words[language] ?? words[language.split('-')[0]!] ?? words.en ?? Object.values(words)[0] ?? ''\n}\n\n/** Whether a recipe can be put in now: one for a part needs a part chosen. */\nexport function recipeReady(recipe: Pick<FigureRecipe, 'target'>, selected: string): boolean {\n return recipe.target === 'figure' || !!selected\n}\n\n/**\n * A field's value as the recipe takes it. A ratio is shown and typed as a percentage (35 for 0.35), since that is how a\n * person says a share; the rest are taken as they are. A number field left empty or not a number keeps the default.\n */\nexport function recipeValueOf(param: FigureRecipeParam, typed: string | boolean): FigureRecipeValue {\n if (param.kind === 'flag') return typed === true || typed === 'true'\n if (param.kind === 'ratio' || param.kind === 'mm') {\n const n = typeof typed === 'string' && typed.trim() !== '' ? Number(typed) : NaN\n if (!Number.isFinite(n)) return param.default\n return param.kind === 'ratio' ? Math.round(n * 1e4) / 1e6 : n\n }\n const option = (param.options ?? []).find(o => String(o) === String(typed))\n return option ?? param.default\n}\n\n/** What a field shows for a value: a ratio as a percentage. */\nexport function recipeFieldOf(param: FigureRecipeParam, value: FigureRecipeValue): string {\n if (param.kind === 'ratio' && typeof value === 'number') return String(Math.round(value * 1e6) / 1e4)\n return String(value)\n}\n\n\n/** The templates a category and words find: a word matches the title, the description, the name or a tag. */\nexport function recipesMatching<T extends { category: string; title: string; description: string; name: string; tags: string[] }>(templates: readonly T[], category: string, query: string): T[] {\n const words = query.trim().toLowerCase().split(/\\s+/).filter(Boolean)\n const found = templates.filter(t => {\n if (category && t.category !== category) return false\n const text = [t.title, t.description, t.name, ...t.tags].join(' ').toLowerCase()\n return words.every(w => text.includes(w))\n })\n if (!words.length) return found\n /*\n What the search names comes first: a title that is the words, then one that starts with them, then a title word that\n does, then the rest in their order. 「다리」 listed 사다리 before 다리 넷 (walk 1, 2026-09-26).\n */\n const rank = (t: T) => {\n const title = t.title.toLowerCase()\n const query = words.join(' ')\n if (title === query) return 0\n if (title.startsWith(query)) return 1\n if (words.every(w => title.split(/\\s+/).some(part => part.startsWith(w)))) return 2\n if (words.every(w => title.includes(w))) return 3\n return 4\n }\n return found.map((t, i) => ({ t, i, r: rank(t) })).sort((a, b) => a.r - b.r || a.i - b.i).map(x => x.t)\n}\n"]}
@@ -139,4 +139,4 @@ export function inputRangeRefusalOf(error, say) {
139
139
  const params = { value: number(value), min: number(min), max: number(max) };
140
140
  return axis ? say('figure.text.input-range-size', { ...params, axis: axis.toUpperCase() }) : say('figure.text.input-range', params);
141
141
  }
142
- //# sourceMappingURL=v3-refusals.js.map
142
+ //# sourceMappingURL=refusals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refusals.js","sourceRoot":"","sources":["../../client/modeller/refusals.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * A command refused because the figure could not be drawn at an end of its declared size range, in the author's words\n * with the numbers and where to put it right -- not the kernel's English (user, 2026-09-24: 「what is this warning\n * message means?」). Kept apart from the element so it is tested without a browser.\n */\n\ntype Say = (key: string, params: Record<string, string>) => string\n\n/** The refusal in words, or nothing for any other refusal. */\nexport function sizeRangeRefusalOf(error: unknown, say: Say): string | null {\n if ((error as { code?: string })?.code !== 'INSTANCE_SIZE_RANGE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /size\\.([xyz]):\\s*(below|above) ([\\d.]+) mm [^(;]*(?:\\(([^)]+)\\))?;/.exec(message)\n if (!found) return null\n const [, axis, side, mm, part] = found\n return say(side === 'below' ? 'figure.text.size-range-too-small' : 'figure.text.size-range-too-large', {\n axis: axis!.toUpperCase(),\n mm: Number(mm).toLocaleString(undefined, { maximumFractionDigits: 1 }),\n part: part ?? ''\n })\n}\n\n/**\n * A link refused because the size range it would leave cannot hold: measuring again cannot help (the link is not there\n * to measure), so the author is offered the same link that narrows the range to what the figure then allows.\n */\nexport function narrowingRetryOf<A extends { kind: string }>(action: A, error: unknown, say: Say): { message: string; label: string; retry: A & { narrowRange: true } } | null {\n if (action.kind !== 'link-dimension' || (error as { code?: string })?.code !== 'INSTANCE_SIZE_RANGE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /size\\.([xyz]):\\s*(below|above) ([\\d.]+) mm [^(;]*(?:\\(([^)]+)\\))?;/.exec(message)\n if (!found) return null\n const [, axis, side, raw, part] = found\n const mm = Number(raw).toLocaleString(undefined, { maximumFractionDigits: 1 })\n const words = { axis: axis!.toUpperCase(), mm, part: part ?? '' }\n return {\n message: say(side === 'below' ? 'figure.text.link-needs-smaller-range' : 'figure.text.link-needs-larger-range', words),\n label: say(side === 'below' ? 'figure.button.narrow-range-from' : 'figure.button.narrow-range-to', words),\n retry: { ...action, narrowRange: true }\n }\n}\n\n/**\n * A placement refused because a part is fastened to the mounting plane by a face the new plane does not take (a bottom\n * on the floor, when the figure is to hang on a wall), said in the author's words with the parts it names.\n */\nexport function placementRefusalOf(error: unknown, say: Say): string | null {\n if ((error as { code?: string })?.code !== 'PLACEMENT_PLANE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /: (.+?) (?:is|are) fastened to the mounting plane by a face an? (\\w+) does not take \\(([^)]+)\\)/.exec(message)\n if (!found) return null\n return say('figure.text.placement-plane-refused', { parts: found[1]!, placement: say('figure.label.placement-' + found[2]!, {}), faces: found[3]! })\n}\n\n/** A part refused because the declared room reads it -- the one refusal deleting it with the room refitted answers. */\nexport function inDeclaredRoom(error: unknown): boolean {\n return (error as { code?: string })?.code === 'PART_REFERENCED' && /is in the space the figure declares/.test(error instanceof Error ? error.message : String(error))\n}\n\n/**\n * Why a part cannot be deleted, in the author's words. Since the chief architect's ruling of 2026-09-27 a part that\n * holds others, leads a motion or is followed goes, and what depended on it is let go of (`removalNoticeOf`); what is\n * left is the declared space (with a way on: fit it again) and a row -- one laid along the part, or hanging in its row.\n */\nexport function partRefusalOf(error: unknown, part: string, say: Say): string | null {\n const code = (error as { code?: string })?.code\n if (code !== 'PART_REFERENCED' && code !== 'PART_ROW') return null\n /* figure-model's sentence after its code and path: 「PART_ROW: bed: roller is a row laid along bed; …」. */\n const message = (error instanceof Error ? error.message : String(error)).replace(/^[A-Z_]+: [^:]+: /, '')\n if (/is in the space the figure declares/.test(message)) return say('figure.text.part-in-declared-space', { part })\n const along = /^(.+?) (?:is a row|are rows) laid along /.exec(message)\n if (along) return say('figure.text.part-row-along', { part, rows: along[1]! })\n const carried = /^(.+?) hangs? in the row /.exec(message)\n if (carried) return say('figure.text.part-row-carries', { part, others: carried[1]! })\n return say('figure.text.part-is-referenced', { part })\n}\n\n/** What removing a part let go of (figure-model's `RemovalNotice`), said in one line, or nothing when it let go of nothing. */\nexport function removalNoticeOf(\n notice:\n | {\n released: Array<{ part: string; control?: string }>\n fixed: Array<{ part: string }>\n controls: Array<{ part: string; control: string; min: number; max: number }>\n mountingFace?: boolean\n bindings?: Array<{ id: string; label?: string }>\n }\n | undefined,\n say: Say\n): string | null {\n if (!notice) return null\n const number = (v: number) => v.toLocaleString(undefined, { maximumFractionDigits: 3 })\n const lines: string[] = []\n const still = notice.released.filter(r => !r.control).map(r => r.part)\n if (still.length) lines.push(say('figure.text.removal-released', { parts: still.join(', ') }))\n for (const r of notice.released.filter(r => r.control)) lines.push(say('figure.text.removal-released-motion', { part: r.part, control: r.control! }))\n for (const c of notice.controls) lines.push(say('figure.text.removal-own-control', { part: c.part, control: c.control, min: number(c.min), max: number(c.max) }))\n const fixed = [...new Set(notice.fixed.map(f => f.part))]\n if (fixed.length) lines.push(say('figure.text.removal-fixed', { parts: fixed.join(', ') }))\n if (notice.bindings?.length) lines.push(say('figure.text.removal-bindings', { places: notice.bindings.map(b => b.label ?? b.id).join(', ') }))\n if (notice.mountingFace) lines.push(say('figure.text.removal-mounting-face', {}))\n return lines.length ? lines.join(' ') : null\n}\n\n/**\n * A recipe refused at one of its steps: which step, and why -- the particular sentence when there is one (a size\n * range, a value's range, a placement), otherwise the kernel's code. The kernel says 「steps[2]: attach: …」.\n */\nexport function recipeRefusalOf(error: unknown, say: Say): string | null {\n const step = /^steps\\[(\\d+)\\]$/.exec((error as { path?: string })?.path ?? '')\n if (!step) return null\n const why = sizeRangeRefusalOf(error, say) ?? inputRangeRefusalOf(error, say) ?? placementRefusalOf(error, say)\n return say('figure.text.recipe-step-refused', { step: String(Number(step[1]) + 1), why: why ?? '', code: (error as { code?: string })?.code ?? '' })\n}\n\n/**\n * A refusal no sentence above knows, said as a refusal with its code -- never the kernel's English on the screen (the\n * duplicate of a row's part showed 「EDIT_TARGET: … not a repeated template」, 2026-09-27). The figure's node limit\n * is said with its number.\n */\nexport function editRefusalOf(error: unknown, say: Say): string {\n const code = (error as { code?: string })?.code\n const message = error instanceof Error ? error.message : String(error)\n if (code === 'DOCUMENT_LIMIT') return say('figure.text.edit-refused-node-limit', { max: /maximum (\\d+) nodes/.exec(message)?.[1] ?? '' })\n return say('figure.text.edit-refused', { code: code ?? '' })\n}\n\n/**\n * A value outside the range its input declares, with the range and the value given -- the kernel says\n * 「size.x: 6021100 outside [300,1200]」. The figure's own size is named by its axis; any other input by its range only.\n * The repeat pitch's refusal shares the code and has its own words (`figure.text.repeat-pitch-too-small`).\n */\nexport function inputRangeRefusalOf(error: unknown, say: Say): string | null {\n if ((error as { code?: string })?.code !== 'INPUT_RANGE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /([\\w.-]+): (-?[\\d.e+]+) outside \\[(-?[\\d.e+]+),\\s*(-?[\\d.e+]+)\\]/.exec(message)\n if (!found) return null\n const [, input, value, min, max] = found\n const number = (text: string) => Number(text).toLocaleString(undefined, { maximumFractionDigits: 3 })\n const axis = /^size\\.([xyz])$/.exec(input!)?.[1]\n const params = { value: number(value!), min: number(min!), max: number(max!) }\n return axis ? say('figure.text.input-range-size', { ...params, axis: axis.toUpperCase() }) : say('figure.text.input-range', params)\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import * as THREE from 'three';
2
- /** Evaluated V3 boundary: graph values are resolved before reaching the renderer. */
3
- export interface V3RenderPart {
2
+ /** Evaluated boundary: graph values are resolved before reaching the renderer. */
3
+ export interface FigureRenderPart {
4
4
  id: string;
5
5
  shape: {
6
6
  provider: string;
@@ -31,10 +31,10 @@ export interface V3RenderPart {
31
31
  *
32
32
  * Two are left out. A scalar body carries no shape or pose — it is a number the graph produced, not something
33
33
  * on screen. A body the asset hides is evaluated, placed and gated exactly as a shown one, and excluded from
34
- * rendering, from shadows and from pointer picking (V3 designer's ruling 2026-09-22); drawing it would make
34
+ * rendering, from shadows and from pointer picking (designer's ruling 2026-09-22); drawing it would make
35
35
  * "hidden" mean nothing in the modeller while it means something on a board.
36
36
  */
37
- export declare function drawableV3Parts(geometry: readonly unknown[]): V3RenderPart[];
38
- export declare function disposeV3Meshes(group: THREE.Group): void;
37
+ export declare function drawableFigureParts(geometry: readonly unknown[]): FigureRenderPart[];
38
+ export declare function disposeFigureMeshes(group: THREE.Group): void;
39
39
  /** Build first, then swap; failed rendering must not erase the previous scene. No old meshes survive a successful swap. */
40
- export declare function replaceV3Meshes(group: THREE.Group, parts: readonly V3RenderPart[], palette: Record<string, string>): void;
40
+ export declare function replaceFigureMeshes(group: THREE.Group, parts: readonly FigureRenderPart[], palette: Record<string, string>): void;