@openbim/ifcx 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +125 -2
- package/openbim_ifcx_wasm.d.ts +137 -0
- package/openbim_ifcx_wasm.js +489 -0
- package/openbim_ifcx_wasm_bg.wasm +0 -0
- package/openbim_ifcx_wasm_bg.wasm.d.ts +18 -0
- package/package.json +24 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 point-grey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,126 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @openbim/ifcx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Read, write, validate and compose **IFC5 / IFCX** files, and export them as
|
|
4
|
+
GLB, from JavaScript and TypeScript. A WebAssembly build of the
|
|
5
|
+
[`openbim-ifcx`](https://crates.io/crates/openbim-ifcx) Rust crate, from the
|
|
6
|
+
`openbim-ifcx-wasm` crate in [openbimrs/ifcx](https://github.com/openbimrs/ifcx).
|
|
7
|
+
|
|
8
|
+
Published to npm as `@openbim/ifcx`, a CommonJS build for Node 18 and later.
|
|
9
|
+
Browser bundling works in principle (the crate builds for
|
|
10
|
+
`wasm32-unknown-unknown`) but has no tested recipe yet.
|
|
11
|
+
|
|
12
|
+
Targets the `ifcx_alpha` draft of buildingSMART's IFC5. IFCX is still a
|
|
13
|
+
moving draft; see the
|
|
14
|
+
[capabilities](https://github.com/openbimrs/ifcx/blob/main/docs/capabilities.md).
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install @openbim/ifcx
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
const { readFileSync } = require("node:fs");
|
|
26
|
+
const { writeFileSync } = require("node:fs");
|
|
27
|
+
const { IfcxFile, compose, exportGlb } = require("@openbim/ifcx");
|
|
28
|
+
|
|
29
|
+
const model = readFileSync("model.ifcx"); // a Buffer is a Uint8Array
|
|
30
|
+
const file = IfcxFile.parse(model); // or a string
|
|
31
|
+
console.log(file.header.id, file.nodeCount);
|
|
32
|
+
|
|
33
|
+
const report = file.validate();
|
|
34
|
+
for (const f of report.failures) {
|
|
35
|
+
console.log(f.node, f.attribute, f.pointer, f.kind, f.message);
|
|
36
|
+
}
|
|
37
|
+
const text = file.write(); // JSON text, unchanged from the input
|
|
38
|
+
|
|
39
|
+
// Layers weakest first: the last layer's opinions win.
|
|
40
|
+
const tree = compose([model, readFileSync("overlay.ifcx")]);
|
|
41
|
+
console.log(Object.keys(tree.children)); // the root nodes
|
|
42
|
+
|
|
43
|
+
// Any glTF viewer opens the result.
|
|
44
|
+
writeFileSync("model.glb", exportGlb([model, readFileSync("overlay.ifcx")]));
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
| Call | Returns |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| `IfcxFile.parse(input)` | an `IfcxFile`; `input` is JSON text or UTF-8 bytes |
|
|
52
|
+
| `file.write(pretty?)` | the file as JSON text, lossless |
|
|
53
|
+
| `file.toJSON()` | the file as a plain object (`JSON.stringify(file)` works) |
|
|
54
|
+
| `file.header` | the `header` object |
|
|
55
|
+
| `file.nodeCount` | number of entries in `data` |
|
|
56
|
+
| `file.validate()` | a `ValidationReport` against the file's own `schemas` |
|
|
57
|
+
| `compose(layers, options?)` | the composed tree as a `ComposedNode` |
|
|
58
|
+
| `validate(layers, options?)` | a `ValidationReport` over all layers and resolved imports |
|
|
59
|
+
| `exportGlb(layers, options?)` | the composed model as binary glTF 2.0, a `Uint8Array` |
|
|
60
|
+
|
|
61
|
+
`layers` is one input or an array of them, weakest first. TypeScript
|
|
62
|
+
declarations ship with the package.
|
|
63
|
+
|
|
64
|
+
**Lossless round trip.** `write()` keeps key order, fields the draft does
|
|
65
|
+
not define, `null` deletions and every number exactly as read. A plain
|
|
66
|
+
object from `toJSON()` cannot promise that: JavaScript lists integer-like
|
|
67
|
+
keys first and rounds integers beyond 2^53. Keep the `IfcxFile` and call
|
|
68
|
+
`write()` to save a file.
|
|
69
|
+
|
|
70
|
+
**Composed tree.** `compose` returns the artificial root (path `""`) over
|
|
71
|
+
every root node. Each node is `{ path, attributes, children }`, the shape of
|
|
72
|
+
upstream's `PostCompositionNode`, with `children` keyed by child name. Nodes
|
|
73
|
+
shared through inheritance appear once per place they are used.
|
|
74
|
+
|
|
75
|
+
**Imports.** Without `options.imports`, imports are not resolved: the layers'
|
|
76
|
+
schemas and data are concatenated in order, as upstream's `Federate` does.
|
|
77
|
+
With `options.imports` (an object or a `Map` from the exact import `uri` to
|
|
78
|
+
a file), the layers become the imports of a synthetic main layer, as
|
|
79
|
+
upstream's `ifcx compose` command builds it, and every import must be
|
|
80
|
+
supplied. `integrity` values are checked against the supplied bytes. In
|
|
81
|
+
upstream order an import overrides the layer that imports it, and a later
|
|
82
|
+
layer overrides both. Nothing is fetched from the network or the
|
|
83
|
+
filesystem.
|
|
84
|
+
|
|
85
|
+
**GLB export.** `exportGlb` writes the render scene of the composed tree:
|
|
86
|
+
transformed, instanced meshes, lines and points with their materials, one
|
|
87
|
+
glTF node per instance named by its IFCX path. The root node turns IFCX's
|
|
88
|
+
Z-up into glTF's Y-up (`yUp: false` keeps Z-up) and carries the scene
|
|
89
|
+
origin, so georeferenced models keep their coordinates
|
|
90
|
+
(`originOnRoot: false` centres the model on the glTF origin instead).
|
|
91
|
+
Geometry values that do not decode are left out. `options.imports` works
|
|
92
|
+
as for `compose`.
|
|
93
|
+
|
|
94
|
+
**Validation report.** `{ valid, failures }`, each failure
|
|
95
|
+
`{ node, attribute, pointer, kind, message }`: the node path, the attribute
|
|
96
|
+
id, an RFC 6901 pointer into the value (`""` for the value itself), a stable
|
|
97
|
+
`kind` such as `missing-schema`, `type-mismatch`, `not-an-integer`,
|
|
98
|
+
`not-an-option`, `missing-key`, `too-few-elements` or `too-many-elements`,
|
|
99
|
+
and a human message.
|
|
100
|
+
|
|
101
|
+
## Errors
|
|
102
|
+
|
|
103
|
+
Every failure throws an `Error` with `name === "IfcxError"` and a stable
|
|
104
|
+
`code`:
|
|
105
|
+
|
|
106
|
+
| `code` | Meaning |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| `read` | not an IFCX file: invalid JSON or the wrong shape; the message gives line and column |
|
|
109
|
+
| `write` | the file could not be written |
|
|
110
|
+
| `layer` | imports could not be resolved: a missing file, an import cycle, an `integrity` mismatch |
|
|
111
|
+
| `compose` | a reference cycle, or a reference to a node no layer defines |
|
|
112
|
+
| `invalid-argument` | an argument of the wrong type, or no layers |
|
|
113
|
+
| `glb` | the scene could not be written as GLB (over 4 GiB) |
|
|
114
|
+
|
|
115
|
+
A code is never renamed or reused.
|
|
116
|
+
|
|
117
|
+
## Building
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
cargo install wasm-bindgen-cli --version 0.2.128 --locked
|
|
121
|
+
crates/openbim-ifcx-wasm/scripts/build-node-pkg.sh # builds pkg/ and runs the Node suite
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
MIT, like the rest of `openbimrs/ifcx`.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/** An IFCX file as JSON text or as its UTF-8 bytes. */
|
|
5
|
+
export type IfcxInput = string | Uint8Array;
|
|
6
|
+
|
|
7
|
+
/** Options for `compose` and `validate`. */
|
|
8
|
+
export interface LayerOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Files that imports name, keyed by the exact import `uri`. When given
|
|
11
|
+
* (even empty), imports are resolved as upstream does and every import
|
|
12
|
+
* must be here; without it, imports are not resolved.
|
|
13
|
+
*/
|
|
14
|
+
imports?: Record<string, IfcxInput> | Map<string, IfcxInput>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** One node of a composed tree. The root has path `""`. */
|
|
18
|
+
export interface ComposedNode {
|
|
19
|
+
path: string;
|
|
20
|
+
attributes: Record<string, unknown>;
|
|
21
|
+
children: Record<string, ComposedNode>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** The `kind` of a validation failure. */
|
|
25
|
+
export type ValidationFailureKind =
|
|
26
|
+
| "missing-schema"
|
|
27
|
+
| "unknown-inherited-schema"
|
|
28
|
+
| "inheritance-cycle"
|
|
29
|
+
| "type-mismatch"
|
|
30
|
+
| "not-an-integer"
|
|
31
|
+
| "not-an-option"
|
|
32
|
+
| "missing-key"
|
|
33
|
+
| "too-few-elements"
|
|
34
|
+
| "too-many-elements"
|
|
35
|
+
| "missing-restrictions"
|
|
36
|
+
| "unknown-data-type"
|
|
37
|
+
| "other";
|
|
38
|
+
|
|
39
|
+
/** One attribute value that does not match its schema. */
|
|
40
|
+
export interface ValidationFailure {
|
|
41
|
+
/** Path of the node carrying the attribute. */
|
|
42
|
+
node: string;
|
|
43
|
+
/** Attribute id, which is also the schema id. */
|
|
44
|
+
attribute: string;
|
|
45
|
+
/** RFC 6901 JSON pointer into the value; `""` for the value itself. */
|
|
46
|
+
pointer: string;
|
|
47
|
+
kind: ValidationFailureKind;
|
|
48
|
+
message: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface ValidationReport {
|
|
52
|
+
valid: boolean;
|
|
53
|
+
failures: ValidationFailure[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Compose layers, weakest first, into a tree of plain objects: the
|
|
58
|
+
* artificial root (path `""`) over every root node.
|
|
59
|
+
*/
|
|
60
|
+
export function compose(layers: IfcxInput | IfcxInput[], options?: LayerOptions): ComposedNode;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Check the attributes of the layers, weakest first, against the schemas of
|
|
64
|
+
* every layer (and of resolved imports), after merging nodes that share a
|
|
65
|
+
* path.
|
|
66
|
+
*/
|
|
67
|
+
export function validate(layers: IfcxInput | IfcxInput[], options?: LayerOptions): ValidationReport;
|
|
68
|
+
|
|
69
|
+
/** Options for `exportGlb`. */
|
|
70
|
+
export interface GlbOptions extends LayerOptions {
|
|
71
|
+
/** Rotate IFCX's Z-up axes to glTF's Y-up. Default `true`. */
|
|
72
|
+
yUp?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Keep the model's coordinates by putting the scene origin on the root
|
|
75
|
+
* node. With `false` the model sits around the glTF origin, which is then
|
|
76
|
+
* only recorded in the root's `extras.ifcxOrigin`. Default `true`.
|
|
77
|
+
*/
|
|
78
|
+
originOnRoot?: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Compose layers, weakest first, and write their render scene as a binary
|
|
83
|
+
* glTF 2.0 (`.glb`) file: transformed, instanced meshes, lines and points
|
|
84
|
+
* with their materials, one glTF node per instance named by its IFCX path.
|
|
85
|
+
*/
|
|
86
|
+
export function exportGlb(layers: IfcxInput | IfcxInput[], options?: GlbOptions): Uint8Array;
|
|
87
|
+
|
|
88
|
+
/** The `code` of an `IfcxError`. */
|
|
89
|
+
export type IfcxErrorCode =
|
|
90
|
+
| "read"
|
|
91
|
+
| "write"
|
|
92
|
+
| "layer"
|
|
93
|
+
| "compose"
|
|
94
|
+
| "invalid-argument"
|
|
95
|
+
| "glb";
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* One IFCX file. Writing it back is lossless: key order, unknown fields,
|
|
101
|
+
* `null` deletions and every number stay as read.
|
|
102
|
+
*
|
|
103
|
+
* A newtype because `wasm_bindgen` can only export a type defined in this
|
|
104
|
+
* crate; all state and behaviour are the core's.
|
|
105
|
+
*/
|
|
106
|
+
export class IfcxFile {
|
|
107
|
+
private constructor();
|
|
108
|
+
free(): void;
|
|
109
|
+
[Symbol.dispose](): void;
|
|
110
|
+
/**
|
|
111
|
+
* Read an IFCX file from its JSON text or UTF-8 bytes.
|
|
112
|
+
*/
|
|
113
|
+
static parse(input: IfcxInput): IfcxFile;
|
|
114
|
+
/**
|
|
115
|
+
* The file as a plain object, so `JSON.stringify(file)` works. Unlike
|
|
116
|
+
* `write`, a plain object may reorder integer-like keys and round
|
|
117
|
+
* integers beyond 2^53.
|
|
118
|
+
*/
|
|
119
|
+
toJSON(): Record<string, unknown>;
|
|
120
|
+
/**
|
|
121
|
+
* Check every attribute against this file's own `schemas`. Imports are
|
|
122
|
+
* not resolved; use the `validate` function to include them.
|
|
123
|
+
*/
|
|
124
|
+
validate(): ValidationReport;
|
|
125
|
+
/**
|
|
126
|
+
* The file as JSON text; `pretty` indents it by two spaces.
|
|
127
|
+
*/
|
|
128
|
+
write(pretty?: boolean | null): string;
|
|
129
|
+
/**
|
|
130
|
+
* The `header` object.
|
|
131
|
+
*/
|
|
132
|
+
readonly header: Record<string, unknown>;
|
|
133
|
+
/**
|
|
134
|
+
* Number of entries in `data`; several may share a path.
|
|
135
|
+
*/
|
|
136
|
+
readonly nodeCount: number;
|
|
137
|
+
}
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/* @ts-self-types="./openbim_ifcx_wasm.d.ts" */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One IFCX file. Writing it back is lossless: key order, unknown fields,
|
|
5
|
+
* `null` deletions and every number stay as read.
|
|
6
|
+
*
|
|
7
|
+
* A newtype because `wasm_bindgen` can only export a type defined in this
|
|
8
|
+
* crate; all state and behaviour are the core's.
|
|
9
|
+
*/
|
|
10
|
+
class IfcxFile {
|
|
11
|
+
static __wrap(ptr) {
|
|
12
|
+
const obj = Object.create(IfcxFile.prototype);
|
|
13
|
+
obj.__wbg_ptr = ptr;
|
|
14
|
+
IfcxFileFinalization.register(obj, obj.__wbg_ptr, obj);
|
|
15
|
+
return obj;
|
|
16
|
+
}
|
|
17
|
+
__destroy_into_raw() {
|
|
18
|
+
const ptr = this.__wbg_ptr;
|
|
19
|
+
this.__wbg_ptr = 0;
|
|
20
|
+
IfcxFileFinalization.unregister(this);
|
|
21
|
+
return ptr;
|
|
22
|
+
}
|
|
23
|
+
free() {
|
|
24
|
+
const ptr = this.__destroy_into_raw();
|
|
25
|
+
wasm.__wbg_ifcxfile_free(ptr, 0);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The `header` object.
|
|
29
|
+
* @returns {Record<string, unknown>}
|
|
30
|
+
*/
|
|
31
|
+
get header() {
|
|
32
|
+
try {
|
|
33
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
34
|
+
wasm.ifcxfile_header(retptr, this.__wbg_ptr);
|
|
35
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
36
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
37
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
38
|
+
if (r2) {
|
|
39
|
+
throw takeObject(r1);
|
|
40
|
+
}
|
|
41
|
+
return takeObject(r0);
|
|
42
|
+
} finally {
|
|
43
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Number of entries in `data`; several may share a path.
|
|
48
|
+
* @returns {number}
|
|
49
|
+
*/
|
|
50
|
+
get nodeCount() {
|
|
51
|
+
const ret = wasm.ifcxfile_nodeCount(this.__wbg_ptr);
|
|
52
|
+
return ret >>> 0;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Read an IFCX file from its JSON text or UTF-8 bytes.
|
|
56
|
+
* @param {IfcxInput} input
|
|
57
|
+
* @returns {IfcxFile}
|
|
58
|
+
*/
|
|
59
|
+
static parse(input) {
|
|
60
|
+
try {
|
|
61
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
62
|
+
wasm.ifcxfile_parse(retptr, addBorrowedObject(input));
|
|
63
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
64
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
65
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
66
|
+
if (r2) {
|
|
67
|
+
throw takeObject(r1);
|
|
68
|
+
}
|
|
69
|
+
return IfcxFile.__wrap(r0);
|
|
70
|
+
} finally {
|
|
71
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
72
|
+
heap[stack_pointer++] = undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The file as a plain object, so `JSON.stringify(file)` works. Unlike
|
|
77
|
+
* `write`, a plain object may reorder integer-like keys and round
|
|
78
|
+
* integers beyond 2^53.
|
|
79
|
+
* @returns {Record<string, unknown>}
|
|
80
|
+
*/
|
|
81
|
+
toJSON() {
|
|
82
|
+
try {
|
|
83
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
84
|
+
wasm.ifcxfile_toJSON(retptr, this.__wbg_ptr);
|
|
85
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
86
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
87
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
88
|
+
if (r2) {
|
|
89
|
+
throw takeObject(r1);
|
|
90
|
+
}
|
|
91
|
+
return takeObject(r0);
|
|
92
|
+
} finally {
|
|
93
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check every attribute against this file's own `schemas`. Imports are
|
|
98
|
+
* not resolved; use the `validate` function to include them.
|
|
99
|
+
* @returns {ValidationReport}
|
|
100
|
+
*/
|
|
101
|
+
validate() {
|
|
102
|
+
try {
|
|
103
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
104
|
+
wasm.ifcxfile_validate(retptr, this.__wbg_ptr);
|
|
105
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
106
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
107
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
108
|
+
if (r2) {
|
|
109
|
+
throw takeObject(r1);
|
|
110
|
+
}
|
|
111
|
+
return takeObject(r0);
|
|
112
|
+
} finally {
|
|
113
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The file as JSON text; `pretty` indents it by two spaces.
|
|
118
|
+
* @param {boolean | null} [pretty]
|
|
119
|
+
* @returns {string}
|
|
120
|
+
*/
|
|
121
|
+
write(pretty) {
|
|
122
|
+
let deferred2_0;
|
|
123
|
+
let deferred2_1;
|
|
124
|
+
try {
|
|
125
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
126
|
+
wasm.ifcxfile_write(retptr, this.__wbg_ptr, isLikeNone(pretty) ? 0xFFFFFF : pretty ? 1 : 0);
|
|
127
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
128
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
129
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
130
|
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
|
131
|
+
var ptr1 = r0;
|
|
132
|
+
var len1 = r1;
|
|
133
|
+
if (r3) {
|
|
134
|
+
ptr1 = 0; len1 = 0;
|
|
135
|
+
throw takeObject(r2);
|
|
136
|
+
}
|
|
137
|
+
deferred2_0 = ptr1;
|
|
138
|
+
deferred2_1 = len1;
|
|
139
|
+
return getStringFromWasm0(ptr1, len1);
|
|
140
|
+
} finally {
|
|
141
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
142
|
+
wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (Symbol.dispose) IfcxFile.prototype[Symbol.dispose] = IfcxFile.prototype.free;
|
|
147
|
+
exports.IfcxFile = IfcxFile;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Compose layers, weakest first, into a tree of plain objects: the
|
|
151
|
+
* artificial root (path `""`) over every root node. Declared for
|
|
152
|
+
* TypeScript in `TYPES`, where `options` can be optional.
|
|
153
|
+
* @param {any} layers
|
|
154
|
+
* @param {any | null} [options]
|
|
155
|
+
* @returns {any}
|
|
156
|
+
*/
|
|
157
|
+
function compose(layers, options) {
|
|
158
|
+
try {
|
|
159
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
160
|
+
wasm.compose(retptr, addBorrowedObject(layers), isLikeNone(options) ? 0 : addHeapObject(options));
|
|
161
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
162
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
163
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
164
|
+
if (r2) {
|
|
165
|
+
throw takeObject(r1);
|
|
166
|
+
}
|
|
167
|
+
return takeObject(r0);
|
|
168
|
+
} finally {
|
|
169
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
170
|
+
heap[stack_pointer++] = undefined;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.compose = compose;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Compose layers, weakest first, and write their render scene as GLB
|
|
177
|
+
* bytes. Declared for TypeScript in `TYPES`.
|
|
178
|
+
* @param {any} layers
|
|
179
|
+
* @param {any | null} [options]
|
|
180
|
+
* @returns {Uint8Array}
|
|
181
|
+
*/
|
|
182
|
+
function exportGlb(layers, options) {
|
|
183
|
+
try {
|
|
184
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
185
|
+
wasm.exportGlb(retptr, addBorrowedObject(layers), isLikeNone(options) ? 0 : addHeapObject(options));
|
|
186
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
187
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
188
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
189
|
+
if (r2) {
|
|
190
|
+
throw takeObject(r1);
|
|
191
|
+
}
|
|
192
|
+
return takeObject(r0);
|
|
193
|
+
} finally {
|
|
194
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
195
|
+
heap[stack_pointer++] = undefined;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
exports.exportGlb = exportGlb;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Check the attributes of the layers, weakest first, against the schemas
|
|
202
|
+
* of every layer (and of resolved imports), after merging nodes that share
|
|
203
|
+
* a path. Declared for TypeScript in `TYPES`.
|
|
204
|
+
* @param {any} layers
|
|
205
|
+
* @param {any | null} [options]
|
|
206
|
+
* @returns {any}
|
|
207
|
+
*/
|
|
208
|
+
function validate(layers, options) {
|
|
209
|
+
try {
|
|
210
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
211
|
+
wasm.validate(retptr, addBorrowedObject(layers), isLikeNone(options) ? 0 : addHeapObject(options));
|
|
212
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
213
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
214
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
215
|
+
if (r2) {
|
|
216
|
+
throw takeObject(r1);
|
|
217
|
+
}
|
|
218
|
+
return takeObject(r0);
|
|
219
|
+
} finally {
|
|
220
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
221
|
+
heap[stack_pointer++] = undefined;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exports.validate = validate;
|
|
225
|
+
function __wbg_get_imports() {
|
|
226
|
+
const import0 = {
|
|
227
|
+
__proto__: null,
|
|
228
|
+
__wbg___wbindgen_boolean_get_7a12af2b3f899c5a: function(arg0) {
|
|
229
|
+
const v = getObject(arg0);
|
|
230
|
+
const ret = typeof(v) === 'boolean' ? v : undefined;
|
|
231
|
+
return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
|
|
232
|
+
},
|
|
233
|
+
__wbg___wbindgen_is_null_5160b3e381865372: function(arg0) {
|
|
234
|
+
const ret = getObject(arg0) === null;
|
|
235
|
+
return ret;
|
|
236
|
+
},
|
|
237
|
+
__wbg___wbindgen_is_object_edb6b15aa3afe12e: function(arg0) {
|
|
238
|
+
const val = getObject(arg0);
|
|
239
|
+
const ret = typeof(val) === 'object' && val !== null;
|
|
240
|
+
return ret;
|
|
241
|
+
},
|
|
242
|
+
__wbg___wbindgen_is_undefined_8c687d0b90d5b524: function(arg0) {
|
|
243
|
+
const ret = getObject(arg0) === undefined;
|
|
244
|
+
return ret;
|
|
245
|
+
},
|
|
246
|
+
__wbg___wbindgen_string_get_92ab86bb19cbc12f: function(arg0, arg1) {
|
|
247
|
+
const obj = getObject(arg1);
|
|
248
|
+
const ret = typeof(obj) === 'string' ? obj : undefined;
|
|
249
|
+
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
250
|
+
var len1 = WASM_VECTOR_LEN;
|
|
251
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
252
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
253
|
+
},
|
|
254
|
+
__wbg___wbindgen_throw_5d9e815e6fdf150f: function(arg0, arg1) {
|
|
255
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
256
|
+
},
|
|
257
|
+
__wbg_entries_20b9608d57d8ddd6: function(arg0) {
|
|
258
|
+
const ret = getObject(arg0).entries();
|
|
259
|
+
return addHeapObject(ret);
|
|
260
|
+
},
|
|
261
|
+
__wbg_entries_972a87586902cf87: function(arg0) {
|
|
262
|
+
const ret = Object.entries(getObject(arg0));
|
|
263
|
+
return addHeapObject(ret);
|
|
264
|
+
},
|
|
265
|
+
__wbg_from_a39669ce566077da: function(arg0) {
|
|
266
|
+
const ret = Array.from(getObject(arg0));
|
|
267
|
+
return addHeapObject(ret);
|
|
268
|
+
},
|
|
269
|
+
__wbg_get_989d0a1309644f2b: function() { return handleError(function (arg0, arg1) {
|
|
270
|
+
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
|
271
|
+
return addHeapObject(ret);
|
|
272
|
+
}, arguments); },
|
|
273
|
+
__wbg_get_b1f0ab13c737f856: function(arg0, arg1) {
|
|
274
|
+
const ret = getObject(arg0)[arg1 >>> 0];
|
|
275
|
+
return addHeapObject(ret);
|
|
276
|
+
},
|
|
277
|
+
__wbg_get_unchecked_363572bdd397d473: function(arg0, arg1) {
|
|
278
|
+
const ret = getObject(arg0)[arg1 >>> 0];
|
|
279
|
+
return addHeapObject(ret);
|
|
280
|
+
},
|
|
281
|
+
__wbg_instanceof_Map_1ff6a2b54c899f0d: function(arg0) {
|
|
282
|
+
let result;
|
|
283
|
+
try {
|
|
284
|
+
result = getObject(arg0) instanceof Map;
|
|
285
|
+
} catch (_) {
|
|
286
|
+
result = false;
|
|
287
|
+
}
|
|
288
|
+
const ret = result;
|
|
289
|
+
return ret;
|
|
290
|
+
},
|
|
291
|
+
__wbg_instanceof_Uint8Array_598adc0fef426aa8: function(arg0) {
|
|
292
|
+
let result;
|
|
293
|
+
try {
|
|
294
|
+
result = getObject(arg0) instanceof Uint8Array;
|
|
295
|
+
} catch (_) {
|
|
296
|
+
result = false;
|
|
297
|
+
}
|
|
298
|
+
const ret = result;
|
|
299
|
+
return ret;
|
|
300
|
+
},
|
|
301
|
+
__wbg_isArray_5674713bb7b79043: function(arg0) {
|
|
302
|
+
const ret = Array.isArray(getObject(arg0));
|
|
303
|
+
return ret;
|
|
304
|
+
},
|
|
305
|
+
__wbg_length_31bdaf014f5fbde2: function(arg0) {
|
|
306
|
+
const ret = getObject(arg0).length;
|
|
307
|
+
return ret;
|
|
308
|
+
},
|
|
309
|
+
__wbg_length_4e1adc0d42e23620: function(arg0) {
|
|
310
|
+
const ret = getObject(arg0).length;
|
|
311
|
+
return ret;
|
|
312
|
+
},
|
|
313
|
+
__wbg_new_a32a1ab6c6655abe: function(arg0, arg1) {
|
|
314
|
+
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
|
315
|
+
return addHeapObject(ret);
|
|
316
|
+
},
|
|
317
|
+
__wbg_new_from_slice_4ee02165f9de919e: function(arg0, arg1) {
|
|
318
|
+
const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));
|
|
319
|
+
return addHeapObject(ret);
|
|
320
|
+
},
|
|
321
|
+
__wbg_parse_6937a9050adfb0e1: function() { return handleError(function (arg0, arg1) {
|
|
322
|
+
const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
|
323
|
+
return addHeapObject(ret);
|
|
324
|
+
}, arguments); },
|
|
325
|
+
__wbg_prototypesetcall_ae9f5e7459250748: function(arg0, arg1, arg2) {
|
|
326
|
+
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2));
|
|
327
|
+
},
|
|
328
|
+
__wbg_set_a377297433dfea63: function() { return handleError(function (arg0, arg1, arg2) {
|
|
329
|
+
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
|
330
|
+
return ret;
|
|
331
|
+
}, arguments); },
|
|
332
|
+
__wbg_set_name_6e2a5da46a9ae1e7: function(arg0, arg1, arg2) {
|
|
333
|
+
getObject(arg0).name = getStringFromWasm0(arg1, arg2);
|
|
334
|
+
},
|
|
335
|
+
__wbindgen_generic_0000000000000001: function(arg0, arg1) {
|
|
336
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
337
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
338
|
+
return addHeapObject(ret);
|
|
339
|
+
},
|
|
340
|
+
__wbindgen_object_drop_ref: function(arg0) {
|
|
341
|
+
takeObject(arg0);
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
return {
|
|
345
|
+
__proto__: null,
|
|
346
|
+
"./openbim_ifcx_wasm_bg.js": import0,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const IfcxFileFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
351
|
+
? { register: () => {}, unregister: () => {} }
|
|
352
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_ifcxfile_free(ptr, 1));
|
|
353
|
+
|
|
354
|
+
function addHeapObject(obj) {
|
|
355
|
+
if (heap_next === heap.length) heap.push(heap.length + 1);
|
|
356
|
+
const idx = heap_next;
|
|
357
|
+
heap_next = heap[idx];
|
|
358
|
+
|
|
359
|
+
heap[idx] = obj;
|
|
360
|
+
return idx;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function addBorrowedObject(obj) {
|
|
364
|
+
if (stack_pointer == 1) throw new Error('out of js stack');
|
|
365
|
+
heap[--stack_pointer] = obj;
|
|
366
|
+
return stack_pointer;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function dropObject(idx) {
|
|
370
|
+
if (idx < 1028) return;
|
|
371
|
+
heap[idx] = heap_next;
|
|
372
|
+
heap_next = idx;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
376
|
+
ptr = ptr >>> 0;
|
|
377
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
let cachedDataViewMemory0 = null;
|
|
381
|
+
function getDataViewMemory0() {
|
|
382
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
383
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
384
|
+
}
|
|
385
|
+
return cachedDataViewMemory0;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function getStringFromWasm0(ptr, len) {
|
|
389
|
+
return decodeText(ptr >>> 0, len);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
let cachedUint8ArrayMemory0 = null;
|
|
393
|
+
function getUint8ArrayMemory0() {
|
|
394
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
395
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
396
|
+
}
|
|
397
|
+
return cachedUint8ArrayMemory0;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function getObject(idx) { return heap[idx]; }
|
|
401
|
+
|
|
402
|
+
function handleError(f, args) {
|
|
403
|
+
try {
|
|
404
|
+
return f.apply(this, args);
|
|
405
|
+
} catch (e) {
|
|
406
|
+
wasm.__wbindgen_export3(addHeapObject(e));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
let heap = new Array(1024).fill(undefined);
|
|
411
|
+
heap.push(undefined, null, true, false);
|
|
412
|
+
|
|
413
|
+
let heap_next = heap.length;
|
|
414
|
+
|
|
415
|
+
function isLikeNone(x) {
|
|
416
|
+
return x === undefined || x === null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
420
|
+
if (realloc === undefined) {
|
|
421
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
422
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
423
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
424
|
+
WASM_VECTOR_LEN = buf.length;
|
|
425
|
+
return ptr;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let len = arg.length;
|
|
429
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
430
|
+
|
|
431
|
+
const mem = getUint8ArrayMemory0();
|
|
432
|
+
|
|
433
|
+
let offset = 0;
|
|
434
|
+
|
|
435
|
+
for (; offset < len; offset++) {
|
|
436
|
+
const code = arg.charCodeAt(offset);
|
|
437
|
+
if (code > 0x7F) break;
|
|
438
|
+
mem[ptr + offset] = code;
|
|
439
|
+
}
|
|
440
|
+
if (offset !== len) {
|
|
441
|
+
if (offset !== 0) {
|
|
442
|
+
arg = arg.slice(offset);
|
|
443
|
+
}
|
|
444
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
445
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
446
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
447
|
+
|
|
448
|
+
offset += ret.written;
|
|
449
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
WASM_VECTOR_LEN = offset;
|
|
453
|
+
return ptr;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
let stack_pointer = 1024;
|
|
457
|
+
|
|
458
|
+
function takeObject(idx) {
|
|
459
|
+
const ret = getObject(idx);
|
|
460
|
+
dropObject(idx);
|
|
461
|
+
return ret;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
465
|
+
cachedTextDecoder.decode();
|
|
466
|
+
function decodeText(ptr, len) {
|
|
467
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const cachedTextEncoder = new TextEncoder();
|
|
471
|
+
|
|
472
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
473
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
474
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
475
|
+
view.set(buf);
|
|
476
|
+
return {
|
|
477
|
+
read: arg.length,
|
|
478
|
+
written: buf.length
|
|
479
|
+
};
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
let WASM_VECTOR_LEN = 0;
|
|
484
|
+
|
|
485
|
+
const wasmPath = `${__dirname}/openbim_ifcx_wasm_bg.wasm`;
|
|
486
|
+
const wasmBytes = require('fs').readFileSync(wasmPath);
|
|
487
|
+
const wasmModule = new WebAssembly.Module(wasmBytes);
|
|
488
|
+
let wasmInstance = new WebAssembly.Instance(wasmModule, __wbg_get_imports());
|
|
489
|
+
let wasm = wasmInstance.exports;
|
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const __wbg_ifcxfile_free: (a: number, b: number) => void;
|
|
5
|
+
export const compose: (a: number, b: number, c: number) => void;
|
|
6
|
+
export const exportGlb: (a: number, b: number, c: number) => void;
|
|
7
|
+
export const ifcxfile_header: (a: number, b: number) => void;
|
|
8
|
+
export const ifcxfile_nodeCount: (a: number) => number;
|
|
9
|
+
export const ifcxfile_parse: (a: number, b: number) => void;
|
|
10
|
+
export const ifcxfile_toJSON: (a: number, b: number) => void;
|
|
11
|
+
export const ifcxfile_validate: (a: number, b: number) => void;
|
|
12
|
+
export const ifcxfile_write: (a: number, b: number, c: number) => void;
|
|
13
|
+
export const validate: (a: number, b: number, c: number) => void;
|
|
14
|
+
export const __wbindgen_export: (a: number, b: number) => number;
|
|
15
|
+
export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
16
|
+
export const __wbindgen_export3: (a: number) => void;
|
|
17
|
+
export const __wbindgen_add_to_stack_pointer: (a: number) => number;
|
|
18
|
+
export const __wbindgen_export4: (a: number, b: number, c: number) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openbim/ifcx",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"description": "Read, write, validate and compose IFC5 / IFCX files, and export GLB, from JavaScript (WebAssembly build of openbim-ifcx).",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/openbimrs/ifcx.git",
|
|
9
|
+
"directory": "crates/openbim-ifcx-wasm"
|
|
10
|
+
},
|
|
11
|
+
"type": "commonjs",
|
|
12
|
+
"main": "openbim_ifcx_wasm.js",
|
|
13
|
+
"types": "openbim_ifcx_wasm.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"openbim_ifcx_wasm.js",
|
|
16
|
+
"openbim_ifcx_wasm.d.ts",
|
|
17
|
+
"openbim_ifcx_wasm_bg.wasm",
|
|
18
|
+
"openbim_ifcx_wasm_bg.wasm.d.ts",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=18"
|
|
24
|
+
},
|
|
25
|
+
"keywords": ["ifcx", "ifc5", "ifc", "bim", "openbim", "gltf", "wasm"]
|
|
26
|
+
}
|