Browse Source

脚本支持

master
修宁 6 months ago
parent
commit
a7d49bdcde
  1. 2
      package.json
  2. 268
      pnpm-lock.yaml
  3. BIN
      public/static/cursor/ruler.cur
  4. BIN
      public/static/cursor/ruler.jpg
  5. 4
      src/components/YvSrcEditor.vue
  6. 40
      src/components/YvSrcEditorInner.vue
  7. 33
      src/core/base/BaseInteraction.ts
  8. 15
      src/core/engine/Viewport.ts
  9. 48
      src/core/manager/CodeDropper.ts
  10. 1
      src/core/manager/DragManager.ts
  11. 9
      src/core/manager/InteractionManager.ts
  12. 12
      src/core/manager/ModuleManager.ts
  13. 6
      src/core/manager/SelectManager.ts
  14. 139
      src/core/manager/TaskManager.ts
  15. 95
      src/core/script/ModelManager.ts
  16. 130
      src/core/script/ScriptSupport.ts
  17. 41
      src/editor/Model2DEditor.vue
  18. 36
      src/editor/menus/EditMenu.ts
  19. 4
      src/editor/widgets/logger/LoggerMeta.ts
  20. 45
      src/editor/widgets/logger/LoggerView.vue
  21. 154
      src/editor/widgets/script/ScriptView.vue
  22. 1
      src/types/ModelTypes.ts
  23. 169
      src/types/ScriptSupport.d.ts
  24. 11
      src/types/Types.d.ts
  25. 121
      vite.config.ts

2
package.json

@ -31,6 +31,8 @@
"@vitejs/plugin-vue": "^5.2.3",
"@vitejs/plugin-vue-jsx": "^4.2.0",
"@vue/tsconfig": "^0.7.0",
"@typescript/vfs": "^1.6.1",
"rollup-plugin-typescript2": "^0.36.0",
"ag-grid-community": "^28.2.1",
"ag-grid-enterprise": "^28.2.1",
"ag-grid-vue3": "^28.2.1",

268
pnpm-lock.yaml

