@things-factory/figure-ui 10.1.271 → 10.1.273
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/canvas.ts +4 -2
- package/client/modeller/clips.ts +74 -4
- package/client/modeller/data-interface.ts +30 -18
- package/client/modeller/editor-styles.ts +17 -6
- package/client/modeller/editor.ts +2 -0
- package/client/modeller/fasten-form.ts +81 -6
- package/client/modeller/fasten-geometry.ts +5 -3
- package/client/modeller/figure-cavity-drawing.ts +1 -3
- package/client/modeller/figure-clips.ts +101 -8
- package/client/modeller/figure-data-panel.ts +384 -200
- package/client/modeller/figure-fasten-dialog.ts +41 -30
- package/client/modeller/figure-fasten-drawing.ts +24 -14
- package/client/modeller/figure-first-save.ts +4 -3
- package/client/modeller/figure-links.ts +109 -37
- package/client/modeller/figure-parts.ts +7 -11
- package/client/modeller/figure-preview.ts +299 -79
- package/client/modeller/figure-size-editor.ts +7 -2
- package/client/modeller/first-save.ts +8 -0
- package/client/modeller/focus-on-render.ts +4 -0
- package/client/modeller/pivot.ts +76 -0
- package/client/modeller/size-response.ts +14 -0
- package/client/modeller/stage-model.ts +50 -6
- package/dist-client/modeller/canvas.d.ts +1 -0
- package/dist-client/modeller/canvas.js +3 -2
- package/dist-client/modeller/canvas.js.map +1 -1
- package/dist-client/modeller/clips.d.ts +17 -3
- package/dist-client/modeller/clips.js +69 -4
- package/dist-client/modeller/clips.js.map +1 -1
- package/dist-client/modeller/data-interface.d.ts +11 -8
- package/dist-client/modeller/data-interface.js +27 -17
- package/dist-client/modeller/data-interface.js.map +1 -1
- package/dist-client/modeller/editor-styles.js +17 -6
- package/dist-client/modeller/editor-styles.js.map +1 -1
- package/dist-client/modeller/editor.js +2 -0
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/fasten-form.d.ts +13 -0
- package/dist-client/modeller/fasten-form.js +72 -7
- package/dist-client/modeller/fasten-form.js.map +1 -1
- package/dist-client/modeller/fasten-geometry.d.ts +3 -2
- package/dist-client/modeller/fasten-geometry.js +5 -3
- package/dist-client/modeller/fasten-geometry.js.map +1 -1
- package/dist-client/modeller/figure-cavity-drawing.js +1 -3
- package/dist-client/modeller/figure-cavity-drawing.js.map +1 -1
- package/dist-client/modeller/figure-clips.d.ts +9 -0
- package/dist-client/modeller/figure-clips.js +104 -8
- package/dist-client/modeller/figure-clips.js.map +1 -1
- package/dist-client/modeller/figure-data-panel.d.ts +10 -19
- package/dist-client/modeller/figure-data-panel.js +382 -190
- package/dist-client/modeller/figure-data-panel.js.map +1 -1
- package/dist-client/modeller/figure-fasten-dialog.js +39 -24
- package/dist-client/modeller/figure-fasten-dialog.js.map +1 -1
- package/dist-client/modeller/figure-fasten-drawing.js +24 -14
- package/dist-client/modeller/figure-fasten-drawing.js.map +1 -1
- package/dist-client/modeller/figure-first-save.js +4 -3
- package/dist-client/modeller/figure-first-save.js.map +1 -1
- package/dist-client/modeller/figure-links.d.ts +9 -0
- package/dist-client/modeller/figure-links.js +120 -51
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/figure-parts.js +7 -11
- package/dist-client/modeller/figure-parts.js.map +1 -1
- package/dist-client/modeller/figure-preview.d.ts +13 -0
- package/dist-client/modeller/figure-preview.js +296 -80
- package/dist-client/modeller/figure-preview.js.map +1 -1
- package/dist-client/modeller/figure-size-editor.js +7 -3
- package/dist-client/modeller/figure-size-editor.js.map +1 -1
- package/dist-client/modeller/first-save.d.ts +5 -0
- package/dist-client/modeller/first-save.js +7 -0
- package/dist-client/modeller/first-save.js.map +1 -1
- package/dist-client/modeller/focus-on-render.d.ts +2 -0
- package/dist-client/modeller/focus-on-render.js +4 -0
- package/dist-client/modeller/focus-on-render.js.map +1 -0
- package/dist-client/modeller/pivot.d.ts +12 -0
- package/dist-client/modeller/pivot.js +59 -0
- package/dist-client/modeller/pivot.js.map +1 -0
- package/dist-client/modeller/size-response.d.ts +6 -0
- package/dist-client/modeller/size-response.js +14 -0
- package/dist-client/modeller/size-response.js.map +1 -1
- package/dist-client/modeller/stage-model.d.ts +17 -3
- package/dist-client/modeller/stage-model.js +44 -6
- package/dist-client/modeller/stage-model.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -7
- package/test/browser/editing-page.js +1 -1
- package/test/browser/editing.check.mjs +6 -5
- package/test/browser/links.check.mjs +30 -0
- package/test/browser/modeller.check.mjs +2 -2
- package/test/browser/parts-page.js +4 -0
- package/test/browser/parts.check.mjs +16 -10
- package/test/browser/screen-page.js +12 -1
- package/test/browser/screen.check.mjs +142 -11
- package/test/browser/section.check.mjs +21 -0
- package/test/browser/serve-response.mjs +5 -2
- package/test/browser/side-panel-sweep.check.mjs +171 -10
- package/test/clips.test.ts +49 -4
- package/test/data-motion.test.ts +39 -8
- package/test/fasten-form.test.ts +69 -0
- package/test/fasten-geometry.test.ts +13 -0
- package/test/first-save.test.ts +11 -1
- package/test/pivot.test.ts +57 -0
- package/test/size-response.test.ts +10 -2
- package/test/stage-model.test.ts +23 -1
- package/translations/en.json +31 -11
- package/translations/es.json +30 -10
- package/translations/ja.json +30 -10
- package/translations/ko.json +32 -12
- package/translations/ms.json +30 -10
- package/translations/zh.json +30 -10
- package/tutorial/humanoid/README.md +22 -0
- package/tutorial/humanoid/chapters.mjs +247 -0
- package/tutorial/humanoid/encode.mjs +26 -0
- package/tutorial/humanoid/lib.mjs +197 -0
- package/tutorial/humanoid/record.mjs +65 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figure-preview.js","sourceRoot":"","sources":["../../client/modeller/figure-preview.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { unitWord } from './unit-words.js'\nimport * as THREE from 'three'\nimport { compileFigureAsset } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureDataRow, FigureDataValue, FigureGraphStateInput } from '@hatiolab/figure-model'\nimport { create, figureLegendSourcesChanged, registerFigure, unregisterFigure } from '@hatiolab/things-scene'\n\nimport { DEFAULT_VIEW, previewBoardDepth, sceneLook, WORKBENCH, type ViewSettings } from '@things-factory/figure-viewer/dist-client/figure-view.js'\nimport { parametersForClip } from '@things-factory/figure-viewer/dist-client/detail-motion.js'\nimport { controlsOf } from '@things-factory/figure-viewer/dist-client/controls.js'\nimport { dialShape } from './angle-dial.js'\nimport { dataValueAt, domainOf, motionWrittenByData, sampledStatesOf, typedValueOf, valueRowsOf } from './data-interface.js'\nimport { derivedOf, type FigureRevision } from './revision.js'\nimport { authoredSizeOf, bodyAtSize, PREVIEW_FACTOR, PREVIEW_WAYS, previewClampsOf, previewInstances, previewOneInstance, previewTypeOf, setupPartOf, sizeSpanOf, sizeWithinRange } from '@things-factory/figure-viewer/dist-client/preview-model.js'\nimport { previewSizeWordsOf } from './preview-size.js'\n\n/**\n * The figure placed on a board.\n *\n * The editing canvas shows the figure at the size it was made. Half of what a figure is lies in how it answers a\n * different size, so here the figure being authored is registered as a board registers it and placed as a\n * `FigureInstance` the author stretches with a slider per axis the figure lets change, its size and its rows' counts\n * said beside it (first 15 minutes, 2026-10-16: eight variants side by side at one scale made a 60 mm roller on a 3 m\n * conveyor a speck). The eight -- the size it was made, and each of the seven ways of growing one, two or three axes\n * twice as large, four to a row -- are a choice in the legend. The board draws them as it will on a real board --\n * placement, lights, environment, the same renderer.\n *\n * The controls: each value that poses the figure with a slider (and a dial for an angle), each clip's\n * speed, and 「이 자세를 기본으로」 to keep the pose as the one it stands in. Nothing here is edited; the canvas edits.\n */\n\ninterface SceneHandle {\n dispose?: () => void\n resize?: () => void\n fit?: (type?: string) => void\n /** The scene's container: it can make the content again while keeping the 3D renderer and the camera (undo and redo use it). */\n rootContainer?: {\n rebuildContentModel?: (model: unknown, options?: { preserveThreeD?: boolean }) => void\n /** The scene's legends, by name (ADR-0166 7): what its figures' tables choose from. */\n style?: Record<string, unknown>\n }\n root?: {\n set?: (patch: Record<string, unknown>) => void\n fitCameraToModel?: () => void\n /** The scene's camera presets: the perspective, or a square-on view from one side. */\n setCameraView?: (view: PreviewView) => void\n components?: { set?: (property: string, value: unknown) => void }[]\n }\n}\n\n/* Where the preview looks from: the edit canvas's presets, which the preview's still scene does not draw (robot dog 2026-11-03). */\ntype PreviewView = 'perspective' | 'front' | 'right' | 'top'\nconst PREVIEW_VIEWS: readonly PreviewView[] = ['perspective', 'front', 'right', 'top']\n\n@customElement('figure-preview')\nexport class FigurePreview extends localize(i18next)(LitElement) {\n static styles = css`\n :host {\n position: relative;\n display: flex;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n background-color: ${unsafeCSS(WORKBENCH)};\n font-size: var(--ui-t-small, 11.5px);\n }\n div[stage] {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n }\n /*\n The size help and the posing controls share the stage's bottom edge. Each stood in its own corner, so on a narrow\n stage (the 1024 width, both side panels open) the controls lay over the help's button. One row that wraps keeps both\n whole: side by side when there is room, the controls above the help when there is not.\n */\n /* A variant's name over its box: small, on the stage, never in the way of the pointer. */\n div[tags] {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n }\n div[tags] span {\n position: absolute;\n transform: translate(-50%, calc(-100% - 4px));\n padding: 1px 6px;\n white-space: nowrap;\n font-size: var(--ui-t-micro, 11px);\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(28, 28, 30, 0.72);\n border-radius: 4px;\n }\n div[foot] {\n position: absolute;\n left: 8px;\n right: 8px;\n bottom: 8px;\n display: flex;\n flex-wrap: wrap-reverse;\n justify-content: space-between;\n align-items: flex-end;\n gap: 8px;\n pointer-events: none;\n }\n div[foot] > * { pointer-events: auto; }\n div[setup] { max-width: min(320px, 100%); padding: 12px; border-radius: 8px; background: rgba(28,28,30,.9); color: #fff; display: grid; gap: 8px; }\n div[setup] p { margin: 0; line-height: 1.5; }\n /* The help's choice and button in the look of the controls beside it, not the browser's grey (sweep 2026-10-27 U7). */\n div[setup] select,\n div[setup] button {\n min-width: 0;\n padding: 4px 8px;\n font: inherit;\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n }\n div[setup] button {\n cursor: pointer;\n }\n div[setup] button:hover {\n background-color: rgba(255, 255, 255, 0.24);\n }\n div[setup] option {\n color: initial;\n }\n /* Which is which: side by side means nothing without a legend. */\n div[legend] {\n position: absolute;\n top: 8px;\n left: 8px;\n display: flex;\n gap: 6px;\n padding: 4px 8px;\n color: rgba(255, 255, 255, 0.9);\n background-color: rgba(28, 28, 30, 0.6);\n border-radius: 6px;\n font-size: var(--ui-t-micro, 11px);\n flex-wrap: wrap;\n max-width: calc(100% - 16px);\n }\n /* One figure or eight: two words in the legend, the one shown pressed. */\n div[legend] button[way] {\n padding: 0 6px;\n font: inherit;\n color: inherit;\n background: none;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n opacity: 0.7;\n }\n div[legend] button[view] {\n padding: 0 6px;\n font: inherit;\n color: inherit;\n background: none;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n opacity: 0.7;\n }\n div[legend] span[views] {\n display: flex;\n gap: 2px;\n padding-left: 6px;\n border-left: 1px solid rgba(255, 255, 255, 0.22);\n }\n div[legend] button[view][aria-pressed='true'],\n div[legend] button[way][aria-pressed='true'] {\n opacity: 1;\n background-color: rgba(255, 255, 255, 0.18);\n }\n /* The one figure's size: under the legend, in the controls' look. */\n div[sizes] {\n position: absolute;\n top: 40px;\n left: 8px;\n display: grid;\n gap: 6px;\n padding: 8px 10px;\n max-width: calc(100% - 16px);\n box-sizing: border-box;\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(28, 28, 30, 0.72);\n border-radius: 8px;\n font-size: var(--ui-t-micro, 11px);\n }\n div[sizes] label {\n display: grid;\n grid-template-columns: 32px 160px 52px;\n align-items: center;\n gap: 8px;\n }\n div[sizes] input {\n width: 100%;\n accent-color: var(--md-sys-color-primary);\n }\n div[sizes] output {\n font-variant-numeric: tabular-nums;\n text-align: right;\n }\n div[sizes] p[said] {\n margin: 0;\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n }\n /* A variant drawn at another size than it asks: the figure does not declare that size. */\n div[legend] small[clamp] {\n margin-left: 4px;\n color: #ffcc80;\n }\n /*\n One grid for every row, each row its subgrid: the rows' names in one column, so a value's field starts where the one\n above it does whatever the names' lengths (a row of its own grid started 28px off, sweep 2026-10-27 U7).\n */\n div[clips] {\n margin-left: auto;\n display: grid;\n grid-template-columns: auto 20px 96px 44px;\n gap: 6px 8px;\n align-items: center;\n padding: 8px 10px;\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(28, 28, 30, 0.72);\n border-radius: 8px;\n font-size: var(--ui-t-micro, 11px);\n }\n div[clips] > * {\n grid-column: 1 / -1;\n }\n div[clips] label {\n display: grid;\n grid-template-columns: subgrid;\n align-items: center;\n }\n /* A motion group's clip: as wide as the dial, slider and value together, so its name reads. */\n div[clips] select {\n grid-column: 2 / -1;\n min-width: 0;\n font: inherit;\n color: inherit;\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n }\n div[clips] svg[dial] {\n width: 20px;\n height: 20px;\n }\n div[clips] svg[dial] path {\n fill: rgba(255, 255, 255, 0.22);\n }\n div[clips] svg[dial] line {\n stroke: var(--md-sys-color-primary, #7cc6ff);\n stroke-width: 2;\n stroke-linecap: round;\n }\n div[clips] svg[dial] circle {\n fill: none;\n stroke: rgba(255, 255, 255, 0.35);\n }\n /* Folded, the controls are one button: what they covered -- a leg, say -- can be seen (robot dog 2026-11-03). */\n div[clips] button[fold-controls] {\n justify-self: end;\n padding: 0 4px;\n font: inherit;\n color: inherit;\n background: none;\n border: none;\n cursor: pointer;\n opacity: 0.75;\n }\n div[clips] button[fold-controls]:hover {\n opacity: 1;\n }\n div[clips] button[pose] {\n align-self: stretch;\n padding: 4px 8px;\n font: inherit;\n font-size: var(--ui-t-micro, 11px);\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n cursor: pointer;\n }\n div[clips] button[pose]:hover {\n background-color: rgba(255, 255, 255, 0.24);\n }\n div[clips] span[drive] {\n opacity: 0.6;\n font-size: var(--ui-t-micro, 11px);\n }\n div[clips] input {\n width: 96px;\n accent-color: var(--md-sys-color-primary);\n }\n /* A value typed, not slid: in the look of the group's clip choice, starting where the sliders start. */\n div[clips] input:not([type='range']) {\n box-sizing: border-box;\n min-width: 0;\n font: inherit;\n color: inherit;\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n }\n div[clips] input:not([type='range']):not([type='number']) {\n grid-column: 3 / -1;\n width: auto;\n }\n /* A control's value, typed where the slider cannot land on it (a step of the range's hundredth, robot dog 2026-11-03). */\n div[clips] input[typed] {\n width: 100%;\n padding: 0 3px;\n text-align: right;\n font-variant-numeric: tabular-nums;\n }\n div[clips] label[sampled] output {\n grid-column: 3 / -1;\n text-align: left;\n }\n div[clips] output {\n font-variant-numeric: tabular-nums;\n text-align: right;\n opacity: 0.85;\n }\n div[cannot] {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 12px;\n text-align: center;\n line-height: 1.6;\n color: #f4f4f4;\n background-color: ${unsafeCSS(WORKBENCH)};\n }\n `\n\n /** The figure being authored, as the editor holds it now. */\n @property({ attribute: false }) revision?: FigureRevision\n private get asset(): FigureAsset | undefined {\n return this.revision?.asset\n }\n /** The size the figure was made at, once per version: without a declared size it is measured by evaluating the figure. */\n private authoredSize(): { x: number; y: number; z: number } {\n const shown = this.revision!\n return derivedOf(shown, 'authored-size', () => authoredSizeOf(shown.asset))\n }\n /** Which figure: the type it is registered under here is this one's own, never a real type a board uses. */\n @property() context = ''\n /**\n * In front. Once made, the preview stays standing behind the edit canvas, so coming back to it is not a new 3D scene\n * (about 300 ms): out of sight it does not follow the figure, and when it is shown again it makes its content again\n * inside the scene that stands if the figure changed meanwhile.\n */\n @property({ type: Boolean }) active = true\n private stale = false\n @property({ attribute: false }) view: ViewSettings = DEFAULT_VIEW\n\n @query('div[stage]') private stage!: HTMLDivElement\n @state() private cannot = ''\n /** Clip speeds and control values given here -- the preview's, not the figure's. */\n @state() private driving: Record<string, number> = {}\n @state() private giving: Record<string, number> = {}\n /** Per motion group, the clip played here and how fast (ADR-0051 §3.2) -- the preview's, as a board's \\`motion\\`. */\n @state() private moving: Record<string, { clip: string; speed: number }> = {}\n /** Data values given here by accessor, as a board's saved `figureValues`: what moves a group whose clip or speed the data writes. */\n @state() private valuing: Record<string, FigureDataValue> = {}\n /** Data tried in the data tab: the preview's figures take it as their \\`data\\`, as a board's data source gives it; null when none is. */\n @property({ attribute: false }) sample: unknown = null\n /** Sample legends by role (ADR-0166 10): the scene's legends named as the roles, as a board would give them. */\n @property({ attribute: false }) legends: Record<string, unknown> = {}\n /** The part chosen in the editor. The size help starts on it, so the help speaks of the part the author was working on. */\n @property() selected = ''\n @state() private setupPart = ''\n /** One figure stretched by sliders, or the eight ways of growing side by side. */\n @state() private way: 'one' | 'eight' = 'one'\n /** Where the camera looks from; a new scene starts in perspective. */\n @state() private looking: PreviewView = 'perspective'\n /** The posing controls folded to their one button. */\n @state() private controlsFolded = false\n /** The size the one figure is tried at; the authored size when the figure stands up. */\n @state() private trying?: { x: number; y: number; z: number }\n private board = { width: 0, height: 0 }\n\n /** What is being tried here now -- clip speeds and control values -- for the AI dock to hear with a request; none when nothing is. */\n tried(): { clips?: Record<string, number>; controls?: Record<string, number> } | undefined {\n const clips = Object.keys(this.driving).length ? { ...this.driving } : undefined\n const controls = Object.keys(this.giving).length ? { ...this.giving } : undefined\n return clips || controls ? { ...(clips ? { clips } : {}), ...(controls ? { controls } : {}) } : undefined\n }\n\n private scene?: SceneHandle\n /* The eight variants named over each one, where the camera shows it (sweep 2026-10-27 M4). */\n @state() private tags: { name: string; x: number; y: number }[] = []\n private tagFrame = 0\n private standing?: string\n private registered?: string\n private watcher?: ResizeObserver\n\n render() {\n const asset = this.asset\n const controls = asset ? asset.document.model.inputs.filter(i => i.role === 'state') : []\n /* Clips in a motion group are played by the group's choice of clip, not each by its own speed. */\n const grouped = new Set((asset?.motionGroups ?? []).flatMap(g => g.clips))\n const clips = asset ? [...new Set((asset.drivers ?? []).map(d => d.clip))].filter(c => !grouped.has(c)) : []\n let clampsByWay: ReturnType<typeof previewClampsOf> = {}\n try {\n clampsByWay = asset ? previewClampsOf(asset, this.authoredSize()) : {}\n } catch {\n clampsByWay = {}\n }\n /* The part the help speaks of: the one picked in it, else the one chosen in the editor, else the first. */\n const setupPart = setupPartOf(this.setupPart, this.selected, asset?.appearance.map(p => p.target) ?? [])\n return html`<div stage></div>\n ${this.tags.length ? html`<div tags>${this.tags.map(t => html`<span style=${`left:${t.x}px;top:${t.y}px`}>${t.name}</span>`)}</div>` : nothing}\n ${this.cannot\n ? html`<div cannot>${this.cannot}</div>`\n : html`<div legend>\n ${(['one', 'eight'] as const).map(\n way => html`<button way=${way} aria-pressed=${String(this.way === way)} @click=${() => this.chooseWay(way)}>${i18next.t(`figure.label.preview-way-${way}`)}</button>`\n )}\n <span views>\n ${PREVIEW_VIEWS.map(\n view => html`<button view=${view} aria-pressed=${String(this.looking === view)} @click=${() => this.lookFrom(view)}>${i18next.t(`figure.label.preview-view-${view}`)}</button>`\n )}\n </span>\n ${this.way === 'one' ? nothing : PREVIEW_WAYS.map(way => {\n const clamps = clampsByWay[way.name] ?? []\n return html`<span>\n ${way.axes.length ? way.name : i18next.t('figure.label.preview-base')}\n ${clamps.length\n ? html`<small clamp>${clamps.map(c => i18next.t('figure.text.preview-clamped', { axis: c.axis.toUpperCase(), asked: c.asked.toLocaleString(), used: c.used.toLocaleString() })).join(' · ')}</small>`\n : nothing}\n </span>`\n })}\n </div>\n ${this.way === 'one' && asset && this.trying ? this.renderSizes(asset, this.trying) : nothing}\n <div foot>${asset?.appearance.length ? html`<div setup>\n <p>${i18next.t('figure.text.preview-setup')}</p>\n <select aria-label=${i18next.t('figure.label.resize-part')} @change=${(e: Event) => this.setupPart = (e.target as HTMLSelectElement).value}>\n ${asset.appearance.map(p => html`<option value=${p.target} ?selected=${p.target === setupPart}>${p.target}</option>`)}\n </select>\n <button @click=${() => this.dispatchEvent(new CustomEvent('configure-size', { detail: { part: setupPart }, bubbles: true, composed: true }))}>${i18next.t('figure.button.configure-size')}</button>\n </div>` : nothing}\n ${controls.length + clips.length + (asset?.motionGroups?.length ?? 0) + (asset ? valueRowsOf(asset).length : 0) ? this.renderDrivers(asset!, controls, clips) : nothing}</div>`}`\n }\n\n private lookFrom(view: PreviewView) {\n this.scene?.root?.setCameraView?.(view)\n this.looking = view\n }\n\n /** The one figure's size: a slider per axis the figure lets change, and what it is at the size tried. */\n private renderSizes(asset: FigureAsset, size: { x: number; y: number; z: number }) {\n const say = (key: string, params?: Record<string, string>) => i18next.t(key, params)\n return html`<div sizes>\n ${(['x', 'y', 'z'] as const).map(axis => {\n const range = sizeSpanOf(asset, axis)\n if (!range) return nothing\n return html`<label>\n <span>${i18next.t(`figure.label.measure-${axis}`)}</span>\n <input type=\"range\" aria-label=${i18next.t(`figure.label.measure-${axis}`)} min=${range.min} max=${range.max} step=\"any\" .value=${String(size[axis])}\n @input=${(e: Event) => this.tryAxis(axis, (e.target as HTMLInputElement).valueAsNumber)}\n @change=${() => this.fitView()} />\n <output>${Math.round(size[axis]).toLocaleString()}</output>\n </label>`\n })}\n <p said>${previewSizeWordsOf(asset, size, say)}</p>\n </div>`\n }\n\n /*\n Each variant's name over its top, followed while the eight stand: the legend alone listed 「x · y · x·y …」 with\n nothing saying which box was which (sweep 2026-10-27 M4).\n */\n private followTags() {\n cancelAnimationFrame(this.tagFrame)\n if (this.way !== 'eight' || !this.scene) {\n if (this.tags.length) this.tags = []\n return\n }\n const names = new Map(PREVIEW_WAYS.map(way => [`at-${way.name}`, way.axes.length ? way.name : i18next.t('figure.label.preview-base')]))\n const box = new THREE.Box3()\n const top = new THREE.Vector3()\n const step = () => {\n const root = this.scene?.root as { activeCamera3d?: THREE.Camera; renderer3d?: THREE.WebGLRenderer; components?: { model?: { id?: string }; _realObject?: { object3d?: THREE.Object3D } }[] } | undefined\n const camera = root?.activeCamera3d\n const canvas = root?.renderer3d?.domElement\n if (!camera || !canvas || this.way !== 'eight') return\n const at = canvas.getBoundingClientRect()\n const host = this.getBoundingClientRect()\n const tags: { name: string; x: number; y: number }[] = []\n for (const component of root?.components ?? []) {\n const name = names.get(component.model?.id ?? '')\n const object = component._realObject?.object3d\n if (!name || !object) continue\n box.setFromObject(object)\n if (box.isEmpty()) continue\n box.getCenter(top)\n top.y = box.max.y\n top.project(camera)\n if (top.z > 1) continue\n tags.push({ name, x: Math.round((top.x * 0.5 + 0.5) * at.width + at.left - host.left), y: Math.round((-top.y * 0.5 + 0.5) * at.height + at.top - host.top) })\n }\n if (JSON.stringify(tags) !== JSON.stringify(this.tags)) this.tags = tags\n this.tagFrame = requestAnimationFrame(step)\n }\n this.tagFrame = requestAnimationFrame(step)\n }\n\n private chooseWay(way: 'one' | 'eight') {\n if (way === this.way) return\n this.way = way\n this.standUp()\n this.followTags()\n /* The content is made again inside the scene standing, which keeps the camera: from one figure to eight it stood inside them. */\n requestAnimationFrame(() => this.fitView())\n }\n\n /** The one figure at another size on an axis, held to what the figure declares, its centre kept on the board's. */\n private tryAxis(axis: 'x' | 'y' | 'z', value: number) {\n const asset = this.asset\n const used = asset ? sizeWithinRange(asset, axis, value) : undefined\n if (used === undefined || !this.trying) return\n this.trying = { ...this.trying, [axis]: used }\n const instance = this.scene?.root?.components?.[0] as { model?: { width?: number; height?: number }; set(props: Record<string, unknown>): void } | undefined\n /* The instance's box is the body at the sizes tried, not the sizes (bodyAtSize). */\n const box = bodyAtSize(asset!, this.trying) ?? this.trying\n instance?.set({ width: box.x, depth: box.y, height: box.z })\n const { width = 0, height = 0 } = instance?.model ?? {}\n instance?.set({ left: this.board.width / 2 - width / 2, top: this.board.height / 2 - height / 2 })\n }\n\n /** The figure as stretched, whole in view: done once the slider is let go, so the ground does not slide under a drag. */\n fitView() {\n this.scene?.fit?.('ratio')\n this.scene?.root?.fitCameraToModel?.()\n }\n\n private renderDrivers(asset: FigureAsset, controls: FigureGraphStateInput[], clips: string[]) {\n const steps = new Map(controlsOf(asset).map(c => [c.id, c.step]))\n const sampledStates = sampledStatesOf(asset, this.sample)\n const changed = controls.filter(c => this.giving[c.id] !== undefined && this.giving[c.id] !== asset.stateDefaults[c.id])\n const fold = html`<button fold-controls aria-expanded=${String(!this.controlsFolded)} @click=${() => (this.controlsFolded = !this.controlsFolded)}>\n ${i18next.t(this.controlsFolded ? 'figure.button.controls-unfold' : 'figure.button.controls-fold')}\n </button>`\n if (this.controlsFolded) return html`<div clips folded>${fold}</div>`\n return html`<div clips>\n ${fold}\n ${changed.length\n ? html`<button pose title=${i18next.t('figure.text.pose-as-default-explained')} @click=${() => this.poseAsDefault()}>\n ${i18next.t('figure.button.pose-as-default')}\n </button>`\n : nothing}\n ${Object.keys(this.giving).length\n ? html`<button clear-tried title=${i18next.t('figure.text.clear-tried-explained')} @click=${() => this.clearTried()}>\n ${i18next.t('figure.button.clear-tried')}\n </button>`\n : nothing}\n ${controls.map(control => {\n /* A control the data tab's sample sets is what the figure shows, as a value row the sample gives: said, not offered. */\n const fromSample = sampledStates[control.id]\n if (fromSample !== undefined)\n return html`<label sampled title=${i18next.t('figure.text.data-value-from-sample')}>\n <span>${asset.stateInputs?.[control.id]?.label ?? control.id} <span drive>${i18next.t('figure.label.data-value-from-sample')}</span></span>\n <output>${Math.round(fromSample * 100) / 100} ${unitWord(control.unit)}</output>\n </label>`\n const value = this.giving[control.id] ?? asset.stateDefaults[control.id] ?? control.min\n /* The step the editor's controls take (\\`controlsOf\\`): a degree for an angle, a hundredth of the range otherwise. */\n const step = steps.get(control.id) ?? (control.max - control.min) / 100\n const label = asset.stateInputs?.[control.id]?.label ?? control.id\n return html`<label>\n <span>${label} <span drive>${unitWord(control.unit)}</span></span>\n ${this.renderDial(control, value)}\n <input\n type=\"range\"\n min=${control.min}\n max=${control.max}\n step=${step}\n .value=${String(value)}\n @input=${(e: Event) => this.give(control.id, Number((e.target as HTMLInputElement).value))}\n />\n <input\n typed\n type=\"number\"\n step=\"any\"\n min=${control.min}\n max=${control.max}\n aria-label=${label}\n .value=${String(Math.round(value * 100) / 100)}\n @change=${(e: Event) => {\n const typed = (e.target as HTMLInputElement).valueAsNumber\n if (Number.isFinite(typed)) this.give(control.id, Math.min(Math.max(typed, control.min), control.max))\n }}\n />\n </label>`\n })}\n ${clips.map(clip => {\n /*\n A clip nothing has driven stands still, here as on a board: the instances get a speed only from `drive`. The\n slider showed 1.00 over rollers that did not turn (2026-10-03). It shows what plays -- 0 until moved.\n */\n const value = this.driving[clip] ?? 0\n return html`<label>\n <span>${clip} <span drive>${i18next.t('figure.label.playback-speed')}</span></span>\n <span></span>\n <input type=\"range\" min=\"0\" max=\"3\" step=\"0.05\" .value=${String(value)} @input=${(e: Event) => this.drive(clip, Number((e.target as HTMLInputElement).value))} />\n <output>${value.toFixed(2)}</output>\n </label>`\n })}\n ${valueRowsOf(asset).map(row => this.renderDataValue(row))}\n ${(asset.motionGroups ?? []).map(group => {\n const playing = this.moving[group.id] ?? { clip: group.defaultClip, speed: 0 }\n /* A field the data writes wins over the group's own setting, here as on a board: it is moved by the data values above. */\n const byData = motionWrittenByData(asset)[group.id] ?? { clip: false, speed: false }\n return html`${byData.clip\n ? nothing\n : html`<label>\n <span>${group.label} <span drive>${i18next.t('figure.label.clip')}</span></span>\n <select aria-label=${group.label} @change=${(e: Event) => this.move(group.id, { ...playing, clip: (e.target as HTMLSelectElement).value })}>\n ${group.clips.map(c => html`<option value=${c} ?selected=${c === playing.clip}>${c}</option>`)}\n </select>\n </label>`}\n ${byData.speed\n ? nothing\n : html`<label>\n <span>${group.label} <span drive>${i18next.t('figure.label.playback-speed')}</span></span>\n <span></span>\n <input type=\"range\" min=\"0\" max=\"3\" step=\"0.05\" .value=${String(playing.speed)} @input=${(e: Event) => this.move(group.id, { ...playing, speed: Number((e.target as HTMLInputElement).value) })} />\n <output>${playing.speed.toFixed(2)}</output>\n </label>`}`\n })}\n </div>`\n }\n\n /** A value the data's bindings read, as the board's saved values give it: a number on a slider when it has a range, a choice when it is closed. */\n private renderDataValue(row: FigureDataRow) {\n const node = row.node\n const label = row.label ?? row.path\n /*\n The data tab's sample, when it gives the row, is what the figure shows: a value given here is not read. Said, and\n the field not offered, rather than one that changes nothing (robot dog 2026-11-03).\n */\n const sampled = this.sample === null || this.sample === undefined ? undefined : dataValueAt(this.sample, row.path)\n if (sampled !== undefined)\n return html`<label sampled title=${i18next.t('figure.text.data-value-from-sample')}>\n <span>${label} <span drive>${i18next.t('figure.label.data-value-from-sample')}</span></span>\n <output>${typeof sampled === 'object' ? JSON.stringify(sampled) : String(sampled)}</output>\n </label>`\n const fallback = 'default' in node ? node.default : undefined\n const value = this.valuing[row.path] ?? fallback\n if (node.kind === 'number') {\n const ranged = node.min !== undefined && node.max !== undefined && node.max > node.min\n return html`<label>\n <span>${label} <span drive>${unitWord(node.unit)}</span></span>\n <span></span>\n ${ranged\n ? html`<input type=\"range\" min=${node.min!} max=${node.max!} step=${Math.max((node.max! - node.min!) / 100, 0.01)} .value=${String(value ?? node.min)} @input=${(e: Event) => this.value(row, (e.target as HTMLInputElement).value)} />\n <output>${value === undefined ? '' : Number(value).toFixed(2)}</output>`\n : html`<input type=\"number\" step=\"any\" .value=${value === undefined ? '' : String(value)} @change=${(e: Event) => this.value(row, (e.target as HTMLInputElement).value)} />\n <span></span>`}\n </label>`\n }\n const domain = domainOf(node)\n if (!domain.length)\n return html`<label>\n <span>${label}</span>\n <input aria-label=${label} .value=${value === undefined ? '' : String(value)} @change=${(e: Event) => this.value(row, (e.target as HTMLInputElement).value)} />\n </label>`\n return html`<label>\n <span>${label}</span>\n <select aria-label=${label} @change=${(e: Event) => this.value(row, (e.target as HTMLSelectElement).value)}>\n ${domain.map(v => html`<option value=${String(v)} ?selected=${v === value}>${typeof v === 'boolean' ? i18next.t(v ? 'figure.label.data-true' : 'figure.label.data-false') : v}</option>`)}\n </select>\n </label>`\n }\n\n private value(row: FigureDataRow, typed: string) {\n const value = typedValueOf(row.node, typed)\n const next = { ...this.valuing }\n if (typeof value === 'number' && Number.isNaN(value)) delete next[row.path]\n else next[row.path] = value\n this.valuing = next\n this.tellInstances('figureValues', this.valuing)\n }\n\n private move(group: string, playing: { clip: string; speed: number }) {\n this.moving = { ...this.moving, [group]: playing }\n this.release(playing.clip)\n this.tellInstances('motion', Object.fromEntries(Object.entries(this.moving).map(([id, m]) => [id, { ...m, paused: false }])))\n }\n\n private renderDial(control: { unit: string; min: number; max: number }, value: number) {\n if (control.unit !== 'deg') return html`<span></span>`\n const dial = dialShape(control.min, control.max, value)\n const span = dial.radius * 2 + 2\n return html`<svg dial viewBox=\"0 0 ${span} ${span}\" aria-hidden=\"true\">\n <path d=${dial.sector}></path>\n <circle cx=${dial.centre.x} cy=${dial.centre.y} r=${dial.radius}></circle>\n <line x1=${dial.centre.x} y1=${dial.centre.y} x2=${dial.needle.x} y2=${dial.needle.y}></line>\n </svg>`\n }\n\n private drive(clip: string, value: number) {\n this.driving = { ...this.driving, [clip]: value }\n if (value) this.release(clip)\n this.tellInstances('clips', this.driving)\n }\n\n /*\n A value given here wins over the clips for its control (things-scene's \\`parameters\\`), so a value left from trying held\n the control still while a clip played (robot dog, 2026-11-03). A clip played lets go of the controls it drives, as\n the detail view does (\\`parametersForClip\\`).\n */\n private release(clip: string) {\n const asset = this.asset\n if (!asset) return\n const next = parametersForClip(asset, this.giving, clip)\n if (Object.keys(next).length === Object.keys(this.giving).length) return\n this.giving = next\n this.tellInstances('parameters', this.giving)\n }\n\n /** Every value tried here let go: the figure stands in its default pose, and its clips move it again. Nothing is saved. */\n private clearTried() {\n this.giving = {}\n this.tellInstances('parameters', this.giving)\n }\n\n private give(id: string, value: number) {\n this.giving = { ...this.giving, [id]: value }\n this.tellInstances('parameters', this.giving)\n }\n\n private poseAsDefault() {\n this.dispatchEvent(new CustomEvent('part-edit', { detail: { edit: { kind: 'set-state-defaults', values: { ...this.giving } } }, bubbles: true, composed: true }))\n this.giving = {}\n }\n\n private tellInstances(key: 'clips' | 'parameters' | 'motion' | 'figureValues', values: Record<string, unknown> | null) {\n for (const component of this.scene?.root?.components ?? []) component.set?.(key, values === null ? null : { ...values })\n }\n\n /** The tried data to the figures standing now, as their \\`data\\`: the preview's board is not saved. */\n private tellData(data: unknown) {\n for (const component of this.scene?.root?.components ?? []) component.set?.('data', data === null || data === undefined ? null : structuredClone(data))\n }\n\n\n /** The data sample to the figures standing now. */\n private tellSample() {\n if (this.sample !== null && this.sample !== undefined) this.tellData(this.sample)\n }\n\n /** The sample legends as the scene's (its root container's, where a board's are): its tables choose again. */\n private tellLegends() {\n const container = this.scene?.rootContainer\n if (!container) return\n container.style = { ...this.legends }\n figureLegendSourcesChanged()\n }\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('sample') && this.scene) this.tellData(this.sample)\n if (changed.has('legends') && this.scene) this.tellLegends()\n if (!this.hasUpdated) return\n if (!this.active) {\n this.stale = true\n return\n }\n if (this.stale || changed.has('active')) {\n this.stale = false\n this.standUp()\n return\n }\n if (changed.has('revision') || changed.has('context')) {\n this.standUp()\n return\n }\n if (!changed.has('view')) return\n const before = changed.get('view') as ViewSettings | undefined\n const now = this.view ?? DEFAULT_VIEW\n if (before?.placement !== now.placement || before?.ceilingHeight !== now.ceilingHeight) this.standUp()\n else this.scene?.root?.set?.(sceneLook(now))\n }\n\n firstUpdated() {\n this.standUp()\n this.watcher = new ResizeObserver(() => {\n if (this.active) this.scene?.resize?.()\n })\n this.watcher.observe(this)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this.watcher?.disconnect()\n this.watcher = undefined\n this.teardown()\n }\n\n private standUp() {\n const asset = this.asset\n const view = this.view ?? DEFAULT_VIEW\n if (!asset || !asset.appearance.length) {\n this.cannot = i18next.t('figure.text.preview-needs-a-part')\n this.teardown()\n return\n }\n const signature = JSON.stringify([asset, view.placement, view.ceilingHeight, this.way])\n if (this.scene && this.standing === signature) return\n try {\n compileFigureAsset(asset)\n } catch {\n this.cannot = i18next.t('figure.text.preview-blocked-by-errors')\n this.teardown()\n return\n }\n try {\n /* Registered as a board registers it, under a type of this preview's own: a real type's drawings stay as they are. */\n const type = previewTypeOf(this.context)\n const size = this.authoredSize()\n /*\n The figure changed under a scene that is standing: the same type is registered again and the content made again\n inside the same 3D scene. Making a scene anew costs about a third of a second and its first drawing compiles the\n shaders again -- a value typed beside the preview held the screen for seconds. The scene is made anew only when\n there is none, for another figure, or when the content cannot be made again in place.\n */\n const again = this.scene?.rootContainer?.rebuildContentModel && this.registered === type\n if (!again) this.teardown()\n this.driving = {}\n this.moving = {}\n this.valuing = {}\n registerFigure(type, asset)\n this.registered = type\n /* Each instance stands in its body at the size it is asked (bodyAtSize), as a board reads it. */\n const boxOf = (asked: { x: number; y: number; z: number }) => bodyAtSize(asset, asked) ?? asked\n const { components, board } = this.way === 'one' ? previewOneInstance(type, boxOf(size)) : previewInstances(type, size, boxOf)\n this.board = board\n this.trying = this.way === 'one' ? { ...size } : undefined\n const model = {\n type: 'model-layer',\n width: board.width,\n height: board.height,\n /* As tall as the figure may grow: twice for the eight, the top of the height slider for the one. */\n depth: previewBoardDepth({ placement: asset.placement, base: { y: size.y } }, view.ceilingHeight, this.way === 'one' ? Math.max(1, (sizeSpanOf(asset, 'y')?.max ?? size.y) / size.y) : PREVIEW_FACTOR),\n threed: true,\n sky: 'color',\n ...sceneLook(view),\n placement: view.placement,\n heights: { floor: 0, ceiling: view.ceilingHeight },\n pixelRatio: Math.min(3, (window.devicePixelRatio || 1) * 2),\n components\n }\n if (again) {\n try {\n this.scene!.rootContainer!.rebuildContentModel!(model, { preserveThreeD: true })\n this.standing = signature\n this.cannot = ''\n this.tellLegends()\n this.tellSample()\n this.followTags()\n return\n } catch {\n this.teardown()\n registerFigure(type, asset)\n this.registered = type\n }\n }\n this.scene = create({\n target: this.stage,\n model,\n style: { ...this.legends },\n mode: 0\n }) as SceneHandle\n this.standing = signature\n this.looking = 'perspective'\n this.scene.resize?.()\n this.scene.fit?.('ratio')\n this.scene.root?.fitCameraToModel?.()\n this.cannot = ''\n this.tellSample()\n this.followTags()\n } catch (error) {\n this.cannot = (error as Error).message\n }\n }\n\n private teardown() {\n cancelAnimationFrame(this.tagFrame)\n this.tags = []\n this.scene?.dispose?.()\n this.scene = undefined\n this.standing = undefined\n if (this.registered) unregisterFigure(this.registered)\n this.registered = undefined\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"figure-preview.js","sourceRoot":"","sources":["../../client/modeller/figure-preview.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport { css, html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { unitWord } from './unit-words.js'\nimport { scrubLabel } from './live.js'\nimport * as THREE from 'three'\nimport { compileFigureAsset } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureDataRow, FigureDataValue, FigureGraphStateInput } from '@hatiolab/figure-model'\nimport { create, figureLegendSourcesChanged, registerFigure, unregisterFigure } from '@hatiolab/things-scene'\n\nimport { DEFAULT_VIEW, previewBoardDepth, sceneLook, WORKBENCH, type ViewSettings } from '@things-factory/figure-viewer/dist-client/figure-view.js'\nimport { parametersForClip } from '@things-factory/figure-viewer/dist-client/detail-motion.js'\nimport { controlsOf } from '@things-factory/figure-viewer/dist-client/controls.js'\nimport { dialShape } from './angle-dial.js'\nimport { dataValueAt, domainOf, motionWrittenByData, sampledStatesOf, typedValueOf, valueRowsOf } from './data-interface.js'\nimport { derivedOf, type FigureRevision } from './revision.js'\nimport { authoredSizeOf, bodyAtSize, PREVIEW_FACTOR, PREVIEW_WAYS, previewClampsOf, previewInstances, previewOneInstance, previewTypeOf, setupPartOf, sizeSpanOf, sizeWithinRange } from '@things-factory/figure-viewer/dist-client/preview-model.js'\nimport { previewSizeWordsOf } from './preview-size.js'\nimport { playedControlsOf } from './clips.js'\n\n/**\n * The figure placed on a board.\n *\n * The editing canvas shows the figure at the size it was made. Half of what a figure is lies in how it answers a\n * different size, so here the figure being authored is registered as a board registers it and placed as a\n * `FigureInstance` the author stretches with a slider per axis the figure lets change, its size and its rows' counts\n * said beside it (first 15 minutes, 2026-10-16: eight variants side by side at one scale made a 60 mm roller on a 3 m\n * conveyor a speck). The eight -- the size it was made, and each of the seven ways of growing one, two or three axes\n * twice as large, four to a row -- are a choice in the legend. The board draws them as it will on a real board --\n * placement, lights, environment, the same renderer.\n *\n * The controls: each value that poses the figure with a slider (and a dial for an angle), each clip's\n * speed, and 「이 자세를 기본으로」 to keep the pose as the one it stands in. Nothing here is edited; the canvas edits.\n */\n\ninterface SceneHandle {\n dispose?: () => void\n resize?: () => void\n fit?: (type?: string) => void\n /** The scene's container: it can make the content again while keeping the 3D renderer and the camera (undo and redo use it). */\n rootContainer?: {\n rebuildContentModel?: (model: unknown, options?: { preserveThreeD?: boolean }) => void\n /** The scene's legends, by name (ADR-0166 7): what its figures' tables choose from. */\n style?: Record<string, unknown>\n }\n root?: {\n set?: (patch: Record<string, unknown>) => void\n fitCameraToModel?: () => void\n /** The scene's camera presets: the perspective, or a square-on view from one side. */\n setCameraView?: (view: PreviewView) => void\n components?: { set?: (property: string, value: unknown) => void }[]\n }\n}\n\n/* Where the preview looks from: the edit canvas's presets, which the preview's still scene does not draw (robot dog 2026-11-03). */\ntype PreviewView = 'perspective' | 'front' | 'right' | 'top'\nconst PREVIEW_VIEWS: readonly PreviewView[] = ['perspective', 'front', 'right', 'top']\n\n@customElement('figure-preview')\nexport class FigurePreview extends localize(i18next)(LitElement) {\n static styles = css`\n :host {\n position: relative;\n display: flex;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n background-color: ${unsafeCSS(WORKBENCH)};\n font-size: var(--ui-t-small, 11.5px);\n }\n div[stage] {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n }\n /*\n The size help and the posing controls share the stage's bottom edge. Each stood in its own corner, so on a narrow\n stage (the 1024 width, both side panels open) the controls lay over the help's button. One row that wraps keeps both\n whole: side by side when there is room, the controls above the help when there is not.\n */\n /* A variant's name over its box: small, on the stage, never in the way of the pointer. */\n div[tags] {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n }\n div[tags] span {\n position: absolute;\n transform: translate(-50%, calc(-100% - 4px));\n padding: 1px 6px;\n white-space: nowrap;\n font-size: var(--ui-t-micro, 11px);\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(28, 28, 30, 0.72);\n border-radius: 4px;\n }\n /*\n The legend, the size sliders and the controls in one column over the stage: the controls take what is left under\n the two above and scroll inside it. A tall robot's rows in a short preview ran off the stage's top, the keep and\n fold buttons with them, and nothing scrolled (2026-11-12); a legend on two lines in a narrow preview is room taken too.\n */\n div[over] {\n position: absolute;\n inset: 8px;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n pointer-events: none;\n }\n div[over] > div[legend],\n div[over] > div[sizes] {\n pointer-events: auto;\n }\n div[foot] {\n align-self: stretch;\n flex: 1;\n min-height: 0;\n display: flex;\n flex-wrap: wrap-reverse;\n justify-content: space-between;\n align-items: flex-end;\n align-content: flex-start;\n gap: 8px;\n pointer-events: none;\n }\n div[foot] > * { pointer-events: auto; }\n /* One line over the figure -- the part and the button -- its words in its title: three lines covered the figure (user 2026-11-12). */\n div[setup] { max-width: min(320px, 100%); box-sizing: border-box; padding: 6px 8px; border-radius: 8px; background: rgba(28,28,30,.9); color: #fff; display: flex; align-items: center; gap: 6px; font-size: var(--ui-t-micro, 11px); }\n div[setup] select { flex: 1 1 auto; }\n div[setup] button { flex: none; white-space: nowrap; }\n /* The controls' last row: as wide as they are, a line over it in place of a box of its own. */\n div[clips] div[setup] { max-width: none; padding-top: 8px; border-top: 1px solid rgba(255, 255, 255, 0.14); border-radius: 0; color: inherit; }\n /* The help's choice and button in the look of the controls beside it, not the browser's grey (sweep 2026-10-27 U7). */\n div[setup] select,\n div[setup] button {\n min-width: 0;\n padding: 4px 8px;\n font: inherit;\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n }\n div[setup] button {\n cursor: pointer;\n }\n div[setup] button:hover {\n background-color: rgba(255, 255, 255, 0.24);\n }\n div[setup] option {\n color: initial;\n }\n /* Which is which: side by side means nothing without a legend. */\n div[legend] {\n max-width: 100%;\n box-sizing: border-box;\n display: flex;\n gap: 6px;\n padding: 4px 8px;\n color: rgba(255, 255, 255, 0.9);\n background-color: rgba(28, 28, 30, 0.6);\n border-radius: 6px;\n font-size: var(--ui-t-micro, 11px);\n flex-wrap: wrap;\n max-width: calc(100% - 16px);\n }\n /* One figure or eight: two words in the legend, the one shown pressed. */\n div[legend] button[way] {\n padding: 0 6px;\n font: inherit;\n color: inherit;\n background: none;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n opacity: 0.7;\n }\n div[legend] button[view] {\n padding: 0 6px;\n font: inherit;\n color: inherit;\n background: none;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n opacity: 0.7;\n }\n div[legend] span[views] {\n display: flex;\n gap: 2px;\n padding-left: 6px;\n border-left: 1px solid rgba(255, 255, 255, 0.22);\n }\n div[legend] button[view][aria-pressed='true'],\n div[legend] button[way][aria-pressed='true'] {\n opacity: 1;\n background-color: rgba(255, 255, 255, 0.18);\n }\n /* The one figure's size: under the legend, in the controls' look. */\n div[sizes] {\n display: grid;\n gap: 6px;\n padding: 8px 10px;\n max-width: 100%;\n box-sizing: border-box;\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(28, 28, 30, 0.72);\n border-radius: 8px;\n font-size: var(--ui-t-micro, 11px);\n }\n div[sizes] label {\n display: grid;\n grid-template-columns: 32px 160px 52px;\n align-items: center;\n gap: 8px;\n }\n div[sizes] input {\n width: 100%;\n accent-color: var(--md-sys-color-primary);\n }\n div[sizes] output {\n font-variant-numeric: tabular-nums;\n text-align: right;\n }\n /* The size said at the legend's end, on its line: a box of its own under the legend took a second line (user 2026-11-12). */\n div[legend] span[said] {\n padding-left: 6px;\n border-left: 1px solid rgba(255, 255, 255, 0.22);\n align-self: center;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n }\n /* A variant drawn at another size than it asks: the figure does not declare that size. */\n div[legend] small[clamp] {\n margin-left: 4px;\n color: #ffcc80;\n }\n /*\n One grid for every row, each row its subgrid: the rows' names in one column, so a value's field starts where the one\n above it does whatever the names' lengths (a row of its own grid started 28px off, sweep 2026-10-27 U7).\n */\n div[clips] {\n margin-left: auto;\n max-height: 100%;\n box-sizing: border-box;\n overflow-y: auto;\n overscroll-behavior: contain;\n display: grid;\n grid-template-columns: max-content 20px 96px 44px;\n gap: 6px 8px;\n align-items: center;\n padding: 8px 10px;\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(28, 28, 30, 0.72);\n border-radius: 8px;\n font-size: var(--ui-t-micro, 11px);\n }\n div[clips] > * {\n grid-column: 1 / -1;\n }\n div[clips] label {\n display: grid;\n grid-template-columns: subgrid;\n align-items: center;\n }\n /* A name and its unit on one line: 「position.x」 put its 「mm」 on a second line with room beside it (user 2026-11-12). */\n div[clips] label > span:first-child {\n white-space: nowrap;\n }\n /* A motion group's clip: as wide as the dial, slider and value together, so its name reads. */\n div[clips] select {\n grid-column: 2 / -1;\n min-width: 0;\n font: inherit;\n color: inherit;\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n }\n /* A motion group's clips as buttons: a list the system draws is not seen in a recording of the preview. */\n div[clips] span[clip-choices] {\n grid-column: 2 / -1;\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n min-width: 0;\n }\n div[clips] span[clip-choices] button {\n font: inherit;\n color: inherit;\n padding: 1px 8px;\n background-color: rgba(255, 255, 255, 0.08);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 10px;\n cursor: pointer;\n }\n div[clips] span[clip-choices] button[aria-pressed='true'] {\n background-color: rgba(255, 255, 255, 0.3);\n border-color: rgba(255, 255, 255, 0.6);\n font-weight: 600;\n }\n div[clips] svg[dial] {\n width: 20px;\n height: 20px;\n }\n div[clips] svg[dial] path {\n fill: rgba(255, 255, 255, 0.22);\n }\n div[clips] svg[dial] line {\n stroke: var(--md-sys-color-primary, #7cc6ff);\n stroke-width: 2;\n stroke-linecap: round;\n }\n div[clips] svg[dial] circle {\n fill: none;\n stroke: rgba(255, 255, 255, 0.35);\n }\n /* Folded, the controls are one button: what they covered -- a leg, say -- can be seen (robot dog 2026-11-03). */\n div[clips] button[fold-controls] {\n justify-self: end;\n padding: 0 4px;\n font: inherit;\n color: inherit;\n background: none;\n border: none;\n cursor: pointer;\n opacity: 0.75;\n }\n div[clips] button[fold-controls]:hover {\n opacity: 1;\n }\n /* The keep, clear and fold line, and the size help's, stay in sight while the rows between them scroll. */\n div[clips] div[actions],\n div[clips] div[setup] {\n position: sticky;\n z-index: 1;\n margin-left: -10px;\n margin-right: -10px;\n padding-left: 10px;\n padding-right: 10px;\n background-color: rgba(28, 28, 30, 0.96);\n }\n div[clips] div[actions] {\n top: -8px;\n margin-top: -8px;\n padding-top: 8px;\n padding-bottom: 4px;\n }\n div[clips] div[setup] {\n bottom: -8px;\n margin-bottom: -8px;\n padding-bottom: 8px;\n }\n div[clips] div[actions] {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n }\n /* Folded, the box is as wide as its button: the icon and the words that say it opens the controls. */\n div[clips][folded] {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 6px;\n }\n div[clips][folded] button[fold-controls] {\n gap: 4px;\n padding: 2px 4px;\n font-size: var(--ui-t-micro, 11px);\n }\n /* An icon as tall as the two buttons beside it, at the line's right end. */\n div[clips] button[fold-controls] {\n display: inline-flex;\n align-items: center;\n }\n div[clips] button[fold-controls] md-icon {\n --md-icon-size: 16px;\n }\n div[clips] div[actions] button[fold-controls] {\n margin-left: auto;\n padding: 2px 3px;\n border: 1px solid transparent;\n }\n /* On one line with the fold, each word on one line: a label broken inside a word (\"기본으 / 로\") read badly (user 2026-11-12). */\n div[clips] button[pose],\n div[clips] button[clear-tried] {\n flex: none;\n white-space: nowrap;\n padding: 3px 8px;\n font: inherit;\n font-size: var(--ui-t-micro, 11px);\n color: rgba(255, 255, 255, 0.92);\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n cursor: pointer;\n }\n div[clips] button[pose]:disabled,\n div[clips] button[clear-tried]:disabled {\n opacity: 0.4;\n cursor: default;\n }\n div[clips] button[pose]:not(:disabled):hover,\n div[clips] button[clear-tried]:not(:disabled):hover {\n background-color: rgba(255, 255, 255, 0.24);\n }\n div[clips] span[drive] {\n opacity: 0.6;\n font-size: var(--ui-t-micro, 11px);\n }\n div[clips] input {\n width: 96px;\n accent-color: var(--md-sys-color-primary);\n }\n /* A value typed, not slid: in the look of the group's clip choice, starting where the sliders start. */\n /* A name that scrubs its value, in the look the side panel gives it (figure-viewer side-panel-styles \\`[scrub]\\`). */\n div[clips] label > span[scrub] {\n cursor: ew-resize;\n user-select: none;\n touch-action: none;\n }\n /* A check box in the dial's column, where every field starts. */\n div[clips] input[type='checkbox'] {\n grid-column: 2 / -1;\n justify-self: start;\n width: auto;\n margin: 0;\n }\n div[clips] input:not([type='range']):not([type='checkbox']) {\n box-sizing: border-box;\n min-width: 0;\n font: inherit;\n color: inherit;\n background-color: rgba(255, 255, 255, 0.14);\n border: 1px solid rgba(255, 255, 255, 0.22);\n border-radius: 5px;\n }\n /*\n Three widths only: a slider, its value's box, and a field that is the whole row's -- a choice, a text, a number with\n no range -- from where the dial starts to the right edge, as the choices are (user 2026-11-12: every width differed).\n */\n div[clips] input:not([type='range']):not([type='number']):not([type='checkbox']),\n div[clips] input[wide] {\n grid-column: 2 / -1;\n width: auto;\n padding: 1px 4px;\n }\n /* A control's value, typed where the slider cannot land on it (a step of the range's hundredth, robot dog 2026-11-03). */\n div[clips] input[typed] {\n width: 100%;\n padding: 0 3px;\n text-align: right;\n font-variant-numeric: tabular-nums;\n }\n div[clips] label[sampled] output {\n grid-column: 2 / -1;\n text-align: left;\n }\n div[clips] output {\n font-variant-numeric: tabular-nums;\n text-align: right;\n opacity: 0.85;\n }\n div[cannot] {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 12px;\n text-align: center;\n line-height: 1.6;\n color: #f4f4f4;\n background-color: ${unsafeCSS(WORKBENCH)};\n }\n `\n\n /** The figure being authored, as the editor holds it now. */\n @property({ attribute: false }) revision?: FigureRevision\n private get asset(): FigureAsset | undefined {\n return this.revision?.asset\n }\n /** The size the figure was made at, once per version: without a declared size it is measured by evaluating the figure. */\n private authoredSize(): { x: number; y: number; z: number } {\n const shown = this.revision!\n return derivedOf(shown, 'authored-size', () => authoredSizeOf(shown.asset))\n }\n /** Which figure: the type it is registered under here is this one's own, never a real type a board uses. */\n @property() context = ''\n /**\n * In front. Once made, the preview stays standing behind the edit canvas, so coming back to it is not a new 3D scene\n * (about 300 ms): out of sight it does not follow the figure, and when it is shown again it makes its content again\n * inside the scene that stands if the figure changed meanwhile.\n */\n @property({ type: Boolean }) active = true\n private stale = false\n @property({ attribute: false }) view: ViewSettings = DEFAULT_VIEW\n\n @query('div[stage]') private stage!: HTMLDivElement\n @state() private cannot = ''\n /** Clip speeds and control values given here -- the preview's, not the figure's. */\n @state() private driving: Record<string, number> = {}\n @state() private giving: Record<string, number> = {}\n /** Per motion group, the clip played here and how fast (ADR-0051 §3.2) -- the preview's, as a board's \\`motion\\`. */\n @state() private moving: Record<string, { clip: string; speed: number }> = {}\n /** Data values given here by accessor, as a board's saved `figureValues`: what moves a group whose clip or speed the data writes. */\n @state() private valuing: Record<string, FigureDataValue> = {}\n /** Data tried in the data tab: the preview's figures take it as their \\`data\\`, as a board's data source gives it; null when none is. */\n @property({ attribute: false }) sample: unknown = null\n /** Sample legends by role (ADR-0166 10): the scene's legends named as the roles, as a board would give them. */\n @property({ attribute: false }) legends: Record<string, unknown> = {}\n /** The part chosen in the editor. The size help starts on it, so the help speaks of the part the author was working on. */\n @property() selected = ''\n @state() private setupPart = ''\n /** One figure stretched by sliders, or the eight ways of growing side by side. */\n @state() private way: 'one' | 'eight' = 'one'\n /** Where the camera looks from; a new scene starts in perspective. */\n @state() private looking: PreviewView = 'perspective'\n /** The posing controls folded to their one button. */\n @state() private controlsFolded = false\n /** The size the one figure is tried at; the authored size when the figure stands up. */\n @state() private trying?: { x: number; y: number; z: number }\n private board = { width: 0, height: 0 }\n\n /** What is being tried here now -- clip speeds and control values -- for the AI dock to hear with a request; none when nothing is. */\n tried(): { clips?: Record<string, number>; controls?: Record<string, number> } | undefined {\n const clips = Object.keys(this.driving).length ? { ...this.driving } : undefined\n const controls = Object.keys(this.giving).length ? { ...this.giving } : undefined\n return clips || controls ? { ...(clips ? { clips } : {}), ...(controls ? { controls } : {}) } : undefined\n }\n\n private scene?: SceneHandle\n /* The eight variants named over each one, where the camera shows it (sweep 2026-10-27 M4). */\n @state() private tags: { name: string; x: number; y: number }[] = []\n private tagFrame = 0\n private standing?: string\n private registered?: string\n private watcher?: ResizeObserver\n\n render() {\n const asset = this.asset\n const controls = asset ? asset.document.model.inputs.filter(i => i.role === 'state') : []\n /* Clips in a motion group are played by the group's choice of clip, not each by its own speed. */\n const grouped = new Set((asset?.motionGroups ?? []).flatMap(g => g.clips))\n const clips = asset ? [...new Set((asset.drivers ?? []).map(d => d.clip))].filter(c => !grouped.has(c)) : []\n let clampsByWay: ReturnType<typeof previewClampsOf> = {}\n try {\n clampsByWay = asset ? previewClampsOf(asset, this.authoredSize()) : {}\n } catch {\n clampsByWay = {}\n }\n /* The part the help speaks of: the one picked in it, else the one chosen in the editor, else the first. */\n const setupPart = setupPartOf(this.setupPart, this.selected, asset?.appearance.map(p => p.target) ?? [])\n return html`<div stage></div>\n ${this.tags.length ? html`<div tags>${this.tags.map(t => html`<span style=${`left:${t.x}px;top:${t.y}px`}>${t.name}</span>`)}</div>` : nothing}\n ${this.cannot\n ? html`<div cannot>${this.cannot}</div>`\n : html`<div over><div legend>\n ${(['one', 'eight'] as const).map(\n way => html`<button way=${way} aria-pressed=${String(this.way === way)} @click=${() => this.chooseWay(way)}>${i18next.t(`figure.label.preview-way-${way}`)}</button>`\n )}\n <span views>\n ${PREVIEW_VIEWS.map(\n view => html`<button view=${view} aria-pressed=${String(this.looking === view)} @click=${() => this.lookFrom(view)}>${i18next.t(`figure.label.preview-view-${view}`)}</button>`\n )}\n </span>\n ${this.way === 'one' ? nothing : PREVIEW_WAYS.map(way => {\n const clamps = clampsByWay[way.name] ?? []\n return html`<span>\n ${way.axes.length ? way.name : i18next.t('figure.label.preview-base')}\n ${clamps.length\n ? html`<small clamp>${clamps.map(c => i18next.t('figure.text.preview-clamped', { axis: c.axis.toUpperCase(), asked: c.asked.toLocaleString(), used: c.used.toLocaleString() })).join(' · ')}</small>`\n : nothing}\n </span>`\n })}\n ${this.way === 'one' && asset && this.trying\n ? html`<span said>${previewSizeWordsOf(asset, this.trying, (key: string, params?: Record<string, string>) => i18next.t(key, params))}</span>`\n : nothing}\n </div>\n ${this.way === 'one' && asset && this.trying ? this.renderSizes(asset, this.trying) : nothing}\n <div foot>${controls.length + clips.length + (asset?.motionGroups?.length ?? 0) + (asset ? valueRowsOf(asset).length : 0)\n ? this.renderDrivers(asset!, controls, clips, this.renderSetup(asset, setupPart))\n : this.renderSetup(asset, setupPart)}</div></div>`}`\n }\n\n /*\n The size help, shown only where the figure's size can change: the part and the button on one line, its words in its\n title. With controls it is their last row, as wide as they are -- a box of its own left a gap at its right when the\n two stood one over the other, and three lines of it covered the figure (user 2026-11-12).\n */\n private renderSetup(asset: FigureAsset | undefined, setupPart: string) {\n if (!asset?.appearance.length || !(['x', 'y', 'z'] as const).some(axis => sizeSpanOf(asset, axis))) return nothing\n return html`<div setup title=${i18next.t('figure.text.preview-setup')}>\n <select aria-label=${i18next.t('figure.label.resize-part')} @change=${(e: Event) => (this.setupPart = (e.target as HTMLSelectElement).value)}>\n ${asset.appearance.map(p => html`<option value=${p.target} ?selected=${p.target === setupPart}>${p.target}</option>`)}\n </select>\n <button @click=${() => this.dispatchEvent(new CustomEvent('configure-size', { detail: { part: setupPart }, bubbles: true, composed: true }))}>${i18next.t('figure.button.configure-size')}</button>\n </div>`\n }\n\n private lookFrom(view: PreviewView) {\n this.scene?.root?.setCameraView?.(view)\n this.looking = view\n }\n\n /** The one figure's size: a slider per axis the figure lets change, and what it is at the size tried. */\n private renderSizes(asset: FigureAsset, size: { x: number; y: number; z: number }) {\n if (!(['x', 'y', 'z'] as const).some(axis => sizeSpanOf(asset, axis))) return nothing\n return html`<div sizes>\n ${(['x', 'y', 'z'] as const).map(axis => {\n const range = sizeSpanOf(asset, axis)\n if (!range) return nothing\n return html`<label>\n <span>${i18next.t(`figure.label.measure-${axis}`)}</span>\n <input type=\"range\" aria-label=${i18next.t(`figure.label.measure-${axis}`)} min=${range.min} max=${range.max} step=\"any\" .value=${String(size[axis])}\n @input=${(e: Event) => this.tryAxis(axis, (e.target as HTMLInputElement).valueAsNumber)}\n @change=${() => this.fitView()} />\n <output>${Math.round(size[axis]).toLocaleString()}</output>\n </label>`\n })}\n </div>`\n }\n\n /*\n Each variant's name over its top, followed while the eight stand: the legend alone listed 「x · y · x·y …」 with\n nothing saying which box was which (sweep 2026-10-27 M4).\n */\n private followTags() {\n cancelAnimationFrame(this.tagFrame)\n if (this.way !== 'eight' || !this.scene) {\n if (this.tags.length) this.tags = []\n return\n }\n const names = new Map(PREVIEW_WAYS.map(way => [`at-${way.name}`, way.axes.length ? way.name : i18next.t('figure.label.preview-base')]))\n const box = new THREE.Box3()\n const top = new THREE.Vector3()\n const step = () => {\n const root = this.scene?.root as { activeCamera3d?: THREE.Camera; renderer3d?: THREE.WebGLRenderer; components?: { model?: { id?: string }; _realObject?: { object3d?: THREE.Object3D } }[] } | undefined\n const camera = root?.activeCamera3d\n const canvas = root?.renderer3d?.domElement\n if (!camera || !canvas || this.way !== 'eight') return\n const at = canvas.getBoundingClientRect()\n const host = this.getBoundingClientRect()\n const tags: { name: string; x: number; y: number }[] = []\n for (const component of root?.components ?? []) {\n const name = names.get(component.model?.id ?? '')\n const object = component._realObject?.object3d\n if (!name || !object) continue\n box.setFromObject(object)\n if (box.isEmpty()) continue\n box.getCenter(top)\n top.y = box.max.y\n top.project(camera)\n if (top.z > 1) continue\n tags.push({ name, x: Math.round((top.x * 0.5 + 0.5) * at.width + at.left - host.left), y: Math.round((-top.y * 0.5 + 0.5) * at.height + at.top - host.top) })\n }\n if (JSON.stringify(tags) !== JSON.stringify(this.tags)) this.tags = tags\n this.tagFrame = requestAnimationFrame(step)\n }\n this.tagFrame = requestAnimationFrame(step)\n }\n\n private chooseWay(way: 'one' | 'eight') {\n if (way === this.way) return\n this.way = way\n this.standUp()\n this.followTags()\n /* The content is made again inside the scene standing, which keeps the camera: from one figure to eight it stood inside them. */\n requestAnimationFrame(() => this.fitView())\n }\n\n /** The one figure at another size on an axis, held to what the figure declares, its centre kept on the board's. */\n private tryAxis(axis: 'x' | 'y' | 'z', value: number) {\n const asset = this.asset\n const used = asset ? sizeWithinRange(asset, axis, value) : undefined\n if (used === undefined || !this.trying) return\n this.trying = { ...this.trying, [axis]: used }\n const instance = this.scene?.root?.components?.[0] as { model?: { width?: number; height?: number }; set(props: Record<string, unknown>): void } | undefined\n /* The instance's box is the body at the sizes tried, not the sizes (bodyAtSize). */\n const box = bodyAtSize(asset!, this.trying) ?? this.trying\n instance?.set({ width: box.x, depth: box.y, height: box.z })\n const { width = 0, height = 0 } = instance?.model ?? {}\n instance?.set({ left: this.board.width / 2 - width / 2, top: this.board.height / 2 - height / 2 })\n }\n\n /** The figure as stretched, whole in view: done once the slider is let go, so the ground does not slide under a drag. */\n fitView() {\n this.scene?.fit?.('ratio')\n this.scene?.root?.fitCameraToModel?.()\n }\n\n private renderDrivers(asset: FigureAsset, controls: FigureGraphStateInput[], clips: string[], setup: unknown) {\n const steps = new Map(controlsOf(asset).map(c => [c.id, c.step]))\n const sampledStates = sampledStatesOf(asset, this.sample)\n const changed = controls.filter(c => this.giving[c.id] !== undefined && this.giving[c.id] !== asset.stateDefaults[c.id])\n /* An icon, its words in its title: the words took the room of a button (user 2026-11-12). */\n const foldWords = i18next.t(this.controlsFolded ? 'figure.button.controls-unfold' : 'figure.button.controls-fold')\n const fold = html`<button fold-controls aria-expanded=${String(!this.controlsFolded)} title=${foldWords} aria-label=${foldWords} @click=${() => (this.controlsFolded = !this.controlsFolded)}>\n <md-icon>${this.controlsFolded ? 'unfold_more' : 'unfold_less'}</md-icon>\n </button>`\n /* Folded, the icon says what it opens: an icon alone in an empty box said nothing (user 2026-11-12). */\n if (this.controlsFolded)\n return html`<div clips folded>\n <button fold-controls aria-expanded=\"false\" @click=${() => (this.controlsFolded = false)}>\n <md-icon>unfold_more</md-icon>${foldWords}\n </button>\n ${setup}\n </div>`\n const played = playedControlsOf(asset, this.driving, this.moving)\n /*\n Keep, clear and fold on one line, there from the start: keep and clear unable until something is tried. Coming and\n going, they moved the rows under them while a slider was being moved (user 2026-11-12).\n */\n return html`<div clips>\n <div actions>\n <button pose ?disabled=${!changed.length} title=${i18next.t('figure.text.pose-as-default-explained')} @click=${() => this.poseAsDefault()}>\n ${i18next.t('figure.button.pose-as-default')}\n </button>\n <button clear-tried ?disabled=${!Object.keys(this.giving).length} title=${i18next.t('figure.text.clear-tried-explained')} @click=${() => this.clearTried()}>\n ${i18next.t('figure.button.clear-tried')}\n </button>\n ${fold}\n </div>\n ${controls.map(control => {\n /* A control the data tab's sample sets is what the figure shows, as a value row the sample gives: said, not offered. */\n const fromSample = sampledStates[control.id]\n if (fromSample !== undefined)\n return html`<label sampled title=${i18next.t('figure.text.data-value-from-sample')}>\n <span>${asset.stateInputs?.[control.id]?.label ?? control.id} <span drive>${i18next.t('figure.label.data-value-from-sample')}</span></span>\n <output>${Math.round(fromSample * 100) / 100} ${unitWord(control.unit)}</output>\n </label>`\n const value = this.giving[control.id] ?? asset.stateDefaults[control.id] ?? control.min\n /* The step the editor's controls take (\\`controlsOf\\`): a degree for an angle, a hundredth of the range otherwise. */\n const step = steps.get(control.id) ?? (control.max - control.min) / 100\n const label = asset.stateInputs?.[control.id]?.label ?? control.id\n /*\n A control a playing clip drives moves on the figure while its row stood still at its last number -- 0 under a\n walking leg (review 2026-11-11). The row says the clip has it, and is not given a value until the clip stops.\n */\n const by = played.get(control.id)\n if (by)\n return html`<label played title=${i18next.t('figure.text.control-played-explained', { clip: by })}>\n <span>${label} <span drive>${unitWord(control.unit)}</span></span>\n <span></span>\n <input type=\"range\" min=${control.min} max=${control.max} .value=${String(value)} disabled />\n <output>${i18next.t('figure.text.control-played', { clip: by })}</output>\n </label>`\n return html`<label>\n ${this.scrubName(html`${label} <span drive>${unitWord(control.unit)}</span>`, control.unit, value, control.min, control.max, v => this.give(control.id, v))}\n ${this.renderDial(control, value)}\n <input\n type=\"range\"\n min=${control.min}\n max=${control.max}\n step=${step}\n .value=${String(value)}\n @input=${(e: Event) => this.give(control.id, Number((e.target as HTMLInputElement).value))}\n />\n ${this.typedBox(label, value, control.min, control.max, typed => this.give(control.id, typed))}\n </label>`\n })}\n ${clips.map(clip => {\n /*\n A clip nothing has driven stands still, here as on a board: the instances get a speed only from `drive`. The\n slider showed 1.00 over rollers that did not turn (2026-10-03). It shows what plays -- 0 until moved.\n */\n const value = this.driving[clip] ?? 0\n return html`<label>\n ${this.scrubName(html`${clip} <span drive>${i18next.t('figure.label.playback-speed')}</span>`, 'ratio', value, 0, 3, v => this.drive(clip, v))}\n <span></span>\n <input type=\"range\" min=\"0\" max=\"3\" step=\"0.05\" .value=${String(value)} @input=${(e: Event) => this.drive(clip, Number((e.target as HTMLInputElement).value))} />\n ${this.typedBox(clip, value, 0, 3, typed => this.drive(clip, typed))}\n </label>`\n })}\n ${valueRowsOf(asset).map(row => this.renderDataValue(row))}\n ${(asset.motionGroups ?? []).map(group => {\n const playing = this.moving[group.id] ?? { clip: group.defaultClip, speed: 0 }\n /* A field the data writes wins over the group's own setting, here as on a board: it is moved by the data values above. */\n const byData = motionWrittenByData(asset)[group.id] ?? { clip: false, speed: false }\n return html`${byData.clip\n ? nothing\n : html`<label>\n <span>${group.label} <span drive>${i18next.t('figure.label.clip')}</span></span>\n <span clip-choices role=\"group\" aria-label=${group.label}>\n ${group.clips.map(\n c => html`<button type=\"button\" aria-pressed=${String(c === playing.clip)} @click=${() => this.move(group.id, { ...playing, clip: c })}>${c}</button>`\n )}\n </span>\n </label>`}\n ${byData.speed\n ? nothing\n : html`<label>\n ${this.scrubName(html`${group.label} <span drive>${i18next.t('figure.label.playback-speed')}</span>`, 'ratio', playing.speed, 0, 3, v => this.move(group.id, { ...playing, speed: v }))}\n <span></span>\n <input type=\"range\" min=\"0\" max=\"3\" step=\"0.05\" .value=${String(playing.speed)} @input=${(e: Event) => this.move(group.id, { ...playing, speed: Number((e.target as HTMLInputElement).value) })} />\n ${this.typedBox(group.label, playing.speed, 0, 3, typed => this.move(group.id, { ...playing, speed: typed }))}\n </label>`}`\n })}\n ${setup}\n </div>`\n }\n\n /**\n * A row's name that scrubs its value when dragged sideways, as the property panel's names do (\\`scrubLabel\\`): Shift for\n * finer steps, held within the row's range. The preview's values are tried, not recorded, so each move is the value.\n * The sliders ran 360 degrees over 96 pixels, too coarse to land an angle (user 2026-11-12).\n */\n private scrubName(name: unknown, unit: string, value: number, min: number, max: number, set: (value: number) => void) {\n const held = (v: number) => Math.min(Math.max(v, min), max)\n return html`<span\n scrub\n @pointerdown=${(down: PointerEvent) => {\n /* A press that did not move gives nothing: an empty field is not given its slider's start by a click on its name. */\n let moved = false\n scrubLabel(down, { value, unit }, {\n move: v => ((moved = true), set(held(v))),\n release: v => set(held(v)),\n cancel: () => moved && set(value)\n })\n }}\n >${name}</span\n >`\n }\n\n /**\n * A slider's value as a box to type in, the same on every row: the value a slider cannot land on, typed (a step of the\n * range's hundredth, robot dog 2026-11-03); one column of boxes, not boxes over plain numbers (user 2026-11-12).\n */\n private typedBox(label: string, value: number, min: number, max: number, set: (typed: number) => void) {\n return html`<input\n typed\n type=\"number\"\n step=\"any\"\n min=${Number.isFinite(min) ? min : nothing}\n max=${Number.isFinite(max) ? max : nothing}\n aria-label=${label}\n .value=${String(Math.round(value * 100) / 100)}\n @change=${(e: Event) => {\n const typed = (e.target as HTMLInputElement).valueAsNumber\n if (Number.isFinite(typed)) set(Math.min(Math.max(typed, min), max))\n }}\n />`\n }\n\n /** A value the data's bindings read, as the board's saved values give it: a number on a slider when it has a range, a choice when it is closed. */\n private renderDataValue(row: FigureDataRow) {\n const node = row.node\n const label = row.label ?? row.path\n /*\n The data tab's sample, when it gives the row, is what the figure shows: a value given here is not read. Said, and\n the field not offered, rather than one that changes nothing (robot dog 2026-11-03).\n */\n const sampled = this.sample === null || this.sample === undefined ? undefined : dataValueAt(this.sample, row.path)\n if (sampled !== undefined)\n return html`<label sampled title=${i18next.t('figure.text.data-value-from-sample')}>\n <span>${label} <span drive>${i18next.t('figure.label.data-value-from-sample')}</span></span>\n <output>${typeof sampled === 'boolean' ? i18next.t(sampled ? 'figure.label.data-true' : 'figure.label.data-false') : typeof sampled === 'object' ? JSON.stringify(sampled) : String(sampled)}</output>\n </label>`\n const fallback = 'default' in node ? node.default : undefined\n const value = this.valuing[row.path] ?? fallback\n if (node.kind === 'number') {\n const ranged = node.min !== undefined && node.max !== undefined && node.max > node.min\n /*\n An angle is drawn as the controls' angles are -- dial, slider, box -- whether or not its field declares a range:\n one with none slides over one turn, and any angle can still be typed. 「방향 deg」 was a bare number field under\n 「머리 각도 deg」 on a slider (user 2026-11-12).\n */\n const angle = node.unit === 'deg'\n const slide = ranged ? { min: node.min!, max: node.max! } : angle ? { min: 0, max: 360 } : undefined\n const scrubFrom = Number(value ?? slide?.min ?? 0)\n return html`<label>\n ${this.scrubName(html`${label} <span drive>${unitWord(node.unit)}</span>`, node.unit ?? '', Number.isFinite(scrubFrom) ? scrubFrom : 0, ranged ? node.min! : -Infinity, ranged ? node.max! : Infinity, v => this.value(row, String(v)))}\n ${slide\n ? html`${this.renderDial({ unit: node.unit ?? '', ...slide }, Number(value ?? slide.min))}\n <input type=\"range\" min=${slide.min} max=${slide.max} step=${angle ? 1 : Math.max((slide.max - slide.min) / 100, 0.01)} .value=${String(value ?? slide.min)} @input=${(e: Event) => this.value(row, (e.target as HTMLInputElement).value)} />\n ${ranged\n ? this.typedBox(label, Number(value ?? slide.min), slide.min, slide.max, typed => this.value(row, String(typed)))\n : this.typedBox(label, Number(value ?? slide.min), -Infinity, Infinity, typed => this.value(row, String(typed)))}`\n : html`<input wide type=\"number\" step=\"any\" aria-label=${label} .value=${value === undefined ? '' : String(value)} @change=${(e: Event) => this.value(row, (e.target as HTMLInputElement).value)} />`}\n </label>`\n }\n /* A yes or no is a check box, not a list of two words to open (user 2026-11-12). Unchecked is false, as the board reads it. */\n if (node.kind === 'boolean')\n return html`<label>\n <span>${label}</span>\n <input type=\"checkbox\" aria-label=${label} .checked=${value === true} @change=${(e: Event) => this.value(row, String((e.target as HTMLInputElement).checked))} />\n </label>`\n const domain = domainOf(node)\n if (!domain.length)\n return html`<label>\n <span>${label}</span>\n <input aria-label=${label} .value=${value === undefined ? '' : String(value)} @change=${(e: Event) => this.value(row, (e.target as HTMLInputElement).value)} />\n </label>`\n return html`<label>\n <span>${label}</span>\n <select aria-label=${label} @change=${(e: Event) => this.value(row, (e.target as HTMLSelectElement).value)}>\n ${domain.map(v => html`<option value=${String(v)} ?selected=${v === value}>${typeof v === 'boolean' ? i18next.t(v ? 'figure.label.data-true' : 'figure.label.data-false') : v}</option>`)}\n </select>\n </label>`\n }\n\n private value(row: FigureDataRow, typed: string) {\n const value = typedValueOf(row.node, typed)\n const next = { ...this.valuing }\n if (typeof value === 'number' && Number.isNaN(value)) delete next[row.path]\n else next[row.path] = value\n this.valuing = next\n this.tellInstances('figureValues', this.valuing)\n }\n\n private move(group: string, playing: { clip: string; speed: number }) {\n this.moving = { ...this.moving, [group]: playing }\n this.release(playing.clip)\n this.tellInstances('motion', Object.fromEntries(Object.entries(this.moving).map(([id, m]) => [id, { ...m, paused: false }])))\n }\n\n private renderDial(control: { unit: string; min: number; max: number }, value: number) {\n if (control.unit !== 'deg') return html`<span></span>`\n const dial = dialShape(control.min, control.max, value)\n const span = dial.radius * 2 + 2\n return html`<svg dial viewBox=\"0 0 ${span} ${span}\" aria-hidden=\"true\">\n <path d=${dial.sector}></path>\n <circle cx=${dial.centre.x} cy=${dial.centre.y} r=${dial.radius}></circle>\n <line x1=${dial.centre.x} y1=${dial.centre.y} x2=${dial.needle.x} y2=${dial.needle.y}></line>\n </svg>`\n }\n\n private drive(clip: string, value: number) {\n this.driving = { ...this.driving, [clip]: value }\n if (value) this.release(clip)\n this.tellInstances('clips', this.driving)\n }\n\n /*\n A value given here wins over the clips for its control (things-scene's \\`parameters\\`), so a value left from trying held\n the control still while a clip played (robot dog, 2026-11-03). A clip played lets go of the controls it drives, as\n the detail view does (\\`parametersForClip\\`).\n */\n private release(clip: string) {\n const asset = this.asset\n if (!asset) return\n const next = parametersForClip(asset, this.giving, clip)\n if (Object.keys(next).length === Object.keys(this.giving).length) return\n this.giving = next\n this.tellInstances('parameters', this.giving)\n }\n\n /** Every value tried here let go: the figure stands in its default pose, and its clips move it again. Nothing is saved. */\n private clearTried() {\n this.giving = {}\n this.tellInstances('parameters', this.giving)\n }\n\n private give(id: string, value: number) {\n this.giving = { ...this.giving, [id]: value }\n this.tellInstances('parameters', this.giving)\n }\n\n private poseAsDefault() {\n this.dispatchEvent(new CustomEvent('part-edit', { detail: { edit: { kind: 'set-state-defaults', values: { ...this.giving } } }, bubbles: true, composed: true }))\n this.giving = {}\n }\n\n private tellInstances(key: 'clips' | 'parameters' | 'motion' | 'figureValues', values: Record<string, unknown> | null) {\n for (const component of this.scene?.root?.components ?? []) component.set?.(key, values === null ? null : { ...values })\n }\n\n /** The tried data to the figures standing now, as their \\`data\\`: the preview's board is not saved. */\n private tellData(data: unknown) {\n for (const component of this.scene?.root?.components ?? []) component.set?.('data', data === null || data === undefined ? null : structuredClone(data))\n }\n\n\n /** The data sample to the figures standing now. */\n private tellSample() {\n if (this.sample !== null && this.sample !== undefined) this.tellData(this.sample)\n }\n\n /** The sample legends as the scene's (its root container's, where a board's are): its tables choose again. */\n private tellLegends() {\n const container = this.scene?.rootContainer\n if (!container) return\n container.style = { ...this.legends }\n figureLegendSourcesChanged()\n }\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('sample') && this.scene) this.tellData(this.sample)\n if (changed.has('legends') && this.scene) this.tellLegends()\n if (!this.hasUpdated) return\n if (!this.active) {\n this.stale = true\n return\n }\n if (this.stale || changed.has('active')) {\n this.stale = false\n this.standUp()\n return\n }\n if (changed.has('revision') || changed.has('context')) {\n this.standUp()\n return\n }\n if (!changed.has('view')) return\n const before = changed.get('view') as ViewSettings | undefined\n const now = this.view ?? DEFAULT_VIEW\n if (before?.placement !== now.placement || before?.ceilingHeight !== now.ceilingHeight) this.standUp()\n else this.scene?.root?.set?.(sceneLook(now))\n }\n\n firstUpdated() {\n this.standUp()\n this.watcher = new ResizeObserver(() => {\n if (this.active) this.scene?.resize?.()\n })\n this.watcher.observe(this)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this.watcher?.disconnect()\n this.watcher = undefined\n this.teardown()\n }\n\n private standUp() {\n const asset = this.asset\n const view = this.view ?? DEFAULT_VIEW\n if (!asset || !asset.appearance.length) {\n this.cannot = i18next.t('figure.text.preview-needs-a-part')\n this.teardown()\n return\n }\n const signature = JSON.stringify([asset, view.placement, view.ceilingHeight, this.way])\n if (this.scene && this.standing === signature) return\n try {\n compileFigureAsset(asset)\n } catch {\n this.cannot = i18next.t('figure.text.preview-blocked-by-errors')\n this.teardown()\n return\n }\n try {\n /* Registered as a board registers it, under a type of this preview's own: a real type's drawings stay as they are. */\n const type = previewTypeOf(this.context)\n const size = this.authoredSize()\n /*\n The figure changed under a scene that is standing: the same type is registered again and the content made again\n inside the same 3D scene. Making a scene anew costs about a third of a second and its first drawing compiles the\n shaders again -- a value typed beside the preview held the screen for seconds. The scene is made anew only when\n there is none, for another figure, or when the content cannot be made again in place.\n */\n const again = this.scene?.rootContainer?.rebuildContentModel && this.registered === type\n if (!again) this.teardown()\n this.driving = {}\n this.moving = {}\n this.valuing = {}\n registerFigure(type, asset)\n this.registered = type\n /* Each instance stands in its body at the size it is asked (bodyAtSize), as a board reads it. */\n const boxOf = (asked: { x: number; y: number; z: number }) => bodyAtSize(asset, asked) ?? asked\n const { components, board } = this.way === 'one' ? previewOneInstance(type, boxOf(size)) : previewInstances(type, size, boxOf)\n this.board = board\n this.trying = this.way === 'one' ? { ...size } : undefined\n const model = {\n type: 'model-layer',\n width: board.width,\n height: board.height,\n /* As tall as the figure may grow: twice for the eight, the top of the height slider for the one. */\n depth: previewBoardDepth({ placement: asset.placement, base: { y: size.y } }, view.ceilingHeight, this.way === 'one' ? Math.max(1, (sizeSpanOf(asset, 'y')?.max ?? size.y) / size.y) : PREVIEW_FACTOR),\n threed: true,\n sky: 'color',\n ...sceneLook(view),\n placement: view.placement,\n heights: { floor: 0, ceiling: view.ceilingHeight },\n pixelRatio: Math.min(3, (window.devicePixelRatio || 1) * 2),\n components\n }\n if (again) {\n try {\n this.scene!.rootContainer!.rebuildContentModel!(model, { preserveThreeD: true })\n this.standing = signature\n this.cannot = ''\n this.tellLegends()\n this.tellSample()\n this.followTags()\n return\n } catch {\n this.teardown()\n registerFigure(type, asset)\n this.registered = type\n }\n }\n this.scene = create({\n target: this.stage,\n model,\n style: { ...this.legends },\n mode: 0\n }) as SceneHandle\n this.standing = signature\n this.looking = 'perspective'\n this.scene.resize?.()\n this.scene.fit?.('ratio')\n this.scene.root?.fitCameraToModel?.()\n this.cannot = ''\n this.tellSample()\n this.followTags()\n } catch (error) {\n this.cannot = (error as Error).message\n }\n }\n\n private teardown() {\n cancelAnimationFrame(this.tagFrame)\n this.tags = []\n this.scene?.dispose?.()\n this.scene = undefined\n this.standing = undefined\n if (this.registered) unregisterFigure(this.registered)\n this.registered = undefined\n }\n}\n"]}
|
|
@@ -6,7 +6,7 @@ import { i18next, localize } from '@operato/i18n';
|
|
|
6
6
|
import { SidePanelStyles } from '@things-factory/figure-viewer/dist-client/side-panel-styles.js';
|
|
7
7
|
import { AXES, followOf, followableAxes, measureNow } from './links.js';
|
|
8
8
|
import { scrubLabel } from './live.js';
|
|
9
|
-
import { measureFactor, sameSizeSource, sizeInputOf, sizeRelationOf, sizeRelationSteps, sourceMeasureOf, suggestedSizeSource } from './size-response.js';
|
|
9
|
+
import { measureFactor, sameSizeSource, sizeAxisWord, sizeInputOf, sizeRelationOf, sizeRelationSteps, sourceMeasureOf, suggestedSizeSource } from './size-response.js';
|
|
10
10
|
/**
|
|
11
11
|
* A part's measures and what each follows, one row an axis (ADR-0159 3). Made to follow, a measure takes what the part
|
|
12
12
|
* hangs from, along the axis its own axis lies on as it stands -- the author turns it on, nothing more. Another source
|
|
@@ -28,10 +28,13 @@ let FigureSizeEditor = class FigureSizeEditor extends localize(i18next)(LitEleme
|
|
|
28
28
|
:host { display: block; min-width: 0; }
|
|
29
29
|
.heading, .fields {
|
|
30
30
|
display: grid;
|
|
31
|
-
grid-template-columns: 24px minmax(55px, .85fr) 32px minmax(65px, 1fr) 42px;
|
|
31
|
+
grid-template-columns: var(--axis-column, 24px) minmax(55px, .85fr) 32px minmax(65px, 1fr) 42px;
|
|
32
32
|
gap: 6px;
|
|
33
33
|
align-items: center;
|
|
34
34
|
}
|
|
35
|
+
/* A round body's rows name its diameter (「X·Z · 지름」): every row's first column widens alike, so the rows still line up. */
|
|
36
|
+
:host([named-axes]) { --axis-column: 76px; }
|
|
37
|
+
.fields > span:first-child { white-space: nowrap; }
|
|
35
38
|
.heading { color: var(--md-sys-color-on-surface-variant); padding-bottom: 6px; }
|
|
36
39
|
.dimension { padding: 3px 0; }
|
|
37
40
|
.variable { display: flex; align-items: center; justify-content: center; min-height: var(--figure-control-height); }
|
|
@@ -96,6 +99,7 @@ let FigureSizeEditor = class FigureSizeEditor extends localize(i18next)(LitEleme
|
|
|
96
99
|
const axes = followableAxes(asset, this.partId);
|
|
97
100
|
const targets = asset.appearance.map(a => a.target).filter(p => p !== this.partId && followableAxes(asset, p).length);
|
|
98
101
|
const uniform = asset.sizing === 'uniform';
|
|
102
|
+
this.toggleAttribute('named-axes', axes.some(axis => measureFactor(asset, this.partId, axis) === 2));
|
|
99
103
|
return html `
|
|
100
104
|
<div class="heading" aria-hidden="true">
|
|
101
105
|
<span>${i18next.t('figure.label.size-axis')}</span><span>${i18next.t('figure.label.size-measure')}</span><span>${i18next.t('figure.label.size-follows')}</span><span>${i18next.t('figure.label.size-source')}</span><span></span>
|
|
@@ -115,7 +119,7 @@ let FigureSizeEditor = class FigureSizeEditor extends localize(i18next)(LitEleme
|
|
|
115
119
|
}
|
|
116
120
|
const currentMode = mode === 'custom' ? 'ratio' : mode;
|
|
117
121
|
const input = sizeInputOf(asset, this.partId, axis);
|
|
118
|
-
const label =
|
|
122
|
+
const label = sizeAxisWord(asset, this.partId, axis, i18next.t('figure.label.size-diameter'));
|
|
119
123
|
/* The selects show when asked for, or when what it follows is not what its fastening gives -- or nothing is. */
|
|
120
124
|
const choosing = relation.variable && (this.choosing.has(key) || !sameSizeSource(source, suggested));
|
|
121
125
|
const selectedSource = source ? (source.of === 'instance' ? '@figure' : source.part) : '@custom';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figure-size-editor.js","sourceRoot":"","sources":["../../client/modeller/figure-size-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { live } from 'lit/directives/live.js'\nimport { i18next, localize } from '@operato/i18n'\nimport type { FigureAuthoringAction } from '@hatiolab/figure-model'\nimport { SidePanelStyles } from '@things-factory/figure-viewer/dist-client/side-panel-styles.js'\nimport type { FigureRevision } from './revision.js'\nimport { AXES, followOf, followableAxes, measureNow, type Axis } from './links.js'\nimport { scrubLabel } from './live.js'\nimport {\n measureFactor,\n sameSizeSource,\n sizeInputOf,\n sizeRelationOf,\n sizeRelationSteps,\n sourceMeasureOf,\n suggestedSizeSource,\n type SizeMode,\n type SizeSource\n} from './size-response.js'\n\n/**\n * A part's measures and what each follows, one row an axis (ADR-0159 3). Made to follow, a measure takes what the part\n * hangs from, along the axis its own axis lies on as it stands -- the author turns it on, nothing more. Another source\n * is there when asked for, or when there is no such axis (the part lies at an angle) or the measure already follows\n * something else; each way of following says what it will do, in millimetres. A measure of the part's own is a value in\n * hand as on any field (user 2026-09-24): drawn while it is typed or its label is dragged, written once on the release.\n */\n@customElement('figure-size-editor')\nexport class FigureSizeEditor extends localize(i18next)(LitElement) {\n @property({ attribute: false }) revision?: FigureRevision\n @property() partId = ''\n @property({ type: Boolean }) locked = false\n @state() private error = ''\n /* Rows whose source the author asked to choose: `<part>:<axis>`. */\n @state() private choosing = new Set<string>()\n private equivalentModes = new Map<string, 'ratio' | 'difference'>()\n static styles = [SidePanelStyles, css`\n :host { display: block; min-width: 0; }\n .heading, .fields {\n display: grid;\n grid-template-columns: 24px minmax(55px, .85fr) 32px minmax(65px, 1fr) 42px;\n gap: 6px;\n align-items: center;\n }\n .heading { color: var(--md-sys-color-on-surface-variant); padding-bottom: 6px; }\n .dimension { padding: 3px 0; }\n .variable { display: flex; align-items: center; justify-content: center; min-height: var(--figure-control-height); }\n .source { grid-column: 4 / -1; display: flex; align-items: center; gap: 6px; min-width: 0; }\n .source span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .modes { margin: 4px 0 2px 30px; }\n .result { margin: 0 0 6px 30px; }\n [role=alert] { color: var(--md-sys-color-error); }\n `]\n private tell(name: 'size-input' | 'size-typing' | 'size-let-go', detail?: object) {\n this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true }))\n }\n private apply(steps: FigureAuthoringAction[]) {\n if (this.locked) return\n this.error = ''\n this.dispatchEvent(new CustomEvent('size-recipe', { detail: { steps }, bubbles: true, composed: true }))\n this.requestUpdate()\n }\n private configure(axis: Axis, source: SizeSource, mode: 'ratio' | 'difference', mm?: number) {\n if (this.locked || this.revision?.asset.sizing === 'uniform') return\n try {\n this.apply(sizeRelationSteps(this.revision!, this.partId, axis, source, mode, mm))\n this.equivalentModes.set(`${this.partId}:${axis}`, mode)\n } catch (e) {\n this.error = i18next.t((e as Error).message === 'SIZE_VALUE' ? 'figure.text.size-invalid' : 'figure.text.size-unavailable-source')\n this.requestUpdate()\n }\n }\n private choose(key: string, on: boolean) {\n const next = new Set(this.choosing)\n if (on) next.add(key)\n else next.delete(key)\n this.choosing = next\n }\n /** What a source is called on the panel: the figure, or the part, with the axis it is measured along. */\n private sourceWords(source: SizeSource) {\n return `${source.of === 'instance' ? i18next.t('figure.label.size-figure') : source.part} ${source.axis.toUpperCase()}`\n }\n /** What following this way does, in millimetres: the share it is of its source, or the difference it keeps. */\n private resultWords(revision: FigureRevision, source: SizeSource, mode: 'ratio' | 'difference', mm: number | undefined) {\n const theirs = sourceMeasureOf(revision, source)\n if (mm === undefined || theirs === undefined || !(theirs > 0)) return nothing\n const words = { source: this.sourceWords(source), size: Number(theirs.toFixed(1)) }\n if (mode === 'ratio') return i18next.t('figure.text.size-ratio-result', { ...words, pct: Number(((mm / theirs) * 100).toFixed(1)) })\n const gap = Number((theirs - mm).toFixed(1))\n if (Math.abs(gap) < 0.05) return i18next.t('figure.text.size-difference-same', words)\n return i18next.t(gap > 0 ? 'figure.text.size-difference-less' : 'figure.text.size-difference-more', { ...words, gap: Math.abs(gap) })\n }\n render() {\n const revision = this.revision\n if (!revision) return nothing\n const asset = revision.asset\n const axes = followableAxes(asset, this.partId)\n const targets = asset.appearance.map(a => a.target).filter(p => p !== this.partId && followableAxes(asset, p).length)\n const uniform = asset.sizing === 'uniform'\n return html`\n <div class=\"heading\" aria-hidden=\"true\">\n <span>${i18next.t('figure.label.size-axis')}</span><span>${i18next.t('figure.label.size-measure')}</span><span>${i18next.t('figure.label.size-follows')}</span><span>${i18next.t('figure.label.size-source')}</span><span></span>\n </div>\n ${axes.map(axis => {\n const key = `${this.partId}:${axis}`\n const mm = measureNow(revision, this.partId, axis)\n const relation = sizeRelationOf(revision, this.partId, axis)\n const f = followOf(asset, this.partId, axis)\n const source = relation.source\n const suggested = suggestedSizeSource(asset, this.partId, axis)\n let mode: SizeMode = relation.mode\n if (source && (f.of === 'instance' || f.of === 'part') && !f.plus) {\n const same = (source.of === 'part' ? measureFactor(asset, source.part, source.axis) : 1) / measureFactor(asset, this.partId, axis)\n if (Math.abs((f.times ?? 1) - same) < 1e-6) mode = this.equivalentModes.get(key) ?? mode\n }\n const currentMode = mode === 'custom' ? 'ratio' : mode\n const input = sizeInputOf(asset, this.partId, axis)\n const label = `${axis.toUpperCase()}${measureFactor(asset, this.partId, axis) === 2 ? ' · ' + i18next.t('figure.label.size-diameter') : ''}`\n /* The selects show when asked for, or when what it follows is not what its fastening gives -- or nothing is. */\n const choosing = relation.variable && (this.choosing.has(key) || !sameSizeSource(source, suggested))\n const selectedSource = source ? (source.of === 'instance' ? '@figure' : source.part) : '@custom'\n const sourceAxes = source?.of === 'part' ? followableAxes(asset, source.part) : AXES\n const factor = measureFactor(asset, this.partId, axis)\n /* Its own measure, no rule over it: in hand while typed or scrubbed, as the input it is (a diameter, its radius). */\n const own = !relation.variable && !!input && !this.locked\n const typingSize = (e: Event) => {\n const value = (e.target as HTMLInputElement).valueAsNumber\n if (own && Number.isFinite(value) && value > 0) this.tell('size-typing', { input, value: value / factor })\n }\n const scrubSize = (down: PointerEvent) => {\n if (!own || mm === undefined) return\n const field = (down.currentTarget as HTMLElement).closest('.fields')?.querySelector<HTMLInputElement>('input[type=number]')\n if (!field) return\n scrubLabel(down, { value: mm, unit: 'mm' }, {\n move: value => {\n field.value = String(value)\n if (value > 0) this.tell('size-typing', { input, value: value / factor })\n },\n release: value => {\n if (!(value > 0)) {\n field.value = String(mm)\n this.tell('size-let-go')\n return\n }\n this.error = ''\n this.tell('size-input', { input, value: value / factor, part: this.partId })\n this.requestUpdate()\n },\n cancel: () => {\n field.value = String(mm)\n this.tell('size-let-go')\n }\n })\n }\n const changeSize = (e: Event) => {\n const value = (e.target as HTMLInputElement).valueAsNumber\n if (!(Number.isFinite(value) && value > 0)) {\n this.error = i18next.t('figure.text.size-invalid')\n this.requestUpdate()\n return\n }\n if (relation.variable && source && mode !== 'custom') this.configure(axis, source, mode, value)\n else if (!relation.variable && input) {\n this.error = ''\n this.tell('size-input', { input, value: value / factor, part: this.partId })\n this.requestUpdate()\n }\n }\n const follows = (e: Event) => {\n if ((e.target as HTMLInputElement).checked) {\n if (suggested) this.configure(axis, suggested, 'ratio')\n else {\n /* At an angle to what it hangs from: which of its measures it follows is the author's to pick. */\n this.choose(key, true)\n this.error = i18next.t('figure.text.size-unpaired')\n }\n } else if (mm !== undefined) {\n this.choose(key, false)\n this.apply([{ kind: 'unlink-dimension', part: this.partId, axis, mm: mm / measureFactor(asset, this.partId, axis) }])\n }\n }\n return html`<div class=\"dimension\" data-axis=${axis}>\n <div class=\"fields\">\n <span ?scrub=${own} @pointerdown=${scrubSize}>${label}</span>\n <input type=\"number\" step=\"any\" min=\"0\" aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-measure')}`} .value=${live(mm === undefined ? '' : String(Number(mm.toFixed(6))))}\n ?disabled=${this.locked} ?readonly=${relation.variable ? mode === 'custom' || uniform : !input} @input=${typingSize} @change=${changeSize}>\n <label class=\"variable\"><input type=\"checkbox\" aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-follows')}`} .checked=${live(relation.variable || this.choosing.has(key))} ?disabled=${this.locked || uniform}\n @change=${follows}></label>\n ${choosing || (this.choosing.has(key) && !relation.variable)\n ? html`\n <select aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-source')}`} .value=${live(selectedSource)} ?disabled=${this.locked || uniform}\n @change=${(e: Event) => {\n const target = (e.target as HTMLSelectElement).value\n const possible = target === '@figure' ? AXES : followableAxes(asset, target)\n const targetAxis = possible.includes(source?.axis ?? axis) ? (source?.axis ?? axis) : possible[0]!\n this.configure(axis, target === '@figure' ? { of: 'instance', axis: targetAxis } : { of: 'part', part: target, axis: targetAxis }, currentMode)\n }}>\n ${!source ? html`<option value=\"@custom\" disabled>${i18next.t(relation.variable ? 'figure.label.size-existing-rule' : 'figure.label.size-pick-source')}</option>` : nothing}\n <option value=\"@figure\" ?selected=${selectedSource === '@figure'}>${i18next.t('figure.label.size-figure')}</option>\n ${targets.map(p => html`<option value=${p} ?selected=${selectedSource === p}>${p}</option>`)}\n </select>\n <select aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-source-axis')}`} .value=${live(source?.axis ?? axis)} ?disabled=${this.locked || uniform || !source}\n @change=${(e: Event) => source && this.configure(axis, { ...source, axis: (e.target as HTMLSelectElement).value as Axis }, currentMode)}>\n ${sourceAxes.map(a => html`<option value=${a} ?selected=${a === (source?.axis ?? axis)}>${a.toUpperCase()}</option>`)}\n </select>`\n : relation.variable && source\n ? html`<div class=\"source\">\n <span>${this.sourceWords(source)}</span>\n <button quiet ?disabled=${this.locked || uniform} @click=${() => this.choose(key, true)}>${i18next.t('figure.button.size-other-source')}</button>\n </div>`\n : html`<span></span><span></span>`}\n </div>\n ${relation.variable\n ? html`<div class=\"modes\" choice-row>\n ${(['ratio', 'difference'] as const).map(\n m => html`<label toggle><input type=\"radio\" name=${`mode-${this.partId}-${axis}`} .checked=${live(mode === m)} ?disabled=${this.locked || uniform || !source}\n @change=${() => source && this.configure(axis, source, m)}>${i18next.t(`figure.label.size-${m}`)}</label>`\n )}\n </div>\n ${mode === 'custom'\n ? html`<p hint>${i18next.t('figure.text.size-custom-rule')}</p>`\n : source\n ? html`<p hint class=\"result\">${this.resultWords(revision, source, currentMode, mm)}</p>`\n : nothing}`\n : nothing}\n </div>`\n })}\n ${uniform ? html`<p hint>${i18next.t('figure.text.size-uniform')}</p>` : nothing}\n ${this.error ? html`<p hint role=\"alert\">${this.error}</p>` : nothing}\n `\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"figure-size-editor.js","sourceRoot":"","sources":["../../client/modeller/figure-size-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { live } from 'lit/directives/live.js'\nimport { i18next, localize } from '@operato/i18n'\nimport type { FigureAuthoringAction } from '@hatiolab/figure-model'\nimport { SidePanelStyles } from '@things-factory/figure-viewer/dist-client/side-panel-styles.js'\nimport type { FigureRevision } from './revision.js'\nimport { AXES, followOf, followableAxes, measureNow, type Axis } from './links.js'\nimport { scrubLabel } from './live.js'\nimport {\n measureFactor,\n sameSizeSource,\n sizeAxisWord,\n sizeInputOf,\n sizeRelationOf,\n sizeRelationSteps,\n sourceMeasureOf,\n suggestedSizeSource,\n type SizeMode,\n type SizeSource\n} from './size-response.js'\n\n/**\n * A part's measures and what each follows, one row an axis (ADR-0159 3). Made to follow, a measure takes what the part\n * hangs from, along the axis its own axis lies on as it stands -- the author turns it on, nothing more. Another source\n * is there when asked for, or when there is no such axis (the part lies at an angle) or the measure already follows\n * something else; each way of following says what it will do, in millimetres. A measure of the part's own is a value in\n * hand as on any field (user 2026-09-24): drawn while it is typed or its label is dragged, written once on the release.\n */\n@customElement('figure-size-editor')\nexport class FigureSizeEditor extends localize(i18next)(LitElement) {\n @property({ attribute: false }) revision?: FigureRevision\n @property() partId = ''\n @property({ type: Boolean }) locked = false\n @state() private error = ''\n /* Rows whose source the author asked to choose: `<part>:<axis>`. */\n @state() private choosing = new Set<string>()\n private equivalentModes = new Map<string, 'ratio' | 'difference'>()\n static styles = [SidePanelStyles, css`\n :host { display: block; min-width: 0; }\n .heading, .fields {\n display: grid;\n grid-template-columns: var(--axis-column, 24px) minmax(55px, .85fr) 32px minmax(65px, 1fr) 42px;\n gap: 6px;\n align-items: center;\n }\n /* A round body's rows name its diameter (「X·Z · 지름」): every row's first column widens alike, so the rows still line up. */\n :host([named-axes]) { --axis-column: 76px; }\n .fields > span:first-child { white-space: nowrap; }\n .heading { color: var(--md-sys-color-on-surface-variant); padding-bottom: 6px; }\n .dimension { padding: 3px 0; }\n .variable { display: flex; align-items: center; justify-content: center; min-height: var(--figure-control-height); }\n .source { grid-column: 4 / -1; display: flex; align-items: center; gap: 6px; min-width: 0; }\n .source span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .modes { margin: 4px 0 2px 30px; }\n .result { margin: 0 0 6px 30px; }\n [role=alert] { color: var(--md-sys-color-error); }\n `]\n private tell(name: 'size-input' | 'size-typing' | 'size-let-go', detail?: object) {\n this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true }))\n }\n private apply(steps: FigureAuthoringAction[]) {\n if (this.locked) return\n this.error = ''\n this.dispatchEvent(new CustomEvent('size-recipe', { detail: { steps }, bubbles: true, composed: true }))\n this.requestUpdate()\n }\n private configure(axis: Axis, source: SizeSource, mode: 'ratio' | 'difference', mm?: number) {\n if (this.locked || this.revision?.asset.sizing === 'uniform') return\n try {\n this.apply(sizeRelationSteps(this.revision!, this.partId, axis, source, mode, mm))\n this.equivalentModes.set(`${this.partId}:${axis}`, mode)\n } catch (e) {\n this.error = i18next.t((e as Error).message === 'SIZE_VALUE' ? 'figure.text.size-invalid' : 'figure.text.size-unavailable-source')\n this.requestUpdate()\n }\n }\n private choose(key: string, on: boolean) {\n const next = new Set(this.choosing)\n if (on) next.add(key)\n else next.delete(key)\n this.choosing = next\n }\n /** What a source is called on the panel: the figure, or the part, with the axis it is measured along. */\n private sourceWords(source: SizeSource) {\n return `${source.of === 'instance' ? i18next.t('figure.label.size-figure') : source.part} ${source.axis.toUpperCase()}`\n }\n /** What following this way does, in millimetres: the share it is of its source, or the difference it keeps. */\n private resultWords(revision: FigureRevision, source: SizeSource, mode: 'ratio' | 'difference', mm: number | undefined) {\n const theirs = sourceMeasureOf(revision, source)\n if (mm === undefined || theirs === undefined || !(theirs > 0)) return nothing\n const words = { source: this.sourceWords(source), size: Number(theirs.toFixed(1)) }\n if (mode === 'ratio') return i18next.t('figure.text.size-ratio-result', { ...words, pct: Number(((mm / theirs) * 100).toFixed(1)) })\n const gap = Number((theirs - mm).toFixed(1))\n if (Math.abs(gap) < 0.05) return i18next.t('figure.text.size-difference-same', words)\n return i18next.t(gap > 0 ? 'figure.text.size-difference-less' : 'figure.text.size-difference-more', { ...words, gap: Math.abs(gap) })\n }\n render() {\n const revision = this.revision\n if (!revision) return nothing\n const asset = revision.asset\n const axes = followableAxes(asset, this.partId)\n const targets = asset.appearance.map(a => a.target).filter(p => p !== this.partId && followableAxes(asset, p).length)\n const uniform = asset.sizing === 'uniform'\n this.toggleAttribute('named-axes', axes.some(axis => measureFactor(asset, this.partId, axis) === 2))\n return html`\n <div class=\"heading\" aria-hidden=\"true\">\n <span>${i18next.t('figure.label.size-axis')}</span><span>${i18next.t('figure.label.size-measure')}</span><span>${i18next.t('figure.label.size-follows')}</span><span>${i18next.t('figure.label.size-source')}</span><span></span>\n </div>\n ${axes.map(axis => {\n const key = `${this.partId}:${axis}`\n const mm = measureNow(revision, this.partId, axis)\n const relation = sizeRelationOf(revision, this.partId, axis)\n const f = followOf(asset, this.partId, axis)\n const source = relation.source\n const suggested = suggestedSizeSource(asset, this.partId, axis)\n let mode: SizeMode = relation.mode\n if (source && (f.of === 'instance' || f.of === 'part') && !f.plus) {\n const same = (source.of === 'part' ? measureFactor(asset, source.part, source.axis) : 1) / measureFactor(asset, this.partId, axis)\n if (Math.abs((f.times ?? 1) - same) < 1e-6) mode = this.equivalentModes.get(key) ?? mode\n }\n const currentMode = mode === 'custom' ? 'ratio' : mode\n const input = sizeInputOf(asset, this.partId, axis)\n const label = sizeAxisWord(asset, this.partId, axis, i18next.t('figure.label.size-diameter'))\n /* The selects show when asked for, or when what it follows is not what its fastening gives -- or nothing is. */\n const choosing = relation.variable && (this.choosing.has(key) || !sameSizeSource(source, suggested))\n const selectedSource = source ? (source.of === 'instance' ? '@figure' : source.part) : '@custom'\n const sourceAxes = source?.of === 'part' ? followableAxes(asset, source.part) : AXES\n const factor = measureFactor(asset, this.partId, axis)\n /* Its own measure, no rule over it: in hand while typed or scrubbed, as the input it is (a diameter, its radius). */\n const own = !relation.variable && !!input && !this.locked\n const typingSize = (e: Event) => {\n const value = (e.target as HTMLInputElement).valueAsNumber\n if (own && Number.isFinite(value) && value > 0) this.tell('size-typing', { input, value: value / factor })\n }\n const scrubSize = (down: PointerEvent) => {\n if (!own || mm === undefined) return\n const field = (down.currentTarget as HTMLElement).closest('.fields')?.querySelector<HTMLInputElement>('input[type=number]')\n if (!field) return\n scrubLabel(down, { value: mm, unit: 'mm' }, {\n move: value => {\n field.value = String(value)\n if (value > 0) this.tell('size-typing', { input, value: value / factor })\n },\n release: value => {\n if (!(value > 0)) {\n field.value = String(mm)\n this.tell('size-let-go')\n return\n }\n this.error = ''\n this.tell('size-input', { input, value: value / factor, part: this.partId })\n this.requestUpdate()\n },\n cancel: () => {\n field.value = String(mm)\n this.tell('size-let-go')\n }\n })\n }\n const changeSize = (e: Event) => {\n const value = (e.target as HTMLInputElement).valueAsNumber\n if (!(Number.isFinite(value) && value > 0)) {\n this.error = i18next.t('figure.text.size-invalid')\n this.requestUpdate()\n return\n }\n if (relation.variable && source && mode !== 'custom') this.configure(axis, source, mode, value)\n else if (!relation.variable && input) {\n this.error = ''\n this.tell('size-input', { input, value: value / factor, part: this.partId })\n this.requestUpdate()\n }\n }\n const follows = (e: Event) => {\n if ((e.target as HTMLInputElement).checked) {\n if (suggested) this.configure(axis, suggested, 'ratio')\n else {\n /* At an angle to what it hangs from: which of its measures it follows is the author's to pick. */\n this.choose(key, true)\n this.error = i18next.t('figure.text.size-unpaired')\n }\n } else if (mm !== undefined) {\n this.choose(key, false)\n this.apply([{ kind: 'unlink-dimension', part: this.partId, axis, mm: mm / measureFactor(asset, this.partId, axis) }])\n }\n }\n return html`<div class=\"dimension\" data-axis=${axis}>\n <div class=\"fields\">\n <span ?scrub=${own} @pointerdown=${scrubSize}>${label}</span>\n <input type=\"number\" step=\"any\" min=\"0\" aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-measure')}`} .value=${live(mm === undefined ? '' : String(Number(mm.toFixed(6))))}\n ?disabled=${this.locked} ?readonly=${relation.variable ? mode === 'custom' || uniform : !input} @input=${typingSize} @change=${changeSize}>\n <label class=\"variable\"><input type=\"checkbox\" aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-follows')}`} .checked=${live(relation.variable || this.choosing.has(key))} ?disabled=${this.locked || uniform}\n @change=${follows}></label>\n ${choosing || (this.choosing.has(key) && !relation.variable)\n ? html`\n <select aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-source')}`} .value=${live(selectedSource)} ?disabled=${this.locked || uniform}\n @change=${(e: Event) => {\n const target = (e.target as HTMLSelectElement).value\n const possible = target === '@figure' ? AXES : followableAxes(asset, target)\n const targetAxis = possible.includes(source?.axis ?? axis) ? (source?.axis ?? axis) : possible[0]!\n this.configure(axis, target === '@figure' ? { of: 'instance', axis: targetAxis } : { of: 'part', part: target, axis: targetAxis }, currentMode)\n }}>\n ${!source ? html`<option value=\"@custom\" disabled>${i18next.t(relation.variable ? 'figure.label.size-existing-rule' : 'figure.label.size-pick-source')}</option>` : nothing}\n <option value=\"@figure\" ?selected=${selectedSource === '@figure'}>${i18next.t('figure.label.size-figure')}</option>\n ${targets.map(p => html`<option value=${p} ?selected=${selectedSource === p}>${p}</option>`)}\n </select>\n <select aria-label=${`${this.partId} ${label} ${i18next.t('figure.label.size-source-axis')}`} .value=${live(source?.axis ?? axis)} ?disabled=${this.locked || uniform || !source}\n @change=${(e: Event) => source && this.configure(axis, { ...source, axis: (e.target as HTMLSelectElement).value as Axis }, currentMode)}>\n ${sourceAxes.map(a => html`<option value=${a} ?selected=${a === (source?.axis ?? axis)}>${a.toUpperCase()}</option>`)}\n </select>`\n : relation.variable && source\n ? html`<div class=\"source\">\n <span>${this.sourceWords(source)}</span>\n <button quiet ?disabled=${this.locked || uniform} @click=${() => this.choose(key, true)}>${i18next.t('figure.button.size-other-source')}</button>\n </div>`\n : html`<span></span><span></span>`}\n </div>\n ${relation.variable\n ? html`<div class=\"modes\" choice-row>\n ${(['ratio', 'difference'] as const).map(\n m => html`<label toggle><input type=\"radio\" name=${`mode-${this.partId}-${axis}`} .checked=${live(mode === m)} ?disabled=${this.locked || uniform || !source}\n @change=${() => source && this.configure(axis, source, m)}>${i18next.t(`figure.label.size-${m}`)}</label>`\n )}\n </div>\n ${mode === 'custom'\n ? html`<p hint>${i18next.t('figure.text.size-custom-rule')}</p>`\n : source\n ? html`<p hint class=\"result\">${this.resultWords(revision, source, currentMode, mm)}</p>`\n : nothing}`\n : nothing}\n </div>`\n })}\n ${uniform ? html`<p hint>${i18next.t('figure.text.size-uniform')}</p>` : nothing}\n ${this.error ? html`<p hint role=\"alert\">${this.error}</p>` : nothing}\n `\n }\n}\n"]}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/** A type as typed, made into the shape a type has: lower-case letters and digits joined by single hyphens. */
|
|
2
2
|
export declare function typeOf(raw: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* The identifier as it is being typed: `typeOf`, but the hyphen just typed at the end stays, so the next word can follow
|
|
5
|
+
* it (tutorial 2026-11-11: `fork-agv` typed key by key came out `forkagv`). The save takes `typeOf` of it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function typingTypeOf(raw: string): string;
|
|
3
8
|
/**
|
|
4
9
|
* Whether this name could be released, by the format's own rules (`type-not-identifier`, `type-is-placeholder`).
|
|
5
10
|
* Saving under it is not blocked -- it can still change before release -- but the author hears it now.
|
|
@@ -8,6 +8,13 @@ import { isPlaceholderType, TYPE_LENGTH, TYPE_PATTERN } from '@hatiolab/figure-m
|
|
|
8
8
|
export function typeOf(raw) {
|
|
9
9
|
return raw.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The identifier as it is being typed: `typeOf`, but the hyphen just typed at the end stays, so the next word can follow
|
|
13
|
+
* it (tutorial 2026-11-11: `fork-agv` typed key by key came out `forkagv`). The save takes `typeOf` of it.
|
|
14
|
+
*/
|
|
15
|
+
export function typingTypeOf(raw) {
|
|
16
|
+
return raw.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+/, '');
|
|
17
|
+
}
|
|
11
18
|
/**
|
|
12
19
|
* Whether this name could be released, by the format's own rules (`type-not-identifier`, `type-is-placeholder`).
|
|
13
20
|
* Saving under it is not blocked -- it can still change before release -- but the author hears it now.
|