mirror of
https://github.com/brunopostle/ifcurl.git
synced 2026-07-12 10:18:14 +00:00
forgejo: add @thatopen/components-front, fix click-to-identify and model overview
Bundle OBCF (components-front) alongside OBC so Highlighter is sourced from the correct package. Update click handler to use item.getGuid() — GlobalId is no longer in the attributes map in fragments 3.4.x. Fix populateMetaPanel crash (ClassificationGroupData now wraps ids in a .map property, not a plain object). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
889645c2b2
commit
950349941c
7 changed files with 1719 additions and 312 deletions
|
|
@ -45,6 +45,7 @@
|
||||||
{"id":"ifcurl-ei8","title":"Fix syncCameraUrl: convert WebGL coords to IFC world space","description":"syncCameraUrl in viewer.py currently records camera.position/direction/up directly from Three.js, which are in WebGL/Three.js coordinate space (Y-up, different scale/orientation than IFC). The ifc:// URL spec expects IFC world coordinates (Z-up, matching BCF viewpoint conventions). Need to find the IFC→Three.js transform that @thatopen/components applies when loading a model, then apply its inverse in syncCameraUrl before serialising the camera params. Repos cloned for reference: ~/src/engine_components and ~/src/engine_fragment.","status":"closed","priority":2,"issue_type":"bug","owner":"bruno@postle.net","created_at":"2026-04-23T05:53:06Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:36Z","closed_at":"2026-04-23T06:14:36Z","close_reason":"Split into atomic tasks: ifcurl-ldk, ifcurl-j2s, ifcurl-cmd","dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"id":"ifcurl-ei8","title":"Fix syncCameraUrl: convert WebGL coords to IFC world space","description":"syncCameraUrl in viewer.py currently records camera.position/direction/up directly from Three.js, which are in WebGL/Three.js coordinate space (Y-up, different scale/orientation than IFC). The ifc:// URL spec expects IFC world coordinates (Z-up, matching BCF viewpoint conventions). Need to find the IFC→Three.js transform that @thatopen/components applies when loading a model, then apply its inverse in syncCameraUrl before serialising the camera params. Repos cloned for reference: ~/src/engine_components and ~/src/engine_fragment.","status":"closed","priority":2,"issue_type":"bug","owner":"bruno@postle.net","created_at":"2026-04-23T05:53:06Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:36Z","closed_at":"2026-04-23T06:14:36Z","close_reason":"Split into atomic tasks: ifcurl-ldk, ifcurl-j2s, ifcurl-cmd","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"id":"ifcurl-i1s","title":"Test Phase 3b web viewer end-to-end","description":"After deploying the footer template (ifcurl-ach), test the full flow: open an .ifc file in Forgejo at localhost:3000, click 'View in 3D', verify the viewer loads the model. CDN versions (@thatopen/components 2.4.0, three 0.160.0, web-ifc 0.0.66) may need adjustment if the API has changed.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:01Z","created_by":"Bruno Postle","updated_at":"2026-04-23T20:05:04Z","started_at":"2026-04-23T19:54:56Z","closed_at":"2026-04-23T20:05:04Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-49o","type":"blocks","created_at":"2026-04-23T07:14:12Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-4yu","type":"blocks","created_at":"2026-04-23T07:14:11Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ach","type":"blocks","created_at":"2026-04-23T06:48:10Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:54Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":4,"dependent_count":1,"comment_count":0}
|
{"id":"ifcurl-i1s","title":"Test Phase 3b web viewer end-to-end","description":"After deploying the footer template (ifcurl-ach), test the full flow: open an .ifc file in Forgejo at localhost:3000, click 'View in 3D', verify the viewer loads the model. CDN versions (@thatopen/components 2.4.0, three 0.160.0, web-ifc 0.0.66) may need adjustment if the API has changed.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:01Z","created_by":"Bruno Postle","updated_at":"2026-04-23T20:05:04Z","started_at":"2026-04-23T19:54:56Z","closed_at":"2026-04-23T20:05:04Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-49o","type":"blocks","created_at":"2026-04-23T07:14:12Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-4yu","type":"blocks","created_at":"2026-04-23T07:14:11Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ach","type":"blocks","created_at":"2026-04-23T06:48:10Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:54Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":4,"dependent_count":1,"comment_count":0}
|
||||||
{"id":"ifcurl-ach","title":"Deploy Phase 3b footer template to Forgejo","description":"The footer.tmpl file that injects a 'View in 3D' button on .ifc file pages has been written but not yet deployed. Deploy it to /etc/forgejo/templates/custom/footer.tmpl and verify the button appears when viewing an .ifc file on localhost:3000.","status":"closed","priority":2,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-23T05:47:53Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:35Z","closed_at":"2026-04-23T06:14:35Z","close_reason":"Split into atomic tasks: ifcurl-ohq, ifcurl-49o","dependencies":[{"issue_id":"ifcurl-ach","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:40Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
|
{"id":"ifcurl-ach","title":"Deploy Phase 3b footer template to Forgejo","description":"The footer.tmpl file that injects a 'View in 3D' button on .ifc file pages has been written but not yet deployed. Deploy it to /etc/forgejo/templates/custom/footer.tmpl and verify the button appears when viewing an .ifc file on localhost:3000.","status":"closed","priority":2,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-23T05:47:53Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:35Z","closed_at":"2026-04-23T06:14:35Z","close_reason":"Split into atomic tasks: ifcurl-ohq, ifcurl-49o","dependencies":[{"issue_id":"ifcurl-ach","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:40Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
|
||||||
|
{"id":"ifcurl-3td","title":"Add status hint when clip mode is active","description":"When the user enters clip mode the cursor changes to a crosshair but there is no other feedback explaining that a double-click is needed to place a plane. Add a short hint (e.g. in the status bar or as a tooltip) saying 'Double-click to place clip plane' while clip mode is active, and clear it when clip mode is deactivated.","status":"open","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-27T19:45:47Z","created_by":"Bruno Postle","updated_at":"2026-04-27T19:45:47Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"id":"ifcurl-5u6","title":"Evaluate replacing ifc_url.go markdown extension with JS injection","description":"ifc_url.go is a Goldmark AST extension that replaces ifc:// URLs in rendered markdown with preview figure elements (img + link). This requires patching and recompiling Forgejo. A JS alternative in footer.tmpl could handle the [title](ifc://...) markdown link case by scanning document.querySelectorAll('a[href^=\"ifc://\"]') and replacing matched anchors with figure elements at runtime — no Go changes needed. The limitation: bare ifc://... text in markdown won't be auto-linked by Goldmark (unknown scheme renders as plain text), so bare URLs would need text-node scanning in JS, which is fiddly and causes a render flash. Decision: replace with JS if users can commit to always using [title](ifc://...) link syntax; keep Go extension if bare URLs in markdown are a real use case.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T06:05:32Z","created_by":"Bruno Postle","updated_at":"2026-04-27T06:40:02Z","started_at":"2026-04-27T06:39:11Z","closed_at":"2026-04-27T06:40:02Z","close_reason":"Keep Go extension. Issue button (viewer.js:261) emits bare ifc:// URLs into markdown, making bare-URL rendering essential. JS text-node scanning works but causes a render flash. A clean alternative would be registering ifc:// as a Goldmark autolink scheme so bare URLs become \u003ca\u003e elements JS can pick up — worth revisiting if upgrade burden grows, but not worth doing now.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"id":"ifcurl-5u6","title":"Evaluate replacing ifc_url.go markdown extension with JS injection","description":"ifc_url.go is a Goldmark AST extension that replaces ifc:// URLs in rendered markdown with preview figure elements (img + link). This requires patching and recompiling Forgejo. A JS alternative in footer.tmpl could handle the [title](ifc://...) markdown link case by scanning document.querySelectorAll('a[href^=\"ifc://\"]') and replacing matched anchors with figure elements at runtime — no Go changes needed. The limitation: bare ifc://... text in markdown won't be auto-linked by Goldmark (unknown scheme renders as plain text), so bare URLs would need text-node scanning in JS, which is fiddly and causes a render flash. Decision: replace with JS if users can commit to always using [title](ifc://...) link syntax; keep Go extension if bare URLs in markdown are a real use case.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T06:05:32Z","created_by":"Bruno Postle","updated_at":"2026-04-27T06:40:02Z","started_at":"2026-04-27T06:39:11Z","closed_at":"2026-04-27T06:40:02Z","close_reason":"Keep Go extension. Issue button (viewer.js:261) emits bare ifc:// URLs into markdown, making bare-URL rendering essential. JS text-node scanning works but causes a render flash. A clean alternative would be registering ifc:// as a Goldmark autolink scheme so bare URLs become \u003ca\u003e elements JS can pick up — worth revisiting if upgrade burden grows, but not worth doing now.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"id":"ifcurl-71f","title":"Extract footer.tmpl JS into a separate ifcurl.js asset file","description":"footer.tmpl is 200 lines of JavaScript wrapped in a single \u003cscript\u003e tag. Moving it to /var/lib/forgejo/custom/public/assets/ifcurl.js (served at /assets/ifcurl.js) would reduce footer.tmpl to a one-liner \u003cscript src='/assets/ifcurl.js'\u003e\u003c/script\u003e. Benefits: proper editor syntax highlighting and linting, no HTML-escaping concerns, cleaner separation of concerns. Two files to deploy instead of one, but that's manageable.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T06:05:05Z","created_by":"Bruno Postle","updated_at":"2026-04-27T06:36:55Z","started_at":"2026-04-27T06:33:57Z","closed_at":"2026-04-27T06:36:55Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"id":"ifcurl-71f","title":"Extract footer.tmpl JS into a separate ifcurl.js asset file","description":"footer.tmpl is 200 lines of JavaScript wrapped in a single \u003cscript\u003e tag. Moving it to /var/lib/forgejo/custom/public/assets/ifcurl.js (served at /assets/ifcurl.js) would reduce footer.tmpl to a one-liner \u003cscript src='/assets/ifcurl.js'\u003e\u003c/script\u003e. Benefits: proper editor syntax highlighting and linting, no HTML-escaping concerns, cleaner separation of concerns. Two files to deploy instead of one, but that's manageable.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T06:05:05Z","created_by":"Bruno Postle","updated_at":"2026-04-27T06:36:55Z","started_at":"2026-04-27T06:33:57Z","closed_at":"2026-04-27T06:36:55Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"id":"ifcurl-5a6","title":"viewer: wrap ifc:// text in anchor tags for future browser URL handler","description":"At some point we will register a browser protocol handler for ifc:// URLs so they can open desktop tools (Bonsai etc). In preparation, all ifc:// URLs generated alongside embedded snapshots should be wrapped in \u003ca href=\"ifc://...\"\u003e anchor tags. Currently they will not do anything (no handler registered), but having them as links now means the UI is ready when the handler exists, and users can at least see and copy the URL.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T05:36:42Z","created_by":"Bruno Postle","updated_at":"2026-04-27T05:59:25Z","started_at":"2026-04-27T05:39:30Z","closed_at":"2026-04-27T05:59:25Z","close_reason":"Closed","dependency_count":0,"dependent_count":1,"comment_count":0}
|
{"id":"ifcurl-5a6","title":"viewer: wrap ifc:// text in anchor tags for future browser URL handler","description":"At some point we will register a browser protocol handler for ifc:// URLs so they can open desktop tools (Bonsai etc). In preparation, all ifc:// URLs generated alongside embedded snapshots should be wrapped in \u003ca href=\"ifc://...\"\u003e anchor tags. Currently they will not do anything (no handler registered), but having them as links now means the UI is ready when the handler exists, and users can at least see and copy the URL.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T05:36:42Z","created_by":"Bruno Postle","updated_at":"2026-04-27T05:59:25Z","started_at":"2026-04-27T05:39:30Z","closed_at":"2026-04-27T05:59:25Z","close_reason":"Closed","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ Output files (committed to the repository):
|
||||||
|
|
||||||
| File | Source | Purpose |
|
| File | Source | Purpose |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `custom/public/assets/viewer-deps.js` | three + @thatopen/components + jszip | Main viewer dependencies |
|
| `custom/public/assets/viewer-deps.js` | three + @thatopen/components + @thatopen/components-front + jszip | Main viewer dependencies |
|
||||||
| `custom/public/assets/fragments-worker.js` | @thatopen/fragments worker | IFC parsing web worker |
|
| `custom/public/assets/fragments-worker.js` | @thatopen/fragments worker | IFC parsing web worker |
|
||||||
| `custom/public/assets/web-ifc.wasm` | web-ifc | IFC geometry kernel (single-threaded) |
|
| `custom/public/assets/web-ifc.wasm` | web-ifc | IFC geometry kernel (single-threaded) |
|
||||||
| `custom/public/assets/web-ifc-mt.wasm` | web-ifc | IFC geometry kernel (multi-threaded) |
|
| `custom/public/assets/web-ifc-mt.wasm` | web-ifc | IFC geometry kernel (multi-threaded) |
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2026 The Forgejo Authors. All rights reserved.
|
// Copyright 2026 The Forgejo Authors. All rights reserved.
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
import { THREE, OBC, JSZip } from "/assets/viewer-deps.js";
|
import { THREE, OBC, OBCF, JSZip } from "/assets/viewer-deps.js";
|
||||||
import { parseIfcUrl, toRawUrl, buildIfcUrl as _buildIfcUrl } from "./viewer-url.js";
|
import { parseIfcUrl, toRawUrl, buildIfcUrl as _buildIfcUrl } from "./viewer-url.js";
|
||||||
import { isSimpleTypeSelector, subtractIdMap, isCommitHash } from "./viewer-util.js";
|
import { isSimpleTypeSelector, subtractIdMap, isCommitHash } from "./viewer-util.js";
|
||||||
|
|
||||||
|
|
@ -836,15 +836,10 @@ async function importBcf(file) {
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Element properties panel
|
// Element properties panel
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
function showPropsPanel(props, webIfc) {
|
function showPropsPanel(typeName, name, guid) {
|
||||||
let typeName = String(props.type ?? "");
|
propsType.textContent = typeName ?? "";
|
||||||
try {
|
propsName.textContent = name ?? "";
|
||||||
const name = webIfc?.GetNameFromTypeCode(props.type);
|
propsGuid.textContent = guid ?? "";
|
||||||
if (name) typeName = name;
|
|
||||||
} catch { /* not available in this version */ }
|
|
||||||
propsType.textContent = typeName;
|
|
||||||
propsName.textContent = props.Name?.value ?? props.LongName?.value ?? "";
|
|
||||||
propsGuid.textContent = props.GlobalId?.value ?? "";
|
|
||||||
propsPanel.style.display = "";
|
propsPanel.style.display = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -862,7 +857,7 @@ async function populateMetaPanel(components) {
|
||||||
if (categories) {
|
if (categories) {
|
||||||
for (const [name, groupData] of categories) {
|
for (const [name, groupData] of categories) {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (const ids of Object.values(groupData)) count += [...ids].length;
|
for (const ids of Object.values(groupData.map)) { if (ids) count += ids.length; }
|
||||||
if (count > 0) types.push({ name, count });
|
if (count > 0) types.push({ name, count });
|
||||||
}
|
}
|
||||||
types.sort((a, b) => b.count - a.count);
|
types.sort((a, b) => b.count - a.count);
|
||||||
|
|
@ -1097,14 +1092,25 @@ async function main() {
|
||||||
// Set up Highlighter before selector so visibility=highlight can use it.
|
// Set up Highlighter before selector so visibility=highlight can use it.
|
||||||
let highlighter = null;
|
let highlighter = null;
|
||||||
try {
|
try {
|
||||||
highlighter = components.get(OBC.Highlighter);
|
highlighter = components.get(OBCF.Highlighter);
|
||||||
highlighter.setup({ world });
|
highlighter.setup({ world });
|
||||||
highlighter.events.select.onHighlight.add(async (fragmentIdMap) => {
|
highlighter.events.select.onHighlight.add(async (fragmentIdMap) => {
|
||||||
for (const expressIds of Object.values(fragmentIdMap)) {
|
for (const localIds of Object.values(fragmentIdMap)) {
|
||||||
const expressId = [...expressIds][0];
|
if (!localIds) continue;
|
||||||
if (expressId == null) continue;
|
const localId = [...localIds][0];
|
||||||
const props = await model.getLocalProperties(expressId);
|
if (localId == null) continue;
|
||||||
if (props) showPropsPanel(props, ifcLoader.webIfc);
|
const item = model.getItem(localId);
|
||||||
|
if (!item) continue;
|
||||||
|
const [attrs, [category], guid] = await Promise.all([
|
||||||
|
item.getAttributes(),
|
||||||
|
model.threads.invoke(model.modelId, "getItemsCategories", [[localId]]),
|
||||||
|
item.getGuid(),
|
||||||
|
]);
|
||||||
|
if (attrs) showPropsPanel(
|
||||||
|
category ?? "",
|
||||||
|
attrs.get("Name")?.value ?? attrs.get("LongName")?.value ?? "",
|
||||||
|
guid ?? "",
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
16
forgejo/package-lock.json
generated
16
forgejo/package-lock.json
generated
|
|
@ -7,6 +7,7 @@
|
||||||
"name": "ifcurl-viewer",
|
"name": "ifcurl-viewer",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@thatopen/components": "3.4.2",
|
"@thatopen/components": "3.4.2",
|
||||||
|
"@thatopen/components-front": "^3.4.2",
|
||||||
"@thatopen/fragments": "3.4.3",
|
"@thatopen/fragments": "3.4.3",
|
||||||
"camera-controls": "3.1.2",
|
"camera-controls": "3.1.2",
|
||||||
"jszip": "3.10.1",
|
"jszip": "3.10.1",
|
||||||
|
|
@ -476,6 +477,21 @@
|
||||||
"web-ifc": ">=0.0.77"
|
"web-ifc": ">=0.0.77"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@thatopen/components-front": {
|
||||||
|
"version": "3.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@thatopen/components-front/-/components-front-3.4.2.tgz",
|
||||||
|
"integrity": "sha512-Mac9dbxFE5fW4KIp9hPfS30+v2ySFtOHUjpl5VORTvgnlv2x9VVEdYsFV/K3xVOTXoxvsCtnU8sGbyTH8noYUA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@thatopen/components": "~3.4.0",
|
||||||
|
"earcut": "^3.0.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@thatopen/fragments": "~3.4.0",
|
||||||
|
"three": ">=0.182.0",
|
||||||
|
"web-ifc": ">=0.0.77"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@thatopen/fragments": {
|
"node_modules/@thatopen/fragments": {
|
||||||
"version": "3.4.3",
|
"version": "3.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/@thatopen/fragments/-/fragments-3.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@thatopen/fragments/-/fragments-3.4.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@thatopen/components": "3.4.2",
|
"@thatopen/components": "3.4.2",
|
||||||
|
"@thatopen/components-front": "^3.4.2",
|
||||||
"@thatopen/fragments": "3.4.3",
|
"@thatopen/fragments": "3.4.3",
|
||||||
"camera-controls": "3.1.2",
|
"camera-controls": "3.1.2",
|
||||||
"jszip": "3.10.1",
|
"jszip": "3.10.1",
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,5 @@
|
||||||
// viewer.html can do: import { THREE, OBC, JSZip } from "/assets/viewer-deps.js"
|
// viewer.html can do: import { THREE, OBC, JSZip } from "/assets/viewer-deps.js"
|
||||||
export * as THREE from "three";
|
export * as THREE from "three";
|
||||||
export * as OBC from "@thatopen/components";
|
export * as OBC from "@thatopen/components";
|
||||||
|
export * as OBCF from "@thatopen/components-front";
|
||||||
export { default as JSZip } from "jszip";
|
export { default as JSZip } from "jszip";
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue