@nika-js/onlymap 0.6.0 → 0.6.1

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/README.md +18 -6
  3. package/THIRD-PARTY-LICENSES.md +27 -0
  4. package/dist/{LercDecode.es-fbo6h5rt.js → LercDecode.es-CJnypw8j.js} +1 -1
  5. package/dist/{basemap-CprSan9q.js → basemap-DrQ0-eyR.js} +1 -1
  6. package/dist/cityjson-D_V5GY8b.js +332 -0
  7. package/dist/crs-Ciu7Xs7a.js +108 -0
  8. package/dist/crs.d.ts +50 -0
  9. package/dist/ctx.d.ts +8 -1
  10. package/dist/elements/om-map.d.ts +26 -2
  11. package/dist/elements/om-overlay.d.ts +1 -1
  12. package/dist/elements/om-widget.d.ts +4 -0
  13. package/dist/feature-colors.d.ts +41 -0
  14. package/dist/{geoparquet-Bm8pfxyo.js → geoparquet-Dix4lTNy.js} +1 -1
  15. package/dist/html-data.d.ts +1 -1
  16. package/dist/ifc-Dc-TdSJr.js +877 -0
  17. package/dist/ifc.d.ts +406 -0
  18. package/dist/{index-Bz-rbmhj.js → index-1UgNlfGR.js} +20892 -18886
  19. package/dist/{index-GOwMjqm6.js → index-BQMjW5w0.js} +1 -1
  20. package/dist/{index-DSRIZR81.js → index-B_1PPJgC.js} +1 -1
  21. package/dist/{index-CCQttJzO.js → index-CAuT5j9Y.js} +2 -2
  22. package/dist/{index-UzmNhuS0.js → index-CXPaeisL.js} +1 -1
  23. package/dist/index.d.ts +8 -0
  24. package/dist/layer-registry.d.ts +14 -0
  25. package/dist/layers/bim-layer.d.ts +104 -0
  26. package/dist/layers/feature-mesh-layer.d.ts +288 -0
  27. package/dist/layers/gltf-scene-walk.d.ts +55 -0
  28. package/dist/{lerc-CuifOkoA.js → lerc-CbTjQ7uI.js} +2 -2
  29. package/dist/meshopt_simplifier-Co6uRDDA.js +370 -0
  30. package/dist/onlymap.standalone.js +57996 -54706
  31. package/dist/onlymapjs.js +69 -67
  32. package/dist/programmatic.d.ts +22 -2
  33. package/dist/{raster-dysYIQ_k.js → raster-0b0nSHUh.js} +2 -2
  34. package/dist/{raster-pipeline-ZdCOGfqV.js → raster-pipeline-D8siq7-4.js} +1 -1
  35. package/dist/react/om-overlay.d.ts +9 -0
  36. package/dist/react.js +144 -144
  37. package/dist/runtime-core.d.ts +110 -3
  38. package/dist/selection.d.ts +33 -0
  39. package/dist/site-placement.d.ts +85 -0
  40. package/dist/testing.d.ts +6 -2
  41. package/dist/tile3d-metadata.d.ts +185 -0
  42. package/dist/version.d.ts +1 -1
  43. package/dist/widget-registry.d.ts +11 -0
  44. package/dist/widgets/ifc-clash.d.ts +18 -0
  45. package/dist/widgets/ifc.d.ts +41 -0
  46. package/dist/{zarr-OewK7k2K.js → zarr-DCYro_Vs.js} +79 -66
  47. package/docs/testing.md +2 -2
  48. package/llms.txt +3 -3
  49. package/onlymapjs.html-data.json +152 -0
  50. package/package.json +3 -1
  51. package/skills/onlymapjs/SKILL.md +4 -2
  52. package/skills/onlymapjs/references/react.md +1 -1
  53. package/skills/onlymapjs/references/syntax.md +298 -11
  54. package/dist/cityjson-urQeujQv.js +0 -407
