@things-factory/figure-ui 10.1.208 → 10.1.210
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 +74 -57
- package/client/modeller/fasten-geometry.ts +2 -1
- package/client/modeller/figure-links.ts +26 -120
- package/client/modeller/figure-size-editor.ts +196 -0
- package/client/modeller/joint-drag.ts +25 -21
- package/client/modeller/joint-fan.ts +4 -3
- package/client/modeller/links.ts +36 -24
- 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 +9 -1
- package/dist-client/modeller/editor.js +80 -58
- 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 +1 -4
- package/dist-client/modeller/figure-links.js +26 -107
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/figure-size-editor.d.ts +27 -0
- package/dist-client/modeller/figure-size-editor.js +221 -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 +9 -6
- package/dist-client/modeller/links.js +33 -21
- package/dist-client/modeller/links.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/route.d.ts +1 -1
- 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 +28 -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 +51 -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 +21 -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 +44 -10
- package/translations/es.json +44 -10
- package/translations/ja.json +44 -10
- package/translations/ko.json +49 -15
- package/translations/ms.json +44 -10
- package/translations/zh.json +44 -10
|
@@ -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,6 +260,13 @@ 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;
|
|
@@ -6,7 +6,7 @@ import '@operato/layout';
|
|
|
6
6
|
import { openPopup } from '@operato/layout';
|
|
7
7
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
8
8
|
import { live } from 'lit/directives/live.js';
|
|
9
|
-
import { figurePartFaceOf, PART_LIMIT, parseFigureRecipe, resolveFigureRecipe, figurePartCountOf, figurePartIdFor, figureRecipeIdFor, figureSizeEditOf, figureSizeEditorOf, figureSectionMeasuresOf, figurePlaneAlignChanges, figureRowOf, figureFaceOverhangOf } from '@hatiolab/figure-model';
|
|
9
|
+
import { figureFastenAxesOf, figurePartFaceOf, PART_LIMIT, parseFigureRecipe, resolveFigureRecipe, figurePartCountOf, figurePartIdFor, figureRecipeIdFor, figureSizeEditOf, figureSizeEditorOf, figureSectionMeasuresOf, figurePlaneAlignChanges, figureRowOf, figureFaceOverhangOf } from '@hatiolab/figure-model';
|
|
10
10
|
import './figure-recipe-catalog.js';
|
|
11
11
|
import { captureFigureThumbnail } from './thumbnail.js';
|
|
12
12
|
import { drawableFigureParts } from './renderer.js';
|
|
@@ -50,13 +50,14 @@ import { nudgeOf, placementOf } from './stage-model.js';
|
|
|
50
50
|
import { gateFindingStyles, renderGateFinding } from './gate-findings.js';
|
|
51
51
|
import { editRefusalOf, partNameRefusalOf, sizeRangeFitsOf, partRefusalOf, placedRefusalOf, recipeRefusalOf, removalNoticeOf } from './refusals.js';
|
|
52
52
|
import { HelpToggles } from './help.js';
|
|
53
|
-
import {
|
|
53
|
+
import { sizeInputOf } from './size-response.js';
|
|
54
|
+
import { canFollow, followableAxes, endPlaceKeyOf, followOf, sizeFollowersOf, measureNow, partSummaryOf, instanceRangeOf, instanceSizeToDeclare, proportionToFollow, rangeWith, turnsAboutAJoint, valueNow } from './links.js';
|
|
54
55
|
import { jointFanOf } from './joint-fan.js';
|
|
55
56
|
import { derivedOf } from './revision.js';
|
|
56
57
|
import { jointDragOf } from './joint-drag.js';
|
|
57
58
|
import { liveOverSession, NOTHING_LIVE, scrubbed, scrubStep } from './live.js';
|
|
58
59
|
import { startingShapeKindOfBody } from './starting-shape.js';
|
|
59
|
-
import {
|
|
60
|
+
import { GroupMenuStyles } from './group-menu.js';
|
|
60
61
|
/** The person's own fold of the properties' 「더 보기」, kept in their browser. */
|
|
61
62
|
const MORE_OPEN_KEY = 'figure-properties-more-open';
|
|
62
63
|
/** Product editor surface. The injected session is shared by page persistence and AI commands. */
|
|
@@ -330,10 +331,16 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
330
331
|
}
|
|
331
332
|
/**
|
|
332
333
|
* A refusal no particular sentence knows: figure-model's code said as a refusal, never its English; any other error
|
|
333
|
-
* (the network, the server) as it came.
|
|
334
|
+
* (the network, the server) as it came. A loop is said as a loop whichever way it was made: a command, or the size
|
|
335
|
+
* editor's steps (a measure made to follow what follows it, 2026-10-24 -- said as a bare refused step before).
|
|
334
336
|
*/
|
|
335
337
|
said(error) {
|
|
336
|
-
|
|
338
|
+
const code = error?.code;
|
|
339
|
+
if (code === 'DIMENSION_CYCLE')
|
|
340
|
+
return i18next.t('figure.text.follow-would-loop');
|
|
341
|
+
if (code === 'FASTEN_CYCLE' || code === 'ATTACH_CYCLE')
|
|
342
|
+
return i18next.t('figure.text.fasten-would-loop');
|
|
343
|
+
return code ? editRefusalOf(error, (key, params) => i18next.t(key, params)) : error instanceof Error ? error.message : String(error);
|
|
337
344
|
}
|
|
338
345
|
run(action) {
|
|
339
346
|
try {
|
|
@@ -824,6 +831,8 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
824
831
|
.partId=${this.selected}
|
|
825
832
|
?locked=${unavailable}
|
|
826
833
|
@command=${(e) => this.linkCommand(e.detail.action)}
|
|
834
|
+
@size-recipe=${(e) => this.applySizeSteps(e.detail.steps)}
|
|
835
|
+
@size-input=${(e) => this.run(() => this.session.apply(figureSizeEditOf(this.shown().asset, e.detail.part, [{ kind: 'set-design', input: e.detail.input, unit: 'mm', value: e.detail.value }], { keep: 'centre' }).changes))}
|
|
827
836
|
@fasten-open=${() => this.openFastening()}
|
|
828
837
|
.previewWords=${this.commandPreview.words()}
|
|
829
838
|
.detachWords=${this.commandPreview.detachWords(shown)}
|
|
@@ -843,18 +852,22 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
843
852
|
*/
|
|
844
853
|
renderPartGroups(shown, geometry, fields, unavailable, held) {
|
|
845
854
|
const groups = this.withSizeRow(groupFields(fields, this.selected), held);
|
|
846
|
-
const
|
|
855
|
+
const integrated = !!shown && canFollow(shown.asset, this.selected);
|
|
856
|
+
const dimensionInputs = new Set(integrated ? followableAxes(shown.asset, this.selected).map(axis => sizeInputOf(shown.asset, this.selected, axis)) : []);
|
|
857
|
+
const singles = groups.singles.filter(g => g.kind !== 'single' || !dimensionInputs.has(g.field.id));
|
|
858
|
+
const size = integrated ? [] : groups.vectors.filter(g => g.kind === 'vector' && g.name === 'size');
|
|
847
859
|
const place = groups.vectors.filter(g => g.kind === 'vector' && g.name !== 'size');
|
|
848
860
|
const fastened = !!this.asset()?.joints?.some(j => j.body1.part === ownerOf(this.selected));
|
|
849
861
|
const placeLocked = fastened && place.every(g => g.kind === 'vector' && ['x', 'y', 'z'].every(axis => !g.cells[axis]));
|
|
850
|
-
return this.renderLinks(unavailable, 'shape', html `${size.length ||
|
|
851
|
-
? html `<
|
|
862
|
+
return this.renderLinks(unavailable, 'shape', html `${size.length || singles.length
|
|
863
|
+
? html `<section slot="size" group-fields>
|
|
864
|
+
<h3>${i18next.t(integrated ? 'figure.label.group-shape' : 'figure.label.group-size')}</h3>
|
|
852
865
|
${size.map(g => this.renderVector(g, unavailable, held))}
|
|
853
|
-
${
|
|
854
|
-
? html `<div form>${
|
|
866
|
+
${singles.length
|
|
867
|
+
? html `<div form>${singles.map(g => (g.kind === 'single' ? this.renderSingle(g.name, g.field, unavailable) : nothing))}</div>`
|
|
855
868
|
: nothing}
|
|
856
|
-
${this.renderSizeKeeps()}
|
|
857
|
-
</
|
|
869
|
+
${!integrated ? this.renderSizeKeeps() : nothing}
|
|
870
|
+
</section>`
|
|
858
871
|
: nothing}
|
|
859
872
|
${place.length && !placeLocked
|
|
860
873
|
? html `<div slot="place" group-fields>${place.map(g => this.renderVector(g, unavailable, held))}${this.renderHeldAxes(place)}</div>`
|
|
@@ -862,7 +875,7 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
862
875
|
}
|
|
863
876
|
/** The 「반응형」 tab of a part: the links' response groups, its row's own section put in by slot. */
|
|
864
877
|
renderResponse(shown, geometry, unavailable) {
|
|
865
|
-
return this.renderLinks(unavailable, 'response', this.renderRepeat(shown, geometry, unavailable));
|
|
878
|
+
return this.renderLinks(unavailable, 'response', html `<div slot="size-note">${this.renderSizeKeeps()}</div>${this.renderRepeat(shown, geometry, unavailable)}`);
|
|
866
879
|
}
|
|
867
880
|
/**
|
|
868
881
|
* 「더 보기」: what few parts need, folded by default and left as this person last left it (chief architect
|
|
@@ -970,6 +983,25 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
970
983
|
if (done && held.from === 'section-editor')
|
|
971
984
|
this.closeSectionEditor();
|
|
972
985
|
}
|
|
986
|
+
/** The figure's size, declared for a part to follow, in one line (ADR ruling Q1). */
|
|
987
|
+
sizeDeclaredWords() {
|
|
988
|
+
const size = this.designValues();
|
|
989
|
+
return i18next.t('figure.text.size-declared-to-follow', {
|
|
990
|
+
x: Math.round(size['size.x'] ?? 0).toLocaleString(),
|
|
991
|
+
y: Math.round(size['size.y'] ?? 0).toLocaleString(),
|
|
992
|
+
z: Math.round(size['size.z'] ?? 0).toLocaleString()
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* The size editor's steps, one step of the history. A measure made to follow the figure on a figure with no size
|
|
997
|
+
* declares it on the way; that is said in one line, as follow-size said it (ADR ruling Q1, 2026-10-24).
|
|
998
|
+
*/
|
|
999
|
+
applySizeSteps(steps) {
|
|
1000
|
+
const hadSize = this.hasSize();
|
|
1001
|
+
this.run(() => this.session.applyRecipe(steps));
|
|
1002
|
+
if (!hadSize && !this.error && this.hasSize())
|
|
1003
|
+
this.notice = this.sizeDeclaredWords();
|
|
1004
|
+
}
|
|
973
1005
|
/** Runs a command; true when it was taken. */
|
|
974
1006
|
linkCommand(action, from = 'panel') {
|
|
975
1007
|
/* Committed or refused, a command in hand is let go of: the figure as it stands is drawn again. */
|
|
@@ -981,14 +1013,8 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
981
1013
|
this.error = '';
|
|
982
1014
|
this.faceMapping = undefined;
|
|
983
1015
|
/* What the command did besides what was asked, in one line: the figure's size declared to follow (ADR ruling Q1). */
|
|
984
|
-
if (action.kind === 'follow-size' && !hadSize)
|
|
985
|
-
|
|
986
|
-
this.notice = i18next.t('figure.text.size-declared-to-follow', {
|
|
987
|
-
x: Math.round(size['size.x'] ?? 0).toLocaleString(),
|
|
988
|
-
y: Math.round(size['size.y'] ?? 0).toLocaleString(),
|
|
989
|
-
z: Math.round(size['size.z'] ?? 0).toLocaleString()
|
|
990
|
-
});
|
|
991
|
-
}
|
|
1016
|
+
if (action.kind === 'follow-size' && !hadSize)
|
|
1017
|
+
this.notice = this.sizeDeclaredWords();
|
|
992
1018
|
this.changed();
|
|
993
1019
|
return true;
|
|
994
1020
|
}
|
|
@@ -1003,12 +1029,7 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1003
1029
|
this.error = '';
|
|
1004
1030
|
return false;
|
|
1005
1031
|
}
|
|
1006
|
-
this.error =
|
|
1007
|
-
code === 'DIMENSION_CYCLE'
|
|
1008
|
-
? i18next.t('figure.text.follow-would-loop')
|
|
1009
|
-
: code === 'FASTEN_CYCLE' || code === 'ATTACH_CYCLE'
|
|
1010
|
-
? i18next.t('figure.text.fasten-would-loop')
|
|
1011
|
-
: this.said(error);
|
|
1032
|
+
this.error = this.said(error);
|
|
1012
1033
|
return false;
|
|
1013
1034
|
}
|
|
1014
1035
|
}
|
|
@@ -1256,45 +1277,46 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1256
1277
|
const axis = model.nodes.find(n => n.id === `${this.selected}.repeat`)?.params?.axis ?? '?';
|
|
1257
1278
|
const own = `${this.selected}.repeat.pitch`;
|
|
1258
1279
|
/* The pitch as it stands: the part's own number, a constant, or what a pitch that follows a length comes to. */
|
|
1259
|
-
const pitch = asset.designInputs[own] ?? model.constants.find(c => c.id === layout?.args[4])?.value ?? valueNow(shown, layout?.args[4]);
|
|
1260
1280
|
const fits = layout?.op === 'fit-pitch@1';
|
|
1261
|
-
|
|
1262
|
-
const lengthRef = layout?.args[0] ?? '';
|
|
1263
|
-
const length = asset.designInputs[lengthRef];
|
|
1264
|
-
const longest = model.inputs.find(i => i.id === lengthRef)?.max;
|
|
1265
|
-
const limit = model.constants.find(c => c.id === layout?.args[6])?.value;
|
|
1281
|
+
const pitch = fits ? asset.designInputs[own] ?? model.constants.find(c => c.id === layout?.args[4])?.value ?? valueNow(shown, layout?.args[4]) : this.rowNow(shown)?.pitch;
|
|
1266
1282
|
const field = { id: own, unit: 'mm', role: 'design', value: pitch ?? 0 };
|
|
1267
|
-
const
|
|
1283
|
+
const record = asset.joints?.find(j => j.body1.part === this.selected && j.repeat);
|
|
1284
|
+
const parent = record && 'part' in record.body0 ? record.body0.part : undefined;
|
|
1285
|
+
const removable = !!record;
|
|
1286
|
+
const axes = record && 'part' in record.body0 && 'face' in record.body0 ? figureFastenAxesOf(asset, record.body0) : [];
|
|
1287
|
+
const update = (change) => {
|
|
1288
|
+
if (!record?.repeat || unavailable)
|
|
1289
|
+
return;
|
|
1290
|
+
this.run(() => this.session.command({ kind: 'set-joint', joint: { ...record, repeat: { ...record.repeat, ...change } } }));
|
|
1291
|
+
};
|
|
1268
1292
|
return html `<section slot="row" row>
|
|
1269
1293
|
<h3>
|
|
1270
1294
|
${i18next.t('figure.label.repeat')}
|
|
1271
|
-
|
|
1295
|
+
<span section-state active>${i18next.t('figure.label.repeat-active')}</span>
|
|
1272
1296
|
</h3>
|
|
1273
|
-
<div
|
|
1274
|
-
|
|
1297
|
+
<div choice-row role="radiogroup" aria-label=${i18next.t('figure.label.row-basis')}>
|
|
1298
|
+
<label toggle><input type="radio" name="applied-repeat-mode" .checked=${live(fits)} ?disabled=${unavailable || !record} @change=${() => update({ count: undefined, pitch: pitch && pitch > 0 ? pitch : 200 })}>${i18next.t('figure.label.repeat-fills')}</label>
|
|
1299
|
+
<label toggle><input type="radio" name="applied-repeat-mode" .checked=${live(!fits)} ?disabled=${unavailable || !record} @change=${() => update({ count: repeat.count })}>${i18next.t('figure.label.row-by-count')}</label>
|
|
1300
|
+
</div>
|
|
1301
|
+
<p hint>${i18next.t(fits ? 'figure.text.repeat-mode-pitch' : 'figure.text.repeat-mode-count')}</p>
|
|
1302
|
+
<div inline-field><label>${i18next.t('figure.label.size-source')}</label><span value>${parent ?? '—'}</span></div>
|
|
1303
|
+
<div inline-field><label>${i18next.t('figure.label.repeat-axis')}</label>${axes.length ? html `<select aria-label=${i18next.t('figure.label.repeat-axis')} ?disabled=${unavailable} .value=${live(axis)} @change=${(e) => update({ axis: e.target.value.toUpperCase() })}>${axes.map(a => html `<option value=${a} ?selected=${a === axis}>${a.toUpperCase()}</option>`)}</select>` : html `<span value>${axis.toUpperCase()}</span>`}</div>
|
|
1304
|
+
<div inline-field><label>${i18next.t('figure.label.repeat-count')}</label>${!fits && record ? html `<input type="number" min="1" step="1" aria-label=${i18next.t('figure.label.repeat-count')} .value=${live(String(repeat.count))} ?disabled=${unavailable} @change=${(e) => update({ count: e.target.valueAsNumber })}>` : html `<span value>${repeat.count}</span>`}</div>
|
|
1275
1305
|
<div inline-field>
|
|
1276
1306
|
<label>${i18next.t('figure.label.repeat-gap')} <span unit>mm</span></label>
|
|
1277
|
-
|
|
1307
|
+
${fits ? html `<input
|
|
1278
1308
|
type="number"
|
|
1279
1309
|
step="any"
|
|
1280
|
-
aria-label=${
|
|
1281
|
-
.value=${String(pitch ?? '')}
|
|
1282
|
-
?disabled=${unavailable
|
|
1310
|
+
aria-label=${i18next.t('figure.label.repeat-gap')}
|
|
1311
|
+
.value=${live(String(pitch ?? ''))}
|
|
1312
|
+
?disabled=${unavailable}
|
|
1283
1313
|
@change=${(e) => this.setPitch(field, e)}
|
|
1284
|
-
|
|
1314
|
+
/>` : html `<span value>${pitch === undefined ? '—' : Number(pitch.toFixed(3))}</span>`}
|
|
1285
1315
|
</div>
|
|
1286
|
-
<ul row-reading>${rowWordsOf(this.rowNow(shown), (key, params) => i18next.t(key, params)).map(line => html `<li>${line}</li>`)}</ul>
|
|
1287
|
-
<
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
length: length.toLocaleString(),
|
|
1291
|
-
count: repeat.count,
|
|
1292
|
-
longest: longest.toLocaleString(),
|
|
1293
|
-
limit
|
|
1294
|
-
})
|
|
1295
|
-
: i18next.t(fits ? 'figure.text.repeat-fits-length' : 'figure.text.repeat-fixed-count')}
|
|
1296
|
-
</p>
|
|
1297
|
-
${this.renderPublicPitch(asset, pitch ?? 0, unavailable)}
|
|
1316
|
+
<ul row-reading>${rowWordsOf(this.rowNow(shown), (key, params) => i18next.t(key, params)).slice(1).map(line => html `<li>${line}</li>`)}</ul>
|
|
1317
|
+
<button quiet ?disabled=${unavailable || !removable} @click=${() => this.run(() => this.session.command({ kind: 'remove-repeat', part: this.selected }))}>${i18next.t('figure.button.remove-repeat')}</button>
|
|
1318
|
+
<p hint>${i18next.t('figure.text.repeat-remove-explained')}</p>
|
|
1319
|
+
${fits ? this.renderPublicPitch(asset, pitch ?? 0, unavailable) : nothing}
|
|
1298
1320
|
</section>`;
|
|
1299
1321
|
}
|
|
1300
1322
|
/** The selected row as it is drawn now, read by figure-model: nothing when it cannot be read. */
|
|
@@ -1610,8 +1632,8 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1610
1632
|
/** A side tab says what it is in words under its icon: the icons alone had to be learnt (designer 2026-09-27, U05). */
|
|
1611
1633
|
renderTab(tab, icon, label) {
|
|
1612
1634
|
/* Its accessible name is the name it shows (designer 2026-09-27); the longer title stays as its tooltip. */
|
|
1613
|
-
const name = i18next.t('figure.label.tab-short-' + tab);
|
|
1614
|
-
return html `<button tab ?on=${this.tab === tab} title=${label} aria-label=${name} @click=${() => (this.tab = tab)}>
|
|
1635
|
+
const name = i18next.t(tab === 'response' && this.selected ? 'figure.label.tab-arrangement' : 'figure.label.tab-short-' + tab);
|
|
1636
|
+
return html `<button tab ?on=${this.tab === tab} title=${tab === 'response' && this.selected ? name : label} aria-label=${name} @click=${() => (this.tab = tab)}>
|
|
1615
1637
|
<md-icon>${icon}</md-icon><span tab-label aria-hidden="true">${name}</span>
|
|
1616
1638
|
</button>`;
|
|
1617
1639
|
}
|
|
@@ -1741,8 +1763,8 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1741
1763
|
return nothing;
|
|
1742
1764
|
return html `<div subject>
|
|
1743
1765
|
<div subject-summary>
|
|
1744
|
-
|
|
1745
|
-
${summary.
|
|
1766
|
+
<b>${ownerOf(this.selected)}</b>
|
|
1767
|
+
${summary.kind ? html `<small>${summary.kind}</small>` : nothing}
|
|
1746
1768
|
</div>
|
|
1747
1769
|
</div>`;
|
|
1748
1770
|
}
|