@ -45,6 +45,9 @@ importers:
'@types/three':
specifier: ^0.176.0
version: 0.176.0
'@typescript/vfs':
specifier: ^1.6.1
version: 1.6.1(typescript@5.8.3)
'@vicons/antd':
specifier: ^0.13.0
version: 0.13.0
@ -123,6 +126,9 @@ importers:
rimraf:
specifier: ^6.0.1
version: 6.0.1
rollup-plugin-typescript2:
specifier: ^0.36.0
version: 0.36.0(rollup@4.41.0)(typescript@5.8.3)
sortablejs:
specifier: 1.15.6
version: 1.15.6
@ -333,151 +339,151 @@ packages:
vue: ^3.2.0
'@esbuild/aix-ppc64@0.25.4':
resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==, tarball: https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz}
resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.25.4':
resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz}
resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.25.4':
resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.4.tgz}
resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.25.4':
resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.4.tgz}
resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.25.4':
resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz}
resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.25.4':
resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz}
resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.25.4':
resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz}
resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.25.4':
resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz}
resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.25.4':
resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz}
resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.25.4':
resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz}
resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.25.4':
resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz}
resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.25.4':
resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz}
resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.25.4':
resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz}
resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.25.4':
resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz}
resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.25.4':
resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz}
resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.25.4':
resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz}
resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.25.4':
resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz}
resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.25.4':
resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz}
resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.25.4':
resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz}
resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.25.4':
resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz}
resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.25.4':
resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz}
resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/sunos-x64@0.25.4':
resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz}
resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.25.4':
resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz}
resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.25.4':
resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz}
resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.25.4':
resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz}
resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
@ -552,6 +558,10 @@ packages:
'@rolldown/pluginutils@1.0.0-beta.8-commit.56abf23':
resolution: {integrity: sha512-Zoa3/5c/qDR8R2QLZooPO/7OA4OFe135yiJveWX04AK5F8Jj0aOihhczsw+TyxYbOEeD3/Vlf311ExBgMlBSqA==}
'@rollup/pluginutils@4.2.1':
resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
engines: {node: '>= 8.0.0'}
'@rollup/pluginutils@5.1.4':
resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==}
engines: {node: '>=14.0.0'}
@ -562,102 +572,102 @@ packages:
optional: true
'@rollup/rollup-android-arm-eabi@4.41.0':
resolution: {integrity: sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.0.tgz}
resolution: {integrity: sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==}
cpu: [arm]
os: [android]
'@rollup/rollup-android-arm64@4.41.0':
resolution: {integrity: sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.0.tgz}
resolution: {integrity: sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==}
cpu: [arm64]
os: [android]
'@rollup/rollup-darwin-arm64@4.41.0':
resolution: {integrity: sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.0.tgz}
resolution: {integrity: sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.41.0':
resolution: {integrity: sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.0.tgz}
resolution: {integrity: sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.41.0':
resolution: {integrity: sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.0.tgz}
resolution: {integrity: sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==}
cpu: [arm64]
os: [freebsd]
'@rollup/rollup-freebsd-x64@4.41.0':
resolution: {integrity: sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.0.tgz}
resolution: {integrity: sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==}
cpu: [x64]
os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.41.0':
resolution: {integrity: sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.0.tgz}
resolution: {integrity: sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm-musleabihf@4.41.0':
resolution: {integrity: sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.0.tgz}
resolution: {integrity: sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.41.0':
resolution: {integrity: sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.0.tgz}
resolution: {integrity: sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-arm64-musl@4.41.0':
resolution: {integrity: sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.0.tgz}
resolution: {integrity: sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-loongarch64-gnu@4.41.0':
resolution: {integrity: sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.0.tgz}
resolution: {integrity: sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==}
cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-powerpc64le-gnu@4.41.0':
resolution: {integrity: sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.0.tgz}
resolution: {integrity: sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==}
cpu: [ppc64]
os: [linux]
'@rollup/rollup-linux-riscv64-gnu@4.41.0':
resolution: {integrity: sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.0.tgz}
resolution: {integrity: sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-riscv64-musl@4.41.0':
resolution: {integrity: sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.0.tgz}
resolution: {integrity: sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.41.0':
resolution: {integrity: sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.0.tgz}
resolution: {integrity: sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==}
cpu: [s390x]
os: [linux]
'@rollup/rollup-linux-x64-gnu@4.41.0':
resolution: {integrity: sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.0.tgz}
resolution: {integrity: sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==}
cpu: [x64]
os: [linux]
'@rollup/rollup-linux-x64-musl@4.41.0':
resolution: {integrity: sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.0.tgz}
resolution: {integrity: sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==}
cpu: [x64]
os: [linux]
'@rollup/rollup-win32-arm64-msvc@4.41.0':
resolution: {integrity: sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.0.tgz}
resolution: {integrity: sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==}
cpu: [arm64]
os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.41.0':
resolution: {integrity: sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.0.tgz}
resolution: {integrity: sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==}
cpu: [ia32]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.41.0':
resolution: {integrity: sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.0.tgz}
resolution: {integrity: sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==}
cpu: [x64]
os: [win32]
@ -669,7 +679,7 @@ packages:
engines: {node: '>=18'}
'@sxzz/popperjs-es@2.11.7':
resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==, tarball: https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz}
resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
'@tsconfig/node22@22.0.2':
resolution: {integrity: sha512-Kmwj4u8sDRDrMYRoN9FDEcXD8UpBSaPQQ24Gz+Gamqfm7xxn+GBR7ge/Z7pK8OXNGyUzbSwJj+TH6B+DS/epyA==}
@ -716,6 +726,11 @@ packages:
'@types/webxr@0.5.22':
resolution: {integrity: sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==}
'@typescript/vfs@1.6.1':
resolution: {integrity: sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA==}
peerDependencies:
typescript: '*'
'@vicons/antd@0.13.0':
resolution: {integrity: sha512-yrUGoUSz2BbGupk9ghQOahc04n5H3MwUDM9pVPsLh9U1uqB47oRWZvYRiZaT1JKPqgTgSE6BXcVw4i9MOF4M+g==}
@ -896,7 +911,7 @@ packages:
resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz}
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-regex@6.1.0:
@ -904,7 +919,7 @@ packages:
engines: {node: '>=12'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz}
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansi-styles@6.2.1:
@ -961,11 +976,11 @@ packages:
resolution: {integrity: sha512-+aFkvqhaAVr1gferNMuN8vkTSrWIFvzlMV9I2KBLCWS2WpZ2+UAkZjlMZmEuT+gcXTi6RrGQCkWq1/bDtGqhIA==}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz}
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz}
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
@ -974,6 +989,9 @@ packages:
commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
commondir@1.0.1:
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
@ -1049,7 +1067,7 @@ packages:
vue: ^3.2.0
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, tarball: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz}
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
@ -1059,7 +1077,7 @@ packages:
engines: {node: '>=0.12'}
errno@0.1.8:
resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==, tarball: https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz}
resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
hasBin: true
error-stack-parser-es@0.1.5:
@ -1115,6 +1133,14 @@ packages:
resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
engines: {node: '>=18'}
find-cache-dir@3.3.2:
resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==}
engines: {node: '>=8'}
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
follow-redirects@1.15.9:
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
engines: {node: '>=4.0'}
@ -1132,12 +1158,16 @@ packages:
resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==}
engines: {node: '>= 6'}
fs-extra@10.1.0:
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
engines: {node: '>=12'}
fs-extra@11.3.0:
resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==}
engines: {node: '>=14.14'}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz}
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
@ -1174,7 +1204,7 @@ packages:
engines: {node: '>= 0.4'}
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz}
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
gsap@3.13.0:
resolution: {integrity: sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==, tarball: https://registry.npmmirror.com/gsap/-/gsap-3.13.0.tgz}
@ -1210,7 +1240,7 @@ packages:
engines: {node: '>=0.10.0'}
image-size@0.5.5:
resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==, tarball: https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz}
resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
engines: {node: '>=0.10.0'}
hasBin: true
@ -1223,7 +1253,7 @@ packages:
hasBin: true
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, tarball: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz}
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-inside-container@1.0.0:
@ -1302,6 +1332,10 @@ packages:
localforage@1.10.0:
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
lodash-es@4.17.21:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
@ -1326,9 +1360,13 @@ packages:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
make-dir@2.1.0:
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==, tarball: https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz}
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
engines: {node: '>=6'}
make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
@ -1352,7 +1390,7 @@ packages:
engines: {node: '>= 0.6'}
mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, tarball: https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz}
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
engines: {node: '>=4'}
hasBin: true
@ -1395,7 +1433,7 @@ packages:
hasBin: true
needle@3.3.1:
resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==, tarball: https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz}
resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==}
engines: {node: '>= 4.4.x'}
hasBin: true
@ -1429,6 +1467,18 @@ packages:
resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==}
engines: {node: '>=18'}
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
@ -1443,6 +1493,10 @@ packages:
path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@ -1464,6 +1518,10 @@ packages:
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
picomatch@4.0.2:
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
engines: {node: '>=12'}
@ -1486,6 +1544,10 @@ packages:
typescript:
optional: true
pkg-dir@4.2.0:
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
engines: {node: '>=8'}
postcss@8.5.3:
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
engines: {node: ^10 || ^12 || >=14}
@ -1525,6 +1587,12 @@ packages:
engines: {node: 20 || >=22}
hasBin: true
rollup-plugin-typescript2@0.36.0:
resolution: {integrity: sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==}
peerDependencies:
rollup: '>=1.26.3'
typescript: '>=2.4.0'
rollup@4.41.0:
resolution: {integrity: sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@ -1548,6 +1616,11 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
semver@7.7.2:
resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
engines: {node: '>=10'}
hasBin: true
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@ -1592,7 +1665,7 @@ packages:
engines: {node: '>=0.10.0'}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz}
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
speakingurl@14.0.1:
@ -1606,7 +1679,7 @@ packages:
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, tarball: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz}
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string-width@5.1.2:
@ -1614,7 +1687,7 @@ packages:
engines: {node: '>=12'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz}
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-ansi@7.1.0:
@ -1822,7 +1895,7 @@ packages:
hasBin: true
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz}
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
wrap-ansi@8.1.0:
@ -2217,6 +2290,11 @@ snapshots:
'@rolldown/pluginutils@1.0.0-beta.8-commit.56abf23': {}
'@rollup/pluginutils@4.2.1':
dependencies:
estree-walker: 2.0.2
picomatch: 2.3.1
'@rollup/pluginutils@5.1.4(rollup@4.41.0)':
dependencies:
'@types/estree': 1.0.7
@ -2339,6 +2417,13 @@ snapshots:
'@types/webxr@0.5.22': {}
'@typescript/vfs@1.6.1(typescript@5.8.3)':
dependencies:
debug: 4.4.1
typescript: 5.8.3
transitivePeerDependencies:
- supports-color
'@vicons/antd@0.13.0': {}
'@vicons/fa@0.12.0': {}
@ -2685,6 +2770,8 @@ snapshots:
commander@2.20.3: {}
commondir@1.0.1: {}
convert-source-map@2.0.0: {}
copy-anything@2.0.6:
@ -2850,6 +2937,17 @@ snapshots:
dependencies:
is-unicode-supported: 2.1.0
find-cache-dir@3.3.2:
dependencies:
commondir: 1.0.1
make-dir: 3.1.0
pkg-dir: 4.2.0
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
path-exists: 4.0.0
follow-redirects@1.15.9: {}
foreground-child@3.3.1:
@ -2864,6 +2962,12 @@ snapshots:
es-set-tostringtag: 2.1.0
mime-types: 2.1.35
fs-extra@10.1.0:
dependencies:
graceful-fs: 4.2.11
jsonfile: 6.1.0
universalify: 2.0.1
fs-extra@11.3.0:
dependencies:
graceful-fs: 4.2.11
@ -3015,6 +3119,10 @@ snapshots:
dependencies:
lie: 3.1.1
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
lodash-es@4.17.21: {}
lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21):
@ -3041,6 +3149,10 @@ snapshots:
semver: 5.7.2
optional: true
make-dir@3.1.0:
dependencies:
semver: 6.3.1
math-intrinsics@1.1.0: {}
memoize-one@6.0.0: {}
@ -3121,6 +3233,16 @@ snapshots:
is-inside-container: 1.0.0
is-wsl: 3.1.0
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
p-locate@4.1.0:
dependencies:
p-limit: 2.3.0
p-try@2.2.0: {}
package-json-from-dist@1.0.1: {}
parse-ms@4.0.0: {}
@ -3129,6 +3251,8 @@ snapshots:
path-browserify@1.0.1: {}
path-exists@4.0.0: {}
path-key@3.1.1: {}
path-key@4.0.0: {}
@ -3144,6 +3268,8 @@ snapshots:
picocolors@1.1.1: {}
picomatch@2.3.1: {}
picomatch@4.0.2: {}
pidtree@0.6.0: {}
@ -3158,6 +3284,10 @@ snapshots:
optionalDependencies:
typescript: 5.8.3
pkg-dir@4.2.0:
dependencies:
find-up: 4.1.0
postcss@8.5.3:
dependencies:
nanoid: 3.3.11
@ -3193,6 +3323,16 @@ snapshots:
glob: 11.0.2
package-json-from-dist: 1.0.1
rollup-plugin-typescript2@0.36.0(rollup@4.41.0)(typescript@5.8.3):
dependencies:
'@rollup/pluginutils': 4.2.1
find-cache-dir: 3.3.2
fs-extra: 10.1.0
rollup: 4.41.0
semver: 7.7.2
tslib: 2.8.1
typescript: 5.8.3
rollup@4.41.0:
dependencies:
'@types/estree': 1.0.7
@ -3232,6 +3372,8 @@ snapshots:
semver@6.3.1: {}
semver@7.7.2: {}
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0

