@things-factory/figure-ui 10.1.205 → 10.1.207
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/editor-styles.ts +16 -0
- package/client/modeller/editor.ts +53 -137
- package/client/modeller/fasten-form.ts +50 -11
- package/client/modeller/figure-facts.ts +1 -1
- package/client/modeller/figure-fasten-dialog.ts +3 -2
- package/client/modeller/figure-history-panel.ts +1 -29
- package/client/modeller/figure-links.ts +2 -2
- package/client/modeller/figure-preview.ts +10 -12
- package/client/modeller/figure-verdict.ts +2 -17
- package/client/modeller/gizmo.ts +10 -0
- package/client/modeller/keys.ts +10 -1
- package/client/modeller/links.ts +32 -41
- package/client/modeller/maturity.ts +11 -27
- package/client/modeller/palette.ts +1 -1
- package/client/modeller/product-session.ts +16 -4
- package/client/modeller/refusal-teller.ts +3 -25
- package/client/modeller/refusals.ts +20 -33
- package/client/pages/figure-modeller-page.ts +7 -22
- package/dist-client/modeller/editor-styles.js +16 -0
- package/dist-client/modeller/editor-styles.js.map +1 -1
- package/dist-client/modeller/editor.d.ts +8 -11
- package/dist-client/modeller/editor.js +57 -138
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/fasten-form.d.ts +16 -7
- package/dist-client/modeller/fasten-form.js +45 -11
- package/dist-client/modeller/fasten-form.js.map +1 -1
- package/dist-client/modeller/figure-facts.js +1 -1
- package/dist-client/modeller/figure-facts.js.map +1 -1
- package/dist-client/modeller/figure-fasten-dialog.js +3 -3
- package/dist-client/modeller/figure-fasten-dialog.js.map +1 -1
- package/dist-client/modeller/figure-history-panel.d.ts +0 -16
- package/dist-client/modeller/figure-history-panel.js +1 -27
- package/dist-client/modeller/figure-history-panel.js.map +1 -1
- package/dist-client/modeller/figure-links.js +2 -2
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/figure-preview.js +8 -11
- package/dist-client/modeller/figure-preview.js.map +1 -1
- package/dist-client/modeller/figure-verdict.d.ts +0 -5
- package/dist-client/modeller/figure-verdict.js +2 -21
- package/dist-client/modeller/figure-verdict.js.map +1 -1
- package/dist-client/modeller/gizmo.d.ts +6 -0
- package/dist-client/modeller/gizmo.js +11 -0
- package/dist-client/modeller/gizmo.js.map +1 -1
- package/dist-client/modeller/keys.d.ts +1 -1
- package/dist-client/modeller/keys.js +6 -0
- package/dist-client/modeller/keys.js.map +1 -1
- package/dist-client/modeller/links.d.ts +16 -22
- package/dist-client/modeller/links.js +26 -39
- package/dist-client/modeller/links.js.map +1 -1
- package/dist-client/modeller/maturity.d.ts +2 -4
- package/dist-client/modeller/maturity.js +12 -26
- package/dist-client/modeller/maturity.js.map +1 -1
- package/dist-client/modeller/palette.js +1 -1
- package/dist-client/modeller/palette.js.map +1 -1
- package/dist-client/modeller/product-session.d.ts +15 -13
- package/dist-client/modeller/product-session.js +15 -5
- package/dist-client/modeller/product-session.js.map +1 -1
- package/dist-client/modeller/refusal-teller.d.ts +1 -12
- package/dist-client/modeller/refusal-teller.js +3 -22
- package/dist-client/modeller/refusal-teller.js.map +1 -1
- package/dist-client/modeller/refusals.d.ts +7 -17
- package/dist-client/modeller/refusals.js +17 -34
- package/dist-client/modeller/refusals.js.map +1 -1
- package/dist-client/pages/figure-modeller-page.d.ts +1 -3
- package/dist-client/pages/figure-modeller-page.js +7 -23
- package/dist-client/pages/figure-modeller-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/test/browser/acceptance-page.js +4 -4
- package/test/browser/detail-page.js +1 -3
- package/test/browser/detail-tabs-page.js +1 -2
- package/test/browser/links.check.mjs +32 -50
- package/test/browser/modeller.check.mjs +46 -19
- package/test/browser/parts-page.js +2 -2
- package/test/browser/parts.check.mjs +51 -12
- package/test/browser/product-page.check.mjs +6 -9
- package/test/browser/product-page.js +1 -2
- package/test/browser/screen-page.js +2 -6
- package/test/browser/screen.check.mjs +8 -65
- package/test/browser/section.check.mjs +27 -0
- package/test/fasten-form.test.ts +42 -2
- package/test/first-minute.test.ts +2 -3
- package/test/fixtures/joint-column.json +1 -66
- package/test/fixtures/joint-roller.json +1 -66
- package/test/fixtures/robot-arm-6dof.json +2 -67
- package/test/gizmo.test.ts +12 -1
- package/test/keys.test.ts +11 -0
- package/test/links.test.ts +39 -34
- package/test/parts-wiring.test.ts +1 -1
- package/test/properties.test.ts +9 -12
- package/test/refusals.test.ts +20 -42
- package/test/resize-with-placement.test.ts +13 -15
- package/test/revision.test.ts +1 -2
- package/test/verdict.test.ts +1 -15
- package/translations/en.json +8 -32
- package/translations/es.json +8 -32
- package/translations/ja.json +8 -32
- package/translations/ko.json +8 -32
- package/translations/ms.json +8 -32
- package/translations/zh.json +8 -32
- package/client/modeller/occupancy.ts +0 -51
- package/dist-client/modeller/occupancy.d.ts +0 -31
- package/dist-client/modeller/occupancy.js +0 -36
- package/dist-client/modeller/occupancy.js.map +0 -1
- package/test/release-panel.test.ts +0 -53
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gizmo.js","sourceRoot":"","sources":["../../client/modeller/gizmo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AA0CnF,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAA;AAErC,MAAM,UAAU,YAAY,CAAC,KAAgB,EAAE,IAAY;IACzD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAA;IAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9F,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC,CAAA;IACzE,MAAM,SAAS,GAAG,CAAC,GAAa,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IACpE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,OAAO,CAAC,CAAA;IAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,CAAA;IAC5E,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,OAAO,IAAI,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,YAAY,CAAA;IACxH;;;MAGE;IACF,MAAM,QAAQ,GACZ,CAAC,CAAC,IAAI;QACN,IAAI,CAAC,EAAE,KAAK,SAAS;QACrB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,SAAS,CAAC;QACjD,mBAAmB,CAAC,KAA+B,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;IACrE,MAAM,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAA;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,QAAQ,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,CAAC,GAAa,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5F;;;;MAIE;IACF,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,KAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC1E,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAA;IAC3B,MAAM,KAAK,GAAG,CAAC,IAAqB,EAAE,EAAE;QACtC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,CAAA;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAE,CAAC,CAAC,CAAC,SAAS,CAAA;IACjE,CAAC,CAAA;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAChC,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAChI,IAAI,KAA0B,CAAA;IAC9B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAM,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;QACtI,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAA;QACrE,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAE,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAE,CAAC,CAAA;QACzC,IAAI,CAAC,GAAG,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAAE,KAAK,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAA;IAC9I,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,QAAqB,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9E,MAAM,KAAK,GACT,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,MAAmC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3I;;;;MAIE;IACF,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAA;IACtD,MAAM,UAAU,GAAG,CAAC,EAAU,EAAiB,EAAE;QAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,EAAE,CAAA;QAC1D,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;QACjF,MAAM,GAAG,GAAG,MAAM,EAAE,EAAE,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAA;QAC3H,OAAO,GAAG,IAAI,MAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACjH,CAAC,CAAA;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnF,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACzC,OAAO;QACL,SAAS,EAAE,KAAK,IAAI,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,IAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QACxG,MAAM,EAAE,KAAK,IAAI,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,IAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;QACzG,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO;QACpC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5B,CAAA;AACH,CAAC;AAWD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,IAAyB;IAClD,MAAM,IAAI,GAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IACpE,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,IAAK,CAAC,IAAI,CAAC,CAAC,CAAE,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;AAC3H,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAiB,EAAE,MAAmB,EAAE,KAA6B;IAC9G,MAAM,OAAO,GAAwB,EAAE,CAAA;IACvC,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,IAA+B,EAAE,KAAa,EAAE,EAAE,CAC5E,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAuB,CAAC,CAAA;IAC/E,IAAI,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS;QACpC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,aAAa,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAA;IACpG,IAAI,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM;QACjC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,aAAa,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAS,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC/G,IAAI,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;QAC5C,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5B,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS;gBAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAE,GAAG,MAAM,CAAC,KAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAA;QACrG,CAAC,CAAC,CAAA;IACJ,IAAI,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ;QAC/C,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAM,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,GAAG,IAAI;gBAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAE,GAAG,MAAM,CAAC,KAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAA;QACrJ,CAAC,CAAC,CAAA;IACJ,IAAI,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/C,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,CAAA;QACjC,4FAA4F;QAC5F,MAAM,IAAI,GAAG,CAAC,OAAiB,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5G,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAG,EAAE,EAAG,EAAE,EAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAG,EAAE,EAAG,CAAC,CAAC,CAAA;QAChE,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM;YAAE,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS;gBAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QAC7H,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK;YAAE,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS;gBAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAE,GAAG,EAAG,CAAC,CAAC,CAAC,CAAA;IAC3H,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC","sourcesContent":["import { figureAttachmentsOf, figureShapeProviderOf } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureInputChange, FigureSizeKeep } from '@hatiolab/figure-model'\n\n/**\n * What the gizmo may write for a part: move · turn · size, on a asset.\n *\n * A drag can only be written back where the part is placed by its own numbers. A part the create commands made is:\n * its pose is `rigid@1` into the asset frame from `<part>.position.*` and `<part>.rotation.*`, and its shape takes its\n * measures from inputs of its own — `<part>.size.*` from `addFigureBox`, `<part>.dimension.*` from the editor's shape\n * palette — at the arguments the shape itself names (figure-model's provider). A part fastened to another, following an instance size or placed by\n * expressions has no such numbers; the gizmo does not offer what it could not write back, rather\n * than move something the next evaluation would put back.\n */\nexport interface GizmoReach {\n translate: boolean\n rotate: boolean\n scale: boolean\n /** The inputs sizing the part along X, Y and Z, when it can be sized. */\n sizes?: [string, string, string]\n /**\n * Per axis, the part's own measure, or null where the measure follows another (a square section's depth following\n * its width): a scale drag writes the own ones and leaves a followed one to what it follows.\n */\n ownSizes?: (string | null)[]\n /**\n * A round part keeps its section round: the radii across (X and Z) take the one factor\n * the drag gave most; the length along Y takes its own. A sphere's three radii take one factor together.\n */\n round?: { across: string[]; along: string[] }\n}\n\ninterface Node {\n id: string\n op: string\n args: string[]\n outputs?: Record<string, string>\n params?: Record<string, unknown>\n}\ninterface AssetLike {\n document: { model: { nodes: Node[]; inputs: Array<{ id: string; role?: string }>; constants?: Array<{ id: string; value: number }> } }\n}\n\nconst AXES = ['x', 'y', 'z'] as const\n\nexport function gizmoReachOf(asset: AssetLike, part: string): GizmoReach {\n const { nodes, inputs } = asset.document.model\n const design = new Set(inputs.filter(input => input.role === 'design').map(input => input.id))\n const own = (name: string) => AXES.map(axis => `${part}.${name}.${axis}`)\n const allDesign = (ids: string[]) => ids.every(id => design.has(id))\n const pose = nodes.find(node => node.id === `${part}.pose`)\n const placed = nodes.find(node => node.id === part && node.op === 'place@1')\n const direct = !!pose && pose.op === 'rigid@1' && pose.params?.to === 'asset' && placed?.args[1] === `${part}.poseValue`\n /*\n A part taken off another (detach) stands on a seat into the asset frame with its own position numbers back. It\n can be moved like a part never fastened — unless it moves by itself, when where it is drawn is not its position.\n */\n const reseated =\n !!pose &&\n pose.op === 'rigid@1' &&\n !nodes.some(node => node.id === `${part}.motion`) &&\n figureAttachmentsOf(asset as unknown as FigureAsset)[part] === null\n const posed = direct || reseated\n const shape = nodes.find(node => node.id === `${part}.shape`)\n const mine = (ids: string[]) => ids.every(id => id.startsWith(`${part}.`) && design.has(id))\n /*\n Which argument sizes the part along X, Y and Z: the shape says (figure-model's provider, ADR-0100) -- never its first\n three arguments. A round section written from one radius, a sphere and a taper keep their shape: their radii take one\n factor together.\n */\n const provider = shape ? figureShapeProviderOf(shape as never) : undefined\n const edit = provider?.edit\n const refOf = (axis: 'x' | 'y' | 'z') => {\n const e = edit?.[axis]\n return e && !('refused' in e) ? shape!.args[e.arg]! : undefined\n }\n const measures = AXES.map(refOf)\n const shared = !!edit && AXES.some(axis => { const e = edit[axis]; return !('refused' in e) && !!(e.sameAs || e.with?.length) })\n let round: GizmoReach['round']\n if (shared && edit) {\n const withs = AXES.flatMap(axis => { const e = edit[axis]; return !('refused' in e) ? (e.with ?? []).map(i => shape!.args[i]!) : [] })\n const sphere = !!provider && Object.keys(provider.faces).length === 0\n const across = [...new Set([refOf('x')!, ...withs])]\n const along = sphere ? [] : [refOf('y')!]\n if ([...across, ...along].every(id => id && mine([id]))) round = { across: sphere ? [...new Set([...across, refOf('y')!])] : across, along }\n }\n const extent = !round && measures.every(Boolean) ? (measures as string[]) : []\n const sizes =\n extent.length === 3 && extent.every(id => id.startsWith(`${part}.`) && design.has(id)) ? (extent as [string, string, string]) : undefined\n /*\n The part's own measure, also when another reads it: a measure some other part follows is read through a node of its\n own times 1 (`link-dimension`), and it is still the author's number -- the upper arm's width, which the forearm\n follows, is the upper arm's to drag.\n */\n const constants = asset.document.model.constants ?? []\n const ownMeasure = (id: string): string | null => {\n if (id.startsWith(`${part}.`) && design.has(id)) return id\n const writer = nodes.find(node => Object.values(node.outputs ?? {}).includes(id))\n const one = writer?.op === 'mul@1' && writer.args.length === 2 && constants.find(c => c.id === writer.args[1])?.value === 1\n return one && writer!.args[0]!.startsWith(`${part}.`) && design.has(writer!.args[0]!) ? writer!.args[0]! : null\n }\n const ownSizes = extent.length === 3 && !sizes ? extent.map(ownMeasure) : undefined\n const someOwn = !!ownSizes?.some(Boolean)\n return {\n translate: posed && allDesign(own('position')) && own('position').every((id, i) => pose!.args[i] === id),\n rotate: posed && allDesign(own('rotation')) && own('rotation').every((id, i) => pose!.args[3 + i] === id),\n scale: !!sizes || !!round || someOwn,\n ...(sizes ? { sizes } : {}),\n ...(someOwn ? { ownSizes } : {}),\n ...(round ? { round } : {})\n }\n}\n\n/** Where a drag left the part, in the asset frame: millimetres, degrees and per-axis scale. */\nexport interface GizmoResult {\n position?: [number, number, number]\n rotation?: [number, number, number]\n scale?: [number, number, number]\n /** The handle a size drag held, per own axis -1 · 0 · 1 (the scene's `scaleGrab`): what figure-model keeps from. */\n grab?: { x: number; y: number; z: number }\n}\n\n/**\n * What a size drag keeps (ADR-0140 4.1): the side opposite a handle on one axis; the middle for the uniform handle, or\n * when no handle is known -- figure-model's own words for it, so the drag and its commit ask the same.\n */\nexport function sizeKeepOf(grab: GizmoResult['grab']): FigureSizeKeep {\n const held = (['x', 'y', 'z'] as const).filter(axis => grab?.[axis])\n return held.length === 1 ? { keep: 'opposite', axis: held[0]!, side: grab![held[0]!]! > 0 ? 1 : -1 } : { keep: 'centre' }\n}\n\n/**\n * The input changes a drag makes — one list, applied as one step. Millimetres to the millimetre and degrees to a\n * tenth (a drag otherwise stores 722.4180046035418 mm). A size never goes below 1 mm.\n */\nexport function gizmoChanges(part: string, reach: GizmoReach, result: GizmoResult, sizes: Record<string, number>): FigureInputChange[] {\n const changes: FigureInputChange[] = []\n const put = (input: string, unit: FigureInputChange['unit'], value: number) =>\n changes.push({ kind: 'set-design', input, unit, value } as FigureInputChange)\n if (result.position && reach.translate)\n AXES.forEach((axis, i) => put(`${part}.position.${axis}`, 'mm', Math.round(result.position![i]!)))\n if (result.rotation && reach.rotate)\n AXES.forEach((axis, i) => put(`${part}.rotation.${axis}`, 'deg', Math.round(result.rotation![i]! * 10) / 10))\n if (result.scale && reach.scale && reach.sizes)\n reach.sizes.forEach((id, i) => {\n if (sizes[id] !== undefined) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * result.scale![i]!)))\n })\n if (result.scale && reach.scale && reach.ownSizes)\n reach.ownSizes.forEach((id, i) => {\n if (id && sizes[id] !== undefined && Math.abs(result.scale![i]! - 1) > 1e-4) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * result.scale![i]!)))\n })\n if (result.scale && reach.scale && reach.round) {\n const [sx, sy, sz] = result.scale\n /* The factor the drag moved most: across for a cylinder (X or Z), any axis for a sphere. */\n const most = (factors: number[]) => factors.reduce((a, b) => (Math.abs(b - 1) > Math.abs(a - 1) ? b : a), 1)\n const sphere = reach.round.along.length === 0\n const across = sphere ? most([sx!, sy!, sz!]) : most([sx!, sz!])\n for (const id of reach.round.across) if (sizes[id] !== undefined) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * across)))\n for (const id of reach.round.along) if (sizes[id] !== undefined) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * sy!)))\n }\n return changes\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gizmo.js","sourceRoot":"","sources":["../../client/modeller/gizmo.ts"],"names":[],"mappings":"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","sourcesContent":["import { figureAttachmentsOf, figureShapeProviderOf } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureInputChange, FigureSizeKeep } from '@hatiolab/figure-model'\n\n/**\n * What the gizmo may write for a part: move · turn · size, on a asset.\n *\n * A drag can only be written back where the part is placed by its own numbers. A part the create commands made is:\n * its pose is `rigid@1` into the asset frame from `<part>.position.*` and `<part>.rotation.*`, and its shape takes its\n * measures from inputs of its own — `<part>.size.*` from `addFigureBox`, `<part>.dimension.*` from the editor's shape\n * palette — at the arguments the shape itself names (figure-model's provider). A part fastened to another, following an instance size or placed by\n * expressions has no such numbers; the gizmo does not offer what it could not write back, rather\n * than move something the next evaluation would put back.\n */\nexport interface GizmoReach {\n translate: boolean\n rotate: boolean\n scale: boolean\n /** The inputs sizing the part along X, Y and Z, when it can be sized. */\n sizes?: [string, string, string]\n /**\n * Per axis, the part's own measure, or null where the measure follows another (a square section's depth following\n * its width): a scale drag writes the own ones and leaves a followed one to what it follows.\n */\n ownSizes?: (string | null)[]\n /**\n * A round part keeps its section round: the radii across (X and Z) take the one factor\n * the drag gave most; the length along Y takes its own. A sphere's three radii take one factor together.\n */\n round?: { across: string[]; along: string[] }\n}\n\ninterface Node {\n id: string\n op: string\n args: string[]\n outputs?: Record<string, string>\n params?: Record<string, unknown>\n}\ninterface AssetLike {\n document: { model: { nodes: Node[]; inputs: Array<{ id: string; role?: string }>; constants?: Array<{ id: string; value: number }> } }\n}\n\nconst AXES = ['x', 'y', 'z'] as const\n\nexport function gizmoReachOf(asset: AssetLike, part: string): GizmoReach {\n const { nodes, inputs } = asset.document.model\n const design = new Set(inputs.filter(input => input.role === 'design').map(input => input.id))\n const own = (name: string) => AXES.map(axis => `${part}.${name}.${axis}`)\n const allDesign = (ids: string[]) => ids.every(id => design.has(id))\n const pose = nodes.find(node => node.id === `${part}.pose`)\n const placed = nodes.find(node => node.id === part && node.op === 'place@1')\n const direct = !!pose && pose.op === 'rigid@1' && pose.params?.to === 'asset' && placed?.args[1] === `${part}.poseValue`\n /*\n A part taken off another (detach) stands on a seat into the asset frame with its own position numbers back. It\n can be moved like a part never fastened — unless it moves by itself, when where it is drawn is not its position.\n */\n const reseated =\n !!pose &&\n pose.op === 'rigid@1' &&\n !nodes.some(node => node.id === `${part}.motion`) &&\n figureAttachmentsOf(asset as unknown as FigureAsset)[part] === null\n const posed = direct || reseated\n const shape = nodes.find(node => node.id === `${part}.shape`)\n const mine = (ids: string[]) => ids.every(id => id.startsWith(`${part}.`) && design.has(id))\n /*\n Which argument sizes the part along X, Y and Z: the shape says (figure-model's provider, ADR-0100) -- never its first\n three arguments. A round section written from one radius, a sphere and a taper keep their shape: their radii take one\n factor together.\n */\n const provider = shape ? figureShapeProviderOf(shape as never) : undefined\n const edit = provider?.edit\n const refOf = (axis: 'x' | 'y' | 'z') => {\n const e = edit?.[axis]\n return e && !('refused' in e) ? shape!.args[e.arg]! : undefined\n }\n const measures = AXES.map(refOf)\n const shared = !!edit && AXES.some(axis => { const e = edit[axis]; return !('refused' in e) && !!(e.sameAs || e.with?.length) })\n let round: GizmoReach['round']\n if (shared && edit) {\n const withs = AXES.flatMap(axis => { const e = edit[axis]; return !('refused' in e) ? (e.with ?? []).map(i => shape!.args[i]!) : [] })\n const sphere = !!provider && Object.keys(provider.faces).length === 0\n const across = [...new Set([refOf('x')!, ...withs])]\n const along = sphere ? [] : [refOf('y')!]\n if ([...across, ...along].every(id => id && mine([id]))) round = { across: sphere ? [...new Set([...across, refOf('y')!])] : across, along }\n }\n const extent = !round && measures.every(Boolean) ? (measures as string[]) : []\n const sizes =\n extent.length === 3 && extent.every(id => id.startsWith(`${part}.`) && design.has(id)) ? (extent as [string, string, string]) : undefined\n /*\n The part's own measure, also when another reads it: a measure some other part follows is read through a node of its\n own times 1 (`link-dimension`), and it is still the author's number -- the upper arm's width, which the forearm\n follows, is the upper arm's to drag.\n */\n const constants = asset.document.model.constants ?? []\n const ownMeasure = (id: string): string | null => {\n if (id.startsWith(`${part}.`) && design.has(id)) return id\n const writer = nodes.find(node => Object.values(node.outputs ?? {}).includes(id))\n const one = writer?.op === 'mul@1' && writer.args.length === 2 && constants.find(c => c.id === writer.args[1])?.value === 1\n return one && writer!.args[0]!.startsWith(`${part}.`) && design.has(writer!.args[0]!) ? writer!.args[0]! : null\n }\n const ownSizes = extent.length === 3 && !sizes ? extent.map(ownMeasure) : undefined\n const someOwn = !!ownSizes?.some(Boolean)\n return {\n translate: posed && allDesign(own('position')) && own('position').every((id, i) => pose!.args[i] === id),\n rotate: posed && allDesign(own('rotation')) && own('rotation').every((id, i) => pose!.args[3 + i] === id),\n scale: !!sizes || !!round || someOwn,\n ...(sizes ? { sizes } : {}),\n ...(someOwn ? { ownSizes } : {}),\n ...(round ? { round } : {})\n }\n}\n\n/** Where a drag left the part, in the asset frame: millimetres, degrees and per-axis scale. */\n/**\n * The size handles that change one measure (ADR-0140 4.1): a round part's radius across is one value, so its X and Z\n * handles are the same diameter, and a sphere's three are one. Said on the canvas while the size tool is on, to see how\n * it handles before deciding to show fewer. Nothing for a part whose handles each change their own measure.\n */\nexport function sameMeasureAxesOf(reach: GizmoReach): Array<'x' | 'y' | 'z'> | undefined {\n if (!reach.scale || !reach.round) return undefined\n return reach.round.along.length ? ['x', 'z'] : ['x', 'y', 'z']\n}\n\nexport interface GizmoResult {\n position?: [number, number, number]\n rotation?: [number, number, number]\n scale?: [number, number, number]\n /** The handle a size drag held, per own axis -1 · 0 · 1 (the scene's `scaleGrab`): what figure-model keeps from. */\n grab?: { x: number; y: number; z: number }\n}\n\n/**\n * What a size drag keeps (ADR-0140 4.1): the side opposite a handle on one axis; the middle for the uniform handle, or\n * when no handle is known -- figure-model's own words for it, so the drag and its commit ask the same.\n */\nexport function sizeKeepOf(grab: GizmoResult['grab']): FigureSizeKeep {\n const held = (['x', 'y', 'z'] as const).filter(axis => grab?.[axis])\n return held.length === 1 ? { keep: 'opposite', axis: held[0]!, side: grab![held[0]!]! > 0 ? 1 : -1 } : { keep: 'centre' }\n}\n\n/**\n * The input changes a drag makes — one list, applied as one step. Millimetres to the millimetre and degrees to a\n * tenth (a drag otherwise stores 722.4180046035418 mm). A size never goes below 1 mm.\n */\nexport function gizmoChanges(part: string, reach: GizmoReach, result: GizmoResult, sizes: Record<string, number>): FigureInputChange[] {\n const changes: FigureInputChange[] = []\n const put = (input: string, unit: FigureInputChange['unit'], value: number) =>\n changes.push({ kind: 'set-design', input, unit, value } as FigureInputChange)\n if (result.position && reach.translate)\n AXES.forEach((axis, i) => put(`${part}.position.${axis}`, 'mm', Math.round(result.position![i]!)))\n if (result.rotation && reach.rotate)\n AXES.forEach((axis, i) => put(`${part}.rotation.${axis}`, 'deg', Math.round(result.rotation![i]! * 10) / 10))\n if (result.scale && reach.scale && reach.sizes)\n reach.sizes.forEach((id, i) => {\n if (sizes[id] !== undefined) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * result.scale![i]!)))\n })\n if (result.scale && reach.scale && reach.ownSizes)\n reach.ownSizes.forEach((id, i) => {\n if (id && sizes[id] !== undefined && Math.abs(result.scale![i]! - 1) > 1e-4) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * result.scale![i]!)))\n })\n if (result.scale && reach.scale && reach.round) {\n const [sx, sy, sz] = result.scale\n /* The factor the drag moved most: across for a cylinder (X or Z), any axis for a sphere. */\n const most = (factors: number[]) => factors.reduce((a, b) => (Math.abs(b - 1) > Math.abs(a - 1) ? b : a), 1)\n const sphere = reach.round.along.length === 0\n const across = sphere ? most([sx!, sy!, sz!]) : most([sx!, sz!])\n for (const id of reach.round.across) if (sizes[id] !== undefined) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * across)))\n for (const id of reach.round.along) if (sizes[id] !== undefined) put(id, 'mm', Math.max(1, Math.round(sizes[id]! * sy!)))\n }\n return changes\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type KeyAction = 'undo' | 'redo' | 'duplicate' | 'remove' | 'deselect' | GizmoKey;
|
|
1
|
+
export type KeyAction = 'undo' | 'redo' | 'duplicate' | 'remove' | 'deselect' | 'copy' | 'paste' | 'hold' | GizmoKey;
|
|
2
2
|
/** The gizmo's modes on W, E and R, as the scene has them. */
|
|
3
3
|
export type GizmoKey = 'translate' | 'rotate' | 'scale';
|
|
4
4
|
export interface KeyLike {
|
|
@@ -11,6 +11,12 @@ export function keyActionOf(e, selected) {
|
|
|
11
11
|
return e.shiftKey ? 'redo' : 'undo';
|
|
12
12
|
if (mod && key === 'y')
|
|
13
13
|
return 'redo';
|
|
14
|
+
if (mod && key === 'c')
|
|
15
|
+
return selected ? 'copy' : 'hold';
|
|
16
|
+
if (mod && key === 'v')
|
|
17
|
+
return e.shiftKey ? 'hold' : 'paste';
|
|
18
|
+
if (mod && key === 'x')
|
|
19
|
+
return 'hold';
|
|
14
20
|
if (!selected)
|
|
15
21
|
return null;
|
|
16
22
|
if (mod && key === 'd')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../client/modeller/keys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../client/modeller/keys.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,GAA6B,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAA;AAkBxF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;AAEvD,MAAM,UAAU,WAAW,CAAC,CAAU,EAAE,QAAgB;IACtD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/G,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACzB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;IACtC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAA;IAC/B,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;IAC3D,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,MAAM,CAAA;IACrC,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;IACzD,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IAC5D,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,MAAM,CAAA;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC1B,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,WAAW,CAAA;IAC1C,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,WAAW,CAAC;QAAE,OAAO,QAAQ,CAAA;IACtE,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAA;IAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAA;IAChF,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["/*\n * The modeller's keys: undo and redo on Ctrl+Z / Ctrl+Y, and what a person reaches for next. Read apart\n * from the element so the rule is tested without a browser.\n *\n * Typing is never taken: a key pressed in a field belongs to the field -- Backspace in a name box deletes a letter,\n * not the part.\n */\n/*\n * `copy` · `paste` are the modeller's own: a part copied and pasted is the kernel's duplicate, with a name of its own.\n * Left to the scene, Ctrl+C / Ctrl+V copied the canvas object with the part's name -- two objects of one name, the copy\n * moving the original (user 2026-10-21). `hold` is a key kept from the scene that the modeller has no use for: the\n * scene's cut and bulk paste act on canvas objects alone and leave the figure out of step with them.\n */\nexport type KeyAction = 'undo' | 'redo' | 'duplicate' | 'remove' | 'deselect' | 'copy' | 'paste' | 'hold' | GizmoKey\n\n/** The gizmo's modes on W, E and R, as the scene has them. */\nexport type GizmoKey = 'translate' | 'rotate' | 'scale'\nconst GIZMO_KEYS: Record<string, GizmoKey> = { w: 'translate', e: 'rotate', r: 'scale' }\n\nexport interface KeyLike {\n key: string\n ctrlKey?: boolean\n metaKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n /** The element the key was pressed in -- the first of the event's composed path. */\n target?: { tagName?: string; isContentEditable?: boolean } | null\n /**\n * Pressed with the canvas focused. The scene takes W, E and R there itself; they are passed on only from elsewhere\n * -- a part picked in the parts list left the focus there, and the gizmo could not be had at all (2026-09-25).\n * Passing a key the scene already took would toggle the gizmo off again.\n */\n inScene?: boolean\n}\n\nconst TYPING = new Set(['INPUT', 'SELECT', 'TEXTAREA'])\n\nexport function keyActionOf(e: KeyLike, selected: string): KeyAction | null {\n if (e.target && (TYPING.has(String(e.target.tagName).toUpperCase()) || e.target.isContentEditable)) return null\n if (e.altKey) return null\n const mod = !!(e.ctrlKey || e.metaKey)\n const key = e.key.toLowerCase()\n if (mod && key === 'z') return e.shiftKey ? 'redo' : 'undo'\n if (mod && key === 'y') return 'redo'\n if (mod && key === 'c') return selected ? 'copy' : 'hold'\n if (mod && key === 'v') return e.shiftKey ? 'hold' : 'paste'\n if (mod && key === 'x') return 'hold'\n if (!selected) return null\n if (mod && key === 'd') return 'duplicate'\n if (!mod && (key === 'delete' || key === 'backspace')) return 'remove'\n if (!mod && key === 'escape') return 'deselect'\n if (!mod && !e.shiftKey && !e.inScene && GIZMO_KEYS[key]) return GIZMO_KEYS[key]\n return null\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { figureJointAsFixed } from '@hatiolab/figure-model';
|
|
2
|
-
import type { FigureFollow,
|
|
2
|
+
import type { FigureFollow, FigureInstanceSizeRange } from '@hatiolab/figure-model';
|
|
3
3
|
import type { FigureAsset, FigureAuthoringAction, FigureBindingPlace, FigureFace, FigureFacing, FigureJoint, FigureSurfacePlace } from '@hatiolab/figure-model';
|
|
4
4
|
import { type FigureRevision } from './revision.js';
|
|
5
5
|
import { type JointAxisVector } from './joint-axis.js';
|
|
@@ -227,7 +227,7 @@ export declare function placeKeptOf(revision: FigureRevision, part: string, targ
|
|
|
227
227
|
export declare function alignOf(asset: FigureAsset, target: {
|
|
228
228
|
part: string;
|
|
229
229
|
face: string;
|
|
230
|
-
} | 'plane', how: Partial<Record<Axis, Alignment>>, mm: Partial<Record<Axis, number>>, inputs?: Partial<Record<Axis, string>>): Partial<Record<Axis, "
|
|
230
|
+
} | 'plane', how: Partial<Record<Axis, Alignment>>, mm: Partial<Record<Axis, number>>, inputs?: Partial<Record<Axis, string>>): Partial<Record<Axis, "max" | "min" | {
|
|
231
231
|
mm: number | {
|
|
232
232
|
from: {
|
|
233
233
|
of: "instance";
|
|
@@ -358,32 +358,27 @@ export declare const holdsThings: (asset: FigureAsset) => boolean;
|
|
|
358
358
|
/** What `accepts` a person typed: names split on commas, trimmed, blanks and repeats dropped. */
|
|
359
359
|
export declare const acceptsOf: (typed: string) => string[];
|
|
360
360
|
/**
|
|
361
|
-
* The sizes a board may give this figure: the
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
* made to grow with the figure; measuring again gives the figure its whole range back. Nothing when no size is declared.
|
|
361
|
+
* The sizes a board may give this figure, per axis: the ends its author narrowed, and the rest as far as its parts
|
|
362
|
+
* allow, computed by figure-model (`figureInstanceSizeRangeOf`, ADR-0087 decision 6) -- the screen does not measure
|
|
363
|
+
* on its own. Nothing when no size is declared.
|
|
365
364
|
*/
|
|
366
|
-
export declare function instanceRangeOf(asset: FigureAsset):
|
|
367
|
-
declared: FigureSizeRange;
|
|
368
|
-
measured: FigureSizeRange;
|
|
369
|
-
} | undefined;
|
|
365
|
+
export declare function instanceRangeOf(asset: FigureAsset): Record<Axis, FigureInstanceSizeRange> | undefined;
|
|
370
366
|
/**
|
|
371
|
-
* The size
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).
|
|
367
|
+
* The size to declare for a figure that has none yet: its parts' extent now, the size it is authored at. Undefined when
|
|
368
|
+
* the figure already has a size or has nothing to measure. Without a declared size a board cannot resize the figure,
|
|
369
|
+
* and no part is offered to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).
|
|
375
370
|
*/
|
|
376
|
-
export declare function
|
|
377
|
-
range: FigureSizeRange;
|
|
371
|
+
export declare function instanceSizeToDeclare(asset: FigureAsset): {
|
|
378
372
|
at: Record<Axis, number>;
|
|
379
373
|
} | undefined;
|
|
380
|
-
/** Whether measuring again would change the declared range (to a micrometre). */
|
|
381
374
|
/**
|
|
382
|
-
* The
|
|
383
|
-
*
|
|
384
|
-
* value is not a number; whether the figure holds there is the command's to say.
|
|
375
|
+
* The ends the author narrowed, with one end typed or cleared: a number narrows that end, an empty field opens it
|
|
376
|
+
* again to what the parts allow. Whether the figure holds there is the command's to say.
|
|
385
377
|
*/
|
|
386
|
-
export declare function rangeWith(
|
|
378
|
+
export declare function rangeWith(range: Record<Axis, FigureInstanceSizeRange>, axis: Axis, bound: 'min' | 'max', value: number): Partial<Record<Axis, {
|
|
379
|
+
min?: number;
|
|
380
|
+
max?: number;
|
|
381
|
+
}>>;
|
|
387
382
|
/**
|
|
388
383
|
* For a figure that grows by one ratio: how many of its lengths would follow the ratio, and which it leaves with their
|
|
389
384
|
* own number (not those that follow another length -- they grow with it). Nothing for a figure of another sizing.
|
|
@@ -394,7 +389,6 @@ export declare function proportionToFollow(asset: FigureAsset): {
|
|
|
394
389
|
} | undefined;
|
|
395
390
|
/** A value of the figure as it stands, by its graph reference. */
|
|
396
391
|
export declare function valueNow(revision: FigureRevision, ref: string | undefined): number | undefined;
|
|
397
|
-
export declare function rangeDiffers(a: FigureSizeRange, b: FigureSizeRange): boolean;
|
|
398
392
|
/**
|
|
399
393
|
* Whether the figure is a mechanism -- a part turns about a joint. Such a figure should grow by one ratio (chief
|
|
400
394
|
* architect's ruling 2026-09-24); the modeller proposes it, the author declares it.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { figureShapeFaces, figurePartsExtentOf, figureFollowOf, proposeFigureProportion,
|
|
1
|
+
import { figureShapeFaces, figurePartsExtentOf, figureFollowOf, proposeFigureProportion, figureAttachmentsOf, figureBindingsOf, figureInstanceSizeRangeOf, figureFollowableAxesOf, figureShapeProviderOf, figureMimicTermsOf, figureFastenKeptPlaceOf, figureFastenAxesOf, figureJointAsFixed, figureJointWithMotion, figureSurfaceOf } from '@hatiolab/figure-model';
|
|
2
2
|
import { startingShapeKindOf } from './starting-shape.js';
|
|
3
3
|
import { boxOf } from './align.js';
|
|
4
4
|
import { graphValuesOf } from './revision.js';
|
|
@@ -629,55 +629,45 @@ export const holdsThings = (asset) => (asset.document.capabilities.names ?? []).
|
|
|
629
629
|
/** What `accepts` a person typed: names split on commas, trimmed, blanks and repeats dropped. */
|
|
630
630
|
export const acceptsOf = (typed) => [...new Set(typed.split(',').map(one => one.trim()).filter(Boolean))];
|
|
631
631
|
/**
|
|
632
|
-
* The sizes a board may give this figure: the
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
* made to grow with the figure; measuring again gives the figure its whole range back. Nothing when no size is declared.
|
|
632
|
+
* The sizes a board may give this figure, per axis: the ends its author narrowed, and the rest as far as its parts
|
|
633
|
+
* allow, computed by figure-model (`figureInstanceSizeRangeOf`, ADR-0087 decision 6) -- the screen does not measure
|
|
634
|
+
* on its own. Nothing when no size is declared.
|
|
636
635
|
*/
|
|
637
636
|
export function instanceRangeOf(asset) {
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
const authored = {};
|
|
641
|
-
for (const axis of AXES) {
|
|
642
|
-
const input = inputs.find(i => i.id === `size.${axis}` && i.role === 'design');
|
|
643
|
-
const at = asset.designInputs[`size.${axis}`];
|
|
644
|
-
if (!input || typeof at !== 'number')
|
|
645
|
-
return undefined;
|
|
646
|
-
declared[axis] = { min: input.min ?? 0, max: input.max ?? Infinity };
|
|
647
|
-
authored[axis] = at;
|
|
648
|
-
}
|
|
649
|
-
const start = defaultInstanceSizeRange(authored);
|
|
650
|
-
const measured = foldInstanceSizeRange(start, figureInstanceSizeLimitsOf(asset, start)).range;
|
|
651
|
-
return { declared, measured };
|
|
637
|
+
const range = figureInstanceSizeRangeOf(asset);
|
|
638
|
+
return AXES.every(axis => range[axis]) ? range : undefined;
|
|
652
639
|
}
|
|
653
640
|
/**
|
|
654
|
-
* The size
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
* to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).
|
|
641
|
+
* The size to declare for a figure that has none yet: its parts' extent now, the size it is authored at. Undefined when
|
|
642
|
+
* the figure already has a size or has nothing to measure. Without a declared size a board cannot resize the figure,
|
|
643
|
+
* and no part is offered to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).
|
|
658
644
|
*/
|
|
659
|
-
export function
|
|
645
|
+
export function instanceSizeToDeclare(asset) {
|
|
660
646
|
if (instanceRangeOf(asset) || !asset.appearance.length)
|
|
661
647
|
return undefined;
|
|
662
648
|
/* The parts as they rest -- not the room their joints swing them through, which declared a door 8208 mm every way. */
|
|
663
649
|
const at = figurePartsExtentOf(asset);
|
|
664
650
|
if (AXES.some(axis => !(at[axis] > 0)))
|
|
665
651
|
return undefined;
|
|
666
|
-
|
|
667
|
-
return { range: foldInstanceSizeRange(start, figureInstanceSizeLimitsOf(asset, start)).range, at };
|
|
652
|
+
return { at };
|
|
668
653
|
}
|
|
669
|
-
/** Whether measuring again would change the declared range (to a micrometre). */
|
|
670
654
|
/**
|
|
671
|
-
* The
|
|
672
|
-
*
|
|
673
|
-
* value is not a number; whether the figure holds there is the command's to say.
|
|
655
|
+
* The ends the author narrowed, with one end typed or cleared: a number narrows that end, an empty field opens it
|
|
656
|
+
* again to what the parts allow. Whether the figure holds there is the command's to say.
|
|
674
657
|
*/
|
|
675
|
-
export function rangeWith(
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
658
|
+
export function rangeWith(range, axis, bound, value) {
|
|
659
|
+
const out = {};
|
|
660
|
+
for (const a of AXES) {
|
|
661
|
+
const ends = {};
|
|
662
|
+
for (const b of ['min', 'max']) {
|
|
663
|
+
const typed = a === axis && b === bound;
|
|
664
|
+
if (typed ? Number.isFinite(value) : range[a].narrowed[b])
|
|
665
|
+
ends[b] = typed ? value : range[a][b];
|
|
666
|
+
}
|
|
667
|
+
if (Object.keys(ends).length)
|
|
668
|
+
out[a] = ends;
|
|
669
|
+
}
|
|
670
|
+
return out;
|
|
681
671
|
}
|
|
682
672
|
/**
|
|
683
673
|
* For a figure that grows by one ratio: how many of its lengths would follow the ratio, and which it leaves with their
|
|
@@ -706,9 +696,6 @@ export function valueNow(revision, ref) {
|
|
|
706
696
|
return undefined;
|
|
707
697
|
}
|
|
708
698
|
}
|
|
709
|
-
export function rangeDiffers(a, b) {
|
|
710
|
-
return AXES.some(axis => Math.abs(a[axis].min - b[axis].min) > 1e-3 || Math.abs(a[axis].max - b[axis].max) > 1e-3);
|
|
711
|
-
}
|
|
712
699
|
/**
|
|
713
700
|
* Whether the figure is a mechanism -- a part turns about a joint. Such a figure should grow by one ratio (chief
|
|
714
701
|
* architect's ruling 2026-09-24); the modeller proposes it, the author declares it.
|