@things-factory/figure-ui 10.1.208 → 10.1.211
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/client/modeller/data-interface.ts +5 -5
- package/client/modeller/editor.ts +97 -88
- package/client/modeller/fasten-geometry.ts +2 -1
- package/client/modeller/figure-links.ts +87 -157
- package/client/modeller/figure-size-editor.ts +233 -0
- package/client/modeller/joint-drag.ts +25 -21
- package/client/modeller/joint-fan.ts +4 -3
- package/client/modeller/links.ts +87 -36
- package/client/modeller/live.ts +33 -0
- package/client/modeller/motion-ends.ts +10 -6
- package/client/modeller/size-response.ts +95 -0
- package/dist-client/modeller/data-interface.d.ts +1 -1
- package/dist-client/modeller/data-interface.js +5 -5
- package/dist-client/modeller/data-interface.js.map +1 -1
- package/dist-client/modeller/editor.d.ts +14 -1
- package/dist-client/modeller/editor.js +103 -89
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/fasten-geometry.js +1 -1
- package/dist-client/modeller/fasten-geometry.js.map +1 -1
- package/dist-client/modeller/figure-links.d.ts +3 -4
- package/dist-client/modeller/figure-links.js +91 -145
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/figure-size-editor.d.ts +29 -0
- package/dist-client/modeller/figure-size-editor.js +262 -0
- package/dist-client/modeller/figure-size-editor.js.map +1 -0
- package/dist-client/modeller/joint-drag.d.ts +1 -1
- package/dist-client/modeller/joint-drag.js +27 -22
- package/dist-client/modeller/joint-drag.js.map +1 -1
- package/dist-client/modeller/joint-fan.js +4 -3
- package/dist-client/modeller/joint-fan.js.map +1 -1
- package/dist-client/modeller/links.d.ts +21 -9
- package/dist-client/modeller/links.js +85 -35
- package/dist-client/modeller/links.js.map +1 -1
- package/dist-client/modeller/live.d.ts +14 -0
- package/dist-client/modeller/live.js +31 -0
- package/dist-client/modeller/live.js.map +1 -1
- package/dist-client/modeller/motion-ends.d.ts +4 -1
- package/dist-client/modeller/motion-ends.js +10 -6
- package/dist-client/modeller/motion-ends.js.map +1 -1
- package/dist-client/modeller/size-response.d.ts +29 -0
- package/dist-client/modeller/size-response.js +99 -0
- package/dist-client/modeller/size-response.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/docs/evidence/2026-10-24/current-size-panel.png +0 -0
- package/docs/evidence/2026-10-24/integrated-size.png +0 -0
- package/docs/evidence/2026-10-24/multipart-response.png +0 -0
- package/docs/evidence/2026-10-24/repeat-layout.png +0 -0
- package/docs/evidence/2026-10-24/repeat-shared-style.png +0 -0
- package/docs/evidence/2026-10-24/size-in-layout.png +0 -0
- package/docs/evidence/2026-10-24/size-shared-style.png +0 -0
- package/docs/evidence/2026-10-24/width-preview.png +0 -0
- package/docs/multipart-response-review-2026-10-24.md +77 -0
- package/docs/response-authoring-2026-10-24.md +46 -0
- package/docs/size-and-repeat-ux-2026-10-24.md +67 -0
- package/package.json +7 -7
- package/test/attachment-size-contract.test.ts +47 -0
- package/test/browser/acceptance-page.js +1 -1
- package/test/browser/detail-page.js +1 -1
- package/test/browser/detail-tabs-page.js +1 -1
- package/test/browser/editing-page.js +1 -1
- package/test/browser/editing.check.mjs +66 -14
- package/test/browser/links.check.mjs +41 -22
- package/test/browser/modeller-page.js +1 -1
- package/test/browser/modeller-revision.check.mjs +21 -7
- package/test/browser/modeller.check.mjs +106 -39
- package/test/browser/multipart-response-page.js +8 -0
- package/test/browser/parts.check.mjs +2 -1
- package/test/browser/product-page.js +1 -1
- package/test/browser/props.check.mjs +17 -14
- package/test/browser/response-page.js +12 -0
- package/test/browser/row-preview.check.mjs +3 -3
- package/test/browser/screen.check.mjs +57 -13
- package/test/browser/serve-response.mjs +24 -0
- package/test/clip-ai-proposal.test.ts +1 -1
- package/test/clip-consent.test.ts +2 -2
- package/test/command-preview.test.ts +7 -7
- package/test/joint-drag.test.ts +6 -6
- package/test/joint-frames.test.ts +33 -32
- package/test/joints.ts +1 -6
- package/test/links.test.ts +60 -20
- package/test/multipart-response-fixture.js +17 -0
- package/test/multipart-response.test.ts +37 -0
- package/test/refusals.test.ts +2 -2
- package/test/resize-with-placement.test.ts +23 -1
- package/test/size-response.test.ts +49 -0
- package/test/size-source-pairing.test.ts +66 -0
- package/translations/en.json +47 -10
- package/translations/es.json +47 -10
- package/translations/ja.json +47 -10
- package/translations/ko.json +52 -15
- package/translations/ms.json +47 -10
- package/translations/zh.json +47 -10
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { figureAxisPairsOf, figurePartsExtentOf, figureShapeProviderOf } from '@hatiolab/figure-model'
|
|
2
|
+
import type { FigureAsset, FigureAuthoringAction, FigureDimensionSource } from '@hatiolab/figure-model'
|
|
3
|
+
import type { FigureRevision } from './revision.js'
|
|
4
|
+
import { dimensionNow, followOf, followableAxes, measureNow, type Axis } from './links.js'
|
|
5
|
+
|
|
6
|
+
export type SizeMode = 'ratio' | 'difference' | 'custom'
|
|
7
|
+
export type SizeSource = Extract<FigureDimensionSource, { of: 'instance' | 'part' }>
|
|
8
|
+
|
|
9
|
+
function editOf(asset: FigureAsset, part: string, axis: Axis) {
|
|
10
|
+
const shape = asset.document.model.nodes.find(n => n.id === `${part}.shape`)
|
|
11
|
+
const edit = shape && figureShapeProviderOf(shape)?.edit[axis]
|
|
12
|
+
return shape && edit && !('refused' in edit) ? { shape, edit } : undefined
|
|
13
|
+
}
|
|
14
|
+
export const measureFactor = (asset: FigureAsset, part: string, axis: Axis) => editOf(asset, part, axis)?.edit.k ?? 1
|
|
15
|
+
|
|
16
|
+
/** Only expose direct own inputs (including the canonical identity wrapper). Never overwrite an arbitrary expression. */
|
|
17
|
+
export function sizeInputOf(asset: FigureAsset, part: string, axis: Axis): string | undefined {
|
|
18
|
+
const e = editOf(asset, part, axis)
|
|
19
|
+
if (!e) return undefined
|
|
20
|
+
const model = asset.document.model
|
|
21
|
+
let ref = e.shape.args[e.edit.arg]
|
|
22
|
+
const seen = new Set<string>()
|
|
23
|
+
while (ref && !seen.has(ref)) {
|
|
24
|
+
seen.add(ref)
|
|
25
|
+
if (model.inputs.some(i => i.id === ref && i.role === 'design' && i.unit === 'mm') && ref.startsWith(`${part}.`)) return ref
|
|
26
|
+
const writer = model.nodes.find(n => Object.values(n.outputs).includes(ref!))
|
|
27
|
+
if (writer?.op !== 'mul@1' || model.constants.find(c => c.id === writer.args[1])?.value !== 1) return undefined
|
|
28
|
+
ref = writer.args[0]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function sizeRelationOf(revision: FigureRevision, part: string, axis: Axis): { source?: SizeSource; mode: SizeMode; variable: boolean } {
|
|
32
|
+
const f = followOf(revision.asset, part, axis)
|
|
33
|
+
if (f.of === 'own') return { mode: 'ratio', variable: false }
|
|
34
|
+
if (f.of !== 'instance' && f.of !== 'part') return { mode: 'custom', variable: true }
|
|
35
|
+
const source: SizeSource = f.of === 'instance' ? { of: 'instance', axis: f.axis } : { of: 'part', part: f.part, axis: f.axis }
|
|
36
|
+
const equalFactor = (source.of === 'part' ? measureFactor(revision.asset, source.part, source.axis) : 1) / measureFactor(revision.asset, part, axis)
|
|
37
|
+
const mode = !(f.plus ?? 0) ? 'ratio' : Math.abs((f.times ?? 1) - equalFactor) < 1e-6 ? 'difference' : 'custom'
|
|
38
|
+
return { source, mode, variable: true }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* What a measure follows when it is first made to follow (ADR-0159 3): what the part hangs from, along the axis its own
|
|
43
|
+
* axis lies on as it stands -- a roller laid on its side follows the frame's depth with its length, not the frame's
|
|
44
|
+
* height (the axes paired by figure-model, `figureAxisPairsOf`, never by their letters). On the mounting plane, or
|
|
45
|
+
* fastened to nothing, the figure's size. Nothing when it lies at an angle, or the parent has no measure along that
|
|
46
|
+
* axis: the author picks. Only a suggestion when a relation is made; a measure that already follows something keeps it.
|
|
47
|
+
*/
|
|
48
|
+
export function suggestedSizeSource(asset: FigureAsset, part: string, axis: Axis): SizeSource | undefined {
|
|
49
|
+
const { parent, along } = figureAxisPairsOf(asset, part)
|
|
50
|
+
const on = along[axis]?.axis
|
|
51
|
+
if (!on) return undefined
|
|
52
|
+
if (!parent) return { of: 'instance', axis: on }
|
|
53
|
+
return followableAxes(asset, parent).includes(on) ? { of: 'part', part: parent, axis: on } : undefined
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Whether two sources are one: the same part, or the figure, and the same axis. */
|
|
57
|
+
export const sameSizeSource = (a: SizeSource | undefined, b: SizeSource | undefined) =>
|
|
58
|
+
!!a && !!b && a.of === b.of && a.axis === b.axis && (a.of !== 'part' || (b.of === 'part' && a.part === b.part))
|
|
59
|
+
|
|
60
|
+
/** How long the source is now, in millimetres as the panel shows it (a radius read as a diameter). */
|
|
61
|
+
export function sourceMeasureOf(revision: FigureRevision, source: SizeSource): number | undefined {
|
|
62
|
+
if (source.of === 'instance') return revision.asset.designInputs[`size.${source.axis}`] ?? figurePartsExtentOf(revision.asset)[source.axis]
|
|
63
|
+
return measureNow(revision, source.part, source.axis)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Preserve the displayed size when choosing a source or mode. mm edits change only that row's relation. */
|
|
67
|
+
export function sizeRelationSteps(revision: FigureRevision, part: string, axis: Axis, source: SizeSource, mode: Exclude<SizeMode, 'custom'>, mm = measureNow(revision, part, axis)): FigureAuthoringAction[] {
|
|
68
|
+
if (!(typeof mm === 'number' && Number.isFinite(mm) && mm > 0)) throw Error('SIZE_VALUE')
|
|
69
|
+
if (source.of === 'part' && source.part === part) throw Error('SIZE_SOURCE')
|
|
70
|
+
const asset = revision.asset
|
|
71
|
+
const steps: FigureAuthoringAction[] = []
|
|
72
|
+
let raw: number | undefined
|
|
73
|
+
let sourceFactor = 1
|
|
74
|
+
if (source.of === 'instance') {
|
|
75
|
+
const declared = asset.document.model.inputs.some(i => i.id === `size.${source.axis}` && i.role === 'design')
|
|
76
|
+
if (declared) raw = asset.designInputs[`size.${source.axis}`]
|
|
77
|
+
else {
|
|
78
|
+
// Do not replace an existing partial size declaration while configuring an unrelated axis.
|
|
79
|
+
if (asset.document.model.inputs.some(i => /^size\.[xyz]$/.test(i.id))) throw Error('SIZE_SOURCE')
|
|
80
|
+
const at = figurePartsExtentOf(asset)
|
|
81
|
+
steps.push({ kind: 'declare-instance-size', at })
|
|
82
|
+
raw = at[source.axis]
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
if (!followableAxes(asset, source.part).includes(source.axis)) throw Error('SIZE_SOURCE')
|
|
86
|
+
raw = dimensionNow(revision, source.part, source.axis)
|
|
87
|
+
sourceFactor = measureFactor(asset, source.part, source.axis)
|
|
88
|
+
}
|
|
89
|
+
if (!(typeof raw === 'number' && raw > 0 && Number.isFinite(raw))) throw Error('SIZE_SOURCE')
|
|
90
|
+
const ownFactor = measureFactor(asset, part, axis)
|
|
91
|
+
const times = mode === 'ratio' ? mm / ownFactor / raw : sourceFactor / ownFactor
|
|
92
|
+
const plus = mode === 'difference' ? (mm - raw * sourceFactor) / ownFactor : 0
|
|
93
|
+
steps.push({ kind: 'link-dimension', part, axis, source, times, ...(plus ? { plus } : {}), replace: true })
|
|
94
|
+
return steps
|
|
95
|
+
}
|
|
@@ -78,7 +78,7 @@ export interface EndlessJoint {
|
|
|
78
78
|
label: string;
|
|
79
79
|
unit: 'deg' | 'rad';
|
|
80
80
|
}
|
|
81
|
-
/** The
|
|
81
|
+
/** The axes that turn without end: revolute, with no limits, following no one (ADR-0159: every axis of every joint). */
|
|
82
82
|
export declare function endlessJointsOf(asset: FigureAsset): EndlessJoint[];
|
|
83
83
|
/** What the rotation card is told: the joint, and the data fields that turn it on, set its speed and its direction. */
|
|
84
84
|
export interface RotationChoice {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* of data is things-scene's; this only lists what there is to choose, drafts a binding the kernel then checks, and edits
|
|
5
5
|
* the schema as a tree. Kept apart from the element so it is tested without a browser.
|
|
6
6
|
*/
|
|
7
|
-
import { FIGURE_PART_ID, FIGURE_MOTION_SPEED_MAX, FigureContractError, figureDataRows, parseFigureAccessor } from '@hatiolab/figure-model';
|
|
7
|
+
import { FIGURE_PART_ID, FIGURE_MOTION_SPEED_MAX, FigureContractError, figureAxesOf, figureDataRows, motionStateIdOf, parseFigureAccessor } from '@hatiolab/figure-model';
|
|
8
8
|
import { FigureInputs } from '@hatiolab/things-scene';
|
|
9
9
|
export const behaviorKeyOf = (b) => b.kind === 'state'
|
|
10
10
|
? `state:${b.input}`
|
|
@@ -269,13 +269,13 @@ export function motionWrittenByData(asset) {
|
|
|
269
269
|
}
|
|
270
270
|
return out;
|
|
271
271
|
}
|
|
272
|
-
/** The
|
|
272
|
+
/** The axes that turn without end: revolute, with no limits, following no one (ADR-0159: every axis of every joint). */
|
|
273
273
|
export function endlessJointsOf(asset) {
|
|
274
274
|
const out = [];
|
|
275
|
-
for (const
|
|
276
|
-
if (
|
|
275
|
+
for (const { motion: a } of figureAxesOf(asset.joints)) {
|
|
276
|
+
if (a.type !== 'revolute' || a.lowerLimit !== undefined || a.upperLimit !== undefined || a.mimic)
|
|
277
277
|
continue;
|
|
278
|
-
const input =
|
|
278
|
+
const input = motionStateIdOf(a);
|
|
279
279
|
const unit = asset.document.model.inputs.find(i => i.id === input)?.unit;
|
|
280
280
|
if (unit !== 'deg' && unit !== 'rad')
|
|
281
281
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-interface.js","sourceRoot":"","sources":["../../client/modeller/data-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The figure's data and what it moves (ADR-0051 §8, data binding design appendix A): what the data tab offers and\n * shows. Every rule is figure-model's -- which accessor holds, which rule's results a behavior takes -- and the reading\n * of data is things-scene's; this only lists what there is to choose, drafts a binding the kernel then checks, and edits\n * the schema as a tree. Kept apart from the element so it is tested without a browser.\n */\nimport { FIGURE_PART_ID, FIGURE_MOTION_SPEED_MAX, FigureContractError, figureDataRows, parseFigureAccessor } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureDataBehavior, FigureDataBinding, FigureDataField, FigureDataNode, FigureDataRow, FigureDataValue, FigureDataValueIssue, FigureProposalStep, FigureStatusPort } from '@hatiolab/figure-model'\nimport { FigureInputs, type FigureDataResult } from '@hatiolab/things-scene'\n\n/** Something a binding can move, with what the screen shows of it. */\nexport interface BehaviorChoice {\n /** One string per behavior, for a select's value. */\n key: string\n behavior: FigureDataBehavior\n /** The screen's word for the kind: a control, a colour, a group's clip, … */\n kind: FigureDataBehavior['kind']\n /** The control's label, the colour token, the group's label, the port's label, the axis. */\n name: string\n unit?: string\n min?: number\n max?: number\n}\n\nexport const behaviorKeyOf = (b: FigureDataBehavior): string =>\n b.kind === 'state'\n ? `state:${b.input}`\n : b.kind === 'palette'\n ? `palette:${b.token}`\n : b.kind === 'status'\n ? `status:${b.port}`\n : b.kind === 'pose'\n ? `pose:${b.axis}`\n : b.kind === 'items'\n ? `items:${b.slot ?? ''}`\n : `${b.kind}:${b.group}`\n\n/**\n * Everything the figure can do that data may drive: each control, each colour, each motion group's clip, speed and\n * pause, each status port, its position and heading, and -- when it has places -- the items in them.\n */\nexport function behaviorsOf(asset: FigureAsset): BehaviorChoice[] {\n const out: BehaviorChoice[] = []\n const add = (behavior: FigureDataBehavior, name: string, more: Partial<BehaviorChoice> = {}) => out.push({ key: behaviorKeyOf(behavior), behavior, kind: behavior.kind, name, ...more })\n for (const input of asset.document.model.inputs) {\n if (input.role !== 'state') continue\n add({ kind: 'state', input: input.id, sourceMode: 'observed' }, asset.stateInputs?.[input.id]?.label ?? input.id, { unit: input.unit, min: input.min, max: input.max })\n }\n for (const token of Object.keys(asset.palette)) add({ kind: 'palette', token }, token)\n for (const group of asset.motionGroups ?? []) {\n add({ kind: 'motion-clip', group: group.id }, group.label)\n add({ kind: 'motion-speed', group: group.id }, group.label, { min: 0, max: FIGURE_MOTION_SPEED_MAX })\n add({ kind: 'motion-paused', group: group.id }, group.label)\n }\n for (const port of asset.dataInterface?.ports ?? []) add({ kind: 'status', port: port.id }, port.label)\n for (const axis of ['x', 'z', 'y', 'heading'] as const) add({ kind: 'pose', axis, seconds: 1 }, axis, { unit: axis === 'heading' ? 'deg' : 'mm' })\n if (asset.document.capabilities.slotLayout || asset.document.capabilities.names?.includes('Holdable')) add({ kind: 'items' }, asset.document.capabilities.slotLayout?.label ?? 'items')\n return out\n}\n\nconst isValue = (n: FigureDataNode): n is Extract<FigureDataNode, { kind: 'number' | 'boolean' | 'text' }> => n.kind === 'number' || n.kind === 'boolean' || n.kind === 'text'\n\n/** Whether a field of this kind can drive the behavior, by some rule -- the choices offered for it. */\nexport function fitsField(node: FigureDataNode, choice: BehaviorChoice): boolean {\n if (choice.kind === 'items') return node.kind === 'list' || node.kind === 'text' || node.kind === 'number'\n if (!isValue(node)) return false\n if (choice.kind === 'pose') return node.kind === 'number'\n if (choice.kind === 'motion-speed') return node.kind === 'number' || node.kind === 'boolean'\n if (choice.kind === 'motion-paused') return node.kind === 'boolean' || (node.kind === 'text' && !!node.values)\n if (choice.kind === 'status') return node.kind !== 'boolean'\n return true\n}\n\n/** An id not taken among `taken`: `base`, then `base-2`, `base-3`, … made into the kernel's id shape. */\nexport function freeIdOf(taken: Iterable<string>, base: string): string {\n const used = new Set(taken)\n const cleaned = base.replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^[^a-zA-Z]+/, '').replace(/-+$/, '') || 'binding'\n const id = FIGURE_PART_ID.test(cleaned) ? cleaned : 'binding'\n if (!used.has(id)) return id\n let n = 2\n while (used.has(`${id}-${n}`)) n++\n return `${id}-${n}`\n}\n\n/** How many mm, or degrees, one of a unit is: only lengths and angles are converted. */\nconst TO_MM: Record<string, number> = { mm: 1, cm: 10, m: 1000 }\nconst TO_DEG: Record<string, number> = { deg: 1, rad: 180 / Math.PI }\n\n/** The values a closed field takes: a closed text's values, both booleans. Empty when open. */\nexport const domainOf = (node: FigureDataNode): FigureDataValue[] => (node.kind === 'boolean' ? [false, true] : node.kind === 'text' && node.values ? [...node.values] : [])\n\n/**\n * A first binding of a field to a behavior, for the author to adjust: the value as it is when it already fits, a scale\n * when only its unit or range differs, one result per value (a map) for a closed field, a default for an open one.\n * Each result starts at what the behavior shows now -- the control's rest value, the colour, the group's default clip --\n * or, for a clip, the clip of the value's own name. The kernel says whether it holds.\n */\nexport function bindingDraftOf(asset: FigureAsset, accessor: string, node: FigureDataNode, choice: BehaviorChoice): FigureDataBinding {\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const name = accessor.replace(/\\[\\d+\\]/g, '').split('.').pop() ?? accessor\n const id = freeIdOf(taken, `${name}-${choice.kind === 'state' ? (choice.behavior as { input: string }).input : choice.kind}`)\n const behavior = choice.behavior\n const make = (rule: FigureDataBinding['rule'], param?: FigureDataBinding['param']): FigureDataBinding => ({ id, accessor, behavior, rule, ...(param ? { param } : {}) })\n const domain = domainOf(node)\n const caseMap = (each: (v: FigureDataValue) => FigureDataValue, fallback: FigureDataValue) => Object.fromEntries([...domain.map(v => [String(v), each(v)] as const), ...(domain.length ? [] : [['default', fallback] as const])])\n\n if (behavior.kind === 'items') {\n if (node.kind !== 'list') return make('value')\n const fields = node.item.kind === 'object' ? node.item.fields : []\n const pick = (...words: RegExp[]) => fields.find(f => isValue(f) && words.some(w => w.test(f.name)))?.name\n const itemId = pick(/^id$/i, /name$/i, /id$/i) ?? fields.find(isValue)?.name\n const type = pick(/type$/i)\n const place = pick(/^slot/i, /place/i, /port/i)\n const stack = pick(/stack/i, /level/i)\n return { id, accessor, behavior: { kind: 'items', ...(itemId ? { id: itemId } : {}), ...(type ? { type } : {}), ...(place ? { place } : {}), ...(stack ? { stack } : {}) }, rule: 'value' }\n }\n if (behavior.kind === 'status') return make('value')\n if (behavior.kind === 'palette') {\n const now = asset.palette[behavior.token] ?? '#000000'\n if (node.kind === 'number') return make('range', { default: now })\n return make('map', caseMap(() => now, now))\n }\n if (behavior.kind === 'motion-clip') {\n const group = (asset.motionGroups ?? []).find(g => g.id === behavior.group)\n const clips = group?.clips ?? []\n if (node.kind === 'text' && node.values && node.values.every(v => clips.includes(v))) return make('value')\n return make('map', caseMap(v => (clips.includes(String(v)) ? String(v) : (group?.defaultClip ?? '')), group?.defaultClip ?? ''))\n }\n if (behavior.kind === 'motion-paused') {\n if (node.kind === 'boolean') return make('value')\n return make('map', caseMap(() => false, false))\n }\n if (behavior.kind === 'pose') {\n if (node.kind !== 'number') return make('value')\n const want = behavior.axis === 'heading' ? TO_DEG : TO_MM\n const unit = node.unit ?? ''\n if (unit === (behavior.axis === 'heading' ? 'deg' : 'mm')) return make('value')\n return unit in want ? make('scale', { scale: want[unit]!, offset: 0 }) : make('value')\n }\n /* state and motion-speed: a number into a range. */\n const [lo, hi, unit] =\n behavior.kind === 'motion-speed' ? [0, FIGURE_MOTION_SPEED_MAX, 'ratio'] : [choice.min ?? 0, choice.max ?? 1, choice.unit ?? '']\n if (node.kind === 'number') {\n const sameUnit = behavior.kind === 'motion-speed' ? node.unit === undefined || node.unit === 'ratio' : node.unit === unit\n const inside = node.min !== undefined && node.max !== undefined && node.min >= lo && node.max <= hi\n if (sameUnit && inside) return make('value')\n if (node.min !== undefined && node.max !== undefined && node.max > node.min) {\n /* The field's range laid onto the behavior's. */\n const scale = (hi - lo) / (node.max - node.min)\n return make('scale', { scale: round(scale), offset: round(lo - scale * node.min) })\n }\n return make('value')\n }\n const rest = behavior.kind === 'motion-speed' ? 1 : (asset.stateDefaults[(behavior as { input: string }).input] ?? lo)\n if (node.kind === 'boolean') return make('map', { false: behavior.kind === 'motion-speed' ? 0 : lo, true: behavior.kind === 'motion-speed' ? 1 : hi })\n return make('map', caseMap(() => rest, rest))\n}\nconst round = (v: number) => Math.round(v * 1e6) / 1e6\n\n/* ---------------------------------------------------------------- the schema as a tree */\n\n/** A row's path (`L[].F`) as the accessor a value binding reads (`L[0].F`): the first element of each list. */\nexport const accessorOfRow = (path: string): string => path.replace(/\\[\\]/g, '[0]')\n\n/** The field at a row's path, or undefined. */\nexport function fieldAt(schema: readonly FigureDataField[], path: string): FigureDataField | undefined {\n let list: readonly FigureDataField[] = schema\n let found: FigureDataField | undefined\n for (const part of path.split('.')) {\n const name = part.replace(/\\[\\]/g, '')\n found = list.find(f => f.name === name)\n if (!found) return undefined\n let node: FigureDataNode = found\n while (node.kind === 'list') node = node.item\n list = node.kind === 'object' ? node.fields : []\n }\n return found\n}\n\n/** The fields under a row's path, where a new field goes: the top, an object's fields, a list's element's fields. */\nfunction fieldsUnder(schema: FigureDataField[], path: string): FigureDataField[] | undefined {\n if (!path) return schema\n const field = fieldAt(schema, path)\n if (!field) return undefined\n let node: FigureDataNode = field\n while (node.kind === 'list') node = node.item\n return node.kind === 'object' ? node.fields : undefined\n}\n\n/** The schema with a field added under a path ('' for the top): a copy, the given one left as it is. */\nexport function schemaWithField(schema: readonly FigureDataField[], under: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n fieldsUnder(out, under)?.push(field)\n return out\n}\n\n/** The schema with the field at a path replaced (its name kept unless the new one says another). */\nexport function schemaWithFieldReplaced(schema: readonly FigureDataField[], path: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list[at] = field\n return out\n}\n\n/** The schema without the field at a path. */\nexport function schemaWithoutField(schema: readonly FigureDataField[], path: string): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list.splice(at, 1)\n return out\n}\n\n/** A field of another kind, its name, label and json flag kept, the rest started fresh. */\nexport function fieldOfKind(field: FigureDataField, kind: FigureDataNode['kind']): FigureDataField {\n const head = { name: field.name, ...(field.label ? { label: field.label } : {}) }\n if (kind === 'object') return { ...head, kind, fields: field.kind === 'object' ? field.fields : [] }\n if (kind === 'list') return { ...head, kind, item: field.kind === 'list' ? field.item : { kind: 'object', fields: [] } }\n return { ...head, kind } as FigureDataField\n}\n\n/** The rows of the schema, each with the bindings that read it (figure-model's view). */\nexport const schemaRowsOf = (asset: FigureAsset): FigureDataRow[] => (asset.dataInterface ? figureDataRows(asset.dataInterface) : [])\n\n/* ---------------------------------------------------------------- reading a sample */\n\n/**\n * What a sample of data would do on this figure, read the one way a placed figure reads it (things-scene's figure\n * inputs): what it moves, or why it is refused, each value's reason. Nothing here reads data itself.\n */\nexport function sampleOf(asset: FigureAsset, sample: unknown): { issues: FigureDataValueIssue[]; result: FigureDataResult } {\n const inputs = new FigureInputs(asset)\n const taken = inputs.setData(sample)\n return { issues: taken.accepted ? [] : (taken.issues[0]?.issues ?? []), result: inputs.data }\n}\n\n/** The rows a person gives a value by hand, as a board's saved values: one value, read by a binding, not inside a list. */\nexport const valueRowsOf = (asset: FigureAsset): FigureDataRow[] => schemaRowsOf(asset).filter(r => isValue(r.node) && r.bindings.length > 0 && !r.path.includes('[]'))\n\n/** A value typed or chosen for a row, as its kind reads it: a number (NaN when empty), true or false, or the text. */\nexport function typedValueOf(node: FigureDataNode, typed: string): FigureDataValue {\n if (node.kind === 'number') return typed.trim() === '' ? Number.NaN : Number(typed)\n if (node.kind === 'boolean') return typed === 'true'\n return typed\n}\n\n/** The parts a status port may show on: the parts the figure's appearance names. */\nexport const partsOf = (asset: FigureAsset): string[] => [...new Set(asset.appearance.map(a => a.target))]\n\n/** A first status port: the label as given, on the first colour token, no part yet. The kernel says whether it holds. */\nexport function portDraftOf(asset: FigureAsset, label: string): FigureStatusPort {\n const taken = (asset.dataInterface?.ports ?? []).map(p => p.id)\n const token = Object.keys(asset.palette)[0]\n return { id: freeIdOf(taken, label.trim() || 'status'), label: label.trim(), tokens: token ? [token] : [], parts: [] }\n}\n\n/** Whether a text is an accessor the kernel takes. */\nexport const accessorTaken = (accessor: string): boolean => parseFigureAccessor(accessor) !== null\n\n/**\n * Which fields of each motion group the data binds: its clip, its speed. A field bound wins over the group's own setting\n * whenever the data, a saved value or the schema's default gives it a value, so the preview drives it through the data.\n */\nexport function motionWrittenByData(asset: FigureAsset): Record<string, { clip: boolean; speed: boolean }> {\n const out: Record<string, { clip: boolean; speed: boolean }> = {}\n for (const b of asset.dataInterface?.bindings ?? []) {\n if (b.behavior.kind !== 'motion-clip' && b.behavior.kind !== 'motion-speed') continue\n const one = (out[b.behavior.group] ??= { clip: false, speed: false })\n if (b.behavior.kind === 'motion-clip') one.clip = true\n else one.speed = true\n }\n return out\n}\n\n/* ---------------------------------------------------------------- the rotation card */\n\n/** A joint that turns without end (a roller, a fan, a turntable): its control, by the id the clips write. */\nexport interface EndlessJoint {\n input: string\n label: string\n unit: 'deg' | 'rad'\n}\n\n/** The joints that turn without end: revolute, with no limits, leading no one's mimic. */\nexport function endlessJointsOf(asset: FigureAsset): EndlessJoint[] {\n const out: EndlessJoint[] = []\n for (const j of asset.joints ?? []) {\n if (j.type !== 'revolute' || j.lowerLimit !== undefined || j.upperLimit !== undefined || j.mimic) continue\n const input = j.state?.id ?? j.id\n const unit = asset.document.model.inputs.find(i => i.id === input)?.unit\n if (unit !== 'deg' && unit !== 'rad') continue\n if (!out.some(e => e.input === input)) out.push({ input, label: asset.stateInputs?.[input]?.label ?? input, unit })\n }\n return out\n}\n\n/** What the rotation card is told: the joint, and the data fields that turn it on, set its speed and its direction. */\nexport interface RotationChoice {\n input: string\n /** The motion group's name, shown to a person. */\n label: string\n /** A boolean field: true turns, false stops where it is. */\n on?: string\n /** A number field in turns per minute, and the most it gives; the field's range is set to 0..max when it has none. */\n speed?: { path: string; max: number }\n /** A closed text field, and its value that turns forward and the one that turns back. */\n direction?: { path: string; forward: string; reverse: string }\n}\n\n/**\n * The rotation card's commands (data binding design decision 1, 「회전」): a clip that turns the joint once around and\n * keeps adding the turn (wrap, accumulating), a reverse one when a direction is given, the motion group holding them,\n * and the bindings -- on to the group's pause, speed to its speed, direction to its clip. Nothing new runs them: they\n * are the drivers, the group and the bindings any author could write, and stay editable one by one.\n *\n * The clip lasts `T = 3 × 60 / max rpm` seconds, so the most the field gives plays at the group's top speed, 3 -- the\n * speed range is not widened. One turn per `T` at speed 1, and speed = rpm × T / 60. A stop is a pause: the joint stays\n * where it is, where a stopped clip would jump back to its first key.\n */\nexport function rotationStepsOf(asset: FigureAsset, c: RotationChoice): FigureProposalStep[] {\n const joint = endlessJointsOf(asset).find(j => j.input === c.input)\n if (!joint) throw new FigureContractError('TARGET_ABSENT', c.input, `${c.input} is not a joint that turns without end`)\n const turn = joint.unit === 'deg' ? 360 : 2 * Math.PI\n const seconds = c.speed && c.speed.max > 0 ? round((3 * 60) / c.speed.max) : 1\n const group = freeIdOf((asset.motionGroups ?? []).map(g => g.id), `${joint.input}-spin`)\n const forward = group\n const reverse = `${group}-reverse`\n const steps: FigureProposalStep[] = []\n const schema = asset.dataInterface?.schema ?? []\n if (c.speed) {\n const field = fieldAt(schema, c.speed.path)\n if (field?.kind === 'number' && (field.min === undefined || field.max === undefined))\n steps.push({ kind: 'set-data-schema', schema: schemaWithFieldReplaced(schema, c.speed.path, { ...field, min: field.min ?? 0, max: field.max ?? c.speed.max }) })\n }\n const spin = (clip: string, way: 1 | -1, inGroup: boolean): FigureProposalStep => ({\n kind: 'set-driver',\n state: joint.input,\n clip,\n duration: seconds,\n keys: [\n { seconds: 0, value: 0 },\n { seconds, value: way * turn }\n ],\n interpolation: 'linear',\n loop: 'wrap',\n accumulates: true,\n ...(inGroup ? { group } : {})\n })\n const clips = c.direction ? [forward, reverse] : [forward]\n steps.push(spin(forward, 1, false))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips: [forward], defaultClip: forward, transitionSeconds: 0 } })\n if (c.direction) {\n steps.push(spin(reverse, -1, true))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips, defaultClip: forward, transitionSeconds: 0 } })\n }\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const bind = (base: string, binding: Omit<FigureDataBinding, 'id'>): FigureProposalStep => {\n const id = freeIdOf(taken, base)\n taken.push(id)\n return { kind: 'set-data-binding', binding: { id, ...binding } }\n }\n if (c.on) steps.push(bind(`${group}-on`, { accessor: c.on, behavior: { kind: 'motion-paused', group }, rule: 'map', param: { true: false, false: true } }))\n if (c.speed) steps.push(bind(`${group}-speed`, { accessor: c.speed.path, behavior: { kind: 'motion-speed', group }, rule: 'scale', param: { scale: round(seconds / 60), offset: 0 } }))\n if (c.direction) {\n const values = domainOf(fieldAt(schema, c.direction.path) ?? { kind: 'text' }).map(String)\n const covered = values.every(v => v === c.direction!.forward || v === c.direction!.reverse)\n steps.push(\n bind(`${group}-direction`, {\n accessor: c.direction.path,\n behavior: { kind: 'motion-clip', group },\n rule: 'map',\n param: { [c.direction.forward]: forward, [c.direction.reverse]: reverse, ...(covered ? {} : { default: forward }) }\n })\n )\n }\n return steps\n}\n"]}
|
|
1
|
+
{"version":3,"file":"data-interface.js","sourceRoot":"","sources":["../../client/modeller/data-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The figure's data and what it moves (ADR-0051 §8, data binding design appendix A): what the data tab offers and\n * shows. Every rule is figure-model's -- which accessor holds, which rule's results a behavior takes -- and the reading\n * of data is things-scene's; this only lists what there is to choose, drafts a binding the kernel then checks, and edits\n * the schema as a tree. Kept apart from the element so it is tested without a browser.\n */\nimport { FIGURE_PART_ID, FIGURE_MOTION_SPEED_MAX, FigureContractError, figureAxesOf, figureDataRows, motionStateIdOf, parseFigureAccessor } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureDataBehavior, FigureDataBinding, FigureDataField, FigureDataNode, FigureDataRow, FigureDataValue, FigureDataValueIssue, FigureProposalStep, FigureStatusPort } from '@hatiolab/figure-model'\nimport { FigureInputs, type FigureDataResult } from '@hatiolab/things-scene'\n\n/** Something a binding can move, with what the screen shows of it. */\nexport interface BehaviorChoice {\n /** One string per behavior, for a select's value. */\n key: string\n behavior: FigureDataBehavior\n /** The screen's word for the kind: a control, a colour, a group's clip, … */\n kind: FigureDataBehavior['kind']\n /** The control's label, the colour token, the group's label, the port's label, the axis. */\n name: string\n unit?: string\n min?: number\n max?: number\n}\n\nexport const behaviorKeyOf = (b: FigureDataBehavior): string =>\n b.kind === 'state'\n ? `state:${b.input}`\n : b.kind === 'palette'\n ? `palette:${b.token}`\n : b.kind === 'status'\n ? `status:${b.port}`\n : b.kind === 'pose'\n ? `pose:${b.axis}`\n : b.kind === 'items'\n ? `items:${b.slot ?? ''}`\n : `${b.kind}:${b.group}`\n\n/**\n * Everything the figure can do that data may drive: each control, each colour, each motion group's clip, speed and\n * pause, each status port, its position and heading, and -- when it has places -- the items in them.\n */\nexport function behaviorsOf(asset: FigureAsset): BehaviorChoice[] {\n const out: BehaviorChoice[] = []\n const add = (behavior: FigureDataBehavior, name: string, more: Partial<BehaviorChoice> = {}) => out.push({ key: behaviorKeyOf(behavior), behavior, kind: behavior.kind, name, ...more })\n for (const input of asset.document.model.inputs) {\n if (input.role !== 'state') continue\n add({ kind: 'state', input: input.id, sourceMode: 'observed' }, asset.stateInputs?.[input.id]?.label ?? input.id, { unit: input.unit, min: input.min, max: input.max })\n }\n for (const token of Object.keys(asset.palette)) add({ kind: 'palette', token }, token)\n for (const group of asset.motionGroups ?? []) {\n add({ kind: 'motion-clip', group: group.id }, group.label)\n add({ kind: 'motion-speed', group: group.id }, group.label, { min: 0, max: FIGURE_MOTION_SPEED_MAX })\n add({ kind: 'motion-paused', group: group.id }, group.label)\n }\n for (const port of asset.dataInterface?.ports ?? []) add({ kind: 'status', port: port.id }, port.label)\n for (const axis of ['x', 'z', 'y', 'heading'] as const) add({ kind: 'pose', axis, seconds: 1 }, axis, { unit: axis === 'heading' ? 'deg' : 'mm' })\n if (asset.document.capabilities.slotLayout || asset.document.capabilities.names?.includes('Holdable')) add({ kind: 'items' }, asset.document.capabilities.slotLayout?.label ?? 'items')\n return out\n}\n\nconst isValue = (n: FigureDataNode): n is Extract<FigureDataNode, { kind: 'number' | 'boolean' | 'text' }> => n.kind === 'number' || n.kind === 'boolean' || n.kind === 'text'\n\n/** Whether a field of this kind can drive the behavior, by some rule -- the choices offered for it. */\nexport function fitsField(node: FigureDataNode, choice: BehaviorChoice): boolean {\n if (choice.kind === 'items') return node.kind === 'list' || node.kind === 'text' || node.kind === 'number'\n if (!isValue(node)) return false\n if (choice.kind === 'pose') return node.kind === 'number'\n if (choice.kind === 'motion-speed') return node.kind === 'number' || node.kind === 'boolean'\n if (choice.kind === 'motion-paused') return node.kind === 'boolean' || (node.kind === 'text' && !!node.values)\n if (choice.kind === 'status') return node.kind !== 'boolean'\n return true\n}\n\n/** An id not taken among `taken`: `base`, then `base-2`, `base-3`, … made into the kernel's id shape. */\nexport function freeIdOf(taken: Iterable<string>, base: string): string {\n const used = new Set(taken)\n const cleaned = base.replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^[^a-zA-Z]+/, '').replace(/-+$/, '') || 'binding'\n const id = FIGURE_PART_ID.test(cleaned) ? cleaned : 'binding'\n if (!used.has(id)) return id\n let n = 2\n while (used.has(`${id}-${n}`)) n++\n return `${id}-${n}`\n}\n\n/** How many mm, or degrees, one of a unit is: only lengths and angles are converted. */\nconst TO_MM: Record<string, number> = { mm: 1, cm: 10, m: 1000 }\nconst TO_DEG: Record<string, number> = { deg: 1, rad: 180 / Math.PI }\n\n/** The values a closed field takes: a closed text's values, both booleans. Empty when open. */\nexport const domainOf = (node: FigureDataNode): FigureDataValue[] => (node.kind === 'boolean' ? [false, true] : node.kind === 'text' && node.values ? [...node.values] : [])\n\n/**\n * A first binding of a field to a behavior, for the author to adjust: the value as it is when it already fits, a scale\n * when only its unit or range differs, one result per value (a map) for a closed field, a default for an open one.\n * Each result starts at what the behavior shows now -- the control's rest value, the colour, the group's default clip --\n * or, for a clip, the clip of the value's own name. The kernel says whether it holds.\n */\nexport function bindingDraftOf(asset: FigureAsset, accessor: string, node: FigureDataNode, choice: BehaviorChoice): FigureDataBinding {\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const name = accessor.replace(/\\[\\d+\\]/g, '').split('.').pop() ?? accessor\n const id = freeIdOf(taken, `${name}-${choice.kind === 'state' ? (choice.behavior as { input: string }).input : choice.kind}`)\n const behavior = choice.behavior\n const make = (rule: FigureDataBinding['rule'], param?: FigureDataBinding['param']): FigureDataBinding => ({ id, accessor, behavior, rule, ...(param ? { param } : {}) })\n const domain = domainOf(node)\n const caseMap = (each: (v: FigureDataValue) => FigureDataValue, fallback: FigureDataValue) => Object.fromEntries([...domain.map(v => [String(v), each(v)] as const), ...(domain.length ? [] : [['default', fallback] as const])])\n\n if (behavior.kind === 'items') {\n if (node.kind !== 'list') return make('value')\n const fields = node.item.kind === 'object' ? node.item.fields : []\n const pick = (...words: RegExp[]) => fields.find(f => isValue(f) && words.some(w => w.test(f.name)))?.name\n const itemId = pick(/^id$/i, /name$/i, /id$/i) ?? fields.find(isValue)?.name\n const type = pick(/type$/i)\n const place = pick(/^slot/i, /place/i, /port/i)\n const stack = pick(/stack/i, /level/i)\n return { id, accessor, behavior: { kind: 'items', ...(itemId ? { id: itemId } : {}), ...(type ? { type } : {}), ...(place ? { place } : {}), ...(stack ? { stack } : {}) }, rule: 'value' }\n }\n if (behavior.kind === 'status') return make('value')\n if (behavior.kind === 'palette') {\n const now = asset.palette[behavior.token] ?? '#000000'\n if (node.kind === 'number') return make('range', { default: now })\n return make('map', caseMap(() => now, now))\n }\n if (behavior.kind === 'motion-clip') {\n const group = (asset.motionGroups ?? []).find(g => g.id === behavior.group)\n const clips = group?.clips ?? []\n if (node.kind === 'text' && node.values && node.values.every(v => clips.includes(v))) return make('value')\n return make('map', caseMap(v => (clips.includes(String(v)) ? String(v) : (group?.defaultClip ?? '')), group?.defaultClip ?? ''))\n }\n if (behavior.kind === 'motion-paused') {\n if (node.kind === 'boolean') return make('value')\n return make('map', caseMap(() => false, false))\n }\n if (behavior.kind === 'pose') {\n if (node.kind !== 'number') return make('value')\n const want = behavior.axis === 'heading' ? TO_DEG : TO_MM\n const unit = node.unit ?? ''\n if (unit === (behavior.axis === 'heading' ? 'deg' : 'mm')) return make('value')\n return unit in want ? make('scale', { scale: want[unit]!, offset: 0 }) : make('value')\n }\n /* state and motion-speed: a number into a range. */\n const [lo, hi, unit] =\n behavior.kind === 'motion-speed' ? [0, FIGURE_MOTION_SPEED_MAX, 'ratio'] : [choice.min ?? 0, choice.max ?? 1, choice.unit ?? '']\n if (node.kind === 'number') {\n const sameUnit = behavior.kind === 'motion-speed' ? node.unit === undefined || node.unit === 'ratio' : node.unit === unit\n const inside = node.min !== undefined && node.max !== undefined && node.min >= lo && node.max <= hi\n if (sameUnit && inside) return make('value')\n if (node.min !== undefined && node.max !== undefined && node.max > node.min) {\n /* The field's range laid onto the behavior's. */\n const scale = (hi - lo) / (node.max - node.min)\n return make('scale', { scale: round(scale), offset: round(lo - scale * node.min) })\n }\n return make('value')\n }\n const rest = behavior.kind === 'motion-speed' ? 1 : (asset.stateDefaults[(behavior as { input: string }).input] ?? lo)\n if (node.kind === 'boolean') return make('map', { false: behavior.kind === 'motion-speed' ? 0 : lo, true: behavior.kind === 'motion-speed' ? 1 : hi })\n return make('map', caseMap(() => rest, rest))\n}\nconst round = (v: number) => Math.round(v * 1e6) / 1e6\n\n/* ---------------------------------------------------------------- the schema as a tree */\n\n/** A row's path (`L[].F`) as the accessor a value binding reads (`L[0].F`): the first element of each list. */\nexport const accessorOfRow = (path: string): string => path.replace(/\\[\\]/g, '[0]')\n\n/** The field at a row's path, or undefined. */\nexport function fieldAt(schema: readonly FigureDataField[], path: string): FigureDataField | undefined {\n let list: readonly FigureDataField[] = schema\n let found: FigureDataField | undefined\n for (const part of path.split('.')) {\n const name = part.replace(/\\[\\]/g, '')\n found = list.find(f => f.name === name)\n if (!found) return undefined\n let node: FigureDataNode = found\n while (node.kind === 'list') node = node.item\n list = node.kind === 'object' ? node.fields : []\n }\n return found\n}\n\n/** The fields under a row's path, where a new field goes: the top, an object's fields, a list's element's fields. */\nfunction fieldsUnder(schema: FigureDataField[], path: string): FigureDataField[] | undefined {\n if (!path) return schema\n const field = fieldAt(schema, path)\n if (!field) return undefined\n let node: FigureDataNode = field\n while (node.kind === 'list') node = node.item\n return node.kind === 'object' ? node.fields : undefined\n}\n\n/** The schema with a field added under a path ('' for the top): a copy, the given one left as it is. */\nexport function schemaWithField(schema: readonly FigureDataField[], under: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n fieldsUnder(out, under)?.push(field)\n return out\n}\n\n/** The schema with the field at a path replaced (its name kept unless the new one says another). */\nexport function schemaWithFieldReplaced(schema: readonly FigureDataField[], path: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list[at] = field\n return out\n}\n\n/** The schema without the field at a path. */\nexport function schemaWithoutField(schema: readonly FigureDataField[], path: string): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list.splice(at, 1)\n return out\n}\n\n/** A field of another kind, its name, label and json flag kept, the rest started fresh. */\nexport function fieldOfKind(field: FigureDataField, kind: FigureDataNode['kind']): FigureDataField {\n const head = { name: field.name, ...(field.label ? { label: field.label } : {}) }\n if (kind === 'object') return { ...head, kind, fields: field.kind === 'object' ? field.fields : [] }\n if (kind === 'list') return { ...head, kind, item: field.kind === 'list' ? field.item : { kind: 'object', fields: [] } }\n return { ...head, kind } as FigureDataField\n}\n\n/** The rows of the schema, each with the bindings that read it (figure-model's view). */\nexport const schemaRowsOf = (asset: FigureAsset): FigureDataRow[] => (asset.dataInterface ? figureDataRows(asset.dataInterface) : [])\n\n/* ---------------------------------------------------------------- reading a sample */\n\n/**\n * What a sample of data would do on this figure, read the one way a placed figure reads it (things-scene's figure\n * inputs): what it moves, or why it is refused, each value's reason. Nothing here reads data itself.\n */\nexport function sampleOf(asset: FigureAsset, sample: unknown): { issues: FigureDataValueIssue[]; result: FigureDataResult } {\n const inputs = new FigureInputs(asset)\n const taken = inputs.setData(sample)\n return { issues: taken.accepted ? [] : (taken.issues[0]?.issues ?? []), result: inputs.data }\n}\n\n/** The rows a person gives a value by hand, as a board's saved values: one value, read by a binding, not inside a list. */\nexport const valueRowsOf = (asset: FigureAsset): FigureDataRow[] => schemaRowsOf(asset).filter(r => isValue(r.node) && r.bindings.length > 0 && !r.path.includes('[]'))\n\n/** A value typed or chosen for a row, as its kind reads it: a number (NaN when empty), true or false, or the text. */\nexport function typedValueOf(node: FigureDataNode, typed: string): FigureDataValue {\n if (node.kind === 'number') return typed.trim() === '' ? Number.NaN : Number(typed)\n if (node.kind === 'boolean') return typed === 'true'\n return typed\n}\n\n/** The parts a status port may show on: the parts the figure's appearance names. */\nexport const partsOf = (asset: FigureAsset): string[] => [...new Set(asset.appearance.map(a => a.target))]\n\n/** A first status port: the label as given, on the first colour token, no part yet. The kernel says whether it holds. */\nexport function portDraftOf(asset: FigureAsset, label: string): FigureStatusPort {\n const taken = (asset.dataInterface?.ports ?? []).map(p => p.id)\n const token = Object.keys(asset.palette)[0]\n return { id: freeIdOf(taken, label.trim() || 'status'), label: label.trim(), tokens: token ? [token] : [], parts: [] }\n}\n\n/** Whether a text is an accessor the kernel takes. */\nexport const accessorTaken = (accessor: string): boolean => parseFigureAccessor(accessor) !== null\n\n/**\n * Which fields of each motion group the data binds: its clip, its speed. A field bound wins over the group's own setting\n * whenever the data, a saved value or the schema's default gives it a value, so the preview drives it through the data.\n */\nexport function motionWrittenByData(asset: FigureAsset): Record<string, { clip: boolean; speed: boolean }> {\n const out: Record<string, { clip: boolean; speed: boolean }> = {}\n for (const b of asset.dataInterface?.bindings ?? []) {\n if (b.behavior.kind !== 'motion-clip' && b.behavior.kind !== 'motion-speed') continue\n const one = (out[b.behavior.group] ??= { clip: false, speed: false })\n if (b.behavior.kind === 'motion-clip') one.clip = true\n else one.speed = true\n }\n return out\n}\n\n/* ---------------------------------------------------------------- the rotation card */\n\n/** A joint that turns without end (a roller, a fan, a turntable): its control, by the id the clips write. */\nexport interface EndlessJoint {\n input: string\n label: string\n unit: 'deg' | 'rad'\n}\n\n/** The axes that turn without end: revolute, with no limits, following no one (ADR-0159: every axis of every joint). */\nexport function endlessJointsOf(asset: FigureAsset): EndlessJoint[] {\n const out: EndlessJoint[] = []\n for (const { motion: a } of figureAxesOf(asset.joints)) {\n if (a.type !== 'revolute' || a.lowerLimit !== undefined || a.upperLimit !== undefined || a.mimic) continue\n const input = motionStateIdOf(a)\n const unit = asset.document.model.inputs.find(i => i.id === input)?.unit\n if (unit !== 'deg' && unit !== 'rad') continue\n if (!out.some(e => e.input === input)) out.push({ input, label: asset.stateInputs?.[input]?.label ?? input, unit })\n }\n return out\n}\n\n/** What the rotation card is told: the joint, and the data fields that turn it on, set its speed and its direction. */\nexport interface RotationChoice {\n input: string\n /** The motion group's name, shown to a person. */\n label: string\n /** A boolean field: true turns, false stops where it is. */\n on?: string\n /** A number field in turns per minute, and the most it gives; the field's range is set to 0..max when it has none. */\n speed?: { path: string; max: number }\n /** A closed text field, and its value that turns forward and the one that turns back. */\n direction?: { path: string; forward: string; reverse: string }\n}\n\n/**\n * The rotation card's commands (data binding design decision 1, 「회전」): a clip that turns the joint once around and\n * keeps adding the turn (wrap, accumulating), a reverse one when a direction is given, the motion group holding them,\n * and the bindings -- on to the group's pause, speed to its speed, direction to its clip. Nothing new runs them: they\n * are the drivers, the group and the bindings any author could write, and stay editable one by one.\n *\n * The clip lasts `T = 3 × 60 / max rpm` seconds, so the most the field gives plays at the group's top speed, 3 -- the\n * speed range is not widened. One turn per `T` at speed 1, and speed = rpm × T / 60. A stop is a pause: the joint stays\n * where it is, where a stopped clip would jump back to its first key.\n */\nexport function rotationStepsOf(asset: FigureAsset, c: RotationChoice): FigureProposalStep[] {\n const joint = endlessJointsOf(asset).find(j => j.input === c.input)\n if (!joint) throw new FigureContractError('TARGET_ABSENT', c.input, `${c.input} is not a joint that turns without end`)\n const turn = joint.unit === 'deg' ? 360 : 2 * Math.PI\n const seconds = c.speed && c.speed.max > 0 ? round((3 * 60) / c.speed.max) : 1\n const group = freeIdOf((asset.motionGroups ?? []).map(g => g.id), `${joint.input}-spin`)\n const forward = group\n const reverse = `${group}-reverse`\n const steps: FigureProposalStep[] = []\n const schema = asset.dataInterface?.schema ?? []\n if (c.speed) {\n const field = fieldAt(schema, c.speed.path)\n if (field?.kind === 'number' && (field.min === undefined || field.max === undefined))\n steps.push({ kind: 'set-data-schema', schema: schemaWithFieldReplaced(schema, c.speed.path, { ...field, min: field.min ?? 0, max: field.max ?? c.speed.max }) })\n }\n const spin = (clip: string, way: 1 | -1, inGroup: boolean): FigureProposalStep => ({\n kind: 'set-driver',\n state: joint.input,\n clip,\n duration: seconds,\n keys: [\n { seconds: 0, value: 0 },\n { seconds, value: way * turn }\n ],\n interpolation: 'linear',\n loop: 'wrap',\n accumulates: true,\n ...(inGroup ? { group } : {})\n })\n const clips = c.direction ? [forward, reverse] : [forward]\n steps.push(spin(forward, 1, false))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips: [forward], defaultClip: forward, transitionSeconds: 0 } })\n if (c.direction) {\n steps.push(spin(reverse, -1, true))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips, defaultClip: forward, transitionSeconds: 0 } })\n }\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const bind = (base: string, binding: Omit<FigureDataBinding, 'id'>): FigureProposalStep => {\n const id = freeIdOf(taken, base)\n taken.push(id)\n return { kind: 'set-data-binding', binding: { id, ...binding } }\n }\n if (c.on) steps.push(bind(`${group}-on`, { accessor: c.on, behavior: { kind: 'motion-paused', group }, rule: 'map', param: { true: false, false: true } }))\n if (c.speed) steps.push(bind(`${group}-speed`, { accessor: c.speed.path, behavior: { kind: 'motion-speed', group }, rule: 'scale', param: { scale: round(seconds / 60), offset: 0 } }))\n if (c.direction) {\n const values = domainOf(fieldAt(schema, c.direction.path) ?? { kind: 'text' }).map(String)\n const covered = values.every(v => v === c.direction!.forward || v === c.direction!.reverse)\n steps.push(\n bind(`${group}-direction`, {\n accessor: c.direction.path,\n behavior: { kind: 'motion-clip', group },\n rule: 'map',\n param: { [c.direction.forward]: forward, [c.direction.reverse]: reverse, ...(covered ? {} : { default: forward }) }\n })\n )\n }\n return steps\n}\n"]}
|
|
@@ -139,7 +139,8 @@ export declare class FigureEditor extends LitElement {
|
|
|
139
139
|
private useGizmo;
|
|
140
140
|
/**
|
|
141
141
|
* A refusal no particular sentence knows: figure-model's code said as a refusal, never its English; any other error
|
|
142
|
-
* (the network, the server) as it came.
|
|
142
|
+
* (the network, the server) as it came. A loop is said as a loop whichever way it was made: a command, or the size
|
|
143
|
+
* editor's steps (a measure made to follow what follows it, 2026-10-24 -- said as a bare refused step before).
|
|
143
144
|
*/
|
|
144
145
|
private said;
|
|
145
146
|
private run;
|
|
@@ -259,9 +260,21 @@ export declare class FigureEditor extends LitElement {
|
|
|
259
260
|
/** One command, one step of the history. A refusal a person can meet here is said in their words. */
|
|
260
261
|
/** Where a held edit goes once the author has chosen where what stands on its lost faces goes. */
|
|
261
262
|
private mapFaces;
|
|
263
|
+
/** The figure's size, declared for a part to follow, in one line (ADR ruling Q1). */
|
|
264
|
+
private sizeDeclaredWords;
|
|
265
|
+
/**
|
|
266
|
+
* The size editor's steps, one step of the history. A measure made to follow the figure on a figure with no size
|
|
267
|
+
* declares it on the way; that is said in one line, as follow-size said it (ADR ruling Q1, 2026-10-24).
|
|
268
|
+
*/
|
|
269
|
+
private applySizeSteps;
|
|
262
270
|
/** Runs a command; true when it was taken. */
|
|
263
271
|
private linkCommand;
|
|
264
272
|
private changeField;
|
|
273
|
+
/**
|
|
274
|
+
* A number written to an input, from a field, a scrub or the size editor's rows: a size keeps the part's middle, or its
|
|
275
|
+
* fastening -- figure-model's one size function (ADR-0140 4.1). Gives the value the input holds after, refused or not.
|
|
276
|
+
*/
|
|
277
|
+
private writeField;
|
|
265
278
|
/** Typing or a held spinner: each number on the way is drawn; the field's change records it. */
|
|
266
279
|
private typing;
|
|
267
280
|
/**
|