BIN
public/static/cursor/ruler.cur

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/static/cursor/ruler.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

4
src/components/YvSrcEditor.vue

@ -1,6 +1,6 @@
<script>
<script lang="ts">
import { defineAsyncComponent } from 'vue'
// yv-src-editor-inner.vue
export default defineAsyncComponent(() => import('./YvSrcEditorInner.vue'))
export default defineAsyncComponent(() => import('./YvSrcEditorInner.vue')) as any
</script>

40
src/components/YvSrcEditorInner.vue

@ -40,16 +40,6 @@ export default {
'editor-focus'
],
mounted() {
// const monaco = window['monaco']
// debugger
// monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
// noSemanticValidation: true,
// noSyntaxValidation: false
// })
// monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
// target: monaco.languages.typescript.ScriptTarget.ES2016,
// allowNonTsExtensions: true
// })
},
data() {
const option = {
@ -130,7 +120,9 @@ export default {
this.init()
},
focus() {
this.editor?.focus()
_.defer(() => {
this.editor?.focus()
})
},
insertText(text) {
if (!this.editor) {
@ -147,7 +139,16 @@ export default {
this.editor?.revealLine(this.editor.getModel().getLineCount())
},
appendText(text) {
this.editor?.setValue(this.editor?.getValue() + text)
this.editor?.getModel().pushEditOperations(
[],
[
{
range: new monaco.Range(1, 1, 1, 1),
text: text
}
],
() => null
)
},
init() {
// this.editor.updateOptions(option);
@ -166,6 +167,19 @@ export default {
this.$emit('editor-focus', e)
})
if (this.language === 'typescript' || this.language === 'javascript') {
this.editor.onDidFocusEditorWidget(() => {
window['editor'] = this.editor
window['monaco'] = this.monaco
})
const monaco = this.monaco
const editor = this.editor
editor.addCommand(
monaco.KeyMod.CtrlCmd | monaco.KeyMod.Alt | monaco.KeyCode.KeyL,
() => editor.getAction('editor.action.formatDocument')?.run()
)
}
this.$emit('editor-mounted', this.editor)
// .monacoInitFinished()
},
@ -195,7 +209,7 @@ export default {
font-size: 14px;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon{
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon {
height: 18px;
}
}

33
src/core/base/BaseInteraction.ts

@ -8,6 +8,7 @@ import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'
import { numberToString } from '@/utils/webutils.ts'
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
import type { Object3DLike } from '@/types/ModelTypes.ts'
import Constract from '@/core/Constract.ts'
let pdFn, pmFn, puFn
@ -58,6 +59,10 @@ export default abstract class BaseInteraction {
return false
}
get cursorCSS(): string {
return 'crosshair'
}
constructor(itemTypeName: string) {
this.itemTypeName = itemTypeName
}
@ -153,15 +158,25 @@ export default abstract class BaseInteraction {
this.mouseOnlyClick = true
}
onMove(point: THREE.Vector3, e: MouseEvent): boolean {
return false
}
mousemove(e: MouseEvent): THREE.Vector3 | undefined {
this.mouseOnlyClick = false
// 当前鼠标所在的点
const point = this.viewport.getClosestIntersection(e)
this.lastMovePosition = point
if (!point) {
return
}
if (this.onMove(point, e)) {
// 如果有自定义的移动逻辑,则直接返回
return
}
// 如果按下了 shift 键,则 point 的位置必须位于 startPoint 正上下方,或者正左右方
if (this.linkStartPointObject && e.shiftKey) {
const startPos = this.linkStartPointObject.position
@ -196,7 +211,7 @@ export default abstract class BaseInteraction {
this.tempLabel.element.innerHTML = label
}
this.lastMovePosition = point
// 在鼠标移动时绘制临时点
if (this.tempPointMarker) {
@ -237,6 +252,13 @@ export default abstract class BaseInteraction {
}
}
/**
* true.
*/
onClickItem(item: ItemJson, pos: THREE.Vector3, evt: MouseEvent): boolean {
return false
}
onMouseClicked(e: MouseEvent): THREE.Vector3 | undefined {
// 获取鼠标点击位置的三维坐标
const point = this.lastMovePosition
@ -246,15 +268,18 @@ export default abstract class BaseInteraction {
// 双击触发两次点击事件,我们需要避免这里的第二次点击
const now = Date.now()
if (this.lastClickTime && (now - this.lastClickTime < 50)) {
if (this.lastClickTime && (now - this.lastClickTime < Constract.MOUSE_CLICK_DELAY)) {
return
}
this.lastClickTime = now
// 如果正式的点命中到同类型的节点上,则不添加新的点,只牵线到该点
let catchPoint: ItemJson | null = this.viewport.stateManager.findItemByPosition(point, this.itemTypeName)
let catchPoint: ItemJson | null = this.viewport.stateManager.findItemByPosition(point)
if (this.onClickItem(catchPoint, point, e)) {
// 自定义点击逻辑,如果函数返回 true,则表示已经处理了点击事件
return
}
if (this.isSinglePointMode) {
// 单点模式,直接添加点

15
src/core/engine/Viewport.ts

@ -24,12 +24,13 @@ import type { Object3DLike } from '@/types/ModelTypes.ts'
import type InstanceMeshManager from '@/core/manager/InstanceMeshManager.ts'
import ItemFindManager from '@/core/manager/ItemFindManager.ts'
import { MapControls } from 'three/examples/jsm/controls/MapControls'
import ModelManager from '@/core/script/ModelManager.ts'
/**
*
* ,,,,,
*/
export default class Viewport {
export default class Viewport implements Model {
viewerDom: HTMLElement
camera: THREE.Camera // THREE.OrthographicCamera
renderer: THREE.WebGLRenderer
@ -46,6 +47,7 @@ export default class Viewport {
entityManager = new EntityManager()
itemFindManager = new ItemFindManager()
interactionManager = new InteractionManager()
modelManager = new ModelManager()
// 状态管理器
stateManager: StateManager
@ -57,7 +59,8 @@ export default class Viewport {
markRaw(this.labelManager),
markRaw(this.entityManager),
markRaw(this.itemFindManager),
markRaw(this.interactionManager)
markRaw(this.interactionManager),
markRaw(this.modelManager)
]
// 对象实例管理器 moduleName -> InstanceMeshManager
@ -108,6 +111,14 @@ export default class Viewport {
}
/**
* ID
* @param entityId
*/
find(entityId: string): ItemJson {
return this.entityManager.findItemById(entityId)
}
/**
*
* @param typeName
* @param createFn

48
src/core/manager/CodeDropper.ts

@ -0,0 +1,48 @@
import BaseInteraction from '@/core/base/BaseInteraction.ts'
import type Viewport from '@/core/engine/Viewport.ts'
import { defineModule } from '@/core/manager/ModuleManager.ts'
import * as THREE from 'three'
export default class CodeDropper extends BaseInteraction {
get isSinglePointMode(): boolean {
return true
}
get cursorCSS(): string {
return `url('/static/cursor/ruler.cur'), auto`
}
onMove(point: THREE.Vector3, e: MouseEvent): boolean {
return true
}
onClickItem(item: ItemJson, pos: THREE.Vector3, evt: MouseEvent): boolean {
if (typeof this.droppedItemCallback !== 'function') {
throw new Error('设置 CodeDropper 就必须有回调函数')
}
if (this.droppedItemCallback(item, pos, evt)) {
this.stop()
}
return true
}
static INSTANCE = new CodeDropper('CodeDropper')
/**
*
* @param viewport
* @param fn item, pos, evt, true,
*/
static start(viewport: Viewport, fn: (item: ItemJson, pos: THREE.Vector3, evt: MouseEvent) => boolean) {
CodeDropper.INSTANCE.droppedItemCallback = fn
viewport.state.cursorMode = 'CodeDropper'
}
droppedItemCallback: (item: ItemJson, pos: THREE.Vector3, evt: MouseEvent) => boolean
}
defineModule({
name: 'CodeDropper',
interaction: CodeDropper.INSTANCE
})

1
src/core/manager/DragManager.ts

@ -121,6 +121,7 @@ export default class DragManager {
* pointerup
*/
private onPointerUp = (event: PointerEvent): void => {
if (!this.enabled || !this.domElement) return
if (event.button !== 0) return
if (this.isDragging) {
const startPos = this.dragStartMouse.clone()

9
src/core/manager/InteractionManager.ts

@ -1,7 +1,6 @@
import * as THREE from 'three'
import type Viewport from '@/core/engine/Viewport.ts'
import { watch } from 'vue'
import type IControls from '@/core/controls/IControls.ts'
import type BaseInteraction from '@/core/base/BaseInteraction.ts'
import { getInteraction } from '@/core/manager/ModuleManager.ts'
@ -15,7 +14,7 @@ export interface InteractionOption {
/**
*
*/
export default class InteractionManager implements IControls {
export default class InteractionManager {
private viewport: Viewport
/**
@ -54,8 +53,9 @@ export default class InteractionManager implements IControls {
this.viewport.state.cursorMode = 'normal'
this.viewport.dragManager.enabled = true
this.viewport.selectManager.enabled = true
this.viewport.viewerDom.style.cursor = ''
this.viewport.renderer.domElement.style.cursor = ''
this.option = undefined
// system.msg('退出新建模式')
}
@ -91,11 +91,12 @@ export default class InteractionManager implements IControls {
// 初始化交互
this.currentTool = interaction
this.viewport.dragManager.enabled = false
this.viewport.selectManager.enabled = false
this.currentTool.start(this.viewport, this.option)
// 更新 UI 状态
this.viewport.viewerDom.style.cursor = 'crosshair'
this.viewport.renderer.domElement.style.cursor = interaction.cursorCSS // 'crosshair'
this.viewport.state.cursorMode = mode
// system.msg(`enter [${mode}] interaction`)
}

12
src/core/manager/ModuleManager.ts

@ -10,10 +10,10 @@ export interface ModuleDefineOption {
*
*/
name: string;
renderer: BaseRenderer;
interaction: BaseInteraction;
setter: PropertySetter;
entity: new () => BaseEntity;
renderer?: BaseRenderer;
interaction?: BaseInteraction;
setter?: PropertySetter;
entity?: new () => BaseEntity;
}
// Internal storage for module definitions
@ -28,7 +28,7 @@ export function defineModule(option: ModuleDefineOption): Promise<any> {
throw new Error(`Module with name "${option.name}" is already defined.`)
}
modules.set(option.name, option)
return option.renderer.init()
return option.renderer?.init()
}
/**
@ -76,4 +76,4 @@ export function createEntity<T extends BaseEntity>(name: string, itemjson: ItemJ
v.setItem(itemjson)
v.setObjects(objects)
return v
}
}

6
src/core/manager/SelectManager.ts

@ -15,6 +15,7 @@ import LineSegmentManager from '@/core/manager/LineSegmentManager.ts'
*/
export default class SelectManager {
viewport: Viewport
enabled: boolean = true
/**
* 线
*/
@ -72,6 +73,8 @@ export default class SelectManager {
EventBus.on('multiSelectedObjectsChanged', this.updateMultiSelectionBoxes)
EventBus.on('selectedObjectPropertyChanged', this.updateSelectionBox)
// EventBus.on('multiselectedObjectChanged', this.updateMultiSelectionBoxes)
this.enabled = true
}
updateMultiSelectionBoxes = () => {
@ -264,6 +267,7 @@ export default class SelectManager {
}
private onMouseDown = (event: MouseEvent) => {
if (!this.enabled) return
if (event.button !== 0) return
if (event.shiftKey) {
// 记录鼠标按下位置
@ -279,6 +283,7 @@ export default class SelectManager {
private onMouseMove = (event: MouseEvent) => {
if (!this.enabled) return
if (!this.recStartPos) {
this.calcSelectionRectAndDispose()
}
@ -289,6 +294,7 @@ export default class SelectManager {
}
private onMouseUp = (event: MouseEvent) => {
if (!this.enabled) return
if (event.button !== 0) return
this.calcSelectionRectAndDispose(event)
const clickTime = this.clickTime

139
src/core/manager/TaskManager.ts

@ -1,4 +1,3 @@
// 任务 API
// TaskSequence ts = TaskSequence.create(agv)
// ts.addTask('TASKTYPE_LOAD', item, queue);
@ -10,74 +9,77 @@
// ts.dispatch();
// import {Object3DLike} from "@/types/ModelTypes";
import gsap from 'gsap';
import * as THREE from "three";
import Viewport from "@/core/engine/Viewport";
import {getMatrixFromTf} from "@/core/ModelUtils";
import gsap from 'gsap'
import * as THREE from 'three'
import Viewport from '@/core/engine/Viewport'
interface AgvTask {
type: string;
}
export default class TaskManager implements TaskManagerIF {
interface AgvTaskLoad extends AgvTask {
type: 'TASKTYPE_LOAD';
item: string;
queue: string;
}
static taskMap: Map<object, TaskManager> = new Map()
interface AgvTaskTravel extends AgvTask {
type: 'TASKTYPE_TRAVEL';
entityId: string;
}
interface AgvTaskRotation extends AgvTask {
type: 'TASKTYPE_ROTATION';
angle: number;
}
private readonly obj: any = null
private readonly viewport: Viewport
export default class TaskManager {
private taskSequence: AgvTask[] = []
static taskMap: Map<object, TaskManager> = new Map();
private isRunning: boolean = false
private currentTask: AgvTask
private isStepRunning: boolean = false
private speed: number = 1 // 速度 2m/s
private rotationSpeed: number = 45 // 旋转速度 45°/s
constructor(agv: object, viewport: Viewport) {
this.obj = agv
this.viewport = viewport
TaskManager.taskMap.set(agv, this)
}
private obj: object = null
private viewport: Viewport;
addLoadTask(item: string): void {
this.taskSequence.push({
type: 'TASKTYPE_LOAD',
item: item,
queue: 'default' // 默认队列
})
}
private taskSequence: AgvTask[] = []
addRotationTask(angle: number): void {
this.taskSequence.push({
type: 'TASKTYPE_ROTATION',
angle: angle
})
}
private isRunning: boolean = false
private currentTask: AgvTask;
private isStepRunning: boolean = false;
private speed: number = 1; // 速度 2m/s
private rotationSpeed: number = 45; // 旋转速度 45°/s
static create(agv, viewport: Viewport) {
if (TaskManager.taskMap.has(agv)) {
return TaskManager.taskMap.get(agv);
} else {
const task = new TaskManager();
task.obj = agv;
task.viewport = viewport;
TaskManager.taskMap.set(agv, task);
return task;
}
addTravelTask(entityId: string): void {
this.taskSequence.push({
type: 'TASKTYPE_TRAVEL',
entityId: entityId
})
}
public addTask(task: AgvTask) {
this.taskSequence.push(task);
addUnloadTask(item: string, rack: string, bay?: number, level?: number): void {
this.taskSequence.push({
type: 'TASKTYPE_UNLOAD',
item: item,
rack: rack,
bay: bay, // 可选参数,表示卸载位置的 X 坐标
level: level // 可选参数,表示卸载位置的 Y 坐标
})
}
public runTask() {
if (this.isStepRunning) {
return;
return
}
this.currentTask = this.taskSequence.shift();
this.currentTask = this.taskSequence.shift()
if (this.currentTask) {
switch (this.currentTask.type) {
case 'TASKTYPE_LOAD':
break;
console.error('还没做')
break
case 'TASKTYPE_TRAVEL': {
const task = this.currentTask as AgvTaskTravel;
const position = this.getPositionByEntityId(task.entityId);
let time = position.distanceTo(this.obj.position) / this.speed + 1;
const task = this.currentTask as AgvTaskTravel
const position = Model.getPositionByEntityId(task.entityId)
let time = position.distanceTo(this.obj.position) / this.speed + 1
// if (time < 1.5) {
// time = 1.5
// }
@ -87,16 +89,16 @@ export default class TaskManager {
z: position.z,
duration: time,
repeat: 0,
ease: "sine.inOut"
}).eventCallback("onComplete", () => {
this.runTask();
});
break;
ease: 'sine.inOut'
}).eventCallback('onComplete', () => {
this.runTask()
})
break
}
case 'TASKTYPE_ROTATION':
const task = this.currentTask as AgvTaskRotation;
const task = this.currentTask as AgvTaskRotation
let time = Math.abs(task.angle - THREE.MathUtils.radToDeg(this.obj.rotation.y))/this.rotationSpeed
let time = Math.abs(task.angle - THREE.MathUtils.radToDeg(this.obj.rotation.y)) / this.rotationSpeed
if (time < 0.5) {
time = 0.5
}
@ -105,26 +107,19 @@ export default class TaskManager {
y: THREE.MathUtils.degToRad(task.angle),
duration: time,
repeat: 0,
ease: "none"
}).eventCallback("onComplete", () => {
this.runTask();
});
break;
ease: 'none'
}).eventCallback('onComplete', () => {
this.runTask()
})
break
case 'TASKTYPE_UNLOAD':
break;
console.error('还没做')
break
default:
throw new Error('Invalid task type');
throw new Error('Invalid task type')
}
}
}
public getPositionByEntityId(entityId: string): THREE.Vector3 {
const item = this.viewport.entityManager.findItemById(entityId)
const matrix = getMatrixFromTf(item.tf)
const position = new THREE.Vector3()
matrix.decompose(position, new THREE.Quaternion(), new THREE.Vector3())
return position
}
}

95
src/core/script/ModelManager.ts

@ -0,0 +1,95 @@
import type Viewport from '@/core/engine/Viewport.ts'
import { executeTypeScript } from '@/core/script/ScriptSupport.ts'
import * as THREE from 'three'
import { getMatrixFromTf } from '@/core/ModelUtils.ts'
import type { Object3DLike } from '@/types/ModelTypes.ts'
import TaskManager from '../manager/TaskManager.ts'
export default class ModelManager implements IControls, Model {
private viewport: Viewport
createTask(agv: object): TaskManager {
if (TaskManager.taskMap.has(agv)) {
return TaskManager.taskMap.get(agv)
}
return new TaskManager(agv, this.viewport)
}
get selectedObject(): Object3DLike | undefined {
return this.viewport.state.selectedObject
}
get selectedEntityId(): string | undefined {
return this.viewport.state.selectedEntityId
}
get selectedItem(): ItemJson | undefined {
return this.viewport.state.selectedItem
}
get multiSelectedObjects(): Object3DLike[] {
return this.viewport.state.multiSelectedObjects
}
get multiSelectedItems(): ItemJson[] {
return this.viewport.state.multiSelectedItems
}
get multiSelectedEntityIds(): string[] {
return this.viewport.state.multiSelectedEntityIds
}
logger = {
info: (...args: any[]) => console.info(...args),
error: (...args: any[]) => console.error(...args),
warn: (...args: any[]) => console.warn(...args),
debug: (...args: any[]) => console.debug(...args)
}
init(viewport: Viewport) {
this.viewport = viewport
window['Model'] = this
window['print'] = this.print.bind(this)
window['executestring'] = this.executestring.bind(this)
window['logger'] = this.logger
window['msg'] = this.msg
}
find(entityId: string): ItemJson {
const item = this.viewport.entityManager.findItemById(entityId)
if (!item) {
print(`Item with ID ${entityId} not found in the viewport.`)
}
return item
}
getPositionByEntityId(entityId: string): THREE.Vector3 {
const item = this.viewport.entityManager.findItemById(entityId)
const matrix = getMatrixFromTf(item.tf)
const position = new THREE.Vector3()
matrix.decompose(position, new THREE.Quaternion(), new THREE.Vector3())
return position
}
dispose() {
this.viewport = null as any
window['Model'] = null
}
async executestring(script: string) {
return executeTypeScript.call(this, script, {})
}
print(...data: any[]) {
console.log(...data)
}
msg(content: string, type: number = 1) {
if (type === 1) {
system.showErrorDialog(content)
} else if (type === 2) {
system.showInfoDialog(content)
}
}
}

130
src/core/script/ScriptSupport.ts

@ -1,38 +1,122 @@
import ModelDts from '@/types/model.d.ts?raw'
import TypesDts from '@/types/Types.d.ts?raw'
import ScriptSupportDts from '@/types/ScriptSupport.d.ts?raw'
import * as ts from 'typescript'
import { createDefaultMapFromCDN, createSystem, createVirtualCompilerHost } from '@typescript/vfs'
export async function executeTypeScript(code: string, contextExtend: any = {}) {
const fsMap = await createDefaultMapFromCDN(
{ target: ts.ScriptTarget.ESNext },
'latest',
true, // 缓存
ts
)
fsMap.set('input.ts', code)
// 3. 创建虚拟系统
const system = createSystem(fsMap)
// 4. 创建编译器主机(不需要 Node.js 模块)
const host = createVirtualCompilerHost(system, {}, ts)
// 5. 编译和执行
const program = ts.createProgram({
rootNames: [...fsMap.keys()],
options: {},
host: host.compilerHost
})
program.emit()
// 4. 获取编译后的JS代码
const jsCode = fsMap.get('input.js') || ''
// 5. 安全执行(使用沙箱)
return executeInSandbox(jsCode, contextExtend)
}
export function executeInSandbox(code: string, contextExtend: any = {}) {
// 创建安全上下文
const context = {
...contextExtend,
console,
require: (module: string) => {
if (module === 'fs') throw new Error('FS access forbidden')
//@ts-ignore
return require(module)
}
}
// 使用Function构造函数比eval更安全
try {
const fn = new Function('context', `
with(context) {
${code}
}
`)
fn.call(context, context)
} catch (e) {
console.error('Execution error:', e)
}
}
/**
* monaco
* @param monaco
*/
export function setupMonacoEditor(monaco: any) {
export async function setupMonacoEditor(monaco: any) {
if (!monaco || monaco.__isExtended) {
return
}
// 启用诊断信息(语法、语义错误提示)
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.ESNext,
allowNonTsExtensions: true,
strict: true,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
module: monaco.languages.typescript.ModuleKind.ESNext,
noEmit: true,
lib: ['esnext'] // 关键:只包含 ES 标准库,排除 DOM 库
})
// 移除默认的 TypeScript 诊断提供器
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
noSemanticValidation: false,
noSyntaxValidation: false,
noSuggestionDiagnostics: false
// 过滤掉 return 语句警告
diagnosticCodesToIgnore: [1108]
})
// 注入 mylib 模块的类型定义
// 可选:添加自定义类型定义(如果需要)
monaco.languages.typescript.typescriptDefaults.addExtraLib(
`
declare module 'mylib' {
export function greet(name: string): void;
export const version: string;
}
`,
'file:///node_modules/mylib/index.d.ts'
ModelDts,
'model.d.ts'
)
monaco.languages.typescript.typescriptDefaults.addExtraLib(
TypesDts,
'Types.d.ts'
)
monaco.languages.typescript.typescriptDefaults.addExtraLib(
ScriptSupportDts,
'ScriptSupport.d.ts'
)
// 配置 TypeScript 编译器选项
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.Latest,
module: monaco.languages.typescript.ModuleKind.ESNext,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
noEmit: true,
strict: true,
lib: ['esnext'],
types: [] // 不加载默认 DOM 类型
})
monaco.languages.typescript.typescriptDefaults.addExtraLib(
`declare const myCustomVar: string;`,
'globals.d.ts'
)
// 可选:禁用内置的 DOM 类型(双重保险)
const disableDomTypes = () => {
const libs = monaco.languages.typescript.typescriptDefaults.getExtraLibs()
Object.keys(libs).forEach(path => {
if (path.includes('lib.dom.d.ts')) {
monaco.languages.typescript.typescriptDefaults.setExtraLibs(
Object.fromEntries(
Object.entries(libs).filter(([key]) => !key.includes('lib.dom.d.ts'))
)
)
}
})
}
disableDomTypes()
monaco.__isExtended = true
}

41
src/editor/Model2DEditor.vue

@ -112,8 +112,8 @@ import lodash from 'lodash'
import { DXFViewer } from 'three-dxf-viewer'
import cadFont from '@/assets/fonts/helvetiker_regular.typeface.json?url'
import StateManager from '@/core/manager/StateManager.js'
import gsap from 'gsap';
import TaskManager from "@/core/manager/TaskManager.js";
import gsap from 'gsap'
import TaskManager from '@/core/manager/TaskManager.js'
export default defineComponent({
@ -284,32 +284,19 @@ export default defineComponent({
}).finally()
},
animationClick() {
const op = {x: 5.650, y: 0.1, z: 2.865}
const obj = this.state.selectedObject
if (obj) {
const taskManager = TaskManager.create(obj, this.viewport)
taskManager.addTask( {
type: 'TASKTYPE_TRAVEL',
entityId: "3ZP01pHXJRuyeg24oCaaMq"
})
taskManager.addTask( {
type: 'TASKTYPE_ROTATION',
angle: 0
})
taskManager.addTask( {
type: 'TASKTYPE_TRAVEL',
entityId: "09PTEMUnACWY0MUG4qmk0r"
})
taskManager.addTask( {
type: 'TASKTYPE_ROTATION',
angle: -90
})
taskManager.addTask( {
type: 'TASKTYPE_TRAVEL',
entityId: "5iKoIUBhnU08EM0IsoyOSW"
})
taskManager.runTask()
const op = { x: 5.650, y: 0.1, z: 2.865 }
const obj = Model.selectedObject
if (!obj) {
msg('没有选择对象,无法执行动画')
return
}
const taskManager = Model.createTask(obj)
taskManager.addTravelTask('3ZP01pHXJRuyeg24oCaaMq')
taskManager.addRotationTask(0)
taskManager.addTravelTask('09PTEMUnACWY0MUG4qmk0r')
taskManager.addRotationTask(-90)
taskManager.addTravelTask('5iKoIUBhnU08EM0IsoyOSW')
taskManager.runTask()
},
async addCADDxf(file) {

36
src/editor/menus/EditMenu.ts

@ -40,24 +40,24 @@ export default defineMenu((menus) => {
}
}
},
{
name: 'copy', label: '复制', icon: SvgCode.copy, order: 4, tip: 'Ctrl+C',
click() {
system.msg('复制')
}
},
{
name: 'cut', label: '剪切', icon: SvgCode.cut, order: 5, tip: 'Ctrl+X',
click() {
system.msg('剪切')
}
},
{
name: 'paste', label: '粘贴', icon: SvgCode.paste, order: 6, tip: 'Ctrl+V',
click() {
system.msg('粘贴')
}
},
// {
// name: 'copy', label: '复制', icon: SvgCode.copy, order: 4, tip: 'Ctrl+C',
// click() {
// system.msg('复制')
// }
// },
// {
// name: 'cut', label: '剪切', icon: SvgCode.cut, order: 5, tip: 'Ctrl+X',
// click() {
// system.msg('剪切')
// }
// },
// {
// name: 'paste', label: '粘贴', icon: SvgCode.paste, order: 6, tip: 'Ctrl+V',
// click() {
// system.msg('粘贴')
// }
// },
{
name: 'delete', label: '删除', icon: SvgCode.delete, order: 7, tip: 'key-delete', divided: true,
click() {

4
src/editor/widgets/logger/LoggerMeta.ts

@ -6,7 +6,7 @@ export default defineWidget({
name: 'logger',
title: '日志',
icon: renderIcon('element ToiletPaper'),
side: 'bottom',
side: 'right',
order: 2,
component: LoggerView
})
})

45
src/editor/widgets/logger/LoggerView.vue

@ -11,53 +11,16 @@
</span>
</div>
<div class="calc-bottom-panel">
LoggerView1<br />
LoggerView2<br />
LoggerView3<br />
LoggerView4<br />
LoggerView5<br />
LoggerView6<br />
LoggerView7<br />
LoggerView8<br />
LoggerView9<br />
LoggerView10<br />
LoggerView11<br />
LoggerView12<br />
LoggerView13<br />
LoggerView14<br />
LoggerView15<br />
LoggerView16<br />
LoggerView17<br />
LoggerView18<br />
LoggerView19<br />
LoggerView20<br />
LoggerView21<br />
LoggerView22<br />
LoggerView23<br />
LoggerView24<br />
LoggerView25<br />
LoggerView26<br />
LoggerView27<br />
LoggerView28<br />
LoggerView29<br />
LoggerView30<br />
LoggerView31<br />
LoggerView32<br />
LoggerView33<br />
LoggerView34<br />
LoggerView35<br />
LoggerView36<br />
LoggerView37<br />
LoggerView38<br />
LoggerView39<br />
LoggerView40<br />
<YvSrcEditor ref="jsEditor" language="typescript" v-model="currentLog" />
</div>
</template>
<script>
import IWidgets from '../IWidgets.js'
import YvSrcEditor from '@/components/YvSrcEditor.vue'
export default {
name: 'LoggerView',
components: { YvSrcEditor },
webSocketSubscribe: ['logs'],
mixins: [IWidgets],
data() {
@ -66,4 +29,4 @@ export default {
}
}
}
</script>
</script>

154
src/editor/widgets/script/ScriptView.vue

@ -5,20 +5,28 @@
脚本编辑
</h3>
<el-row>
<el-button :icon="renderIcon('CirclePlus')" link>添加</el-button>
<el-button :icon="renderIcon('CirclePlus')" link
@click="addScript">添加
</el-button>
<el-divider direction="vertical" />
<el-button :icon="renderIcon('antd SaveOutlined')" link>保存</el-button>
<el-button :icon="renderIcon('element FolderOpened')" link>打开</el-button>
<el-button :icon="renderIcon('Delete')" link>删除</el-button>
<el-button :icon="renderIcon('Delete')" link
:disabled="scriptList.length === 0 || !scriptList[scriptIndex]"
@click="removeCurrentScript">删除
</el-button>
<el-divider direction="vertical" />
<el-button :icon="renderIcon('antd PlayCircleOutlined')" link type="primary">运行</el-button>
<el-button :icon="renderIcon('fa EyeDropper')" link>编码吸管</el-button>
<el-button :icon="renderIcon('antd PlayCircleOutlined')" link type="primary"
:disabled="scriptList.length === 0 || !scriptList[scriptIndex]"
:loading="scriptIsRunning"
@click="runScript">运行
</el-button>
<el-button :icon="renderIcon('fa EyeDropper')" link
:disabled="scriptList.length === 0 || !scriptList[scriptIndex]"
@click="setCodeDropper">编码吸管
</el-button>
<el-divider direction="vertical" />
<el-radio-group v-model="scriptIndex" size="small">
<el-radio-button label="脚本1" :value="0" />
<el-radio-button label="脚本2" :value="1" />
<el-radio-button label="脚本3" :value="2" />
<el-radio-button label="脚本4" :value="3" />
<el-radio-button v-for="(item, index) in scriptList" :key="index"
:label="item.name" :value="index" />
</el-radio-group>
</el-row>
<span class="close" @click="closeMe">
@ -26,12 +34,16 @@
</span>
</div>
<div class="calc-bottom-panel">
<YvSrcEditor ref="jsEditor" language="javascript" v-model="script1" />
<YvSrcEditor ref="jsEditor" language="typescript" :key="scriptIndex"
v-if="scriptList.length > 0 && scriptList[scriptIndex]"
v-model="currentScript" />
</div>
</template>
<script>
import localforage from 'localforage'
import YvSrcEditor from '@/components/YvSrcEditor.vue'
import IWidgets from '../IWidgets.js'
import CodeDropper from '@/core/manager/CodeDropper.js'
export default {
name: 'ScriptView',
@ -41,23 +53,129 @@ export default {
mixins: [IWidgets],
data() {
return {
scriptIsRunning: false,
scriptIndex: 0,
script1: '',
scriptList: [],
searchKeyword: ''
}
},
watch: {
scriptList: {
handler(newVal) {
this.saveScriptsToLocalDebounce(this)
},
deep: true
}
},
created() {
this.loadFromLocal()
},
methods: {
runScript() {
this.scriptIsRunning = true
this.viewport.modelManager.executestring(this.currentScript)
.catch(err => {
system.msg('脚本执行失败: ' + err.message, 'error')
})
.finally(() => {
this.scriptIsRunning = false
})
},
setCodeDropper() {
CodeDropper.start(this.viewport, (item) => {
if (item) {
if (!this.$refs.jsEditor) {
system.msg('代码编辑器未加载', 'warning')
return false
}
//@ts-ignore
this.$refs.jsEditor.insertText(`Model.find("${item.id}")`)
//@ts-ignore
this.$refs.jsEditor.focus()
return true
} else {
system.msg('代码吸管没有获取到内容', 'warning')
return false
}
})
},
saveScriptsToLocal() {
localforage.setItem('-yvan-lcc-scriptlist-', JSON.stringify({
scriptList: this.scriptList,
scriptIndex: this.scriptIndex
})).catch(err => {
system.msg('保存脚本到本地失败:', 'error')
})
},
saveScriptsToLocalDebounce: _.debounce(function(me) {
me.saveScriptsToLocal()
}, 1000),
loadFromLocal() {
localforage.getItem('-yvan-lcc-scriptlist-')
.then(value => {
if (value) {
const res = JSON.parse(value)
this.scriptList = res.scriptList || []
this.scriptIndex = res.scriptIndex || 0
} else {
this.scriptList = []
}
})
.catch(err => {
this.scriptList = []
system.msg('加载脚本失败:', 'error')
})
},
addScript() {
this.scriptList.push({
name: 'Script' + (this.scriptList.length + 1),
content: ''
})
this.scriptIndex = this.scriptList.length - 1
},
removeCurrentScript() {
_.remove(this.scriptList, (item, index) => {
return index === this.scriptIndex
})
if (this.scriptList.length === 0) {
this.scriptIndex = 0
} else if (this.scriptIndex >= this.scriptList.length) {
this.scriptIndex = this.scriptList.length - 1
}
}
},
computed: {
currentScript: {
get() {
return this.scriptList[this.scriptIndex]?.content || ''
},
set(value) {
if (!this.scriptList[this.scriptIndex]) {
this.scriptList[this.scriptIndex] = {
name: 'Script' + (this.scriptList.length + 1),
content: ''
}
}
this.scriptList[this.scriptIndex].content = value
}
}
}
}
</script>
<style lang="less">
.title{
& > h3{
margin-right:10px;
.el-icon{
.title {
& > h3 {
margin-right: 10px;
.el-icon {
position: relative;
top:2px;
top: 2px;
}
}
&>.el-row{
& > .el-row {
display: flex;
align-items: center;
}

1
src/types/ModelTypes.ts

@ -73,3 +73,4 @@ export const MaterialQualityEnum = {
Middle: 1,
Low: 2
}

169
src/types/ScriptSupport.d.ts

@ -0,0 +1,169 @@
/**
* API
*/
declare interface Model {
/**
* ID
* @param entityId ID
*/
find(entityId: string): ItemJson
/**
* ID
*/
getPositionByEntityId(entityId: string): Vector3IF
/**
*
* @param agv
* @return
*/
createTask(agv: object): TaskManagerIF
/**
*
*/
selectedObject: any
/**
* ID
*/
selectedEntityId: string | undefined
/**
*
*/
selectedItem: ItemJson | undefined
/**
*
*/
multiSelectedObjects: any[]
/**
*
*/
multiSelectedItems: ItemJson[]
/**
* ID列表
*/
multiSelectedEntityIds: string[]
}
/**
* API
*/
declare const Model: Model
declare interface TaskManagerIF {
// addTask(task: AgvTask)
/**
*
* @param item ID
*/
addLoadTask(item: string): void
/**
*
* @param item ID
* @param rack ID
* @param bay ,
* @param level ,
*/
addUnloadTask(item: string, rack: string, bay?: number, level?: number): void
/**
*
* @param entityId ID
*/
addTravelTask(entityId: string): void
/**
*
* @param angle
*/
addRotationTask(angle: number): void
/**
*
*/
runTask()
}
type AgvTask = AgvTaskLoad | AgvTaskTravel | AgvTaskRotation | AgvTaskUnload
interface AgvTaskLoad {
type: 'TASKTYPE_LOAD';
item: string;
queue: string;
}
interface AgvTaskUnload {
type: 'TASKTYPE_UNLOAD';
item: string;
rack: string;
bay?: number; // 可选参数,表示卸载位置的 X 坐标
level?: number; // 可选参数,表示卸载位置的 Y 坐标
}
interface AgvTaskTravel {
type: 'TASKTYPE_TRAVEL';
entityId: string;
}
interface AgvTaskRotation {
type: 'TASKTYPE_ROTATION';
angle: number;
}
/**
* ,
*/
declare function print(...objany: any[]): void
declare interface ILogger {
/**
*
*/
info(str: string, ...objany: any[]): void
/**
*
*/
error(str: string, ...objany: any[]): void
/**
*
*/
warn(str: string, ...objany: any[]): void
/**
*
*/
debug(str: string, ...objany: any[]): void
}
/**
*
*/
declare const logger: ILogger
declare type MSG_TYPE =
/**
*
*/
1 |
/**
*
*/
2
/**
*
*/
declare function msg(str: string, type: MSG_TYPE = 1): void

11
src/types/Types.d.ts

@ -73,6 +73,15 @@ interface IControls {
init(viewport: any): void
dispose(): void
}
interface Vector3IF {
x: number;
y: number;
z: number;
animate?: () => void;
/**
*
*/
distanceTo(vector: Vector3IF): number;
}

121
vite.config.ts

@ -2,6 +2,7 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import typescript from 'rollup-plugin-typescript2'
// import vueJsx from '@vitejs/plugin-vue-jsx'
// import vueDevTools from 'vite-plugin-vue-devtools'
@ -29,5 +30,125 @@ export default defineConfig({
'element-plus', 'ag-grid-community', 'ag-grid-enterprise', 'ag-grid-vue3',
'codemirror'
]
},
build:{
target: 'modules',
outDir: "./dist",
minify: true,
sourcemap: false,
rollupOptions: {
output: {
chunkFileNames: (chunkInfo) => {
return 'js/[name]-[hash].js';
},
entryFileNames: 'js/yvan-lcc.mjs',
assetFileNames: 'js/yvan-lcc[extname]',
name: "yvan-lcc",
exports: 'named',
globals: {
vue: "Vue",
},
manualChunks: function (id) {
if (id.includes("/yvan-lcc/src")) {
return;
}
if (id.includes('diagram-js')) {
return 'diagram-js';
}
// 无法切包
// if (id.includes('/monaco-editor/')) {
// return 'monaco-editor';
// }
// 无法切包
// if (id.includes('/codemirror/')) {
// return 'codemirror';
// }
// if (id.includes('/@codemirror/')) {
// return 'codemirror2';
// }
if (id.includes('/lodash/') || id.includes('/lodash-es/')) {
return 'lodash';
}
if (id.includes('/vant/')) {
return 'vant';
}
if (id.includes('/zrender/')) {
return 'zrender';
}
if (id.includes('/@vicons/ionicons5/')) {
return 'ionicons5';
}
if (id.includes('/@vicons/antd/')) {
return 'antd-icons';
}
if (id.includes('/@vicons/fa/')) {
return 'fa-icons';
}
if (id.includes('/dayjs/')) {
return 'dayjs';
}
if (id.includes('/@vueuse/')) {
return 'vueuse';
}
if (id.includes('/axios/')) {
return 'axios';
}
if (id.includes('/crypto-js/')) {
return 'crypto-js';
}
if (id.includes('/@interactjs/')) {
return 'interactjs';
}
if (id.includes('bpmn-js')) {
return 'bpmn-js';
}
if (id.includes('/highlight.js/')) {
return 'highlight';
}
if (id.includes('/echarts/')) {
return 'echarts';
}
if (id.includes('/prismjs/')) {
return 'prismjs';
}
if (id.includes('/jquery/')) {
return 'jquery';
}
if (id.includes('/xlsx/')) {
return 'xlsx';
}
if (id.includes('/vue3-markdown-it/')) {
return 'vue3-markdown-it';
}
if (id.includes('/element-plus/') || id.includes('/@element-plus/')) {
return 'element-plus';
}
console.log("id", id)
},
},
external: [
// 'vue',
// 'vue-router',
// 'lodash',
// 'element-plus',
// "codemirror",
// 'ag-grid-community',
// 'ag-grid-enterprise',
// 'ag-grid-vue3',
// 'localforage',
// 'json5',
// "vant",
// "axios",
// "echarts",
// "split.js",
// "pinia",
// "vue3-menus",
// "resize-observer-polyfill",
// "@element-plus/icons-vue",
// "@vicons/fa",
// "@vicons/utils",
// "axios"
],
},
}
})

Loading…
Cancel
Save