@hatiolab/figure-model 0.1.92 → 0.1.94
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.
- package/CHANGELOG.md +12 -12
- package/README.md +25 -25
- package/dist/{v3-asset-types.d.ts → asset-types.d.ts} +73 -67
- package/dist/asset-types.d.ts.map +1 -0
- package/dist/asset-types.js +2 -0
- package/dist/asset-types.js.map +1 -0
- package/dist/asset.d.ts +20 -0
- package/dist/asset.d.ts.map +1 -0
- package/dist/{v3-asset.js → asset.js} +49 -28
- package/dist/asset.js.map +1 -0
- package/dist/{v3-authoring-actions.d.ts → authoring-actions.d.ts} +77 -66
- package/dist/authoring-actions.d.ts.map +1 -0
- package/dist/{v3-authoring-actions.js → authoring-actions.js} +129 -104
- package/dist/authoring-actions.js.map +1 -0
- package/dist/{v3-authoring-session.d.ts → authoring-session.d.ts} +23 -21
- package/dist/authoring-session.d.ts.map +1 -0
- package/dist/{v3-authoring-session.js → authoring-session.js} +4 -4
- package/dist/authoring-session.js.map +1 -0
- package/dist/capabilities.d.ts +3 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/{v3-capabilities.js → capabilities.js} +8 -8
- package/dist/capabilities.js.map +1 -0
- package/dist/clip-keeping.d.ts +30 -0
- package/dist/clip-keeping.d.ts.map +1 -0
- package/dist/clip-keeping.js +77 -0
- package/dist/clip-keeping.js.map +1 -0
- package/dist/command-preview.d.ts +125 -0
- package/dist/command-preview.d.ts.map +1 -0
- package/dist/command-preview.js +246 -0
- package/dist/command-preview.js.map +1 -0
- package/dist/contract.d.ts +7 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +12 -0
- package/dist/contract.js.map +1 -0
- package/dist/{v3-cost.d.ts → cost.d.ts} +5 -5
- package/dist/cost.d.ts.map +1 -0
- package/dist/{v3-cost.js → cost.js} +11 -11
- package/dist/cost.js.map +1 -0
- package/dist/{v3-create.d.ts → create.d.ts} +8 -8
- package/dist/{v3-create.d.ts.map → create.d.ts.map} +1 -1
- package/dist/{v3-create.js → create.js} +26 -26
- package/dist/create.js.map +1 -0
- package/dist/document.d.ts +5 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +31 -0
- package/dist/document.js.map +1 -0
- package/dist/{v3-driver.d.ts → driver.d.ts} +10 -10
- package/dist/driver.d.ts.map +1 -0
- package/dist/{v3-driver.js → driver.js} +10 -10
- package/dist/driver.js.map +1 -0
- package/dist/{v3-editor-workspace.d.ts → editor-workspace.d.ts} +99 -73
- package/dist/editor-workspace.d.ts.map +1 -0
- package/dist/{v3-editor-workspace.js → editor-workspace.js} +48 -32
- package/dist/editor-workspace.js.map +1 -0
- package/dist/{v3-examples.d.ts → examples.d.ts} +5 -5
- package/dist/examples.d.ts.map +1 -0
- package/dist/{v3-examples.js → examples.js} +11 -11
- package/dist/examples.js.map +1 -0
- package/dist/{v3-follow.d.ts → follow.d.ts} +5 -5
- package/dist/follow.d.ts.map +1 -0
- package/dist/{v3-follow.js → follow.js} +2 -2
- package/dist/follow.js.map +1 -0
- package/dist/{v3-gate.d.ts → gate.d.ts} +36 -28
- package/dist/gate.d.ts.map +1 -0
- package/dist/{v3-gate.js → gate.js} +54 -48
- package/dist/gate.js.map +1 -0
- package/dist/{v3-graph-types.d.ts → graph-types.d.ts} +33 -33
- package/dist/graph-types.d.ts.map +1 -0
- package/dist/graph-types.js +2 -0
- package/dist/graph-types.js.map +1 -0
- package/dist/{v3-graph.d.ts → graph.d.ts} +14 -14
- package/dist/graph.d.ts.map +1 -0
- package/dist/{v3-graph.js → graph.js} +16 -16
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +39 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -33
- package/dist/index.js.map +1 -1
- package/dist/{v3-instance-size.d.ts → instance-size.d.ts} +14 -14
- package/dist/instance-size.d.ts.map +1 -0
- package/dist/{v3-instance-size.js → instance-size.js} +13 -13
- package/dist/instance-size.js.map +1 -0
- package/dist/json.d.ts +12 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/{v3-json.js → json.js} +13 -13
- package/dist/json.js.map +1 -0
- package/dist/kernel-version.d.ts +8 -0
- package/dist/kernel-version.d.ts.map +1 -0
- package/dist/{v3-kernel-version.js → kernel-version.js} +4 -4
- package/dist/kernel-version.js.map +1 -0
- package/dist/{v3-part-edit.d.ts → part-edit.d.ts} +12 -11
- package/dist/part-edit.d.ts.map +1 -0
- package/dist/{v3-part-edit.js → part-edit.js} +84 -68
- package/dist/part-edit.js.map +1 -0
- package/dist/proposal.d.ts +55 -0
- package/dist/proposal.d.ts.map +1 -0
- package/dist/{v3-proposal.js → proposal.js} +29 -21
- package/dist/proposal.js.map +1 -0
- package/dist/{v3-public-inputs.d.ts → public-inputs.d.ts} +4 -4
- package/dist/public-inputs.d.ts.map +1 -0
- package/dist/{v3-public-inputs.js → public-inputs.js} +3 -3
- package/dist/public-inputs.js.map +1 -0
- package/dist/recipe-build.d.ts +27 -0
- package/dist/recipe-build.d.ts.map +1 -0
- package/dist/{v3-recipe-build.js → recipe-build.js} +9 -9
- package/dist/recipe-build.js.map +1 -0
- package/dist/recipe-from-parts.d.ts +8 -0
- package/dist/recipe-from-parts.d.ts.map +1 -0
- package/dist/{v3-recipe-from-parts.js → recipe-from-parts.js} +9 -9
- package/dist/recipe-from-parts.js.map +1 -0
- package/dist/{v3-recipe.d.ts → recipe.d.ts} +25 -25
- package/dist/recipe.d.ts.map +1 -0
- package/dist/{v3-recipe.js → recipe.js} +30 -30
- package/dist/recipe.js.map +1 -0
- package/dist/release-contract.d.ts +19 -0
- package/dist/release-contract.d.ts.map +1 -0
- package/dist/{v3-release-contract.js → release-contract.js} +8 -7
- package/dist/release-contract.js.map +1 -0
- package/dist/{v3-render-batches.d.ts → render-batches.d.ts} +8 -8
- package/dist/render-batches.d.ts.map +1 -0
- package/dist/{v3-render-batches.js → render-batches.js} +4 -4
- package/dist/render-batches.js.map +1 -0
- package/dist/resize-plan.d.ts +61 -0
- package/dist/resize-plan.d.ts.map +1 -0
- package/dist/resize-plan.js +189 -0
- package/dist/resize-plan.js.map +1 -0
- package/dist/room.d.ts +53 -0
- package/dist/room.d.ts.map +1 -0
- package/dist/room.js +90 -0
- package/dist/room.js.map +1 -0
- package/dist/{v3-score.d.ts → score.d.ts} +19 -19
- package/dist/score.d.ts.map +1 -0
- package/dist/{v3-score.js → score.js} +32 -32
- package/dist/score.js.map +1 -0
- package/dist/shape-provider.d.ts +37 -0
- package/dist/shape-provider.d.ts.map +1 -0
- package/dist/shape-provider.js +69 -0
- package/dist/shape-provider.js.map +1 -0
- package/dist/{v3-shape-sampling.d.ts → shape-sampling.d.ts} +4 -4
- package/dist/shape-sampling.d.ts.map +1 -0
- package/dist/{v3-shape-sampling.js → shape-sampling.js} +3 -3
- package/dist/shape-sampling.js.map +1 -0
- package/dist/size-edit.d.ts +38 -0
- package/dist/size-edit.d.ts.map +1 -0
- package/dist/size-edit.js +178 -0
- package/dist/size-edit.js.map +1 -0
- package/dist/{v3-surface.d.ts → surface.d.ts} +5 -5
- package/dist/surface.d.ts.map +1 -0
- package/dist/{v3-surface.js → surface.js} +7 -7
- package/dist/surface.js.map +1 -0
- package/dist/{v3-words.d.ts → words.d.ts} +3 -3
- package/dist/words.d.ts.map +1 -0
- package/dist/{v3-words.js → words.js} +3 -3
- package/dist/words.js.map +1 -0
- package/docs/{assembly-constraints-v3.md → assembly-constraints.md} +1 -1
- package/docs/{v3-asset-persistence.md → asset-persistence.md} +8 -8
- package/docs/{v3-authoring-transactions.md → authoring-transactions.md} +2 -2
- package/docs/{v3-capability-bindings.md → capability-bindings.md} +8 -8
- package/docs/{v3-common-kernel-experiment.md → common-kernel-experiment.md} +4 -4
- package/docs/{v3-core-semantics.md → core-semantics.md} +5 -5
- package/docs/{v3-cutover.md → cutover.md} +4 -4
- package/docs/{v3-design.md → design.md} +11 -11
- package/docs/{v3-document-contract.md → document-contract.md} +9 -9
- package/docs/{v3-dryroom-profile-validation.md → dryroom-profile-validation.md} +4 -4
- package/docs/{v3-editor-integration.md → editor-integration.md} +6 -6
- package/docs/{v3-full-conveyor-validation.md → full-conveyor-validation.md} +4 -4
- package/docs/{v3-full-dryroom-validation.md → full-dryroom-validation.md} +4 -4
- package/docs/{v3-full-forklift-validation.md → full-forklift-validation.md} +5 -5
- package/docs/{v3-full-robot-validation.md → full-robot-validation.md} +4 -4
- package/docs/{v3-layout-system.md → layout-system.md} +4 -4
- package/docs/{v3-legacy-risk-audit-2026-09-23.md → legacy-risk-audit-2026-09-23.md} +5 -5
- package/docs/{v3-minimal-model.md → minimal-model.md} +6 -6
- package/docs/{v3-motion-contract.md → motion-contract.md} +3 -3
- package/docs/{v3-openusd-review.md → openusd-review.md} +8 -8
- package/docs/{v3-operator-contracts.md → operator-contracts.md} +6 -6
- package/docs/{v3-payload-collision-validation.md → payload-collision-validation.md} +4 -4
- package/docs/{v3-payload-contact-validation.md → payload-contact-validation.md} +5 -5
- package/docs/prototypes/README.md +10 -10
- package/docs/prototypes/{v3-asset-samples.mjs → asset-samples.mjs} +6 -6
- package/docs/prototypes/{v3-asset-store.mjs → asset-store.mjs} +3 -3
- package/docs/prototypes/{v3-asset-store.test.mjs → asset-store.test.mjs} +6 -6
- package/docs/prototypes/asset.mjs +1 -0
- package/docs/prototypes/{v3-asset.schema.json → asset.schema.json} +2 -2
- package/docs/prototypes/{v3-asset.test.mjs → asset.test.mjs} +10 -10
- package/docs/prototypes/authoring-session.mjs +1 -0
- package/docs/prototypes/{v3-authoring-session.test.mjs → authoring-session.test.mjs} +6 -6
- package/docs/prototypes/capability-plan.mjs +1 -0
- package/docs/prototypes/{v3-capability-plan.test.mjs → capability-plan.test.mjs} +5 -5
- package/docs/prototypes/{v3-capability-samples.mjs → capability-samples.mjs} +2 -2
- package/docs/prototypes/document.mjs +2 -0
- package/docs/prototypes/{v3-document.schema.json → document.schema.json} +1 -1
- package/docs/prototypes/{v3-document.test.mjs → document.test.mjs} +7 -7
- package/docs/prototypes/{v3-dryroom-mesh.mjs → dryroom-mesh.mjs} +1 -1
- package/docs/prototypes/{v3-dryroom-mesh.test.mjs → dryroom-mesh.test.mjs} +1 -1
- package/docs/prototypes/{v3-editor-browser.mjs → editor-browser.mjs} +13 -13
- package/docs/prototypes/editor-workspace.mjs +1 -0
- package/docs/prototypes/{v3-editor-workspace.test.mjs → editor-workspace.test.mjs} +3 -3
- package/docs/prototypes/{v3-feature-pattern.test.mjs → feature-pattern.test.mjs} +1 -1
- package/docs/prototypes/{v3-full-conveyor.mjs → full-conveyor.mjs} +2 -2
- package/docs/prototypes/{v3-full-conveyor.test.mjs → full-conveyor.test.mjs} +3 -3
- package/docs/prototypes/{v3-full-dryroom.mjs → full-dryroom.mjs} +2 -2
- package/docs/prototypes/{v3-full-dryroom.test.mjs → full-dryroom.test.mjs} +3 -3
- package/docs/prototypes/{v3-full-forklift.mjs → full-forklift.mjs} +2 -2
- package/docs/prototypes/{v3-full-forklift.test.mjs → full-forklift.test.mjs} +3 -3
- package/docs/prototypes/{v3-full-robot.mjs → full-robot.mjs} +2 -2
- package/docs/prototypes/{v3-full-robot.test.mjs → full-robot.test.mjs} +4 -4
- package/docs/prototypes/{v3-kernel.test.mjs → kernel.test.mjs} +1 -1
- package/docs/prototypes/{v3-layout.test.mjs → layout.test.mjs} +1 -1
- package/docs/prototypes/{v3-more-samples.test.mjs → more-samples.test.mjs} +2 -2
- package/docs/prototypes/{v3-payload-collision.mjs → payload-collision.mjs} +2 -2
- package/docs/prototypes/{v3-payload-collision.test.mjs → payload-collision.test.mjs} +3 -3
- package/docs/prototypes/{v3-payload-fit.mjs → payload-fit.mjs} +2 -2
- package/docs/prototypes/{v3-payload-fit.test.mjs → payload-fit.test.mjs} +4 -4
- package/docs/prototypes/render-full-dryroom.mjs +12 -12
- package/docs/prototypes/{v3-repeated-binding.mjs → repeated-binding.mjs} +1 -1
- package/docs/prototypes/{v3-repeated-binding.test.mjs → repeated-binding.test.mjs} +6 -6
- package/docs/prototypes/{v3-runtime-browser.mjs → runtime-browser.mjs} +26 -26
- package/docs/prototypes/{v3-samples.test.mjs → samples.test.mjs} +1 -1
- package/docs/prototypes/{v3-spatial-plan.test.mjs → spatial-plan.test.mjs} +1 -1
- package/docs/prototypes/typed-plan.mjs +3 -0
- package/docs/prototypes/{v3-typed-plan.test.mjs → typed-plan.test.mjs} +1 -1
- package/docs/prototypes/{v3-typed-repeat.test.mjs → typed-repeat.test.mjs} +2 -2
- package/docs/{v3-repeated-binding-validation.md → repeated-binding-validation.md} +4 -4
- package/docs/{v3-research-review.md → research-review.md} +2 -2
- package/docs/{v3-review-2026-09-22.md → review-2026-09-22.md} +10 -10
- package/docs/{v3-runtime-extraction.md → runtime-extraction.md} +16 -16
- package/docs/{v3-sample-validation-expanded.md → sample-validation-expanded.md} +5 -5
- package/docs/{v3-sample-validation.md → sample-validation.md} +3 -3
- package/docs/{v3-shape-dimension-contract.md → shape-dimension-contract.md} +12 -12
- package/docs/{v3-shapeassembly-reproduction.md → shapeassembly-reproduction.md} +4 -4
- package/docs/{v3-spatial-contracts.md → spatial-contracts.md} +5 -5
- package/docs/status.md +12 -0
- package/docs/{v3-storage-integration.md → storage-integration.md} +5 -5
- package/docs/{v3-typed-repeat-contracts.md → typed-repeat-contracts.md} +3 -3
- package/package.json +3 -3
- package/dist/v3-asset-types.d.ts.map +0 -1
- package/dist/v3-asset-types.js +0 -2
- package/dist/v3-asset-types.js.map +0 -1
- package/dist/v3-asset.d.ts +0 -8
- package/dist/v3-asset.d.ts.map +0 -1
- package/dist/v3-asset.js.map +0 -1
- package/dist/v3-authoring-actions.d.ts.map +0 -1
- package/dist/v3-authoring-actions.js.map +0 -1
- package/dist/v3-authoring-session.d.ts.map +0 -1
- package/dist/v3-authoring-session.js.map +0 -1
- package/dist/v3-capabilities.d.ts +0 -3
- package/dist/v3-capabilities.d.ts.map +0 -1
- package/dist/v3-capabilities.js.map +0 -1
- package/dist/v3-contract.d.ts +0 -7
- package/dist/v3-contract.d.ts.map +0 -1
- package/dist/v3-contract.js +0 -12
- package/dist/v3-contract.js.map +0 -1
- package/dist/v3-cost.d.ts.map +0 -1
- package/dist/v3-cost.js.map +0 -1
- package/dist/v3-create.js.map +0 -1
- package/dist/v3-document.d.ts +0 -5
- package/dist/v3-document.d.ts.map +0 -1
- package/dist/v3-document.js +0 -31
- package/dist/v3-document.js.map +0 -1
- package/dist/v3-driver.d.ts.map +0 -1
- package/dist/v3-driver.js.map +0 -1
- package/dist/v3-editor-workspace.d.ts.map +0 -1
- package/dist/v3-editor-workspace.js.map +0 -1
- package/dist/v3-examples.d.ts.map +0 -1
- package/dist/v3-examples.js.map +0 -1
- package/dist/v3-follow.d.ts.map +0 -1
- package/dist/v3-follow.js.map +0 -1
- package/dist/v3-gate.d.ts.map +0 -1
- package/dist/v3-gate.js.map +0 -1
- package/dist/v3-graph-types.d.ts.map +0 -1
- package/dist/v3-graph-types.js +0 -2
- package/dist/v3-graph-types.js.map +0 -1
- package/dist/v3-graph.d.ts.map +0 -1
- package/dist/v3-graph.js.map +0 -1
- package/dist/v3-instance-size.d.ts.map +0 -1
- package/dist/v3-instance-size.js.map +0 -1
- package/dist/v3-json.d.ts +0 -12
- package/dist/v3-json.d.ts.map +0 -1
- package/dist/v3-json.js.map +0 -1
- package/dist/v3-kernel-version.d.ts +0 -8
- package/dist/v3-kernel-version.d.ts.map +0 -1
- package/dist/v3-kernel-version.js.map +0 -1
- package/dist/v3-part-edit.d.ts.map +0 -1
- package/dist/v3-part-edit.js.map +0 -1
- package/dist/v3-proposal.d.ts +0 -42
- package/dist/v3-proposal.d.ts.map +0 -1
- package/dist/v3-proposal.js.map +0 -1
- package/dist/v3-public-inputs.d.ts.map +0 -1
- package/dist/v3-public-inputs.js.map +0 -1
- package/dist/v3-recipe-build.d.ts +0 -27
- package/dist/v3-recipe-build.d.ts.map +0 -1
- package/dist/v3-recipe-build.js.map +0 -1
- package/dist/v3-recipe-from-parts.d.ts +0 -8
- package/dist/v3-recipe-from-parts.d.ts.map +0 -1
- package/dist/v3-recipe-from-parts.js.map +0 -1
- package/dist/v3-recipe.d.ts.map +0 -1
- package/dist/v3-recipe.js.map +0 -1
- package/dist/v3-release-contract.d.ts +0 -19
- package/dist/v3-release-contract.d.ts.map +0 -1
- package/dist/v3-release-contract.js.map +0 -1
- package/dist/v3-render-batches.d.ts.map +0 -1
- package/dist/v3-render-batches.js.map +0 -1
- package/dist/v3-score.d.ts.map +0 -1
- package/dist/v3-score.js.map +0 -1
- package/dist/v3-shape-sampling.d.ts.map +0 -1
- package/dist/v3-shape-sampling.js.map +0 -1
- package/dist/v3-surface.d.ts.map +0 -1
- package/dist/v3-surface.js.map +0 -1
- package/dist/v3-words.d.ts.map +0 -1
- package/dist/v3-words.js.map +0 -1
- package/docs/prototypes/v3-asset.mjs +0 -1
- package/docs/prototypes/v3-authoring-session.mjs +0 -1
- package/docs/prototypes/v3-capability-plan.mjs +0 -1
- package/docs/prototypes/v3-document.mjs +0 -2
- package/docs/prototypes/v3-editor-workspace.mjs +0 -1
- package/docs/prototypes/v3-typed-plan.mjs +0 -3
- package/docs/v3-status.md +0 -50
- /package/docs/prototypes/{v3-kernel.mjs → kernel.mjs} +0 -0
- /package/docs/prototypes/{v3-linear-comparison.py → linear-comparison.py} +0 -0
- /package/docs/prototypes/{v3-semantics.test.mjs → semantics.test.mjs} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,30 +8,30 @@
|
|
|
8
8
|
|
|
9
9
|
### 속 빈 상자를 부품으로 (2026-09-26, G4)
|
|
10
10
|
|
|
11
|
-
`
|
|
11
|
+
`addFigurePrimitive` · `add-part` 가 `hollow-box`(윗면이 열린 통: 폭 · 높이 · 깊이 · 모서리 · 벽 두께 · 바닥 두께, `hollow-box@2`)를 만든다.
|
|
12
12
|
안쪽 면(`inside-bottom` · `inside-left` · `inside-right` · `inside-back` · `inside-front`)도 붙이는 면이라 칸막이를 세울 수 있다.
|
|
13
13
|
크기를 따를 때와 공간을 잴 때는 바깥이 치수다. 벽과 바닥은 두께를 지킨다. `set-joint` 도 `narrowRange` 를 받는다.
|
|
14
14
|
|
|
15
15
|
### 모델로 먼저 만든 템플릿을 레시피로 (2026-09-26, ADR-0095 고침)
|
|
16
16
|
|
|
17
|
-
`
|
|
17
|
+
`buildFigureRecipe(spec, models)`: 템플릿을 선택지 조합마다 도형(모델: `host` 상자와 거기에 붙은 부품)으로 만들고, 그 모델들을 레시피
|
|
18
18
|
하나로 합친다. 모든 모델에 있는 명령은 그대로, 일부에만 있는 명령은 그것을 가르는 선택 하나의 `when` 을 붙인다. 사람이 정하는 수는
|
|
19
19
|
명세가 가리키는 명령의 값에 매개변수로 건다(기본값에 대한 배율). 모델이 빠진 조합 · 어느 선택으로도 말할 수 없는 명령 · 걸 수가
|
|
20
|
-
없는 수는 까닭과 함께 거절한다. `
|
|
20
|
+
없는 수는 까닭과 함께 거절한다. `figureRecipeFromParts` 를 되살렸다(재질의 색은 부품마다 제 것만 적는다 — 선택지마다 같게).
|
|
21
21
|
|
|
22
22
|
### 조각 템플릿은 figure-service 의 정적 파일로 · 카탈로그용 설명 (2026-09-26, ADR-0095 고침)
|
|
23
23
|
|
|
24
24
|
0.1.82 가 패키지의 `recipes/*.json` 으로 싣던 조각 셋은 figure-service 의 `recipes/<name>/` 로 옮겼다(백엔드가 정적 파일로 제공한다).
|
|
25
25
|
figure-model 에는 적용과 검사만 남는다. `recipes/` 폴더와 `./recipes/*` export 는 없앴다. 매개변수는 짧은 설명 `hint`(언어별)를 가질 수
|
|
26
|
-
있다. `
|
|
26
|
+
있다. `describeFigureRecipe`: 카탈로그가 보일 것 — 선택에 따라 더해지는 부품 수(가장 적게 · 많게), 움직이는 부품과 방식(미끄러짐 ·
|
|
27
27
|
회전 · 따라 움직임), 더해지는 조작값, 조작값에 따라 보이는 부품, 되풀이 줄. 글로 따로 적지 않고 명령에서 셈한다.
|
|
28
|
-
`
|
|
28
|
+
`figureFollowOf`(치수가 무엇을 따르나, 거꾸로 읽기)를 figure-ui 에서 옮겨 왔다.
|
|
29
29
|
|
|
30
30
|
### 조각(recipe) (2026-09-26, ADR-0095)
|
|
31
31
|
|
|
32
|
-
조각은 매개변수가 붙은 제안 명령 목록이다. `
|
|
32
|
+
조각은 매개변수가 붙은 제안 명령 목록이다. `parseFigureRecipe` · `resolveFigureRecipe` · `applyFigureRecipe`: 자리 채우기 셋(`{id}` ·
|
|
33
33
|
`{target}` · `{매개변수}`), 한 매개변수의 일차식(`{ param, times?, plus? }`), 명령마다 `when` 하나. 식 언어는 없다. 값은 커널보다
|
|
34
|
-
먼저 범위와 선택지로 거르고, 풀린 목록은 `
|
|
34
|
+
먼저 범위와 선택지로 거르고, 풀린 목록은 `applyFigureProposal` 로 적용한다. 넣은 뒤에는 보통 부품이다. 기본 조각 셋을 패키지의
|
|
35
35
|
`recipes/`(미닫이 문 · 여닫이 문 · 롤러 줄)에 싣는다. `make-repeat` 도 `narrowRange` 를 받는다 — 한 줄이 채우는 복제는
|
|
36
36
|
REPEAT_LIMIT 개까지라, 크기를 따르는 도형에 가장 큰 크기가 생긴다.
|
|
37
37
|
|
|
@@ -45,7 +45,7 @@ REPEAT_LIMIT 개까지라, 크기를 따르는 도형에 가장 큰 크기가
|
|
|
45
45
|
|
|
46
46
|
`portal-profile@1`(부호 있는 좌표 여덟)을 `portal-profile@2`로 바꿨다. 입력은 폭 · 높이 · 깊이 · 기둥 두께(`jamb`) · 인방 두께(`head`)이고,
|
|
47
47
|
좌우로 가운데, 바닥에 서고, 깊이로 가운데다. 앞 셋이 상자와 같은 자리라 `link-dimension` 과 크기 따르기가 상자처럼 먹는다
|
|
48
|
-
(이전에는 거절했다). 기둥과 인방은 크기를 따라도 두께를 지킨다. `
|
|
48
|
+
(이전에는 거절했다). 기둥과 인방은 크기를 따라도 두께를 지킨다. `addFigurePrimitive` 의 `portal` 치수도 이 다섯이다.
|
|
49
49
|
@1 은 지웠다 — 저장된 도형 가운데 쓰는 것이 없었다.
|
|
50
50
|
|
|
51
51
|
### 자기 숫자로 놓인 부품 위의 되풀이 (2026-09-26)
|
|
@@ -63,12 +63,12 @@ REPEAT_LIMIT 개까지라, 크기를 따르는 도형에 가장 큰 크기가
|
|
|
63
63
|
|
|
64
64
|
### V1 · V2 형식을 지웠다 (2026-09-26)
|
|
65
65
|
|
|
66
|
-
남은 형식은 `figure-
|
|
67
|
-
크기 반응(`sizing`) · 발행 관문(`gate`) · `contractChanges` · V2→V3 변환기(`
|
|
66
|
+
남은 형식은 `figure-asset-1` 하나다. `FigureSource` · `compile` · `validate` · `costOf` · `scoreOf` ·
|
|
67
|
+
크기 반응(`sizing`) · 발행 관문(`gate`) · `contractChanges` · V2→V3 변환기(`convertV2ToFigure` 와 그 짝)와
|
|
68
68
|
`./types` · `./validate` · `./blueprint` · `./cost` 하위 경로를 지웠다. V3 가 함께 쓰던 낱말(`AXES` ·
|
|
69
69
|
`FIGURE_CAPABILITIES` · `CAPABILITY_NEEDS` · `MATERIAL_PRESETS` · `REPEAT_LIMIT` · `DETAIL_LEVELS` · `PART_LIMIT` ·
|
|
70
|
-
`SKIN` · `LIMITS` · `SEGMENT_PRESETS` · `
|
|
71
|
-
`placeholderType` · `isPlaceholderType`)은 `
|
|
70
|
+
`SKIN` · `LIMITS` · `SEGMENT_PRESETS` · `FIGURE_SIZE_INPUTS` · `FigureGrade` · `TYPE_PATTERN` · `TYPE_LENGTH` ·
|
|
71
|
+
`placeholderType` · `isPlaceholderType`)은 `words.ts` 로 옮겨 그대로 내보낸다.
|
|
72
72
|
V3 컴파일이 혼자 설 수 없는 능력(`Transferable`)을 거절한다 — V2 의 `validate` 가 하던 검사다.
|
|
73
73
|
|
|
74
74
|
아래는 V2 시절의 기록이다.
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @hatiolab/figure-model
|
|
2
2
|
|
|
3
|
-
> Implementation and verification status: [docs/
|
|
3
|
+
> Implementation and verification status: [docs/status.md](docs/status.md).
|
|
4
4
|
|
|
5
|
-
The figure format, `figure-
|
|
5
|
+
The figure format, `figure-asset-1`: its kernel, authoring commands, release gate, score and AI proposal
|
|
6
6
|
grammar. No runtime dependencies.
|
|
7
7
|
|
|
8
8
|
The package contains no renderer. The modeller authors with it, the server judges and stores with it, and the scene
|
|
@@ -31,26 +31,26 @@ npm install @hatiolab/figure-model
|
|
|
31
31
|
Everything is exported from the package root.
|
|
32
32
|
|
|
33
33
|
```ts
|
|
34
|
-
import {
|
|
34
|
+
import { parseFigureAsset, compileFigureAsset, inspectFigureAsset, figureScoreOf } from '@hatiolab/figure-model'
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## Main exports
|
|
38
38
|
|
|
39
39
|
| Area | Exports |
|
|
40
40
|
| --- | --- |
|
|
41
|
-
| Asset document | `
|
|
42
|
-
| Kernel (typed graph) | `
|
|
43
|
-
| Instance size | `
|
|
44
|
-
| Motion and state | `driverValue`, `driverStates`, `normalisePhase`, `
|
|
45
|
-
| Authoring commands | `
|
|
46
|
-
| Authoring session | `
|
|
47
|
-
| Release gate | `
|
|
48
|
-
| Score and cost | `
|
|
49
|
-
| AI proposal grammar | `
|
|
50
|
-
| Capabilities and documents | `
|
|
51
|
-
| JSON input boundary | `
|
|
52
|
-
| Shared words | `AXES`, `FIGURE_CAPABILITIES`, `MATERIAL_PRESETS`, `SEGMENT_PRESETS`, `DETAIL_LEVELS`, `PART_LIMIT`, `LIMITS`, … (`
|
|
53
|
-
| Example | `
|
|
41
|
+
| Asset document | `parseFigureAsset`, `serializeFigureAsset`, `compileFigureAsset`, `captureFigureAuthoredInputs`; types from `asset-types.ts`, `FIGURE_PLACEMENTS` |
|
|
42
|
+
| Kernel (typed graph) | `compileFigureGraph`, `FIGURE_OPERATORS`, `FIGURE_NON_AFFINE_OPERATORS`, `FIGURE_STATE_NON_AFFINE_OPERATORS`, `FIGURE_OPERATOR_STATE_POLICY`, `figureShapeFaces`, `FIGURE_KERNEL_VERSION`, `FIGURE_FACE_NORMALS`; graph types (`FigureGraph`, `FigureCompiledGraph`, …) |
|
|
43
|
+
| Instance size | `FIGURE_INSTANCE_SIZE_INPUTS`, `FIGURE_INSTANCE_SIZE_DEFAULT`, `defaultInstanceSizeRange`, `foldInstanceSizeRange`, `figureInstanceSizeLimitsOf` |
|
|
44
|
+
| Motion and state | `driverValue`, `driverStates`, `normalisePhase`, `validateFigureDrivers`, `validateFigureStateInputs`, `advanceStateValue`, `stateInputPolicy` |
|
|
45
|
+
| Authoring commands | `createFigureAsset`, `addFigureBox`, `addFigurePrimitive`, `editFigurePart`, `applyFigureAuthoring`, `proposeFigureOccupancy`, `proposeFigureProportion`, `checkFigureJoints`, `figureAttachmentsOf`, `figureBindingsOf` |
|
|
46
|
+
| Authoring session | `createFigureAuthoringSession`, `createFigureEditorWorkspace` |
|
|
47
|
+
| Release gate | `inspectFigureAsset`, `figureWorldBoxesOf`, `figureOccupiedBoxesOf`, `figureWritersOf`, `figurePartsExtentOf`, `figureContractChanges` |
|
|
48
|
+
| Score and cost | `figureScoreOf`, `figureGradeOf`, `figurePartCountOf`, `figurePartBudgetOf`, `figureCostOf`, `figureTrianglesOf` |
|
|
49
|
+
| AI proposal grammar | `applyFigureProposal`, `FIGURE_PROPOSAL_GRAMMAR`, `FIGURE_PROPOSAL_KINDS` |
|
|
50
|
+
| Capabilities and documents | `compileFigureCapabilities`, `compileFigureDocument`, `parseFigureDocument`, `serializeFigureDocument` |
|
|
51
|
+
| JSON input boundary | `parseFigureJson`, `assertFigureJson`, `FIGURE_JSON_MAX_BYTES`, `FIGURE_JSON_MAX_DEPTH`, `FigureContractError` |
|
|
52
|
+
| Shared words | `AXES`, `FIGURE_CAPABILITIES`, `MATERIAL_PRESETS`, `SEGMENT_PRESETS`, `DETAIL_LEVELS`, `PART_LIMIT`, `LIMITS`, … (`words.ts`) |
|
|
53
|
+
| Example | `robotArmFigure`, `ROBOT_ARM_CHAIN` |
|
|
54
54
|
|
|
55
55
|
## Commands
|
|
56
56
|
|
|
@@ -76,12 +76,12 @@ No runtime dependencies; it runs unchanged in the browser. The three devDependen
|
|
|
76
76
|
|
|
77
77
|
## Documents
|
|
78
78
|
|
|
79
|
-
- [
|
|
80
|
-
- [
|
|
81
|
-
- [
|
|
82
|
-
- [
|
|
83
|
-
- [
|
|
84
|
-
- [
|
|
85
|
-
- [
|
|
86
|
-
- [
|
|
87
|
-
- [
|
|
79
|
+
- [design.md](docs/design.md) — the design and its reasons
|
|
80
|
+
- [core-semantics.md](docs/core-semantics.md) — core semantics of the kernel
|
|
81
|
+
- [shape-dimension-contract.md](docs/shape-dimension-contract.md) — shape dimensions and how they respond to size
|
|
82
|
+
- [spatial-contracts.md](docs/spatial-contracts.md) — spatial contracts
|
|
83
|
+
- [motion-contract.md](docs/motion-contract.md) — joints, state inputs and drivers
|
|
84
|
+
- [asset-persistence.md](docs/asset-persistence.md) — the stored asset document
|
|
85
|
+
- [authoring-transactions.md](docs/authoring-transactions.md) — authoring commands
|
|
86
|
+
- [capability-bindings.md](docs/capability-bindings.md) — capability bindings
|
|
87
|
+
- [status.md](docs/status.md) — implementation and verification status
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
export interface
|
|
1
|
+
import type { FigureJoint } from './authoring-actions.ts';
|
|
2
|
+
import type { FigureGraph, FigureGeometry, FigurePose, FigureRuntimeValue, FigureValueType } from './graph-types.ts';
|
|
3
|
+
export interface FigureSurfaceReference {
|
|
4
4
|
placement: string;
|
|
5
5
|
feature: string;
|
|
6
6
|
}
|
|
7
|
-
export interface
|
|
7
|
+
export interface FigureBindingDeclaration {
|
|
8
8
|
id: string;
|
|
9
9
|
label: string;
|
|
10
10
|
role: 'seat' | 'grip';
|
|
11
11
|
frame: string;
|
|
12
|
-
pose: string |
|
|
12
|
+
pose: string | FigureSurfaceReference;
|
|
13
13
|
accepts: string[];
|
|
14
14
|
capacity: number;
|
|
15
15
|
region?: {
|
|
16
16
|
kind: 'centered-box';
|
|
17
17
|
dimensions: [string, string, string];
|
|
18
18
|
};
|
|
19
|
-
contacts?:
|
|
19
|
+
contacts?: FigureSurfaceReference[];
|
|
20
20
|
}
|
|
21
|
-
export interface
|
|
21
|
+
export interface FigureCapabilities {
|
|
22
22
|
version: 'r3-capability-3';
|
|
23
23
|
assetFrame: string;
|
|
24
|
-
bindings:
|
|
24
|
+
bindings: FigureBindingDeclaration[];
|
|
25
25
|
/**
|
|
26
26
|
* What the figure can do, by name, for the scene to attach behaviour (ADR-0051 ④, ADR-0087 decision 3).
|
|
27
27
|
* Every name must be in `FIGURE_CAPABILITIES`; the check reads that list, it does not copy it.
|
|
@@ -32,7 +32,7 @@ export interface V3Capabilities {
|
|
|
32
32
|
* The volume the author declares the figure occupies, and the face it is mounted on (ADR-0044, ADR-0045,
|
|
33
33
|
* ADR-0087 decision 3).
|
|
34
34
|
*
|
|
35
|
-
* **The reach on each side of the asset origin, not an extent rising from it** (
|
|
35
|
+
* **The reach on each side of the asset origin, not an extent rising from it** (designer's ruling
|
|
36
36
|
* 2026-09-23). The origin is where the figure is mounted; it is a coordinate reference, not a surface nothing
|
|
37
37
|
* may pass. A robot arm bolted to a bench reaches below the bench, and that is the machine working, not a
|
|
38
38
|
* fault. An extent could only grow upward and outward from the centre, so it could say neither that, nor a
|
|
@@ -40,7 +40,7 @@ export interface V3Capabilities {
|
|
|
40
40
|
*
|
|
41
41
|
* Each of the six names a length value in the graph; `min` is normally negative below or left of the origin.
|
|
42
42
|
* A part outside the declared volume, or a floor figure whose parts do not reach the plane it is mounted on,
|
|
43
|
-
* is a release violation reported by `
|
|
43
|
+
* is a release violation reported by `inspectFigureAsset`.
|
|
44
44
|
*
|
|
45
45
|
* What this is not: a rule about what the figure may do. It describes the room the figure takes up. Whether
|
|
46
46
|
* that room is free is the scene's question, against the real obstacles it has placed.
|
|
@@ -50,9 +50,9 @@ export interface V3Capabilities {
|
|
|
50
50
|
* plane Y = 0 -- a part stands on it by its bottom or hangs from it by its top; a wall is the plane Z = 0, the figure
|
|
51
51
|
* coming out of it along +Z, a part fastened to it by its back; `center` has no plane of its own.
|
|
52
52
|
*/
|
|
53
|
-
export type
|
|
54
|
-
export declare const
|
|
55
|
-
export interface
|
|
53
|
+
export type FigurePlacement = 'floor' | 'ceiling' | 'center' | 'wall';
|
|
54
|
+
export declare const FIGURE_PLACEMENTS: readonly FigurePlacement[];
|
|
55
|
+
export interface FigureOccupancy {
|
|
56
56
|
bounds: {
|
|
57
57
|
x: {
|
|
58
58
|
min: string;
|
|
@@ -67,9 +67,8 @@ export interface V3Occupancy {
|
|
|
67
67
|
max: string;
|
|
68
68
|
};
|
|
69
69
|
};
|
|
70
|
-
placement: V3Placement;
|
|
71
70
|
/**
|
|
72
|
-
* The face of the figure that lies on the plane it is mounted on (
|
|
71
|
+
* The face of the figure that lies on the plane it is mounted on (designer's ruling 2026-09-23).
|
|
73
72
|
*
|
|
74
73
|
* Absent means the figure is not asked to touch anything. The origin is a coordinate reference, not a surface
|
|
75
74
|
* the drawing must reach: a figure may be fastened through a bracket nobody drew, or by a mounting structure
|
|
@@ -80,75 +79,75 @@ export interface V3Occupancy {
|
|
|
80
79
|
* asking for it is a one-sided position test, which passes a body that hangs entirely below the plane and fails
|
|
81
80
|
* a design that reaches under it on purpose. It is also the smallest gap over the parts, which folds, so it
|
|
82
81
|
* could not be settled over a state range. One named face is a single equality and settles both
|
|
83
|
-
* (
|
|
82
|
+
* (designer's ruling 2026-09-23, after two counterexamples).
|
|
84
83
|
*/
|
|
85
84
|
contact?: {
|
|
86
85
|
plane: 'mounting-plane';
|
|
87
|
-
surface:
|
|
86
|
+
surface: FigureSurfaceReference;
|
|
88
87
|
};
|
|
89
88
|
}
|
|
90
|
-
export interface
|
|
91
|
-
version: 'figure-
|
|
92
|
-
model:
|
|
93
|
-
capabilities:
|
|
89
|
+
export interface FigureDocument {
|
|
90
|
+
version: 'figure-prototype-1';
|
|
91
|
+
model: FigureGraph;
|
|
92
|
+
capabilities: FigureCapabilities;
|
|
94
93
|
}
|
|
95
|
-
export interface
|
|
94
|
+
export interface FigureBindingRequest {
|
|
96
95
|
type: string;
|
|
97
96
|
occupied: number;
|
|
98
97
|
}
|
|
99
|
-
export type
|
|
98
|
+
export type FigureCheck = {
|
|
100
99
|
status: 'unverified';
|
|
101
100
|
reason: string;
|
|
102
101
|
} | {
|
|
103
102
|
status: 'satisfied' | 'failed';
|
|
104
103
|
reasons?: string[];
|
|
105
104
|
};
|
|
106
|
-
export interface
|
|
105
|
+
export interface FigureEvaluatedSurface extends FigureSurfaceReference {
|
|
107
106
|
geometryId: string;
|
|
108
107
|
provider: string;
|
|
109
108
|
face: string;
|
|
110
|
-
pose:
|
|
109
|
+
pose: FigurePose;
|
|
111
110
|
normal: number[];
|
|
112
111
|
provenance: 'verified-planar-surface';
|
|
113
112
|
}
|
|
114
|
-
export interface
|
|
113
|
+
export interface FigureEvaluatedBinding {
|
|
115
114
|
id: string;
|
|
116
115
|
label: string;
|
|
117
116
|
role: 'seat' | 'grip';
|
|
118
117
|
frame: string;
|
|
119
|
-
pose:
|
|
118
|
+
pose: FigurePose;
|
|
120
119
|
targetGeometryId?: string;
|
|
121
120
|
region: {
|
|
122
121
|
kind: 'centered-box';
|
|
123
122
|
dimensions: number[];
|
|
124
123
|
} | null;
|
|
125
|
-
contacts:
|
|
124
|
+
contacts: FigureEvaluatedSurface[];
|
|
126
125
|
checks: {
|
|
127
|
-
declaration:
|
|
128
|
-
eligibility:
|
|
129
|
-
spatial:
|
|
130
|
-
collision:
|
|
131
|
-
safety:
|
|
126
|
+
declaration: FigureCheck;
|
|
127
|
+
eligibility: FigureCheck;
|
|
128
|
+
spatial: FigureCheck;
|
|
129
|
+
collision: FigureCheck;
|
|
130
|
+
safety: FigureCheck;
|
|
132
131
|
};
|
|
133
132
|
}
|
|
134
|
-
export interface
|
|
135
|
-
geometry:
|
|
136
|
-
bindings:
|
|
133
|
+
export interface FigureCapabilityEvaluation {
|
|
134
|
+
geometry: FigureGeometry[];
|
|
135
|
+
bindings: FigureEvaluatedBinding[];
|
|
137
136
|
/** Every value the graph produced, so a reader can resolve a reference it declared (such as a visibility flag). */
|
|
138
|
-
values: Record<string,
|
|
137
|
+
values: Record<string, FigureRuntimeValue>;
|
|
139
138
|
}
|
|
140
|
-
export interface
|
|
139
|
+
export interface FigureCompiledCapabilities {
|
|
141
140
|
/** The compiled graph's value types, so a reader can check what a reference names before evaluating. */
|
|
142
|
-
outputTypes: Record<string,
|
|
141
|
+
outputTypes: Record<string, FigureValueType>;
|
|
143
142
|
/** Which state inputs each value depends on (shape-dimension contract §2). */
|
|
144
143
|
dependence: Record<string, string[]>;
|
|
145
|
-
evaluate(inputs: Record<string, number>, requests?: Record<string,
|
|
144
|
+
evaluate(inputs: Record<string, number>, requests?: Record<string, FigureBindingRequest>): FigureCapabilityEvaluation;
|
|
146
145
|
/** An evaluator for one instance: it keeps its last evaluation and runs again only what changed since. */
|
|
147
146
|
evaluator(): {
|
|
148
|
-
evaluate(inputs: Record<string, number>, requests?: Record<string,
|
|
147
|
+
evaluate(inputs: Record<string, number>, requests?: Record<string, FigureBindingRequest>): FigureCapabilityEvaluation;
|
|
149
148
|
};
|
|
150
149
|
}
|
|
151
|
-
export interface
|
|
150
|
+
export interface FigureMaterial {
|
|
152
151
|
token: string;
|
|
153
152
|
preset?: 'default' | 'metal' | 'glass' | 'plastic' | 'wood' | 'ceramic' | 'rubber';
|
|
154
153
|
transparent?: boolean;
|
|
@@ -158,12 +157,12 @@ export interface V3Material {
|
|
|
158
157
|
on: boolean;
|
|
159
158
|
};
|
|
160
159
|
}
|
|
161
|
-
export interface
|
|
160
|
+
export interface FigureAppearance {
|
|
162
161
|
target: string;
|
|
163
|
-
material:
|
|
162
|
+
material: FigureMaterial;
|
|
164
163
|
segments?: number;
|
|
165
164
|
/**
|
|
166
|
-
* A `flag` value in the graph saying whether this part is shown (
|
|
165
|
+
* A `flag` value in the graph saying whether this part is shown (designer's ruling 2026-09-22).
|
|
167
166
|
* Absent means always shown.
|
|
168
167
|
*
|
|
169
168
|
* The evaluation contract for a hidden part:
|
|
@@ -176,10 +175,10 @@ export interface V3Appearance {
|
|
|
176
175
|
visibility?: string;
|
|
177
176
|
}
|
|
178
177
|
/**
|
|
179
|
-
* A driver computes one state input from time (docs/
|
|
178
|
+
* A driver computes one state input from time (docs/motion-contract.md). The kernel never sees time; the
|
|
180
179
|
* consumer that owns time calls `driverValue` and writes the result into the state input it names.
|
|
181
180
|
*/
|
|
182
|
-
export interface
|
|
181
|
+
export interface FigureDriver {
|
|
183
182
|
/** An opaque identifier, unique among the asset's drivers. Nothing is read out of its spelling. */
|
|
184
183
|
id: string;
|
|
185
184
|
/**
|
|
@@ -206,9 +205,9 @@ export interface V3Driver {
|
|
|
206
205
|
}
|
|
207
206
|
/**
|
|
208
207
|
* What a person sees for a state input, and how the figure moves toward a new value for it
|
|
209
|
-
* (
|
|
208
|
+
* (designer's ruling 2026-09-22). Keyed by the input's id, which stays the stable identifier.
|
|
210
209
|
*/
|
|
211
|
-
export interface
|
|
210
|
+
export interface FigureStateInputPolicy {
|
|
212
211
|
/** The name shown to a person. Kept apart from the id so renaming the label never renames the input. */
|
|
213
212
|
label?: string;
|
|
214
213
|
/**
|
|
@@ -220,18 +219,25 @@ export interface V3StateInputPolicy {
|
|
|
220
219
|
*/
|
|
221
220
|
sweep?: number;
|
|
222
221
|
}
|
|
223
|
-
export interface
|
|
224
|
-
version: 'figure-
|
|
222
|
+
export interface FigureAsset {
|
|
223
|
+
version: 'figure-asset-1';
|
|
225
224
|
name: string;
|
|
226
|
-
document:
|
|
225
|
+
document: FigureDocument;
|
|
227
226
|
designInputs: Record<string, number>;
|
|
228
227
|
stateDefaults: Record<string, number>;
|
|
229
228
|
palette: Record<string, string>;
|
|
230
|
-
appearance:
|
|
231
|
-
occupancy?:
|
|
232
|
-
|
|
229
|
+
appearance: FigureAppearance[];
|
|
230
|
+
occupancy?: FigureOccupancy;
|
|
231
|
+
/**
|
|
232
|
+
* Where the figure is authored from -- the floor, the ceiling, a wall or its centre (ADR-0097, designer 2026-09-27).
|
|
233
|
+
* The figure's own setting, apart from the room it declares: it can be chosen before there is a part to measure.
|
|
234
|
+
* Left out, the figure stands on the floor. An asset written before stored it in `occupancy.placement`;
|
|
235
|
+
* `upgradeFigurePlacement` moves it here when the asset is read.
|
|
236
|
+
*/
|
|
237
|
+
placement?: FigurePlacement;
|
|
238
|
+
drivers?: FigureDriver[];
|
|
233
239
|
/** Per state input: its display label and its transition time. Inputs absent here have neither. */
|
|
234
|
-
stateInputs?: Record<string,
|
|
240
|
+
stateInputs?: Record<string, FigureStateInputPolicy>;
|
|
235
241
|
/**
|
|
236
242
|
* How the figure grows when a board gives it another size. Absent: each part follows its own rules. `uniform`:
|
|
237
243
|
* the whole figure by one ratio, the geometric mean of the three axes' -- a mechanism does not shear (chief
|
|
@@ -245,18 +251,18 @@ export interface V3Asset {
|
|
|
245
251
|
*/
|
|
246
252
|
detailLevel?: 'S' | 'M' | 'L';
|
|
247
253
|
/**
|
|
248
|
-
* The joints, URDF's records with
|
|
254
|
+
* The joints, URDF's records with values (ADR-0093): the canon of how parts hang together and move. Their graph
|
|
249
255
|
* nodes are made from them; an asset whose nodes disagree with them is refused on reading.
|
|
250
256
|
*/
|
|
251
|
-
joints?:
|
|
257
|
+
joints?: FigureJoint[];
|
|
252
258
|
/**
|
|
253
259
|
* The design inputs a board may set per instance, chosen by the figure's author (ADR-0096): a roller row's pitch.
|
|
254
260
|
* Each points at an input of the model; its unit, default and range are the input's own. Not the size inputs (a
|
|
255
261
|
* board sets the size from its bounds), not state inputs, and only inputs with a finite range.
|
|
256
262
|
*/
|
|
257
|
-
publicInputs?:
|
|
263
|
+
publicInputs?: FigurePublicInput[];
|
|
258
264
|
}
|
|
259
|
-
export interface
|
|
265
|
+
export interface FigurePublicInput {
|
|
260
266
|
/** The design input's id. */
|
|
261
267
|
input: string;
|
|
262
268
|
/** The name shown to a person on a board. */
|
|
@@ -264,17 +270,17 @@ export interface V3PublicInput {
|
|
|
264
270
|
/** One line on what it sets. */
|
|
265
271
|
hint?: string;
|
|
266
272
|
}
|
|
267
|
-
export type
|
|
273
|
+
export type FigureAssetGeometry = FigureGeometry & Omit<FigureAppearance, 'target' | 'visibility'> & {
|
|
268
274
|
/** Whether the consumer draws this body. False bodies are still evaluated, placed and gated. */
|
|
269
275
|
visible: boolean;
|
|
270
276
|
};
|
|
271
|
-
export interface
|
|
272
|
-
geometry:
|
|
273
|
-
bindings:
|
|
277
|
+
export interface FigureAssetEvaluation {
|
|
278
|
+
geometry: FigureAssetGeometry[];
|
|
279
|
+
bindings: FigureEvaluatedBinding[];
|
|
274
280
|
inputs: Record<string, number>;
|
|
275
281
|
palette: Record<string, string>;
|
|
276
282
|
}
|
|
277
|
-
export interface
|
|
278
|
-
evaluate(stateOverrides?: Record<string, number>):
|
|
283
|
+
export interface FigureCompiledAsset {
|
|
284
|
+
evaluate(stateOverrides?: Record<string, number>): FigureAssetEvaluation;
|
|
279
285
|
}
|
|
280
|
-
//# sourceMappingURL=
|
|
286
|
+
//# sourceMappingURL=asset-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-types.d.ts","sourceRoot":"","sources":["../src/asset-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-types.js","sourceRoot":"","sources":["../src/asset-types.ts"],"names":[],"mappings":"AAoDA,MAAM,CAAC,MAAM,iBAAiB,GAA+B,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA"}
|
package/dist/asset.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FigureAsset, FigureCompiledAsset } from './asset-types.ts';
|
|
2
|
+
import { type FigurePlacement } from './asset-types.ts';
|
|
3
|
+
export declare function compileFigureAsset(source: unknown): FigureCompiledAsset;
|
|
4
|
+
/**
|
|
5
|
+
* An asset written before the placement was its own setting kept it in the room it declared (`occupancy.placement`).
|
|
6
|
+
* Read, it is moved to `placement` -- the one place it is kept now (ADR-0097, designer 2026-09-27: 「두 곳에 서로 다른
|
|
7
|
+
* 배치 값을 유지하지 않는다」). Released snapshots are not rewritten; they are read this way. An asset holding both,
|
|
8
|
+
* differently, is refused: which one was meant cannot be told. Returns the asset itself when there is nothing to move.
|
|
9
|
+
*/
|
|
10
|
+
export declare function upgradeFigurePlacement<T>(source: T): T;
|
|
11
|
+
/** Where the figure is authored from: its own setting, or the floor when it names none. */
|
|
12
|
+
export declare function figurePlacementOf(asset: {
|
|
13
|
+
placement?: FigurePlacement;
|
|
14
|
+
}): FigurePlacement;
|
|
15
|
+
export declare function serializeFigureAsset(asset: unknown): string;
|
|
16
|
+
export declare function parseFigureAsset(text: string): FigureAsset;
|
|
17
|
+
export declare function captureFigureAuthoredInputs(asset: FigureAsset, inputs: Record<string, number>, options?: {
|
|
18
|
+
captureStateDefaults?: boolean;
|
|
19
|
+
}): FigureAsset;
|
|
20
|
+
//# sourceMappingURL=asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../src/asset.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAyB,MAAM,kBAAkB,CAAA;AAC/F,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAc1E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,mBAAmB,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAQtD;AAED,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,eAAe,CAAA;CAAE,GAAG,eAAe,CAEzF;AA4JD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,UAGlD;AACD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAO1D;AACD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,WAAW,CAeb"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Self-contained experimental asset envelope; no product DB/file writes.
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { checkPublicInput } from "./
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { checkFigureJoints } from "./authoring-actions.js";
|
|
3
|
+
import { compileFigureDocument as compileDocument } from "./document.js";
|
|
4
|
+
import { checkPublicInput } from "./public-inputs.js";
|
|
5
|
+
import { assertFigureJson as jsonOnly, parseFigureJson as parseStrictJson, FIGURE_JSON_MAX_BYTES as MAX_BYTES, figureUtf8ByteLength } from "./json.js";
|
|
6
|
+
import { FIGURE_PLACEMENTS } from "./asset-types.js";
|
|
7
|
+
import { FigureContractError as ContractError } from "./contract.js";
|
|
8
|
+
import { validateFigureDrivers, validateFigureStateInputs } from "./driver.js";
|
|
9
|
+
import { resolveFigureSurface } from "./surface.js";
|
|
10
10
|
const fail = (code, path, message) => {
|
|
11
11
|
throw new ContractError(code, path, message);
|
|
12
12
|
};
|
|
@@ -20,15 +20,38 @@ function fields(o, required, optional, path) {
|
|
|
20
20
|
if (![...required, ...optional].includes(k))
|
|
21
21
|
fail('ASSET_SCHEMA', path, `unknown ${k}`);
|
|
22
22
|
}
|
|
23
|
-
export function
|
|
23
|
+
export function compileFigureAsset(source) {
|
|
24
24
|
return compileAsset(source);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
/**
|
|
27
|
+
* An asset written before the placement was its own setting kept it in the room it declared (`occupancy.placement`).
|
|
28
|
+
* Read, it is moved to `placement` -- the one place it is kept now (ADR-0097, designer 2026-09-27: 「두 곳에 서로 다른
|
|
29
|
+
* 배치 값을 유지하지 않는다」). Released snapshots are not rewritten; they are read this way. An asset holding both,
|
|
30
|
+
* differently, is refused: which one was meant cannot be told. Returns the asset itself when there is nothing to move.
|
|
31
|
+
*/
|
|
32
|
+
export function upgradeFigurePlacement(source) {
|
|
33
|
+
const asset = source;
|
|
34
|
+
const old = asset?.occupancy && typeof asset.occupancy === 'object' ? asset.occupancy.placement : undefined;
|
|
35
|
+
if (old === undefined)
|
|
36
|
+
return source;
|
|
37
|
+
if (asset.placement !== undefined && asset.placement !== old)
|
|
38
|
+
fail('PLACEMENT_CONFLICT', 'placement', `the asset says ${String(asset.placement)} and its room says ${String(old)}; keep one`);
|
|
39
|
+
const { placement: _moved, ...occupancy } = asset.occupancy;
|
|
40
|
+
return { ...asset, placement: old, occupancy };
|
|
41
|
+
}
|
|
42
|
+
/** Where the figure is authored from: its own setting, or the floor when it names none. */
|
|
43
|
+
export function figurePlacementOf(asset) {
|
|
44
|
+
return asset.placement ?? 'floor';
|
|
45
|
+
}
|
|
46
|
+
function compileAsset(given) {
|
|
47
|
+
jsonOnly(given);
|
|
48
|
+
const source = upgradeFigurePlacement(given);
|
|
49
|
+
if (figureUtf8ByteLength(JSON.stringify(source)) > MAX_BYTES)
|
|
29
50
|
fail('DOCUMENT_LIMIT', 'asset', 'over 1 MiB');
|
|
30
|
-
fields(source, ['version', 'name', 'document', 'designInputs', 'stateDefaults', 'palette', 'appearance'], ['occupancy', 'drivers', 'stateInputs', 'sizing', 'detailLevel', 'joints', 'publicInputs'], 'asset');
|
|
31
|
-
if (source.
|
|
51
|
+
fields(source, ['version', 'name', 'document', 'designInputs', 'stateDefaults', 'palette', 'appearance'], ['occupancy', 'placement', 'drivers', 'stateInputs', 'sizing', 'detailLevel', 'joints', 'publicInputs'], 'asset');
|
|
52
|
+
if (source.placement !== undefined && !FIGURE_PLACEMENTS.includes(source.placement))
|
|
53
|
+
fail('ASSET_SCHEMA', 'placement', `one of ${FIGURE_PLACEMENTS.join(', ')} required`);
|
|
54
|
+
if (source.version !== 'figure-asset-1')
|
|
32
55
|
fail('VERSION', 'asset', source.version);
|
|
33
56
|
if (typeof source.name !== 'string' || !source.name.trim())
|
|
34
57
|
fail('ASSET_SCHEMA', 'name', 'nonempty name required');
|
|
@@ -114,15 +137,15 @@ function compileAsset(source) {
|
|
|
114
137
|
if (looks.size !== placements.size)
|
|
115
138
|
fail('APPEARANCE_MISSING', 'appearance', 'every source placement/member requires appearance');
|
|
116
139
|
if (asset.occupancy !== undefined) {
|
|
117
|
-
// ADR-0044 · ADR-0045
|
|
118
|
-
fields(asset.occupancy, ['bounds'
|
|
140
|
+
// ADR-0044 · ADR-0045: the declared volume names three length values. The placement is the asset's own (ADR-0097).
|
|
141
|
+
fields(asset.occupancy, ['bounds'], ['contact'], 'occupancy');
|
|
119
142
|
if (asset.occupancy.contact !== undefined) {
|
|
120
143
|
const contact = asset.occupancy.contact;
|
|
121
144
|
fields(contact, ['plane', 'surface'], [], 'occupancy.contact');
|
|
122
145
|
if (contact.plane !== 'mounting-plane')
|
|
123
146
|
fail('OCCUPANCY', 'occupancy.contact', `${String(contact.plane)} is not a plane the figure can be mounted on`);
|
|
124
147
|
// The same reader the capability contacts use, so a mounting face is a real planar face of a drawn body.
|
|
125
|
-
|
|
148
|
+
resolveFigureSurface({ types: plan.outputTypes, writers, model, assetFrame: asset.document.capabilities.assetFrame }, contact.surface, 'occupancy.contact.surface');
|
|
126
149
|
}
|
|
127
150
|
fields(asset.occupancy.bounds, ['x', 'y', 'z'], [], 'occupancy.bounds');
|
|
128
151
|
const lengthType = JSON.stringify([1, 0, 0]);
|
|
@@ -138,18 +161,16 @@ function compileAsset(source) {
|
|
|
138
161
|
fail('OCCUPANCY_STATE', path, `${ref} depends on state input ${plan.dependence[ref].join(', ')}; the occupancy is state-independent`);
|
|
139
162
|
}
|
|
140
163
|
}
|
|
141
|
-
if (!V3_PLACEMENTS.includes(asset.occupancy.placement))
|
|
142
|
-
fail('OCCUPANCY', 'occupancy.placement', `one of ${V3_PLACEMENTS.join(', ')} required`);
|
|
143
164
|
}
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
validateFigureDrivers(asset);
|
|
166
|
+
validateFigureStateInputs(asset);
|
|
146
167
|
function evaluate(stateOverrides = {}) {
|
|
147
168
|
fields(stateOverrides, [], state, 'state overrides');
|
|
148
169
|
const inputs = { ...asset.designInputs, ...asset.stateDefaults, ...stateOverrides }, r = plan.evaluate(inputs);
|
|
149
170
|
const targetOf = (g) => (g.key ? writers.get(g.key)?.id : g.id);
|
|
150
171
|
/*
|
|
151
172
|
Bodies come back in the appearance order — the parts list's order, and the order they are drawn in. The graph
|
|
152
|
-
lists nodes in whatever order they were written, so a list that followed it could not be reordered (the
|
|
173
|
+
lists nodes in whatever order they were written, so a list that followed it could not be reordered (the
|
|
153
174
|
modeller's 「위로」 did nothing, 2026-09-24). The sort is stable: a repeated template's members keep their order.
|
|
154
175
|
*/
|
|
155
176
|
const rank = new Map(asset.appearance.map((look, i) => [look.target, i]));
|
|
@@ -173,20 +194,20 @@ function compileAsset(source) {
|
|
|
173
194
|
evaluate(); // Stored design and state defaults must themselves be executable.
|
|
174
195
|
return { evaluate };
|
|
175
196
|
}
|
|
176
|
-
export function
|
|
197
|
+
export function serializeFigureAsset(asset) {
|
|
177
198
|
compileAsset(asset);
|
|
178
199
|
return JSON.stringify(asset);
|
|
179
200
|
}
|
|
180
|
-
export function
|
|
181
|
-
const asset = parseStrictJson(text);
|
|
201
|
+
export function parseFigureAsset(text) {
|
|
202
|
+
const asset = upgradeFigurePlacement(parseStrictJson(text));
|
|
182
203
|
compileAsset(asset);
|
|
183
204
|
if (asset.joints !== undefined && !Array.isArray(asset.joints))
|
|
184
205
|
fail('ASSET_SCHEMA', 'joints', 'joints is a list');
|
|
185
206
|
// The joint records are the canon; nodes edited apart from them are refused (ADR-0093).
|
|
186
|
-
|
|
207
|
+
checkFigureJoints(asset);
|
|
187
208
|
return asset;
|
|
188
209
|
}
|
|
189
|
-
export function
|
|
210
|
+
export function captureFigureAuthoredInputs(asset, inputs, options = {}) {
|
|
190
211
|
fields(options, [], ['captureStateDefaults'], 'capture options');
|
|
191
212
|
const captureStateDefaults = options.captureStateDefaults ?? false;
|
|
192
213
|
if (typeof captureStateDefaults !== 'boolean')
|
|
@@ -205,4 +226,4 @@ export function captureV3AuthoredInputs(asset, inputs, options = {}) {
|
|
|
205
226
|
compileAsset(next);
|
|
206
227
|
return next;
|
|
207
228
|
}
|
|
208
|
-
//# sourceMappingURL=
|
|
229
|
+
//# sourceMappingURL=asset.js.map
|