diff --git a/.gitignore b/.gitignore
index 6e4fc41..3a6b5d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,10 @@ dist/
packages/backend/public/
packages/backend/dist/
packages/frontend/dist/
+packages/frontend/public/assets/dxf-parser-worker.js
+packages/frontend/public/assets/libredwg-parser-worker.js
+packages/frontend/public/assets/mtext-renderer-worker.js
+packages/frontend/public/viewer-assets/
.env
.env.local
*.log
diff --git a/LICENSE b/LICENSE
index 01a3e8b..26a1d6f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,17 @@
-MIT License
+GNU GENERAL PUBLIC LICENSE
+Version 3, 29 June 2007
Copyright (c) 2026 sejong-office contributors
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, version 3 of the License.
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+You should have received a copy of the GNU General Public License along with
+this program. If not, see .
+
+SPDX-License-Identifier: GPL-3.0-only
diff --git a/package-lock.json b/package-lock.json
index e4b1488..688f6c3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7,7 +7,7 @@
"": {
"name": "sejong-office",
"version": "0.1.0",
- "license": "MIT",
+ "license": "GPL-3.0-only",
"workspaces": [
"packages/*"
],
@@ -15,6 +15,110 @@
"node": ">=20"
}
},
+ "node_modules/@ai-sdk/anthropic": {
+ "version": "2.0.87",
+ "resolved": "https://registry.npmjs.org/@ai-sdk/anthropic/-/anthropic-2.0.87.tgz",
+ "integrity": "sha512-txxXi/CRaP4/Ubxh0VZx5PEbYMTvSznblOor4a9Xdoro6LxDQzQMT8qRoZrnqG9xFGLbj4+ZZpIbeQ9LIONQyA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ai-sdk/provider": "2.0.3",
+ "@ai-sdk/provider-utils": "3.0.30"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.76 || ^4.1.8"
+ }
+ },
+ "node_modules/@ai-sdk/gateway": {
+ "version": "2.0.116",
+ "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.116.tgz",
+ "integrity": "sha512-pcz//pMnek76mQW9dPX3wOHUoRPLirB3efKv1FOBWPV9ryWXLCaqE631ryV043WkpJCaCEsX30BzyWL7h8qXcg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ai-sdk/provider": "2.0.3",
+ "@ai-sdk/provider-utils": "3.0.30",
+ "@vercel/oidc": "3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.76 || ^4.1.8"
+ }
+ },
+ "node_modules/@ai-sdk/openai": {
+ "version": "2.0.114",
+ "resolved": "https://registry.npmjs.org/@ai-sdk/openai/-/openai-2.0.114.tgz",
+ "integrity": "sha512-cZ1dqr0qDqYvURjoKS7eyRe9bqHzJW6sBeoTMrkuDh7dmeLxuHF09WqWaQvsbYPF2ss3KuUpTCBbyaHDtqCItQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ai-sdk/provider": "2.0.3",
+ "@ai-sdk/provider-utils": "3.0.30"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.76 || ^4.1.8"
+ }
+ },
+ "node_modules/@ai-sdk/provider": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.3.tgz",
+ "integrity": "sha512-h88OPkavHTiN9tMn2l5awAznGB0lXzjcLhgR1/rvjB2zlLprsNxbM2tt6OJsHUxduLC3klq0/eqaSf6fX5XVww==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "json-schema": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@ai-sdk/provider-utils": {
+ "version": "3.0.30",
+ "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.30.tgz",
+ "integrity": "sha512-NCJ9JKow5ENAgEZxzvEvF20thwDiH+hutvzmrUDbloRX0azpJHNst8+7pZIVryYhLM9wgpT5/ShTSjPTFhkxEQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ai-sdk/provider": "2.0.3",
+ "@standard-schema/spec": "^1.0.0",
+ "eventsource-parser": "^3.0.6"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.76 || ^4.1.8"
+ }
+ },
+ "node_modules/@ai-sdk/vue": {
+ "version": "2.0.217",
+ "resolved": "https://registry.npmjs.org/@ai-sdk/vue/-/vue-2.0.217.tgz",
+ "integrity": "sha512-5WnO+kXP6D6pBL5zLubIf6ebsZIUE4aE3+TqkE83H0rLAj7wtoh/F/9/3tf3JB9IDmxmRzs1diSY63vLU28tXQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ai-sdk/provider-utils": "3.0.30",
+ "ai": "5.0.217",
+ "swrv": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "vue": "^3.3.4",
+ "zod": "^3.25.76 || ^4.1.8"
+ },
+ "peerDependenciesMeta": {
+ "vue": {
+ "optional": true
+ },
+ "zod": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@antfu/install-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
@@ -128,6 +232,24 @@
"integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==",
"license": "Apache-2.0"
},
+ "node_modules/@ctrl/tinycolor": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz",
+ "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@element-plus/icons-vue": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
+ "integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": "^3.2.0"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
@@ -714,6 +836,15 @@
"integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==",
"license": "MIT"
},
+ "node_modules/@fxts/core": {
+ "version": "1.26.0",
+ "resolved": "https://registry.npmjs.org/@fxts/core/-/core-1.26.0.tgz",
+ "integrity": "sha512-ONaza1CGr8dLKmJ0HQgi0h4XuyDJMr0P70M7o/My/YeeRxuYoSANHjE2nSY7xO4WHgxUD5ojd5dpxlFOzAEJsA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.0"
+ }
+ },
"node_modules/@iconify/types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
@@ -731,12 +862,82 @@
"import-meta-resolve": "^4.2.0"
}
},
+ "node_modules/@intlify/core-base": {
+ "version": "11.4.7",
+ "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.4.7.tgz",
+ "integrity": "sha512-MSB/sBKwEWJTILvQIhg2rnIcwPpLayo3wGwvVA+dJTNeUBD9GoqQgAaSOLdI9iOPDHCm9YoVnLqpfzza98MpkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@intlify/devtools-types": "11.4.7",
+ "@intlify/message-compiler": "11.4.7",
+ "@intlify/shared": "11.4.7"
+ },
+ "engines": {
+ "node": ">= 22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/devtools-types": {
+ "version": "11.4.7",
+ "resolved": "https://registry.npmjs.org/@intlify/devtools-types/-/devtools-types-11.4.7.tgz",
+ "integrity": "sha512-GSz+J+hqH+AEpAHIYya6fSufS30OaMnG39HiZX7DmGKi3+aaLvassCfsXENEc4Wr4m68q2YP0QdMdB3D9UeAXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@intlify/core-base": "11.4.7",
+ "@intlify/shared": "11.4.7"
+ },
+ "engines": {
+ "node": ">= 22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/message-compiler": {
+ "version": "11.4.7",
+ "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.4.7.tgz",
+ "integrity": "sha512-bHxmh7n94N4N1evADeb7XTkc3jTw6Ki5biMFZVSX6Jmk+iehy8/maeH2XUsBI27rtKIK+Hzc6QnVAKggUwylKw==",
+ "license": "MIT",
+ "dependencies": {
+ "@intlify/shared": "11.4.7",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/shared": {
+ "version": "11.4.7",
+ "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.4.7.tgz",
+ "integrity": "sha512-OtjPZan3No2OZZFnMUiCVsXC6+j+XRwEywaFDk0AoayAbLuPesyDloXhJZLl9JUl5vHZeQUkYSbEA8VX+CWMjg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"license": "MIT"
},
+ "node_modules/@lukeed/csprng": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
+ "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@mermaid-js/parser": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.3.tgz",
@@ -746,6 +947,267 @@
"langium": "3.3.1"
}
},
+ "node_modules/@mlightcad/cad-agent-plugin": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/cad-agent-plugin/-/cad-agent-plugin-1.5.8.tgz",
+ "integrity": "sha512-L/TyEnxWP+am/Sjj1pBZ/P0cYI3OVMTbN6/A5ah2jIT6FHIAVGCVK56aOZJOpr6nQSLs8MB8WP51TrMggars9A==",
+ "license": "MIT",
+ "dependencies": {
+ "@ai-sdk/anthropic": "^2.0.0",
+ "@ai-sdk/openai": "^2.0.0",
+ "@ai-sdk/vue": "^2.0.0",
+ "ai": "^5.0.0",
+ "zod": "^3.24.0"
+ },
+ "peerDependencies": {
+ "@mlightcad/cad-simple-viewer": "1.5.8",
+ "@mlightcad/data-model": "^1.11.1",
+ "vue": "^3.4.21"
+ }
+ },
+ "node_modules/@mlightcad/cad-html-plugin": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/cad-html-plugin/-/cad-html-plugin-1.5.8.tgz",
+ "integrity": "sha512-8acfiCRHr6biuOlL0anVxHfBCEB0WpQ3WORL0fLnp2Go9huDok36dsgTmpAXy9iXKBgNN6KCPYMMe4ayegfG7g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mlightcad/cad-simple-viewer": "1.5.8",
+ "@mlightcad/data-model": "^1.11.1",
+ "@mlightcad/three-renderer": "1.5.8",
+ "three": "^0.172.0"
+ }
+ },
+ "node_modules/@mlightcad/cad-pdf-plugin": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/cad-pdf-plugin/-/cad-pdf-plugin-1.5.8.tgz",
+ "integrity": "sha512-jB+FhRnCUItfi6iig+fc53aVqG3SoDBKYDfDu1YAQ6V4pN/qynU02ye5VXu5bGRYEIIyDSQ41hl83GtKBVy3vA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mlightcad/cad-simple-viewer": "1.5.8",
+ "@mlightcad/cad-svg-plugin": "1.5.8",
+ "@mlightcad/data-model": "^1.11.1"
+ }
+ },
+ "node_modules/@mlightcad/cad-simple-viewer": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/cad-simple-viewer/-/cad-simple-viewer-1.5.8.tgz",
+ "integrity": "sha512-6wiZA/mY5NRbFkcbSunoe8uqbiGm5zrpgPy6Z3rLi5PonsGGt/zst5jaCw4PW0DVexpRI8Y9yfDyUsP8RDQFQg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mlightcad/data-model": "^1.11.1",
+ "@mlightcad/dxf-json-converter": "^1.11.1",
+ "lodash-es": "4.17.21",
+ "three": "^0.172.0"
+ }
+ },
+ "node_modules/@mlightcad/cad-svg-plugin": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/cad-svg-plugin/-/cad-svg-plugin-1.5.8.tgz",
+ "integrity": "sha512-P4AemnklXzdX+eBbamGkKKJjaHxaNr0qAeU0M25oJalDhI4xEUYXueNq3MaeCImg4XvRCPFFFc86EfXDemWLkA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mlightcad/cad-simple-viewer": "1.5.8",
+ "@mlightcad/data-model": "^1.11.1",
+ "@mlightcad/mtext-parser": "^1.4.1",
+ "@mlightcad/mtext-renderer": "^0.11.10"
+ }
+ },
+ "node_modules/@mlightcad/cad-viewer": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/cad-viewer/-/cad-viewer-1.5.8.tgz",
+ "integrity": "sha512-R9nBIyNzJFQWX2ddPDRyAy+A1Pk3K9f1lyC6C5LF3t2JhFXPGU0kPZgB3AnuW/Ehh+aPUAZdJKILVxpZ6VlgNg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mlightcad/cad-agent-plugin": "1.5.8",
+ "@mlightcad/cad-html-plugin": "1.5.8",
+ "@mlightcad/cad-pdf-plugin": "1.5.8",
+ "@mlightcad/cad-simple-viewer": "1.5.8",
+ "@mlightcad/cad-svg-plugin": "1.5.8",
+ "@mlightcad/data-model": "^1.11.1",
+ "@vueuse/core": "^11.1.0",
+ "element-plus": "^2.12.0",
+ "lodash-es": "4.17.21",
+ "three": "^0.172.0",
+ "vue": "^3.4.21",
+ "vue-i18n": "^11.4.4"
+ },
+ "peerDependenciesMeta": {
+ "@mlightcad/cad-agent-plugin": {
+ "optional": true
+ },
+ "@mlightcad/cad-html-plugin": {
+ "optional": true
+ },
+ "@mlightcad/cad-pdf-plugin": {
+ "optional": true
+ },
+ "@mlightcad/cad-svg-plugin": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mlightcad/common": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@mlightcad/common/-/common-1.11.2.tgz",
+ "integrity": "sha512-6vsuiAvjo+wN1zOGUkWS2olz/z99f03i8daLZniY1BD+BoXuRFK18fS5zRho4NnBFfDlaqRQ9lI3Epf4YoMpBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loglevel": "^1.9.1"
+ }
+ },
+ "node_modules/@mlightcad/data-model": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@mlightcad/data-model/-/data-model-1.11.2.tgz",
+ "integrity": "sha512-0L60Nzq0D7ZKjGnahX5qwSQLaEGUvAfeqmxizKfU9S2JHFXp+RmV9dtJ3pCyVq+B4Q4k+Zk4mVJFjOFekhFo4A==",
+ "license": "MIT",
+ "dependencies": {
+ "@mlightcad/common": "1.11.2",
+ "@mlightcad/geometry-engine": "3.11.2",
+ "@mlightcad/graphic-interface": "3.11.2",
+ "iconv-lite": "^0.7.0",
+ "uid": "^2.0.2"
+ }
+ },
+ "node_modules/@mlightcad/data-model/node_modules/iconv-lite": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
+ "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@mlightcad/dxf-json": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/dxf-json/-/dxf-json-1.2.8.tgz",
+ "integrity": "sha512-pn4kY2+cYLq9xVVeUJUwzBPyYGGIuO6uKc+bKAzWfSaZAWTgrbK7WrY+VHR4od9wrWdDwNWknIqVq4KBZPD7SA==",
+ "license": "GPL-3.0",
+ "workspaces": [
+ "integration-test"
+ ],
+ "dependencies": {
+ "@fxts/core": "^1.0.1"
+ }
+ },
+ "node_modules/@mlightcad/dxf-json-converter": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@mlightcad/dxf-json-converter/-/dxf-json-converter-1.11.2.tgz",
+ "integrity": "sha512-BM6+Yu89eUwVX8obxWcZJj63N4JImZdRkLLs7qivrtOOX8mJ5zPJ2rlQDQ2ZlHgkxM60H0uicyF8HO46yV4isQ==",
+ "license": "GPL-3.0",
+ "dependencies": {
+ "@mlightcad/dxf-json": "^1.2.8"
+ },
+ "peerDependencies": {
+ "@mlightcad/data-model": "1.11.2"
+ }
+ },
+ "node_modules/@mlightcad/geometry-engine": {
+ "version": "3.11.2",
+ "resolved": "https://registry.npmjs.org/@mlightcad/geometry-engine/-/geometry-engine-3.11.2.tgz",
+ "integrity": "sha512-WK943vgWSCveaL2FreNhsvW64avT/GAKQqu7jBoZ/s4CrZSWIfbfRtkC0YT5L73kJwGu/W6n84E4zuGmD53QUA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mlightcad/common": "1.11.2"
+ }
+ },
+ "node_modules/@mlightcad/graphic-interface": {
+ "version": "3.11.2",
+ "resolved": "https://registry.npmjs.org/@mlightcad/graphic-interface/-/graphic-interface-3.11.2.tgz",
+ "integrity": "sha512-lEncB971vfE15K2ooHFO7qOEFVaIiPtqOEQR2vejAPKmdVTWGDY8LR27kTBdJGxMSuusbfG4jMT+Uf8faen+aQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mlightcad/common": "1.11.2",
+ "@mlightcad/geometry-engine": "3.11.2"
+ }
+ },
+ "node_modules/@mlightcad/mtext-parser": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@mlightcad/mtext-parser/-/mtext-parser-1.5.0.tgz",
+ "integrity": "sha512-Yl/IQmSIGV1UUl/TyUptoOpNBunywcEE7yh4k9SFDXljHDTTI92VmqkVFxf4eYzhoWF4MNXIl4qgQV1P1Rbn6g==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@mlightcad/mtext-renderer": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/@mlightcad/mtext-renderer/-/mtext-renderer-0.11.10.tgz",
+ "integrity": "sha512-TDKUFAi4iMTevQCLiyOQN1CW16jET4mQFbDQ/KiyUrqsKxkzqHl/EMlR9Ae6z5BchKs2FosnWxKljAK1fT6zQA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@mlightcad/mtext-parser": "^1.5.0",
+ "@mlightcad/shx-parser": "^1.4.5",
+ "iconv-lite": "^0.7.0",
+ "idb": "^8.0.3",
+ "opentype.js": "^2.0.0"
+ },
+ "peerDependencies": {
+ "three": "^0.172.0"
+ }
+ },
+ "node_modules/@mlightcad/mtext-renderer/node_modules/iconv-lite": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
+ "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@mlightcad/shx-parser": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/@mlightcad/shx-parser/-/shx-parser-1.4.5.tgz",
+ "integrity": "sha512-wFY0X7vnuq1IYdP6JRggb7LHcKho1P8zmcWGtXa6XYthwyKZCUoZCswTXr7J26pbzyhBB7KsiCcCL48iwIevdQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@mlightcad/three-renderer": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@mlightcad/three-renderer/-/three-renderer-1.5.8.tgz",
+ "integrity": "sha512-Q+uo5FM5cEfF7pLu3pcSz6IUMOxC97JQcBuGEf+paS9Z7unl9QS/EApJZ5SpDC68GX2zhrxjJYAbfVS74Ec8hw==",
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "@mlightcad/data-model": "^1.11.1",
+ "@mlightcad/mtext-renderer": "^0.11.10",
+ "@velipso/polybool": "^1.1.1",
+ "three": "^0.172.0"
+ }
+ },
+ "node_modules/@opentelemetry/api": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
+ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@popperjs/core": {
+ "name": "@sxzz/popperjs-es",
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.8.tgz",
+ "integrity": "sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@radix-ui/primitive": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
@@ -1917,6 +2379,19 @@
"resolved": "packages/frontend",
"link": true
},
+ "node_modules/@standard-schema/spec": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+ "license": "MIT"
+ },
+ "node_modules/@tweenjs/tween.js": {
+ "version": "23.1.3",
+ "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
+ "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/body-parser": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
@@ -2268,6 +2743,21 @@
"@types/node": "*"
}
},
+ "node_modules/@types/lodash": {
+ "version": "4.17.24",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz",
+ "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/lodash-es": {
+ "version": "4.17.12",
+ "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
+ "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/lodash": "*"
+ }
+ },
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@@ -2369,6 +2859,28 @@
"@types/node": "*"
}
},
+ "node_modules/@types/stats.js": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz",
+ "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/three": {
+ "version": "0.172.0",
+ "resolved": "https://registry.npmjs.org/@types/three/-/three-0.172.0.tgz",
+ "integrity": "sha512-LrUtP3FEG26Zg5WiF0nbg8VoXiKokBLTcqM2iLvM9vzcfEiYmmBAPGdBgV0OYx9fvWlY3R/3ERTZcD9X5sc0NA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tweenjs/tween.js": "~23.1.3",
+ "@types/stats.js": "*",
+ "@types/webxr": "*",
+ "@webgpu/types": "*",
+ "fflate": "~0.8.2",
+ "meshoptimizer": "~0.18.1"
+ }
+ },
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
@@ -2376,6 +2888,19 @@
"license": "MIT",
"optional": true
},
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.20",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
+ "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==",
+ "license": "MIT"
+ },
+ "node_modules/@types/webxr": {
+ "version": "0.5.24",
+ "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
+ "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@upsetjs/venn.js": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz",
@@ -2386,6 +2911,25 @@
"d3-transition": "^3.0.1"
}
},
+ "node_modules/@velipso/polybool": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@velipso/polybool/-/polybool-1.1.1.tgz",
+ "integrity": "sha512-HlWrm/wloLkUDHPQ1AgUdXysKL3y+rqV94udU5CVTtEPci5v6WjEfozNJTOOSwCsz50ySIxJK4gABqfbx1sD7A==",
+ "license": "0BSD",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@vercel/oidc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.1.0.tgz",
+ "integrity": "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 20"
+ }
+ },
"node_modules/@vitejs/plugin-vue": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
@@ -2430,53 +2974,53 @@
}
},
"node_modules/@vue/compiler-core": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz",
- "integrity": "sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
+ "integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
- "@vue/shared": "3.5.39",
+ "@vue/shared": "3.5.40",
"entities": "^7.0.1",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz",
- "integrity": "sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz",
+ "integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-core": "3.5.39",
- "@vue/shared": "3.5.39"
+ "@vue/compiler-core": "3.5.40",
+ "@vue/shared": "3.5.40"
}
},
"node_modules/@vue/compiler-sfc": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.39.tgz",
- "integrity": "sha512-d0ki86iOyN8LoZPBmk5SJWNwHP19CnDDCfuo//+2WJa2g5Ke0Jay983PIBIcSSzldC68I8DrD5GrHV3OSDfodg==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.40.tgz",
+ "integrity": "sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
- "@vue/compiler-core": "3.5.39",
- "@vue/compiler-dom": "3.5.39",
- "@vue/compiler-ssr": "3.5.39",
- "@vue/shared": "3.5.39",
+ "@vue/compiler-core": "3.5.40",
+ "@vue/compiler-dom": "3.5.40",
+ "@vue/compiler-ssr": "3.5.40",
+ "@vue/shared": "3.5.40",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
- "postcss": "^8.5.15",
+ "postcss": "^8.5.19",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-ssr": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.39.tgz",
- "integrity": "sha512-Ce7/wvwMHai74bdszfXExdazFigYnlF9zgCmEQUcM1j0fOymlouZ7XilTYNo8oUjhlnjYOZbGrcYKuqjz89Ucw==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.40.tgz",
+ "integrity": "sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-dom": "3.5.39",
- "@vue/shared": "3.5.39"
+ "@vue/compiler-dom": "3.5.40",
+ "@vue/shared": "3.5.40"
}
},
"node_modules/@vue/compiler-vue2": {
@@ -2522,55 +3066,148 @@
}
},
"node_modules/@vue/reactivity": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.39.tgz",
- "integrity": "sha512-TpsuBJ9gGlZa5d23XcM2y8EXanz9dZeVDQBXRwzy46ItgvM+rWpzs+UVM0wcRLxGvcav0HE5jz2gNL53xlRAog==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz",
+ "integrity": "sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==",
"license": "MIT",
"dependencies": {
- "@vue/shared": "3.5.39"
+ "@vue/shared": "3.5.40"
}
},
"node_modules/@vue/runtime-core": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.39.tgz",
- "integrity": "sha512-9GLtNyRvPAUMbX+7ono0RC2j0guo2LXVi8LvcmAooImACUKm0oFf0jjwbX8/H0AE/t1nxhAkn8RSl9PMCzzxZw==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.40.tgz",
+ "integrity": "sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==",
"license": "MIT",
"dependencies": {
- "@vue/reactivity": "3.5.39",
- "@vue/shared": "3.5.39"
+ "@vue/reactivity": "3.5.40",
+ "@vue/shared": "3.5.40"
}
},
"node_modules/@vue/runtime-dom": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.39.tgz",
- "integrity": "sha512-7Y6aAGboKcXAZ3ECuUy7RrS5yy2r47dhTp2SKaJmYxjopImaVFaNa5Ne66NwGovsrxVAl5S5rwc7m22UG7Lmww==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.40.tgz",
+ "integrity": "sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==",
"license": "MIT",
"dependencies": {
- "@vue/reactivity": "3.5.39",
- "@vue/runtime-core": "3.5.39",
- "@vue/shared": "3.5.39",
+ "@vue/reactivity": "3.5.40",
+ "@vue/runtime-core": "3.5.40",
+ "@vue/shared": "3.5.40",
"csstype": "^3.2.3"
}
},
"node_modules/@vue/server-renderer": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.39.tgz",
- "integrity": "sha512-yZSakiAGw85rZfG7UM8akMnIF+FmeiNk47uvHf2nVBBSe+dIKUhZuZq9+XgJhbV3nS5Z4ALH23/MpXofW+mbcw==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.40.tgz",
+ "integrity": "sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-ssr": "3.5.39",
- "@vue/shared": "3.5.39"
- },
- "peerDependencies": {
- "vue": "3.5.39"
+ "@vue/compiler-ssr": "3.5.40",
+ "@vue/runtime-dom": "3.5.40",
+ "@vue/shared": "3.5.40"
}
},
"node_modules/@vue/shared": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
- "integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
+ "integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
"license": "MIT"
},
+ "node_modules/@vueuse/core": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.3.0.tgz",
+ "integrity": "sha512-7OC4Rl1f9G8IT6rUfi9JrKiXy4bfmHhZ5x2Ceojy0jnd3mHNEvV4JaRygH362ror6/NZ+Nl+n13LPzGiPN8cKA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.20",
+ "@vueuse/metadata": "11.3.0",
+ "@vueuse/shared": "11.3.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/core/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.3.0.tgz",
+ "integrity": "sha512-pwDnDspTqtTo2HwfLw4Rp6yywuuBdYnPYDq+mO38ZYKGebCUQC/nVj/PXSiK9HX5otxLz8Fn7ECPbjiRz2CC3g==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.3.0.tgz",
+ "integrity": "sha512-P8gSSWQeucH5821ek2mn/ciCk+MS/zoRKqdQIM3bHq6p7GXDAJLmnRRKmF5F65sAVJIfzQlwR3aDzwCn10s8hA==",
+ "license": "MIT",
+ "dependencies": {
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@webgpu/types": {
+ "version": "0.1.71",
+ "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.71.tgz",
+ "integrity": "sha512-mMy8/ODcKhab808co15eW+yN+HgXoQxRQHTiBV9Mrvl1r0ufnid7YOcI+gi4eUWSWl9ezD6TW2KXccrL8HCh2A==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -2584,6 +3221,24 @@
"node": ">= 0.6"
}
},
+ "node_modules/ai": {
+ "version": "5.0.217",
+ "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.217.tgz",
+ "integrity": "sha512-JbRLySD6FAB+ncmHCuPDDrdaFlKOmCqU8ZnntxqmjnpYv0sbHFry2VT+0a+q9E1JFQKUaXd0NvoiA8g+e4R0ZQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ai-sdk/gateway": "2.0.116",
+ "@ai-sdk/provider": "2.0.3",
+ "@ai-sdk/provider-utils": "3.0.30",
+ "@opentelemetry/api": "1.9.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.76 || ^4.1.8"
+ }
+ },
"node_modules/alien-signals": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz",
@@ -2640,6 +3295,12 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT"
},
+ "node_modules/async-validator": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
+ "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
+ "license": "MIT"
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -3606,6 +4267,82 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
+ "node_modules/element-plus": {
+ "version": "2.14.3",
+ "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.14.3.tgz",
+ "integrity": "sha512-pJcvxcpZjYruNzuJhAeVwnbYjfNgzBKnWHwSVEhwzM2/kcLI3brzmtIBxtPqd4hQWJfD1PRnjoc1WipLw2eBGg==",
+ "license": "MIT",
+ "dependencies": {
+ "@ctrl/tinycolor": "^4.2.0",
+ "@element-plus/icons-vue": "^2.3.2",
+ "@floating-ui/dom": "^1.7.6",
+ "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.8",
+ "@types/lodash": "^4.17.24",
+ "@types/lodash-es": "^4.17.12",
+ "@vueuse/core": "14.3.0",
+ "async-validator": "^4.2.5",
+ "dayjs": "^1.11.20",
+ "lodash": "^4.18.1",
+ "lodash-es": "^4.18.1",
+ "lodash-unified": "^1.0.3",
+ "memoize-one": "^6.0.0",
+ "normalize-wheel-es": "^1.2.0",
+ "vue-component-type-helpers": "^3.3.5"
+ },
+ "peerDependencies": {
+ "vue": "^3.3.7"
+ }
+ },
+ "node_modules/element-plus/node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
+ "license": "MIT"
+ },
+ "node_modules/element-plus/node_modules/@vueuse/core": {
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-14.3.0.tgz",
+ "integrity": "sha512-aHfz47g0ZhMtTVHmIzMVpJy8ePhhOy68GY5bv110+5DVtZ+W7BsOx+m61UNQqfrWyPztIHIanWa3E2tib3NFIw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.21",
+ "@vueuse/metadata": "14.3.0",
+ "@vueuse/shared": "14.3.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vue": "^3.5.0"
+ }
+ },
+ "node_modules/element-plus/node_modules/@vueuse/metadata": {
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-14.3.0.tgz",
+ "integrity": "sha512-BwxmbAzwAVF50+MW57GXOUEV61nFBGnlBvrTqj49PqWJu3uw7hdu72ztXeZ33RdZtDY6kO+bfCAE1PCn88Tktw==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/element-plus/node_modules/@vueuse/shared": {
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-14.3.0.tgz",
+ "integrity": "sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vue": "^3.5.0"
+ }
+ },
+ "node_modules/element-plus/node_modules/lodash-es": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
+ "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
+ "license": "MIT"
+ },
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -3739,6 +4476,15 @@
"node": ">= 0.6"
}
},
+ "node_modules/eventsource-parser": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz",
+ "integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
"node_modules/express": {
"version": "4.22.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
@@ -3803,6 +4549,13 @@
}
}
},
+ "node_modules/fflate": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz",
+ "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -4039,6 +4792,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/idb": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz",
+ "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==",
+ "license": "ISC",
+ "peer": true
+ },
"node_modules/image-blob-reduce": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/image-blob-reduce/-/image-blob-reduce-3.0.1.tgz",
@@ -4179,6 +4939,12 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT"
},
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
+ },
"node_modules/jsonwebtoken": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
@@ -4286,12 +5052,29 @@
"integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==",
"license": "MIT"
},
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
+ "node_modules/lodash-unified": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
+ "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/lodash-es": "*",
+ "lodash": "*",
+ "lodash-es": "*"
+ }
+ },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -4346,6 +5129,19 @@
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
"license": "MIT"
},
+ "node_modules/loglevel": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz",
+ "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ },
+ "funding": {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/loglevel"
+ }
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -4397,6 +5193,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
+ "license": "MIT"
+ },
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -4474,6 +5276,13 @@
"points-on-path": "^0.2.1"
}
},
+ "node_modules/meshoptimizer": {
+ "version": "0.18.1",
+ "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz",
+ "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -4631,6 +5440,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/normalize-wheel-es": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+ "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -4652,6 +5467,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/occt-import-js": {
+ "version": "0.0.23",
+ "resolved": "https://registry.npmjs.org/occt-import-js/-/occt-import-js-0.0.23.tgz",
+ "integrity": "sha512-RFfYQXYFX5C1mB1Aywm0ShcUKzXOr/VzTnlzhBSDJOR6YCAPt1HYCzeXWg1vwwjn/cUxwqRNhhtf1dlewoZYCQ==",
+ "license": "LGPL-2.1"
+ },
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -4670,6 +5491,16 @@
"integrity": "sha512-vCseG/EQ6/RcvxhUcGJiHViOgrtz4x0XbZepXvKik66TMGkvbmjeJrKFyBEx6daG5rNyyd14zYXhz0hZVwQFOw==",
"license": "MIT"
},
+ "node_modules/opentype.js": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-2.0.0.tgz",
+ "integrity": "sha512-kCyjv6xdDY1W/jLWZ/L3QhhTlKUqDZMQ5+Jdlw12b3dXkKNpYBqqlMMj0YDQPShWFTMwgZI1hG14kN3XUDSg/A==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "ot": "bin/ot"
+ }
+ },
"node_modules/package-manager-detector": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.7.0.tgz",
@@ -5373,6 +6204,21 @@
"integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==",
"license": "MIT"
},
+ "node_modules/swrv": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/swrv/-/swrv-1.2.0.tgz",
+ "integrity": "sha512-lH/g4UcNyj+7lzK4eRGT4C68Q4EhQ6JtM9otPRIASfhhzfLWtbZPHcMuhuba7S9YVYuxkMUGImwMyGpfbkH07A==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "vue": ">=3.2.26 < 4"
+ }
+ },
+ "node_modules/three": {
+ "version": "0.172.0",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.172.0.tgz",
+ "integrity": "sha512-6HMgMlzU97MsV7D/tY8Va38b83kz8YJX+BefKjspMNAv0Vx6dxMogHOrnRl/sbMIs3BPUKijPqDqJ/+UwJbIow==",
+ "license": "MIT"
+ },
"node_modules/tinyexec": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz",
@@ -5496,6 +6342,18 @@
"node": ">=14.17"
}
},
+ "node_modules/uid": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz",
+ "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==",
+ "license": "MIT",
+ "dependencies": {
+ "@lukeed/csprng": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
@@ -6211,16 +7069,16 @@
"license": "MIT"
},
"node_modules/vue": {
- "version": "3.5.39",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.39.tgz",
- "integrity": "sha512-xmZCYabFGcirU8r0fTuvl/LICc1OU620rnqepaJDL/a141ZigkG7AyaxQLdqJ02ZRYzWe6YPaDHeQx7MfknQfA==",
+ "version": "3.5.40",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.40.tgz",
+ "integrity": "sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-dom": "3.5.39",
- "@vue/compiler-sfc": "3.5.39",
- "@vue/runtime-dom": "3.5.39",
- "@vue/server-renderer": "3.5.39",
- "@vue/shared": "3.5.39"
+ "@vue/compiler-dom": "3.5.40",
+ "@vue/compiler-sfc": "3.5.40",
+ "@vue/runtime-dom": "3.5.40",
+ "@vue/server-renderer": "3.5.40",
+ "@vue/shared": "3.5.40"
},
"peerDependencies": {
"typescript": "*"
@@ -6231,6 +7089,33 @@
}
}
},
+ "node_modules/vue-component-type-helpers": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-3.3.7.tgz",
+ "integrity": "sha512-Skkhw9agYSgsWqv7bxSOGJZa9SaiJbZVGdXuFWnrzKaQYHnw9qbjD630rw6RyMqDbp54nfLCLw5SZA55if7JLg==",
+ "license": "MIT"
+ },
+ "node_modules/vue-i18n": {
+ "version": "11.4.7",
+ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.4.7.tgz",
+ "integrity": "sha512-j6RyshdPPzqLiMAUpnpvZGFPM+rRoWi14Sl5yTsquvoW0/56DWyvhAj2o9TO2YXGvb6teg8T0xrYO9jR3urvdw==",
+ "license": "MIT",
+ "dependencies": {
+ "@intlify/core-base": "11.4.7",
+ "@intlify/devtools-types": "11.4.7",
+ "@intlify/shared": "11.4.7",
+ "@vue/devtools-api": "^6.5.0"
+ },
+ "engines": {
+ "node": ">= 22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
"node_modules/vue-router": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
@@ -6263,6 +7148,12 @@
"typescript": ">=5.0.0"
}
},
+ "node_modules/web-ifc": {
+ "version": "0.0.77",
+ "resolved": "https://registry.npmjs.org/web-ifc/-/web-ifc-0.0.77.tgz",
+ "integrity": "sha512-VzQ0W/Iiqbidxn1ECUvz6qJ6p2sXBVNcOsUOBCETzy77psAH6yFLKQm74aXabkx3JH4OvFVHe8k1qS6+Z2zl1w==",
+ "license": "MPL-2.0"
+ },
"node_modules/webworkify": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/webworkify/-/webworkify-1.5.0.tgz",
@@ -6293,6 +7184,15 @@
"node": ">=0.4"
}
},
+ "node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
"node_modules/zustand": {
"version": "4.5.7",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
@@ -6324,6 +7224,7 @@
"packages/backend": {
"name": "@sejong-office/backend",
"version": "0.1.0",
+ "license": "GPL-3.0-only",
"dependencies": {
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
@@ -6347,18 +7248,36 @@
"packages/frontend": {
"name": "@sejong-office/frontend",
"version": "0.1.0",
+ "license": "GPL-3.0-only",
"dependencies": {
+ "@element-plus/icons-vue": "^2.3.2",
"@excalidraw/excalidraw": "^0.18.1",
+ "@mlightcad/cad-agent-plugin": "^1.5.8",
+ "@mlightcad/cad-html-plugin": "^1.5.8",
+ "@mlightcad/cad-pdf-plugin": "^1.5.8",
+ "@mlightcad/cad-simple-viewer": "^1.5.8",
+ "@mlightcad/cad-svg-plugin": "^1.5.8",
+ "@mlightcad/cad-viewer": "^1.5.8",
+ "@mlightcad/data-model": "^1.11.2",
+ "@mlightcad/dxf-json-converter": "^1.11.2",
"@rhwp/editor": "^0.7.18",
+ "@vueuse/core": "^11.3.0",
+ "element-plus": "^2.14.3",
+ "lodash-es": "^4.17.21",
"mermaid": "^11.16.0",
+ "occt-import-js": "^0.0.23",
"react": "^18.3.1",
"react-dom": "^18.3.1",
+ "three": "^0.172.0",
"vue": "^3.5.13",
- "vue-router": "^4.5.0"
+ "vue-i18n": "^11.4.7",
+ "vue-router": "^4.5.0",
+ "web-ifc": "^0.0.77"
},
"devDependencies": {
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
+ "@types/three": "^0.172.0",
"@vitejs/plugin-vue": "^5.2.1",
"typescript": "^5.8.2",
"vite": "^6.2.2",
diff --git a/package.json b/package.json
index 0c1b751..5db3af0 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"description": "Ephemeral OnlyOffice + rhwp document editor",
- "license": "MIT",
+ "license": "GPL-3.0-only",
"workspaces": [
"packages/*"
],
diff --git a/packages/backend/package.json b/packages/backend/package.json
index d888931..c72692e 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -2,6 +2,7 @@
"name": "@sejong-office/backend",
"version": "0.1.0",
"private": true,
+ "license": "GPL-3.0-only",
"type": "module",
"scripts": {
"dev": "tsx watch src/index.ts",
diff --git a/packages/frontend/index.html b/packages/frontend/index.html
index 67dc159..c0674bb 100644
--- a/packages/frontend/index.html
+++ b/packages/frontend/index.html
@@ -2,6 +2,7 @@
+
Sejong Office
{
+ const output = path.join(publicDir, destination);
+ await mkdir(path.dirname(output), { recursive: true });
+ await cp(path.join(nodeModules, source), output);
+ }),
+);
+
+const resources = path.join(publicDir, 'viewer-assets', 'cad-resources');
+await mkdir(path.join(resources, 'fonts'), { recursive: true });
+await mkdir(path.join(resources, 'templates'), { recursive: true });
+await writeFile(path.join(resources, 'fonts.json'), '[]\n');
+await writeFile(
+ path.join(resources, 'README.txt'),
+ [
+ 'Optional CAD fonts and templates can be placed here.',
+ 'Only files with redistribution rights should be added.',
+ 'The read-only viewer does not require a drawing template.',
+ '',
+ ].join('\n'),
+);
diff --git a/packages/frontend/src/App.vue b/packages/frontend/src/App.vue
index 5c7b5e4..fd5431d 100644
--- a/packages/frontend/src/App.vue
+++ b/packages/frontend/src/App.vue
@@ -18,7 +18,9 @@ const viewKey = computed(() => {
if (
route.name === 'excalidraw-editor' ||
route.name === 'mermaid-editor' ||
- route.name === 'drawio-editor'
+ route.name === 'drawio-editor' ||
+ route.name === 'cad-viewer' ||
+ route.name === 'model3d-viewer'
) {
return String(route.name);
}
@@ -35,8 +37,10 @@ const viewKey = computed(() => {
'ExcalidrawEditorView',
'MermaidEditorView',
'DrawioEditorView',
+ 'CadViewerView',
+ 'Model3DViewerView',
]"
- :max="8"
+ :max="10"
>
diff --git a/packages/frontend/src/components/EditorToolbar.vue b/packages/frontend/src/components/EditorToolbar.vue
index f880211..267d9e7 100644
--- a/packages/frontend/src/components/EditorToolbar.vue
+++ b/packages/frontend/src/components/EditorToolbar.vue
@@ -3,12 +3,14 @@ withDefaults(
defineProps<{
filename: string;
saveLabel?: string;
+ showSave?: boolean;
showExportActions?: boolean;
showFilename?: boolean;
busy?: boolean;
}>(),
{
saveLabel: '저장',
+ showSave: true,
showExportActions: false,
showFilename: true,
busy: false,
@@ -36,6 +38,7 @@ defineEmits<{
열기
+
+
+
+
+ CAD·3D 모델
+
+ 서버 업로드 없이 도면과 모델을 조회합니다. glTF·OBJ의 보조 파일은
+ 원본과 함께 선택하세요.
+
+
+
+
diff --git a/packages/frontend/src/views/LicensesView.vue b/packages/frontend/src/views/LicensesView.vue
index aea5a34..c6cca09 100644
--- a/packages/frontend/src/views/LicensesView.vue
+++ b/packages/frontend/src/views/LicensesView.vue
@@ -20,6 +20,17 @@ const thirdParty = [
license: 'MIT',
url: 'https://github.com/mermaid-js/mermaid',
},
+ { name: 'Three.js', license: 'MIT', url: 'https://github.com/mrdoob/three.js' },
+ {
+ name: 'occt-import-js',
+ license: 'LGPL-2.1',
+ url: 'https://github.com/kovacsv/occt-import-js',
+ },
+ {
+ name: 'web-ifc',
+ license: 'MPL-2.0',
+ url: 'https://github.com/ThatOpen/engine_web-ifc',
+ },
{ name: 'Express', license: 'MIT', url: 'https://github.com/expressjs/express' },
{ name: 'jsonwebtoken', license: 'MIT', url: 'https://github.com/auth0/node-jsonwebtoken' },
{ name: 'multer', license: 'MIT', url: 'https://github.com/expressjs/multer' },
@@ -41,7 +52,7 @@ const thirdParty = [
+
+ MLightCAD · LibreDWG
+
+ CAD 화면과 렌더러는
+ MLightCAD CAD Viewer
+ (MIT)를 사용합니다.
+
+
+ DXF 변환기
+ @mlightcad/dxf-json-converter와 DWG Worker에 포함된
+ GNU LibreDWG는 GPL-3.0입니다. 이에 따라 본 앱도
+ GPL-3.0-only로 배포됩니다.
+
+
+ CAD 폰트는 재배포 권리가 명확한 파일만 자체 호스팅해야 합니다. 본 배포본은
+ 상용 AutoCAD 폰트를 포함하지 않으며, 누락된 글꼴은 대체 글꼴로 표시될 수
+ 있습니다.
+
+
+
+
+ 3D 모델 파서
+
+ glTF·OBJ 렌더링은 Three.js(MIT), STEP 변환은
+ occt-import-js(LGPL-2.1)와 OpenCascade, IFC 변환은
+ web-ifc(MPL-2.0)를 사용합니다. 각 WASM 파일은 앱과 함께 자체
+ 호스팅됩니다.
+
+
+ CAD·3D 원본 파일과 보조 파일은 브라우저 메모리에서만 처리하며 앱 서버로
+ 업로드하거나 영구 저장하지 않습니다.
+
+
+
Euro-Office Document Server
diff --git a/packages/frontend/src/views/Model3DViewerView.vue b/packages/frontend/src/views/Model3DViewerView.vue
new file mode 100644
index 0000000..e35f900
--- /dev/null
+++ b/packages/frontend/src/views/Model3DViewerView.vue
@@ -0,0 +1,381 @@
+
+
+
+
+
+
+
+
+
+ {{ error }}
+
+
{{ notice }}
+
+
+
+
+
+ 3D 모델을 선택해 주세요.
+
+ glTF의 BIN·텍스처나 OBJ의 MTL·텍스처도 함께 선택할 수 있습니다.
+
+ 파일 열기
+
+
+ 뷰 초기화
+
+
+
{{ progressLabel }}
+
+
{{ progressPercent }}%
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/workers/modelParser.worker.ts b/packages/frontend/src/workers/modelParser.worker.ts
new file mode 100644
index 0000000..d02b2cb
--- /dev/null
+++ b/packages/frontend/src/workers/modelParser.worker.ts
@@ -0,0 +1,178 @@
+///
+
+import createOcct from 'occt-import-js';
+import { IfcAPI } from 'web-ifc';
+import type {
+ WorkerMesh,
+ WorkerModelResult,
+} from '@/integrations/model3d/types';
+
+interface ParseRequest {
+ id: number;
+ format: 'step' | 'ifc';
+ buffer: ArrayBuffer;
+}
+
+interface ProgressMessage {
+ id: number;
+ type: 'progress';
+ value: number;
+ label: string;
+}
+
+interface ResultMessage {
+ id: number;
+ type: 'result';
+ result: WorkerModelResult;
+}
+
+interface ErrorMessage {
+ id: number;
+ type: 'error';
+ message: string;
+}
+
+function progress(
+ id: number,
+ value: number,
+ label: string,
+): ProgressMessage {
+ return { id, type: 'progress', value, label };
+}
+
+async function parseStep(id: number, buffer: ArrayBuffer) {
+ self.postMessage(progress(id, 0.15, 'OpenCascade WASM 초기화 중'));
+ const occt = await createOcct({
+ locateFile: () => '/viewer-assets/wasm/occt-import-js.wasm',
+ });
+ self.postMessage(progress(id, 0.35, 'STEP 형상 분석 중'));
+ const imported = occt.ReadStepFile(new Uint8Array(buffer), {
+ linearUnit: 'meter',
+ });
+ if (!imported.success) {
+ throw new Error('STEP 형상을 해석하지 못했습니다.');
+ }
+
+ const meshes: WorkerMesh[] = imported.meshes.map((mesh, index) => ({
+ name: mesh.name || `STEP Mesh ${index + 1}`,
+ positions: new Float32Array(mesh.attributes.position.array),
+ normals: mesh.attributes.normal
+ ? new Float32Array(mesh.attributes.normal.array)
+ : undefined,
+ indices: new Uint32Array(mesh.index.array),
+ color: mesh.color ? [...mesh.color, 1] : undefined,
+ }));
+ self.postMessage(progress(id, 0.9, 'STEP 메시 전송 중'));
+ return meshes;
+}
+
+async function parseIfc(id: number, buffer: ArrayBuffer) {
+ self.postMessage(progress(id, 0.1, 'web-ifc WASM 초기화 중'));
+ const api = new IfcAPI();
+ api.SetWasmPath('/viewer-assets/wasm/', true);
+ await api.Init();
+
+ self.postMessage(progress(id, 0.25, 'IFC 모델 분석 중'));
+ const modelId = api.OpenModel(new Uint8Array(buffer), {
+ COORDINATE_TO_ORIGIN: true,
+ CIRCLE_SEGMENTS: 16,
+ MEMORY_LIMIT: 1024 * 1024 * 1024,
+ });
+ if (modelId < 0) {
+ throw new Error('IFC 모델을 열지 못했습니다.');
+ }
+
+ const meshes: WorkerMesh[] = [];
+ try {
+ api.StreamAllMeshes(modelId, (flatMesh, index, total) => {
+ const placed = flatMesh.geometries;
+ for (let i = 0; i < placed.size(); i += 1) {
+ const placement = placed.get(i);
+ const geometry = api.GetGeometry(
+ modelId,
+ placement.geometryExpressID,
+ );
+ const source = api.GetVertexArray(
+ geometry.GetVertexData(),
+ geometry.GetVertexDataSize(),
+ );
+ const positions = new Float32Array((source.length / 6) * 3);
+ const normals = new Float32Array((source.length / 6) * 3);
+ for (let sourceIndex = 0, targetIndex = 0; sourceIndex < source.length; sourceIndex += 6) {
+ positions[targetIndex] = source[sourceIndex];
+ normals[targetIndex] = source[sourceIndex + 3];
+ positions[targetIndex + 1] = source[sourceIndex + 1];
+ normals[targetIndex + 1] = source[sourceIndex + 4];
+ positions[targetIndex + 2] = source[sourceIndex + 2];
+ normals[targetIndex + 2] = source[sourceIndex + 5];
+ targetIndex += 3;
+ }
+ const indices = new Uint32Array(
+ api.GetIndexArray(
+ geometry.GetIndexData(),
+ geometry.GetIndexDataSize(),
+ ),
+ );
+ geometry.delete();
+ meshes.push({
+ name: `IFC #${flatMesh.expressID}`,
+ positions,
+ normals,
+ indices,
+ color: [
+ placement.color.x,
+ placement.color.y,
+ placement.color.z,
+ placement.color.w,
+ ],
+ matrix: Array.from(placement.flatTransformation),
+ });
+ }
+ if (index % 20 === 0 || index + 1 === total) {
+ self.postMessage(
+ progress(
+ id,
+ 0.25 + (0.65 * (index + 1)) / Math.max(1, total),
+ `IFC 형상 ${index + 1}/${total}`,
+ ),
+ );
+ }
+ });
+ } finally {
+ api.CloseModel(modelId);
+ }
+ return meshes;
+}
+
+self.onmessage = async (event: MessageEvent) => {
+ const { id, format, buffer } = event.data;
+ try {
+ const meshes =
+ format === 'step'
+ ? await parseStep(id, buffer)
+ : await parseIfc(id, buffer);
+ const result: ResultMessage = {
+ id,
+ type: 'result',
+ result: { meshes },
+ };
+ const transfer = meshes.flatMap((mesh) => [
+ mesh.positions.buffer,
+ ...(mesh.normals ? [mesh.normals.buffer] : []),
+ mesh.indices.buffer,
+ ]);
+ self.postMessage(result, { transfer });
+ } catch (reason) {
+ const response: ErrorMessage = {
+ id,
+ type: 'error',
+ message:
+ reason instanceof Error
+ ? reason.message
+ : '모델 파싱 중 알 수 없는 오류가 발생했습니다.',
+ };
+ self.postMessage(response);
+ }
+};
+
+export {};