@@ -0,0 +1,877 @@
1
+ import { p as kt, g as Bt, b as Ht } from "./crs-Ciu7Xs7a.js";
2
+ const _t = "0.0.68", Rt = `https://unpkg.com/web-ifc@${_t}/`;
3
+ let Tt = Rt;
4
+ function Pe(t) {
5
+ t.wasmPath && (Tt = t.wasmPath.endsWith("/") ? t.wasmPath : `${t.wasmPath}/`);
6
+ }
7
+ const Et = "", Wt = 3242617779, Xt = 2655215786, qt = 4186316022, Kt = 4097777520, Yt = 3057273783, Jt = 3448662350, Zt = 160246688, Qt = 781010003, te = 919958153, ee = 1307041759, ne = 103090709;
8
+ let St = null;
9
+ function oe(t) {
10
+ let e = "";
11
+ for (let n = 0; n < t.length; n += 32768) e += String.fromCharCode(...t.subarray(n, n + 32768));
12
+ return btoa(e);
13
+ }
14
+ const se = {
15
+ "web-ifc-api.js": "377cf933e274bf812be67752c87694f33d25778a427665a8770709493bb4920c",
16
+ "web-ifc.wasm": "012cc124216024de72cc6562cdc0235f7757ca45bcf29cee7b8947fe77f12135",
17
+ "web-ifc-mt.wasm": "961fff06dae99c318cb6ecc1136f2f32be0573a33537ec85999aced6fe69484f",
18
+ // Byte-identical to web-ifc.wasm at 0.0.68 (verified, not assumed) — kept
19
+ // as its own entry so a future version where the two diverge cannot
20
+ // silently fall through the check.
21
+ "web-ifc-node.wasm": "012cc124216024de72cc6562cdc0235f7757ca45bcf29cee7b8947fe77f12135"
22
+ };
23
+ function ce(t) {
24
+ if (!t.startsWith(Rt)) return null;
25
+ const e = t.slice(Rt.length).split(/[?#]/)[0];
26
+ return se[e] ?? null;
27
+ }
28
+ const ae = async (t) => [...new Uint8Array(await crypto.subtle.digest("SHA-256", t))].map((e) => e.toString(16).padStart(2, "0")).join("");
29
+ async function Ct(t, e, o) {
30
+ if (typeof crypto > "u" || !crypto.subtle) return t;
31
+ const n = await t.arrayBuffer(), s = await ae(n);
32
+ if (s !== e)
33
+ throw new Error(
34
+ `[onlymap] integrity check failed for ${o}: expected sha256 ${e}, got ${s}. Refusing to execute or cache these bytes. If you intend to run a different web-ifc build, self-host it and point the loader at it with configureIfc({ wasmPath }) — integrity is only enforced for the default CDN.`
35
+ );
36
+ return new Response(n, { status: 200, headers: t.headers });
37
+ }
38
+ const Ft = "onlymapjs-web-ifc", $t = `${Ft}-${_t}`;
39
+ let Ot = !1;
40
+ async function re() {
41
+ if (!Ot) {
42
+ Ot = !0;
43
+ try {
44
+ for (const t of await caches.keys())
45
+ t.startsWith(Ft) && t !== $t && await caches.delete(t);
46
+ } catch {
47
+ }
48
+ }
49
+ }
50
+ async function Lt(t, e = fetch) {
51
+ const o = ce(t);
52
+ if (typeof caches > "u") {
53
+ const f = await e(t);
54
+ return o && f.ok ? Ct(f, o, t) : f;
55
+ }
56
+ await re();
57
+ const n = await caches.open($t), s = await n.match(t);
58
+ if (s) {
59
+ if (!o) return s;
60
+ try {
61
+ return await Ct(s, o, t);
62
+ } catch (f) {
63
+ try {
64
+ await n.delete(t);
65
+ } catch {
66
+ }
67
+ throw f;
68
+ }
69
+ }
70
+ const r = await e(t);
71
+ if (!r.ok) return r;
72
+ const c = o ? await Ct(r, o, t) : r;
73
+ try {
74
+ await n.put(t, c.clone());
75
+ } catch {
76
+ }
77
+ return c;
78
+ }
79
+ const ie = /\bweb-ifc(?:-mt|-node)?\.wasm(?:[?#]|$)/;
80
+ async function le() {
81
+ return St ??= (async () => {
82
+ const t = `${Tt}web-ifc-api.js`, e = await (await Lt(t)).text(), o = URL.createObjectURL(new Blob([e], { type: "text/javascript" }));
83
+ let n;
84
+ try {
85
+ n = await import(
86
+ /* @vite-ignore */
87
+ o
88
+ );
89
+ } catch {
90
+ n = await import(`data:text/javascript;base64,${oe(new TextEncoder().encode(e))}`);
91
+ } finally {
92
+ URL.revokeObjectURL(o);
93
+ }
94
+ const s = new n.IfcAPI();
95
+ s.SetWasmPath(Tt, !0);
96
+ const r = typeof caches < "u" ? globalThis.fetch : null;
97
+ r && (globalThis.fetch = ((c, f) => {
98
+ const d = typeof c == "string" ? c : c instanceof URL ? c.href : c.url;
99
+ return ie.test(d) ? Lt(d, r) : r(c, f);
100
+ }));
101
+ try {
102
+ await s.Init();
103
+ } finally {
104
+ r && (globalThis.fetch = r);
105
+ }
106
+ return s;
107
+ })().catch((t) => {
108
+ throw St = null, t;
109
+ }), St;
110
+ }
111
+ const B = (t) => t && typeof t == "object" && "value" in t ? String(t.value ?? "") : t == null ? "" : String(t);
112
+ function Pt(t) {
113
+ const e = t && typeof t == "object" && "value" in t ? t.value : t;
114
+ if (!Array.isArray(e) || e.length < 2) return null;
115
+ const o = e.map((m) => Number(m && typeof m == "object" && "value" in m ? m.value : m) || 0), n = o.some((m) => m < 0), [s = 0, r = 0, c = 0, f = 0] = o.map(Math.abs), d = s + r / 60 + c / 3600 + f / 36e8;
116
+ return n ? -d : d;
117
+ }
118
+ function ft(t) {
119
+ const e = t && typeof t == "object" && "value" in t ? t.value : t;
120
+ if (e == null || e === "") return null;
121
+ const o = Number(e);
122
+ return Number.isFinite(o) ? o : null;
123
+ }
124
+ function fe(t, e, o) {
125
+ const n = Math.hypot(t.xAxisAbscissa, t.xAxisOrdinate), s = n ? t.xAxisAbscissa / n : 1, r = n ? t.xAxisOrdinate / n : 0;
126
+ return [
127
+ t.eastings + t.scale * (e * s - o * r),
128
+ t.northings + t.scale * (e * r + o * s)
129
+ ];
130
+ }
131
+ function ue(t) {
132
+ return {
133
+ code: t.epsg,
134
+ eastings: t.eastings,
135
+ northings: t.northings,
136
+ orthogonalHeight: t.orthogonalHeight,
137
+ xAxisAbscissa: t.xAxisAbscissa,
138
+ xAxisOrdinate: t.xAxisOrdinate,
139
+ scale: 1
140
+ };
141
+ }
142
+ function he(t, e) {
143
+ return t + e;
144
+ }
145
+ const de = {
146
+ EXA: 1e18,
147
+ PETA: 1e15,
148
+ TERA: 1e12,
149
+ GIGA: 1e9,
150
+ MEGA: 1e6,
151
+ KILO: 1e3,
152
+ HECTO: 100,
153
+ DECA: 10,
154
+ DECI: 0.1,
155
+ CENTI: 0.01,
156
+ MILLI: 1e-3,
157
+ MICRO: 1e-6,
158
+ NANO: 1e-9,
159
+ PICO: 1e-12,
160
+ FEMTO: 1e-15,
161
+ ATTO: 1e-18
162
+ }, At = 6378137, Nt = 1 / 298.257223563, Z = Nt * (2 - Nt), Ut = 0.9996, Mt = Z / (1 - Z);
163
+ function Dt(t, e, o, n) {
164
+ const s = t - 5e5, c = (n ? e - 1e7 : e) / Ut / (At * (1 - Z / 4 - 3 * Z ** 2 / 64 - 5 * Z ** 3 / 256)), f = (1 - Math.sqrt(1 - Z)) / (1 + Math.sqrt(1 - Z)), d = c + (3 * f / 2 - 27 * f ** 3 / 32) * Math.sin(2 * c) + (21 * f ** 2 / 16 - 55 * f ** 4 / 32) * Math.sin(4 * c) + 151 * f ** 3 / 96 * Math.sin(6 * c) + 1097 * f ** 4 / 512 * Math.sin(8 * c), m = Mt * Math.cos(d) ** 2, y = Math.tan(d) ** 2, l = Math.sin(d), i = At / Math.sqrt(1 - Z * l * l), h = At * (1 - Z) / (1 - Z * l * l) ** 1.5, g = s / (i * Ut), w = d - i * Math.tan(d) / h * (g ** 2 / 2 - (5 + 3 * y + 10 * m - 4 * m ** 2 - 9 * Mt) * g ** 4 / 24 + (61 + 90 * y + 298 * m + 45 * y ** 2 - 252 * Mt - 3 * m ** 2) * g ** 6 / 720);
165
+ return [(o - 1) * 6 - 180 + 3 + (g - (1 + 2 * y + m) * g ** 3 / 6 + (5 - 2 * m + 28 * y - 3 * m ** 2 + 8 * Mt + 24 * y ** 2) * g ** 5 / 120) / Math.cos(d) * (180 / Math.PI), w * 180 / Math.PI];
166
+ }
167
+ function jt(t) {
168
+ const e = /(?:EPSG:?)\s*(326|327)(\d{2})/i.exec(t);
169
+ if (!e) return null;
170
+ const o = Number(e[2]);
171
+ return o < 1 || o > 60 ? null : { zone: o, south: e[1] === "327" };
172
+ }
173
+ const pe = (t) => (t - 1) * 6 - 180 + 3;
174
+ function ge(t, e, o) {
175
+ const n = (t - pe(o)) * Math.PI / 180, s = e * Math.PI / 180;
176
+ return Math.atan(Math.tan(n) * Math.sin(s)) * 180 / Math.PI;
177
+ }
178
+ async function me(t, e, o) {
179
+ if (t.code == null) return null;
180
+ const [n, s] = fe(t, e, o), r = jt(`EPSG:${t.code}`);
181
+ return r ? Dt(n, s, r.zone, r.south) : kt(t.code, n, s);
182
+ }
183
+ async function ye(t, e, o) {
184
+ let n = o, s = !1;
185
+ try {
186
+ const l = t.GetLineIDsWithType(e, Kt);
187
+ for (let i = 0; i < l.size(); i++) {
188
+ const h = t.GetLine(e, l.get(i), !0), g = Pt(h.RefLatitude), w = Pt(h.RefLongitude);
189
+ if (g != null && w != null && (g || w)) {
190
+ n = [w, g], s = !0;
191
+ break;
192
+ }
193
+ }
194
+ } catch {
195
+ }
196
+ let r = 0, c = 1, f = "assumed", d = s ? "ifc-site" : "fallback", m = null, y = !1;
197
+ try {
198
+ const l = t.GetLineIDsWithType(e, Yt);
199
+ for (let i = 0; i < l.size(); i++) {
200
+ const h = t.GetLine(e, l.get(i), !0), g = ft(h.XAxisAbscissa), w = ft(h.XAxisOrdinate);
201
+ g != null && w != null && (g || w) && (r = -(Math.atan2(w, g) * 180) / Math.PI, f = "map-conversion");
202
+ const I = `${B(h.TargetCRS?.Name)} ${B(h.TargetCRS?.Description)}`, R = ft(h.Eastings), L = ft(h.Northings);
203
+ if (R == null || L == null) break;
204
+ const O = B(h.TargetCRS?.MapUnit?.Name).toUpperCase();
205
+ h.TargetCRS?.MapUnit != null && O !== "METRE" && console.warn(
206
+ `[onlymap] IfcMapConversion's TargetCRS declares a map unit that is not IfcSIUnit.METRE (read as "${O || "unknown"}") — eastings/northings/OrthogonalHeight are being treated as metres regardless, which is wrong for a non-metric unit (e.g. US survey feet) and will misplace the model.`
207
+ );
208
+ const k = de[B(h.TargetCRS?.MapUnit?.Prefix).toUpperCase()] ?? 1, T = R * k, U = L * k, $ = jt(I), D = /EPSG:?\s*(\d{4,6})/i.exec(I);
209
+ let a = $ ? Dt(T, U, $.zone, $.south) : null, u = null;
210
+ if (a && $)
211
+ u = ge(a[0], a[1], $.zone);
212
+ else if (!a && D) {
213
+ const A = Number(D[1]);
214
+ a = await kt(A, T, U), a && (u = await Bt(A, T, U));
215
+ }
216
+ const p = ft(h.OrthogonalHeight);
217
+ y = p != null, m = ue({
218
+ epsg: D ? Number(D[1]) : null,
219
+ eastings: T,
220
+ northings: U,
221
+ orthogonalHeight: (p ?? 0) * k,
222
+ xAxisAbscissa: g ?? 1,
223
+ xAxisOrdinate: w ?? 0
224
+ }), a ? (n = a, s = !0, d = "map-conversion", u != null && (r += u)) : console.warn(
225
+ `[onlymap] IFC declares an IfcMapConversion into "${I.trim()}", which is neither a WGS84 UTM zone nor one of the bundled coordinate systems (EPSG ${Ht().join(", ")}) — its eastings/northings cannot be un-projected, so the position falls back to IfcSite. Set the layer's site-origin to place it.`
226
+ );
227
+ break;
228
+ }
229
+ } catch {
230
+ }
231
+ if (f === "assumed")
232
+ try {
233
+ const l = t.GetLineIDsWithType(e, Jt);
234
+ for (let i = 0; i < l.size(); i++) {
235
+ const h = t.GetLine(e, l.get(i), !0), g = h.ContextType, w = g && typeof g == "object" && "value" in g ? g.value : g;
236
+ if (String(w ?? "") !== "Model") continue;
237
+ const I = h.TrueNorth?.DirectionRatios;
238
+ if (!Array.isArray(I) || I.length < 2) continue;
239
+ const R = ft(I[0]), L = ft(I[1]);
240
+ if (!(R == null || L == null || !R && !L)) {
241
+ r = Math.atan2(L, R) * 180 / Math.PI - 90, f = "true-north";
242
+ break;
243
+ }
244
+ }
245
+ } catch {
246
+ }
247
+ return r = (r % 360 + 360) % 360, r > 180 && (r -= 360), r = Math.round(r * 1e4) / 1e4, { lonLat: n, georeferenced: s, heading: r, scale: c, headingSource: f, originSource: d, affine: m, hasOrthogonalHeight: y };
248
+ }
249
+ function be(t, e) {
250
+ const o = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), y = (a) => {
251
+ if (m.has(a)) return m.get(a);
252
+ let u = null;
253
+ try {
254
+ u = t.GetLine(e, a, !1);
255
+ } catch {
256
+ u = null;
257
+ }
258
+ return m.set(a, u), u;
259
+ }, l = (a) => Number(a?.value ?? a?.expressID ?? -1), i = (a) => {
260
+ const u = l(a);
261
+ return u < 0 ? "" : B(y(u)?.Name);
262
+ }, h = (a, u) => {
263
+ let p;
264
+ try {
265
+ p = t.GetLineIDsWithType(e, a);
266
+ } catch {
267
+ return;
268
+ }
269
+ for (let A = 0; A < p.size(); A++)
270
+ try {
271
+ const S = y(p.get(A));
272
+ S && u(S);
273
+ } catch {
274
+ }
275
+ }, g = /* @__PURE__ */ new Map();
276
+ h(Zt, (a) => {
277
+ const u = l(a.RelatingObject);
278
+ for (const p of a.RelatedObjects ?? []) g.set(l(p), u);
279
+ });
280
+ const w = /* @__PURE__ */ new Map(), I = (a) => {
281
+ const u = w.get(a);
282
+ if (u !== void 0) return u;
283
+ let p = B(y(a)?.Name);
284
+ if (!p)
285
+ try {
286
+ p = t.GetNameFromTypeCode(t.GetLineType(e, a));
287
+ } catch {
288
+ p = "";
289
+ }
290
+ return w.set(a, p), p;
291
+ }, R = /* @__PURE__ */ new Map(), L = (a) => {
292
+ if (a < 0) return "";
293
+ const u = R.get(a);
294
+ if (u !== void 0) return u;
295
+ const p = [], A = /* @__PURE__ */ new Set();
296
+ for (let C = a; C >= 0 && !A.has(C); C = g.get(C) ?? -1) {
297
+ A.add(C);
298
+ let M = -1;
299
+ try {
300
+ M = t.GetLineType(e, C);
301
+ } catch {
302
+ }
303
+ if (M === ne) break;
304
+ const E = I(C);
305
+ E && p.unshift(E);
306
+ }
307
+ const S = p.join(Et);
308
+ return R.set(a, S), S;
309
+ };
310
+ h(Wt, (a) => {
311
+ const u = l(a.RelatingStructure), p = i(a.RelatingStructure), A = L(u);
312
+ for (const S of a.RelatedElements ?? []) {
313
+ const C = l(S);
314
+ o.set(C, p), n.set(C, A);
315
+ }
316
+ }), h(Qt, (a) => {
317
+ const u = l(a.RelatingType);
318
+ if (u < 0) return;
319
+ let p = "";
320
+ try {
321
+ p = t.GetNameFromTypeCode(t.GetLineType(e, u));
322
+ } catch {
323
+ }
324
+ const A = [p, I(u)].filter(Boolean).join(Et);
325
+ if (A)
326
+ for (const S of a.RelatedObjects ?? []) s.set(l(S), A);
327
+ }), h(ee, (a) => {
328
+ const u = l(a.RelatingGroup);
329
+ if (u < 0) return;
330
+ const p = L(u) || I(u);
331
+ if (p)
332
+ for (const A of a.RelatedObjects ?? []) r.set(l(A), p);
333
+ });
334
+ const O = /* @__PURE__ */ new Map(), k = (a) => {
335
+ const u = O.get(a);
336
+ if (u !== void 0) return u;
337
+ const p = [], A = /* @__PURE__ */ new Set();
338
+ for (let C = a; C >= 0 && !A.has(C); ) {
339
+ A.add(C);
340
+ const M = y(C);
341
+ if (!M) break;
342
+ const E = B(M.Identification) || B(M.ItemReference), V = B(M.Name), Q = [E, V].filter(Boolean).join(" ");
343
+ Q && p.unshift(Q), C = l(M.ReferencedSource);
344
+ }
345
+ const S = p.join(Et);
346
+ return O.set(a, S), S;
347
+ };
348
+ h(te, (a) => {
349
+ const u = k(l(a.RelatingClassification));
350
+ if (u)
351
+ for (const p of a.RelatedObjects ?? []) c.set(l(p), u);
352
+ });
353
+ const T = /* @__PURE__ */ new Map(), U = (a) => {
354
+ const u = l(a);
355
+ if (u < 0) return "";
356
+ const p = T.get(u);
357
+ if (p !== void 0) return p;
358
+ const A = y(u);
359
+ let S = B(A?.Name);
360
+ if (!S && A)
361
+ for (const C of ["ForLayerSet", "MaterialLayers", "Materials", "MaterialConstituents", "MaterialProfiles"]) {
362
+ const M = A[C], E = Array.isArray(M) ? M[0] : M;
363
+ if (!E) continue;
364
+ const V = y(l(E));
365
+ if (S = B(V?.Name) || B(V?.LayerSetName) || i(V?.Material), S) break;
366
+ }
367
+ return T.set(u, S), S;
368
+ };
369
+ h(Xt, (a) => {
370
+ const u = U(a.RelatingMaterial);
371
+ for (const p of a.RelatedObjects ?? []) f.set(l(p), u);
372
+ });
373
+ const $ = /* @__PURE__ */ new Map(), D = (a) => {
374
+ const u = l(a);
375
+ if (u < 0) return 0;
376
+ const p = $.get(u);
377
+ if (p !== void 0) return p;
378
+ const A = y(u);
379
+ let S = 0;
380
+ for (const C of A?.Quantities ?? []) {
381
+ const M = y(l(C));
382
+ if (B(M?.Name) === "NetVolume") {
383
+ S = Number(B(M?.VolumeValue)) || 0;
384
+ break;
385
+ }
386
+ }
387
+ return $.set(u, S), S;
388
+ };
389
+ return h(qt, (a) => {
390
+ const u = D(a.RelatingPropertyDefinition);
391
+ if (u)
392
+ for (const p of a.RelatedObjects ?? []) d.set(l(p), u);
393
+ }), { container: o, spatialPath: n, typePath: s, systemPath: r, classificationPath: c, material: f, volume: d };
394
+ }
395
+ const vt = 30, we = 5e3, Ie = 15e4;
396
+ function Me(t, e) {
397
+ return `${Math.floor(t / vt)},${Math.floor(e / vt)}`;
398
+ }
399
+ function Ae(t, e) {
400
+ const o = /* @__PURE__ */ new Map(), n = (c, f, d) => `${Math.round(c * 1e4) / 1e4},${Math.round(f * 1e4) / 1e4},${Math.round(d * 1e4) / 1e4}`;
401
+ for (const c of t.values()) {
402
+ const { positions: f, indices: d, featureIds: m } = c;
403
+ for (let y = 0; y < d.length; y += 3) {
404
+ const l = d[y], i = d[y + 1], h = d[y + 2], g = f[l * 3], w = f[l * 3 + 1], I = f[l * 3 + 2], R = f[i * 3], L = f[i * 3 + 1], O = f[i * 3 + 2], k = f[h * 3], T = f[h * 3 + 1], U = f[h * 3 + 2], $ = R - g, D = L - w, a = O - I, u = k - g, p = T - w, A = U - I, S = D * A - a * p, C = a * u - $ * A, M = $ * p - D * u, E = Math.hypot(S, C, M);
405
+ if (!E) continue;
406
+ const V = [S / E, C / E, M / E], Q = m[l];
407
+ let tt = o.get(Q);
408
+ tt || o.set(Q, tt = /* @__PURE__ */ new Map());
409
+ const K = n(g, w, I), ot = n(R, L, O), st = n(k, T, U), Y = [[K, ot], [ot, st], [st, K]];
410
+ for (const [H, rt] of Y) {
411
+ const lt = H < rt ? `${H}|${rt}` : `${rt}|${H}`, et = tt.get(lt);
412
+ et ? et.push(V) : tt.set(lt, [V]);
413
+ }
414
+ }
415
+ }
416
+ const s = Math.cos(e * Math.PI / 180), r = [];
417
+ for (const [c, f] of o) {
418
+ const d = [];
419
+ for (const [l, i] of f)
420
+ if (i.length === 1) d.push(l);
421
+ else if (i.length >= 2) {
422
+ const [h, g] = i;
423
+ Math.abs(h[0] * g[0] + h[1] * g[1] + h[2] * g[2]) < s && d.push(l);
424
+ }
425
+ const m = /* @__PURE__ */ new Map();
426
+ for (const l of d) {
427
+ const [i, h] = l.split("|");
428
+ (m.get(i) ?? m.set(i, []).get(i)).push(h), (m.get(h) ?? m.set(h, []).get(h)).push(i);
429
+ }
430
+ const y = new Set(d);
431
+ for (; y.size; ) {
432
+ const l = y.values().next().value;
433
+ y.delete(l);
434
+ const i = l.split("|");
435
+ for (const h of [!0, !1])
436
+ for (; ; ) {
437
+ const g = h ? i[0] : i[i.length - 1];
438
+ let w = null;
439
+ for (const I of m.get(g) ?? []) {
440
+ const R = g < I ? `${g}|${I}` : `${I}|${g}`;
441
+ if (y.has(R)) {
442
+ y.delete(R), w = I;
443
+ break;
444
+ }
445
+ }
446
+ if (!w) break;
447
+ h ? i.unshift(w) : i.push(w);
448
+ }
449
+ r.push([c, i.map((h) => h.split(",").map(Number))]);
450
+ }
451
+ }
452
+ return r;
453
+ }
454
+ class Vt {
455
+ parts = [];
456
+ offset = 0;
457
+ bufferViews = [];
458
+ accessors = [];
459
+ view(e, o) {
460
+ const n = (4 - this.offset % 4) % 4;
461
+ n && (this.parts.push(new Uint8Array(n)), this.offset += n);
462
+ const s = this.bufferViews.length;
463
+ return this.bufferViews.push({ buffer: 0, byteOffset: this.offset, byteLength: e.byteLength, ...o ? { target: o } : {} }), this.parts.push(e), this.offset += e.byteLength, s;
464
+ }
465
+ floats(e, o) {
466
+ const n = Float32Array.from(e), r = {
467
+ bufferView: this.view(new Uint8Array(n.buffer), 34962),
468
+ componentType: 5126,
469
+ count: n.length / o,
470
+ type: o === 3 ? "VEC3" : "SCALAR"
471
+ };
472
+ if (o === 3) {
473
+ const c = [1 / 0, 1 / 0, 1 / 0], f = [-1 / 0, -1 / 0, -1 / 0];
474
+ for (let d = 0; d < n.length; d += 3)
475
+ for (let m = 0; m < 3; m++)
476
+ n[d + m] < c[m] && (c[m] = n[d + m]), n[d + m] > f[m] && (f[m] = n[d + m]);
477
+ r.min = c, r.max = f;
478
+ }
479
+ return this.accessors.push(r), this.accessors.length - 1;
480
+ }
481
+ indices(e) {
482
+ const o = Uint32Array.from(e), n = this.view(new Uint8Array(o.buffer), 34963);
483
+ return this.accessors.push({ bufferView: n, componentType: 5125, count: o.length, type: "SCALAR" }), this.accessors.length - 1;
484
+ }
485
+ raw(e) {
486
+ return this.view(e);
487
+ }
488
+ binary() {
489
+ const e = this.parts.reduce((s, r) => s + r.byteLength, 0), o = new Uint8Array(e);
490
+ let n = 0;
491
+ for (const s of this.parts)
492
+ o.set(s, n), n += s.byteLength;
493
+ return o;
494
+ }
495
+ }
496
+ function xe(t) {
497
+ const e = new TextEncoder(), o = t.map((c) => e.encode(c ?? "")), n = new Uint8Array(o.reduce((c, f) => c + f.length, 0)), s = new Uint32Array(t.length + 1);
498
+ let r = 0;
499
+ return o.forEach((c, f) => {
500
+ s[f] = r, n.set(c, r), r += c.length;
501
+ }), s[t.length] = r, { blob: n, offsets: new Uint8Array(s.buffer) };
502
+ }
503
+ function Gt(t, e, o) {
504
+ const n = new Vt(), s = [], r = [];
505
+ for (const i of e.values()) {
506
+ const h = n.floats(i.positions, 3), g = n.floats(i.normals, 3), w = n.floats(i.featureIds, 1), I = n.indices(i.indices), [R, L, O, k] = i.colour;
507
+ s.push({
508
+ name: i.label,
509
+ doubleSided: !0,
510
+ ...k < 1 ? { alphaMode: "BLEND" } : {},
511
+ pbrMetallicRoughness: { baseColorFactor: [R, L, O, k], metallicFactor: 0, roughnessFactor: 0.85 }
512
+ }), r.push({
513
+ name: i.label,
514
+ primitives: [
515
+ {
516
+ attributes: { POSITION: h, NORMAL: g, _FEATURE_ID_0: w },
517
+ indices: I,
518
+ material: s.length - 1,
519
+ mode: 4,
520
+ extensions: { EXT_mesh_features: { featureIds: [{ attribute: 0, propertyTable: 0 }] } }
521
+ }
522
+ ]
523
+ });
524
+ }
525
+ const c = {}, f = {}, m = ["spatialPath", "typePath", "systemPath", "classificationPath"].filter((i) => t.some((h) => h[i]));
526
+ for (const i of ["ifcClass", "name", "material", "container", ...m]) {
527
+ const { blob: h, offsets: g } = xe(t.map((w) => w[i]));
528
+ f[i] = { values: n.raw(h), stringOffsets: n.raw(g) }, c[i] = { name: i, type: "STRING" };
529
+ }
530
+ const y = Float32Array.from(t.map((i) => i.netVolume || 0));
531
+ return f.netVolume = { values: n.raw(new Uint8Array(y.buffer)) }, c.netVolume = { name: "netVolume", type: "SCALAR", componentType: "FLOAT32" }, ["bboxMinE", "bboxMinN", "bboxMinU", "bboxMaxE", "bboxMaxN", "bboxMaxU"].forEach((i, h) => {
532
+ const g = Float32Array.from(t.map((w, I) => {
533
+ const R = o[I]?.[h];
534
+ return Number.isFinite(R) ? R : 0;
535
+ }));
536
+ f[i] = { values: n.raw(new Uint8Array(g.buffer)) }, c[i] = { name: i, type: "SCALAR", componentType: "FLOAT32" };
537
+ }), zt(n, r, s, {
538
+ extensionsUsed: ["EXT_mesh_features", "EXT_structural_metadata"],
539
+ extensions: {
540
+ EXT_structural_metadata: {
541
+ schema: { id: "ifcSchema", classes: { ifcElement: { name: "IFC element", properties: c } } },
542
+ propertyTables: [{ name: "elements", class: "ifcElement", count: t.length, properties: f }]
543
+ }
544
+ }
545
+ });
546
+ }
547
+ function zt(t, e, o, n = {}) {
548
+ const s = t.binary(), r = {
549
+ asset: { version: "2.0", generator: "onlymapjs web-ifc loader" },
550
+ ...n,
551
+ scene: 0,
552
+ scenes: [{ nodes: e.map((w, I) => I) }],
553
+ nodes: e.map((w, I) => ({ mesh: I, name: w.name })),
554
+ meshes: e,
555
+ materials: o,
556
+ accessors: t.accessors,
557
+ bufferViews: t.bufferViews,
558
+ buffers: [{ byteLength: s.byteLength }]
559
+ }, c = new TextEncoder().encode(JSON.stringify(r)), f = (w, I, R) => {
560
+ const L = (4 - I.byteLength % 4) % 4, O = new Uint8Array(8), k = new DataView(O.buffer);
561
+ return k.setUint32(0, I.byteLength + L, !0), k.setUint32(4, w, !0), [O, I, new Uint8Array(L).fill(R)];
562
+ }, d = f(1313821514, c, 32), m = f(5130562, s, 0), y = new Uint8Array(12), l = new DataView(y.buffer);
563
+ l.setUint32(0, 1179937895, !0), l.setUint32(4, 2, !0);
564
+ const i = 12 + [...d, ...m].reduce((w, I) => w + I.byteLength, 0);
565
+ l.setUint32(8, i, !0);
566
+ const h = new Uint8Array(i);
567
+ let g = 0;
568
+ for (const w of [y, ...d, ...m])
569
+ h.set(w, g), g += w.byteLength;
570
+ return h;
571
+ }
572
+ async function Ee(t) {
573
+ const e = /* @__PURE__ */ new Map();
574
+ for (const s of t.values()) {
575
+ const r = s.colour.join(",");
576
+ let c = e.get(r);
577
+ c || e.set(r, c = { vertexCount: 0, indexCount: 0, colour: s.colour }), c.vertexCount += s.positions.length / 3, c.indexCount += s.indices.length;
578
+ }
579
+ const o = /* @__PURE__ */ new Map();
580
+ for (const [s, r] of e)
581
+ o.set(s, {
582
+ positions: new Float32Array(r.vertexCount * 3),
583
+ indices: new Uint32Array(r.indexCount),
584
+ colour: r.colour,
585
+ vertexOffset: 0,
586
+ indexOffset: 0
587
+ });
588
+ let n = 0;
589
+ for (const s of t.values()) {
590
+ n++, n % 50 === 0 && await new Promise((d) => setTimeout(d));
591
+ const r = s.colour.join(","), c = o.get(r), f = c.vertexOffset;
592
+ c.positions.set(s.positions, f * 3);
593
+ for (let d = 0; d < s.indices.length; d++) c.indices[c.indexOffset + d] = s.indices[d] + f;
594
+ c.vertexOffset += s.positions.length / 3, c.indexOffset += s.indices.length;
595
+ }
596
+ return o;
597
+ }
598
+ const Se = vt * 3, Ce = 8, Re = 900, Te = 0.93;
599
+ async function ve(t, e) {
600
+ const { MeshoptSimplifier: o } = await import("./meshopt_simplifier-Co6uRDDA.js");
601
+ await o.ready;
602
+ const n = await Ee(t), s = [...n.values()].reduce((l, i) => l + i.indices.length / 3, 0), r = new Vt(), c = [], f = [];
603
+ let d = 0;
604
+ const m = n.size;
605
+ for (const l of n.values()) {
606
+ d++, e(`Building coarse level of detail… ${d}/${m}`), await new Promise((M) => setTimeout(M));
607
+ const i = l.indices.length / 3;
608
+ if (!i) continue;
609
+ const h = s ? i / s : 0, g = Math.max(1, Math.round(Ie * h)), w = Math.min(l.indices.length, g * 3), I = l.positions, R = l.indices, [L] = o.simplify(R, I, 3, w, 0.2, ["Prune"]), O = [...new Set(L)], k = new Map(O.map((M, E) => [M, E])), T = new Float32Array(O.length * 3);
610
+ for (let M = 0; M < O.length; M++) {
611
+ const E = O[M];
612
+ T[M * 3] = I[E * 3], T[M * 3 + 1] = I[E * 3 + 1], T[M * 3 + 2] = I[E * 3 + 2];
613
+ }
614
+ const U = Uint32Array.from(L, (M) => k.get(M)), $ = new Float32Array(T.length);
615
+ for (let M = 0; M < U.length; M += 3) {
616
+ const [E, V, Q] = [U[M], U[M + 1], U[M + 2]], tt = (et) => [T[et * 3], T[et * 3 + 1], T[et * 3 + 2]], [K, ot, st] = [tt(E), tt(V), tt(Q)], Y = [ot[0] - K[0], ot[1] - K[1], ot[2] - K[2]], H = [st[0] - K[0], st[1] - K[1], st[2] - K[2]], rt = [Y[1] * H[2] - Y[2] * H[1], Y[2] * H[0] - Y[0] * H[2], Y[0] * H[1] - Y[1] * H[0]], lt = Math.hypot(...rt) || 1;
617
+ for (const et of [E, V, Q]) for (let b = 0; b < 3; b++) $[et * 3 + b] = rt[b] / lt;
618
+ }
619
+ const D = r.floats(Array.from(T), 3), a = r.floats(Array.from($), 3), u = r.indices(Array.from(U)), [p, A, S, C] = l.colour;
620
+ c.push({
621
+ name: `lod-${c.length}`,
622
+ doubleSided: !0,
623
+ ...C < 1 ? { alphaMode: "BLEND" } : {},
624
+ pbrMetallicRoughness: { baseColorFactor: [p, A, S, C], metallicFactor: 0, roughnessFactor: 0.85 }
625
+ }), f.push({
626
+ name: `lod-${f.length}`,
627
+ primitives: [{ attributes: { POSITION: D, NORMAL: a }, indices: u, material: c.length - 1, mode: 4 }]
628
+ });
629
+ }
630
+ const y = Ce * Se * Te / Re;
631
+ return { glb: zt(r, f, c), geometricError: y };
632
+ }
633
+ function Oe(t, e) {
634
+ const o = t * Math.PI / 180, n = e * Math.PI / 180, [s, r, c, f] = [Math.sin(o), Math.cos(o), Math.sin(n), Math.cos(n)], d = At / Math.sqrt(1 - Z * c * c);
635
+ return {
636
+ east: [-s, r, 0],
637
+ north: [-c * r, -c * s, f],
638
+ up: [f * r, f * s, c],
639
+ origin: [d * f * r, d * f * s, d * (1 - Z) * c]
640
+ };
641
+ }
642
+ async function Ne(t, e = {}) {
643
+ const { onProgress: o = () => {
644
+ }, fallbackLonLat: n = [-122.41, 37.8], edges: s = !0, creaseDegrees: r = 25 } = e, c = t instanceof Blob ? await t.arrayBuffer() : t, f = c instanceof Uint8Array ? c : new Uint8Array(c), d = {};
645
+ let m = performance.now();
646
+ const y = (h) => {
647
+ d[h] = Math.round(performance.now() - m), m = performance.now();
648
+ };
649
+ o("Starting web-ifc…");
650
+ const l = await le();
651
+ y("boot");
652
+ const i = l.OpenModel(f, { COORDINATE_TO_ORIGIN: !1 });
653
+ try {
654
+ y("open"), o("Indexing relationships…");
655
+ const h = be(l, i);
656
+ y("relationships");
657
+ const g = await ye(l, i, n), { georeferenced: w, heading: I, scale: R, headingSource: L, affine: O, hasOrthogonalHeight: k } = g;
658
+ let T = g.lonLat, U = g.originSource;
659
+ o("Reading geometry…");
660
+ const $ = l.LoadAllGeometry(i);
661
+ y("loadAllGeometry");
662
+ const D = [];
663
+ for (let b = 0; b < $.size(); b++) {
664
+ const x = $.get(b), _ = [];
665
+ for (let G = 0; G < x.geometries.size(); G++) {
666
+ const W = x.geometries.get(G);
667
+ _.push({
668
+ id: W.geometryExpressID,
669
+ colour: [W.color.x, W.color.y, W.color.z, W.color.w],
670
+ matrix: Array.from(W.flatTransformation)
671
+ });
672
+ }
673
+ D.push({ expressID: x.expressID, placed: _ });
674
+ }
675
+ const a = [], u = /* @__PURE__ */ new Map(), p = [1 / 0, 1 / 0, 1 / 0], A = [-1 / 0, -1 / 0, -1 / 0], S = [];
676
+ let C = 0;
677
+ const M = D.length > we;
678
+ for (let b = 0; b < D.length; b++) {
679
+ const x = D[b], _ = a.length;
680
+ let G = "IfcProduct", W = "";
681
+ try {
682
+ G = l.GetNameFromTypeCode(l.GetLineType(i, x.expressID)) || G, W = B(l.GetLine(i, x.expressID, !1).Name);
683
+ } catch {
684
+ }
685
+ a.push({
686
+ ifcClass: G,
687
+ name: W,
688
+ material: h.material.get(x.expressID) ?? "",
689
+ container: h.container.get(x.expressID) ?? "",
690
+ spatialPath: h.spatialPath.get(x.expressID) ?? "",
691
+ typePath: h.typePath.get(x.expressID) ?? "",
692
+ systemPath: h.systemPath.get(x.expressID) ?? "",
693
+ classificationPath: h.classificationPath.get(x.expressID) ?? "",
694
+ netVolume: h.volume.get(x.expressID) ?? 0
695
+ }), S.push([1 / 0, 1 / 0, 1 / 0, -1 / 0, -1 / 0, -1 / 0]);
696
+ const it = x.placed[0]?.matrix, J = M && it ? Me(it[12], -it[14]) : "";
697
+ for (const X of x.placed) {
698
+ const q = l.GetGeometry(i, X.id), ct = l.GetVertexArray(q.GetVertexData(), q.GetVertexDataSize()), mt = l.GetIndexArray(q.GetIndexData(), q.GetIndexDataSize()), v = X.matrix, ut = X.colour.map((z) => Math.round(z * 1e3) / 1e3).join(","), nt = M ? `${J} ${ut}` : ut;
699
+ let j = u.get(nt);
700
+ j || (j = { positions: [], normals: [], featureIds: [], indices: [], colour: X.colour, label: `colour-${u.size}`, cellKey: J }, u.set(nt, j));
701
+ const xt = j.featureIds.length;
702
+ for (let z = 0; z < ct.length; z += 6) {
703
+ const [ht, dt, pt] = [ct[z], ct[z + 1], ct[z + 2]], yt = v[0] * ht + v[4] * dt + v[8] * pt + v[12], bt = v[1] * ht + v[5] * dt + v[9] * pt + v[13], wt = v[2] * ht + v[6] * dt + v[10] * pt + v[14], [gt, P, N] = [ct[z + 3], ct[z + 4], ct[z + 5]];
704
+ j.positions.push(yt, bt, wt), j.normals.push(v[0] * gt + v[4] * P + v[8] * N, v[1] * gt + v[5] * P + v[9] * N, v[2] * gt + v[6] * P + v[10] * N), j.featureIds.push(_);
705
+ const at = [yt, -wt, bt], It = S[_];
706
+ for (let F = 0; F < 3; F++)
707
+ at[F] < p[F] && (p[F] = at[F]), at[F] > A[F] && (A[F] = at[F]), at[F] < It[F] && (It[F] = at[F]), at[F] > It[F + 3] && (It[F + 3] = at[F]);
708
+ }
709
+ for (let z = 0; z < mt.length; z++) j.indices.push(xt + mt[z]);
710
+ C += ct.length / 6, q.delete();
711
+ }
712
+ (b + 1) % 250 === 0 && (o(`Reading geometry… ${b + 1}/${D.length} elements`), await new Promise((X) => setTimeout(X)));
713
+ }
714
+ if (y("meshes"), !a.length) throw new Error("no geometry found in this IFC");
715
+ if (!C)
716
+ throw new Error(`parsed ${a.length} elements but web-ifc returned no vertices for any of them`);
717
+ const E = e.origin ?? [(p[0] + A[0]) / 2, (p[1] + A[1]) / 2, p[2]];
718
+ for (const b of u.values()) {
719
+ const x = b.positions;
720
+ for (let _ = 0; _ < x.length; _ += 3)
721
+ x[_] -= E[0], x[_ + 1] -= E[2], x[_ + 2] += E[1];
722
+ }
723
+ for (const b of S)
724
+ for (let x = 0; x < 3; x++)
725
+ b[x] -= E[x], b[x + 3] -= E[x];
726
+ for (let b = 0; b < 3; b++)
727
+ p[b] -= E[b], A[b] -= E[b];
728
+ if (O?.code != null) {
729
+ const b = await me(O, E[0], E[1]);
730
+ b ? T = b : U === "map-conversion" && (U = "ifc-site", console.warn(
731
+ `[onlymap] IfcMapConversion into EPSG:${O.code} was read but its anchor could not be re-projected at the model centre — the position may be off by the model's origin-to-centre distance. Placement is flagged approximate; set the layer's site-origin to correct it.`
732
+ ));
733
+ }
734
+ const V = Oe(T[0], T[1]), Q = [...V.east, 0, ...V.north, 0, ...V.up, 0, ...V.origin, 1];
735
+ o("Building tiles…");
736
+ const tt = [];
737
+ let K = 0;
738
+ const ot = (b, x) => {
739
+ K += b.byteLength;
740
+ const _ = `${URL.createObjectURL(new Blob([b], { type: "model/gltf-binary" }))}#${x}`;
741
+ return tt.push(_), _;
742
+ }, st = Math.max(...[0, 1, 2].map((b) => A[b] - p[b])) * 0.75 || 25, Y = [0, 0, 0, st, 0, 0, 0, st, 0, 0, 0, st];
743
+ let H;
744
+ if (M) {
745
+ const { glb: b, geometricError: x } = await ve(u, o), _ = ot(b, "lod-root.glb");
746
+ y("lodRoot");
747
+ const G = /* @__PURE__ */ new Map();
748
+ for (const [J, X] of u) {
749
+ let q = G.get(X.cellKey);
750
+ q || G.set(X.cellKey, q = /* @__PURE__ */ new Map()), q.set(J, X);
751
+ }
752
+ const W = [], it = [...G.values()];
753
+ for (let J = 0; J < it.length; J++) {
754
+ o(`Building spatial tiles… ${J + 1}/${it.length}`), await new Promise((P) => setTimeout(P));
755
+ const X = it[J], q = [...new Set([...X.values()].flatMap((P) => P.featureIds))].sort((P, N) => P - N), ct = new Map(q.map((P, N) => [P, N])), mt = q.map((P) => a[P]), v = q.map((P) => S[P]), ut = /* @__PURE__ */ new Map();
756
+ for (const [P, N] of X)
757
+ ut.set(P, { ...N, featureIds: N.featureIds.map((at) => ct.get(at)) });
758
+ const nt = [1 / 0, 1 / 0, 1 / 0], j = [-1 / 0, -1 / 0, -1 / 0];
759
+ for (const P of v)
760
+ for (let N = 0; N < 3; N++)
761
+ P[N] < nt[N] && (nt[N] = P[N]), P[N + 3] > j[N] && (j[N] = P[N + 3]);
762
+ const xt = (nt[0] + j[0]) / 2, z = (nt[1] + j[1]) / 2, ht = (nt[2] + j[2]) / 2, dt = Math.max((j[0] - nt[0]) / 2, 0.5), pt = Math.max((j[1] - nt[1]) / 2, 0.5), yt = Math.max((j[2] - nt[2]) / 2, 0.5), bt = [xt, z, ht, dt, 0, 0, 0, pt, 0, 0, 0, yt], wt = Gt(mt, ut, v), gt = ot(wt, `cell-${J}.glb`);
763
+ W.push({ boundingVolume: { box: bt }, geometricError: 0, content: { uri: gt } });
764
+ }
765
+ y("glb"), H = {
766
+ asset: { version: "1.1" },
767
+ geometricError: x,
768
+ root: {
769
+ boundingVolume: { box: Y },
770
+ geometricError: x,
771
+ refine: "REPLACE",
772
+ transform: Q,
773
+ content: { uri: _ },
774
+ children: W
775
+ }
776
+ };
777
+ } else {
778
+ const b = Gt(a, u, S);
779
+ y("glb");
780
+ const x = ot(b, "model.glb");
781
+ H = {
782
+ asset: { version: "1.1" },
783
+ geometricError: 512,
784
+ root: {
785
+ boundingVolume: { box: Y },
786
+ geometricError: 512,
787
+ refine: "ADD",
788
+ transform: Q,
789
+ // Absolute blob URL on purpose: a relative content path has no
790
+ // meaning resolved against a blob: base.
791
+ children: [{ boundingVolume: { box: Y }, geometricError: 0, content: { uri: x } }]
792
+ }
793
+ };
794
+ }
795
+ const rt = `${URL.createObjectURL(new Blob([JSON.stringify(H)], { type: "application/json" }))}#tileset.json`;
796
+ let lt = null, et = 0;
797
+ if (s) {
798
+ o("Tracing outlines…"), await new Promise((x) => setTimeout(x));
799
+ const b = Ae(u, r).map(([x, _]) => {
800
+ const G = a[x];
801
+ return {
802
+ // Local east/north/up METRES from the model's own anchor, NOT
803
+ // lon/lat. Geographic coordinates would nail the outlines to
804
+ // whatever position the file was parsed at, so `site-origin` and
805
+ // `site-heading` could move the mesh and leave its edges behind.
806
+ // METER_OFFSETS places these from the layer's `site-origin`, the
807
+ // same point the tileset is anchored at. Buckets are glTF Y-up —
808
+ // (east, up, -north) — hence the shuffle. Millimetre rounding is
809
+ // finer than any IFC tolerance and meaningfully cheaper to
810
+ // stringify across a six-figure point count.
811
+ path: _.map(([W, it, J]) => [
812
+ // Bucket positions were shifted by `origin` before the GLB was
813
+ // built, so they are ALREADY tile-local — subtracting again here
814
+ // would move the outlines off the mesh by exactly one origin.
815
+ Math.round(W * 1e3) / 1e3,
816
+ Math.round(-J * 1e3) / 1e3,
817
+ Math.round(it * 1e3) / 1e3
818
+ ]),
819
+ // The same category fields the mesh filters on, so one visible-value
820
+ // set can drive both the mesh and its outline overlay.
821
+ ifcClass: G.ifcClass,
822
+ material: G.material,
823
+ container: G.container,
824
+ spatialPath: G.spatialPath,
825
+ typePath: G.typePath,
826
+ systemPath: G.systemPath,
827
+ classificationPath: G.classificationPath
828
+ };
829
+ });
830
+ et = b.length, lt = URL.createObjectURL(new Blob([JSON.stringify(b)], { type: "application/json" })), y("edges");
831
+ }
832
+ return {
833
+ tilesetUrl: rt,
834
+ edgesUrl: lt,
835
+ loadOptions: { "3d-tiles": { isTileset: !0 }, gltf: { loadBuffers: !0 } },
836
+ features: a,
837
+ lonLat: T,
838
+ georeferenced: w,
839
+ origin: E,
840
+ heading: I,
841
+ scale: R,
842
+ headingSource: L,
843
+ originSource: U,
844
+ // See correctOrthogonalHeightForRecentring's doc comment. `centre[2]`
845
+ // is still the model's ORIGINAL, pre-recentre local height at the
846
+ // point that becomes the tile origin — never mutated, only `lo`/`hi`
847
+ // are.
848
+ orthogonalHeight: k ? he(O.orthogonalHeight, E[2]) : void 0,
849
+ stats: { elements: a.length, primitives: u.size, polylines: et, bytes: K },
850
+ timings: d,
851
+ bounds: { lo: p, hi: A, centre: E },
852
+ revoke() {
853
+ for (const b of [...tt, rt, lt])
854
+ b && URL.revokeObjectURL(b.split("#")[0]);
855
+ }
856
+ };
857
+ } finally {
858
+ l.CloseModel(i);
859
+ }
860
+ }
861
+ export {
862
+ we as GRID_TILING_THRESHOLD,
863
+ Et as SPATIAL_SEPARATOR,
864
+ ue as buildMapConversionAffine,
865
+ Pt as compoundAngleToDegrees,
866
+ Pe as configureIfc,
867
+ he as correctOrthogonalHeightForRecentring,
868
+ Me as gridCellKey,
869
+ Ne as loadIfc,
870
+ fe as mapConversionApply,
871
+ jt as parseUtmCrs,
872
+ ce as pinnedWebIfcSha256,
873
+ ye as readGeoreference,
874
+ me as reanchorMapConversion,
875
+ ge as utmGridConvergence,
876
+ Dt as utmToLonLat
877
+ };