baselode 0.1.18 → 0.1.20

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.
@@ -0,0 +1,2307 @@
1
+ import * as f from "three";
2
+ import { OrbitControls as it } from "three/examples/jsm/controls/OrbitControls";
3
+ import { FlyControls as st } from "three/examples/jsm/controls/FlyControls";
4
+ import { ViewportGizmo as at } from "three-viewport-gizmo";
5
+ import { EffectComposer as lt } from "three/examples/jsm/postprocessing/EffectComposer.js";
6
+ import { RenderPass as ct } from "three/examples/jsm/postprocessing/RenderPass.js";
7
+ import { OutlinePass as ut } from "three/examples/jsm/postprocessing/OutlinePass.js";
8
+ import mt from "papaparse";
9
+ const ar = "datasource", H = "hole_id", dt = "_collar_id", we = "datasource_hole_id", lr = "hole_type", cr = "max_depth", ur = "surface_sample_id", ft = "surface_sample_type", ht = "datasource_surface_sample_id", xe = "project_id", bt = "report_number", ue = "latitude", me = "longitude", de = "elevation", fe = "easting", he = "northing", be = "crs", mr = "date_start", dr = "date_end", W = "azimuth", K = "dip", fr = "survey_type", pt = "sample_id", hr = "datasource_sample_id", ne = "from", Q = "to", pe = "mid", ge = "depth", gt = "strike", Fe = "alpha", ve = "beta", Ce = "geology_code", Ie = "geology_description", yt = "comments", G = "extra", br = -999.25, pr = -999.25, gr = {
10
+ // A unique hole identifier across the entire dataset and all future data sets
11
+ [H]: "string",
12
+ // The hole ID from the original collar source
13
+ [we]: "string",
14
+ // The project ID or project code from the original collar source, if available
15
+ [xe]: "string",
16
+ // The latitude of the collar, in decimal degrees (WGS84)
17
+ [ue]: "number",
18
+ // The longitude of the collar, in decimal degrees (WGS84)
19
+ [me]: "number",
20
+ // The elevation of the collar, in meters above sea level (WGS84)
21
+ [de]: "number",
22
+ // The easting coordinate of the collar, in meters (projected CRS)
23
+ [fe]: "number",
24
+ // The northing coordinate of the collar, in meters (projected CRS)
25
+ [he]: "number",
26
+ // The coordinate reference system of the collar coordinates for easting/northing,
27
+ // as an EPSG code or proj string
28
+ [be]: "string",
29
+ // Internal join key used by source schemas (e.g. raw_gswa) — distinct from
30
+ // the public hole_id.
31
+ [dt]: "string",
32
+ // Per-row dict of source-specific fields outside the canonical schema
33
+ // (populated by `bundleExtras`; empty object when the source had nothing extra).
34
+ [G]: "object"
35
+ }, yr = {
36
+ // The unique hole id that maps to the collar and any other data tables
37
+ [H]: "string",
38
+ // The depth along the hole where the survey measurement was taken / started
39
+ [ge]: "number",
40
+ // The depth along the hole where the survey measurement ended, if applicable
41
+ // (some surveys are point measurements and may not have a 'to' depth)
42
+ [Q]: "number",
43
+ // The azimuth of the hole at the survey depth, in degrees from north
44
+ [W]: "number",
45
+ // The dip of the hole at the survey depth, in degrees from horizontal
46
+ // (negative values indicate downward inclination)
47
+ [K]: "number",
48
+ // Per-row dict of source-specific fields outside the canonical schema.
49
+ [G]: "object"
50
+ }, _r = {
51
+ // The unique hole id that maps to the collar and any other data tables
52
+ [H]: "string",
53
+ // The depth along the hole where the assay interval starts
54
+ [ne]: "number",
55
+ // The depth along the hole where the assay interval ends
56
+ [Q]: "number",
57
+ // The midpoint depth of the assay interval
58
+ [pe]: "number",
59
+ // assay value columns are variable and not standardized here.
60
+ // Assays may be flattened (one column per assay type) or long
61
+ // (one row per assay type with an additional 'assay_type' column).
62
+ // Per-row dict of source-specific fields outside the canonical schema
63
+ // (sample identifiers, lab metadata, detection-limit flags, etc.).
64
+ [G]: "object"
65
+ }, Mr = {
66
+ [H]: "string",
67
+ [ne]: "number",
68
+ [Q]: "number",
69
+ [pe]: "number",
70
+ [Ce]: "string",
71
+ [Ie]: "string",
72
+ // Per-row dict of source-specific fields outside the canonical schema.
73
+ [G]: "object"
74
+ }, Er = {
75
+ [H]: "string",
76
+ [ge]: "number",
77
+ [K]: "number",
78
+ [W]: "number",
79
+ [Fe]: "number",
80
+ [ve]: "number",
81
+ [yt]: "string",
82
+ // Per-row dict of source-specific fields outside the canonical schema.
83
+ [G]: "object"
84
+ }, zr = {
85
+ [H]: "string",
86
+ [ne]: "number",
87
+ [Q]: "number",
88
+ [pe]: "number",
89
+ // value columns are variable — not standardized here
90
+ // Per-row dict of source-specific fields outside the canonical schema.
91
+ [G]: "object"
92
+ }, Nr = {
93
+ [pt]: "string",
94
+ [ht]: "string",
95
+ [bt]: "string",
96
+ [ue]: "number",
97
+ [me]: "number",
98
+ [de]: "number",
99
+ [fe]: "number",
100
+ [he]: "number",
101
+ [be]: "string",
102
+ [ft]: "string",
103
+ // Per-row dict of source-specific fields outside the canonical schema
104
+ // (analyte values, lab metadata, detection-limit flags, anumber, ...).
105
+ [G]: "object"
106
+ }, _t = {
107
+ [H]: ["hole_id", "holeid", "hole id", "hole-id"],
108
+ [we]: ["datasource_hole_id", "datasourceholeid", "datasource hole id", "datasource-hole-id", "company_hole_id", "companyholeid", "company hole id", "company-hole-id"],
109
+ [xe]: ["project_id", "projectid", "project id", "project-id", "project_code", "projectcode", "project code", "project-code", "companyId", "company_id", "companyid", "company id", "company-id", "dataset", "project"],
110
+ [ue]: ["latitude", "lat"],
111
+ [me]: ["longitude", "lon"],
112
+ [de]: ["elevation", "rl", "elev", "z"],
113
+ [fe]: ["easting", "x"],
114
+ [he]: ["northing", "y"],
115
+ [be]: ["crs", "epsg", "projection"],
116
+ [ne]: ["from", "depth_from", "from_depth", "samp_from", "sample_from", "sampfrom", "fromdepth"],
117
+ [Q]: ["to", "depth_to", "to_depth", "samp_to", "sample_to", "sampto", "todepth"],
118
+ [Ce]: [
119
+ "geology_code",
120
+ "geologycode",
121
+ "lith1",
122
+ "lith1code",
123
+ "lith1_code",
124
+ "lithology",
125
+ "plot_lithology",
126
+ "rock1"
127
+ ],
128
+ [Ie]: [
129
+ "geology_description",
130
+ "geologydescription",
131
+ "geology_comment",
132
+ "geologycomment",
133
+ "geology comment",
134
+ "lithology_comment",
135
+ "lithology comment",
136
+ "description",
137
+ "comments"
138
+ ],
139
+ [W]: ["azimuth", "az", "dip_direction", "dipdir", "dip direction", "dipdrn", "dipdirection", "dip_dir", "computed_plane_azimuth", "calc_dipdir", "calc_dipdir_deg", "dipdir_calc", "dipdirect_calc"],
140
+ [K]: ["dip", "computed_plane_dip", "calc_dip", "calc_dip_deg", "dip_calc"],
141
+ [Fe]: ["alpha", "alpha_angle", "alpha_angle_deg", "alpha_2"],
142
+ [ve]: ["beta", "beta_angle", "beta_angle_deg", "beta_2"],
143
+ declination: ["declination", "dec"],
144
+ [ge]: ["depth", "survey_depth", "surveydepth", "md", "measured_depth", "dept"],
145
+ [gt]: ["strike", "str"]
146
+ }, Mt = {};
147
+ for (const [e, t] of Object.entries(_t))
148
+ for (const n of t) {
149
+ const r = n.toLowerCase().trim();
150
+ Mt[r] = e;
151
+ }
152
+ const ie = "[baselode:data]";
153
+ function Et(e, t = "Unknown error") {
154
+ if (e instanceof Error) return e;
155
+ const n = typeof e == "string" && e.trim() ? e : t;
156
+ return new Error(n);
157
+ }
158
+ function se(e, t, n = "Operation failed") {
159
+ const r = Et(t, n), o = new Error(`${e}: ${r.message}`);
160
+ return o.cause = r, o;
161
+ }
162
+ function Or(e, t) {
163
+ if (t !== void 0) {
164
+ console.warn(`${ie} ${e}`, t);
165
+ return;
166
+ }
167
+ console.warn(`${ie} ${e}`);
168
+ }
169
+ function kr(e) {
170
+ console.info(`${ie} ${e}`);
171
+ }
172
+ const J = "numeric", ae = "categorical", le = "comment", ee = "hidden", zt = "tadpole", ze = {
173
+ [J]: [
174
+ { value: "bar", label: "Bars" },
175
+ { value: "markers", label: "Markers" },
176
+ { value: "markers+line", label: "Markers + Line" },
177
+ { value: "line", label: "Line only" }
178
+ ],
179
+ [ae]: [
180
+ { value: "categorical", label: "Categorical bands" }
181
+ ],
182
+ [le]: [
183
+ { value: "comment", label: "Comments" }
184
+ ],
185
+ [zt]: [
186
+ { value: "tadpole", label: "Tadpole" }
187
+ ],
188
+ [ee]: []
189
+ }, Ne = /* @__PURE__ */ new Set([
190
+ // Hole identifiers
191
+ "hole_id",
192
+ "holeid",
193
+ "id",
194
+ "holetype",
195
+ "datasource_hole_id",
196
+ "anumber",
197
+ "collarid",
198
+ "companyholeid",
199
+ "company_hole_id",
200
+ "company_id",
201
+ // Project codes
202
+ "project_id",
203
+ "project_code",
204
+ "project",
205
+ "projectcode",
206
+ "projectid",
207
+ // Geographic coordinates
208
+ "latitude",
209
+ "longitude",
210
+ "lat",
211
+ "lon",
212
+ "lng",
213
+ "easting",
214
+ "northing",
215
+ "x",
216
+ "y",
217
+ "z",
218
+ "elevation",
219
+ "elev",
220
+ "rl",
221
+ // Depth / interval columns
222
+ "from",
223
+ "to",
224
+ "mid",
225
+ "depth",
226
+ "md",
227
+ "samp_from",
228
+ "samp_to",
229
+ "sample_from",
230
+ "sample_to",
231
+ "depth_from",
232
+ "depth_to",
233
+ "fromdepth",
234
+ "todepth",
235
+ // Geometry / CRS
236
+ "shape",
237
+ "geometry",
238
+ "crs",
239
+ "epsg",
240
+ // Internal / synthetic columns
241
+ "data_source",
242
+ "_hole_key",
243
+ "_hole_id_key"
244
+ ]), Nt = /* @__PURE__ */ new Set([
245
+ "comments",
246
+ "comment",
247
+ "notes",
248
+ "note",
249
+ "description",
250
+ "remarks",
251
+ "remark",
252
+ "log_description",
253
+ "struct_comment",
254
+ "structcomment",
255
+ "geology_description"
256
+ ]);
257
+ function Ar(e) {
258
+ if (!(e != null && e.length))
259
+ return { byType: {}, numericCols: [], categoricalCols: [], commentCols: [] };
260
+ const t = new Set(e.flatMap((r) => Object.keys(r || {}))), n = {};
261
+ for (const r of t) {
262
+ const o = r.toLowerCase().trim();
263
+ if (Ne.has(o) || Ne.has(r)) {
264
+ n[r] = ee;
265
+ continue;
266
+ }
267
+ if (Nt.has(o)) {
268
+ const c = e.some((l) => {
269
+ const s = l[r];
270
+ return s != null && String(s).trim() !== "" && String(s) !== "null";
271
+ });
272
+ n[r] = c ? le : ee;
273
+ continue;
274
+ }
275
+ let i = !1, a = !1;
276
+ for (const c of e) {
277
+ const l = c[r];
278
+ if (!(l == null || typeof l == "string" && l.trim() === "") && (a = !0, typeof l == "number" && Number.isFinite(l))) {
279
+ i = !0;
280
+ break;
281
+ }
282
+ }
283
+ a ? i ? n[r] = J : n[r] = ae : n[r] = ee;
284
+ }
285
+ return {
286
+ byType: n,
287
+ numericCols: Object.entries(n).filter(([, r]) => r === J).map(([r]) => r),
288
+ categoricalCols: Object.entries(n).filter(([, r]) => r === ae).map(([r]) => r),
289
+ commentCols: Object.entries(n).filter(([, r]) => r === le).map(([r]) => r)
290
+ };
291
+ }
292
+ function Ot(e) {
293
+ return ze[e] ?? ze[J];
294
+ }
295
+ function Lr(e) {
296
+ const t = Ot(e);
297
+ return t.length ? e === J ? "line" : t[0].value : "markers+line";
298
+ }
299
+ const Te = ["x", "y", "z", "dx", "dy", "dz"], kt = {
300
+ x: ["x", "easting", "center_x", "xc", "xcentre", "xcenter", "x_centre", "x_center", "cx"],
301
+ y: ["y", "northing", "center_y", "yc", "ycentre", "ycenter", "y_centre", "y_center", "cy"],
302
+ z: ["z", "elevation", "center_z", "zc", "zcentre", "zcenter", "z_centre", "z_center", "cz"],
303
+ dx: ["dx", "size_x", "sx", "sizex", "dim_x", "block_size_x"],
304
+ dy: ["dy", "size_y", "sy", "sizey", "dim_y", "block_size_y"],
305
+ dz: ["dz", "size_z", "sz", "sizez", "dim_z", "block_size_z"]
306
+ }, Be = {};
307
+ Object.entries(kt).forEach(([e, t]) => {
308
+ t.forEach((n) => {
309
+ Be[n.toLowerCase()] = e;
310
+ });
311
+ });
312
+ function At(e) {
313
+ const t = {};
314
+ return Object.entries(e).forEach(([n, r]) => {
315
+ const o = Be[n.toLowerCase().trim()] || n;
316
+ t[o] = r;
317
+ }), t;
318
+ }
319
+ function Dr(e) {
320
+ return new Promise((t, n) => {
321
+ mt.parse(e, {
322
+ header: !0,
323
+ dynamicTyping: !0,
324
+ skipEmptyLines: !0,
325
+ complete: (r) => {
326
+ const i = (r.data || []).map(At).filter(
327
+ (c) => c.x !== null && c.y !== null && c.z !== null
328
+ ), a = Object.keys(i[0] || {}).filter(
329
+ (c) => !Te.includes(c)
330
+ );
331
+ t({ data: i, properties: a });
332
+ },
333
+ error: (r) => {
334
+ n(se("parseBlockModelCSV", r));
335
+ }
336
+ });
337
+ });
338
+ }
339
+ function Sr(e) {
340
+ if (typeof e == "string")
341
+ try {
342
+ return JSON.parse(e);
343
+ } catch (t) {
344
+ throw se("loadBlockModelMetadata", t);
345
+ }
346
+ if (e && typeof e == "object") return e;
347
+ throw se("loadBlockModelMetadata", new Error("Invalid metadata source"));
348
+ }
349
+ function Lt(e, t) {
350
+ const n = e.map((i) => i[t]).filter((i) => i != null);
351
+ if (n.length > 0 && n.every((i) => typeof i == "number")) {
352
+ const i = Math.min(...n), a = Math.max(...n);
353
+ return { type: "numeric", min: i, max: a, values: n };
354
+ }
355
+ return { type: "categorical", categories: [...new Set(n)], values: n };
356
+ }
357
+ function wr(e) {
358
+ if (!e || e.length === 0) return {};
359
+ const t = Object.keys(e[0]).filter(
360
+ (r) => !Te.includes(r)
361
+ ), n = {};
362
+ return t.forEach((r) => {
363
+ n[r] = Lt(e, r);
364
+ }), n;
365
+ }
366
+ function Dt(e, t) {
367
+ return !t || typeof t != "object" ? e : e.filter(
368
+ (n) => Object.entries(t).every(([r, o]) => {
369
+ const i = n[r];
370
+ return o == null ? !0 : typeof o != "object" || Array.isArray(o) ? i === o : !("gt" in o && !(i > o.gt) || "gte" in o && !(i >= o.gte) || "lt" in o && !(i < o.lt) || "lte" in o && !(i <= o.lte) || "eq" in o && i !== o.eq || "ne" in o && i === o.ne || "in" in o && !o.in.includes(i));
371
+ })
372
+ );
373
+ }
374
+ function xr(e, t = null) {
375
+ return (t ? Dt(e, t) : e).reduce((r, o) => {
376
+ const i = Number(o.dx) || 0, a = Number(o.dy) || 0, c = Number(o.dz) || 0;
377
+ return r + i * a * c;
378
+ }, 0);
379
+ }
380
+ function St(e, t, n) {
381
+ if (!t) return new n.Color("#888888");
382
+ if (t.type === "numeric") {
383
+ const i = t.max - t.min, c = (1 - (i === 0 ? 0.5 : (e - t.min) / i)) * 240;
384
+ return new n.Color().setHSL(c / 360, 0.8, 0.5);
385
+ }
386
+ const o = t.categories.indexOf(e) / Math.max(t.categories.length, 1) * 360;
387
+ return new n.Color().setHSL(o / 360, 0.7, 0.5);
388
+ }
389
+ function wt(e, t) {
390
+ if (!e || e.length === 0 || !Number.isFinite(t)) return null;
391
+ const n = e.length;
392
+ if (n === 1) {
393
+ const b = e[0];
394
+ return { x: Number(b.x), y: Number(b.y), z: Number(b.z), dx: 0, dy: 0, dz: -1 };
395
+ }
396
+ let r = -1;
397
+ for (let b = 0; b < n - 1; b++) {
398
+ const A = Number(e[b].md), y = Number(e[b + 1].md);
399
+ if (t >= A && t <= y) {
400
+ r = b;
401
+ break;
402
+ }
403
+ }
404
+ let o, i, a;
405
+ if (r === -1) {
406
+ t < Number(e[0].md) ? (o = e[0], i = e[1]) : (o = e[n - 2], i = e[n - 1]);
407
+ const b = Number(o.md), y = Number(i.md) - b;
408
+ a = y > 0 ? (t - b) / y : t < b ? 0 : 1;
409
+ } else {
410
+ o = e[r], i = e[r + 1];
411
+ const b = Number(o.md), y = Number(i.md) - b;
412
+ a = y > 0 ? (t - b) / y : 0;
413
+ }
414
+ const c = Number(o.x) + a * (Number(i.x) - Number(o.x)), l = Number(o.y) + a * (Number(i.y) - Number(o.y)), s = Number(o.z) + a * (Number(i.z) - Number(o.z));
415
+ let u, p, m;
416
+ const h = Number(o.azimuth), d = Number(o.dip), g = Number(i.azimuth), N = Number(i.dip);
417
+ if (Number.isFinite(h) && Number.isFinite(d)) {
418
+ const b = Number.isFinite(g) && Number.isFinite(N) ? h + a * (g - h) : h, A = Number.isFinite(g) && Number.isFinite(N) ? d + a * (N - d) : d, y = b * Math.PI / 180, E = A * Math.PI / 180;
419
+ u = Math.cos(E) * Math.sin(y), p = Math.cos(E) * Math.cos(y), m = -Math.sin(E);
420
+ } else {
421
+ const b = Number(i.x) - Number(o.x), A = Number(i.y) - Number(o.y), y = Number(i.z) - Number(o.z), E = Math.sqrt(b * b + A * A + y * y);
422
+ if (E < 1e-10) return { x: c, y: l, z: s, dx: 0, dy: 0, dz: -1 };
423
+ u = b / E, p = A / E, m = y / E;
424
+ }
425
+ const O = Math.sqrt(u * u + p * p + m * m);
426
+ return O < 1e-10 ? { x: c, y: l, z: s, dx: 0, dy: 0, dz: -1 } : { x: c, y: l, z: s, dx: u / O, dy: p / O, dz: m / O };
427
+ }
428
+ function xt(e, t, n, r = {}) {
429
+ const { betaZeroAxis: o = "B", betaHandedness: i = 1 } = r, { dx: a, dy: c, dz: l } = n, s = [a, c, l];
430
+ let u = [0, 0, 1];
431
+ const p = s[0] * u[0] + s[1] * u[1] + s[2] * u[2];
432
+ Math.abs(p) > 0.99 && (u = [0, 1, 0]);
433
+ const m = [
434
+ u[1] * s[2] - u[2] * s[1],
435
+ u[2] * s[0] - u[0] * s[2],
436
+ u[0] * s[1] - u[1] * s[0]
437
+ ], h = Math.sqrt(m[0] ** 2 + m[1] ** 2 + m[2] ** 2), d = h > 1e-10 ? [m[0] / h, m[1] / h, m[2] / h] : [1, 0, 0], g = [
438
+ s[1] * d[2] - s[2] * d[1],
439
+ s[2] * d[0] - s[0] * d[2],
440
+ s[0] * d[1] - s[1] * d[0]
441
+ ], N = Math.sqrt(g[0] ** 2 + g[1] ** 2 + g[2] ** 2), O = N > 1e-10 ? [g[0] / N, g[1] / N, g[2] / N] : [0, 1, 0], b = o === "R" ? d : O, A = t * Math.PI / 180 * i, y = Math.cos(A), E = Math.sin(A), k = b[0] * s[0] + b[1] * s[1] + b[2] * s[2], D = [
442
+ s[1] * b[2] - s[2] * b[1],
443
+ s[2] * b[0] - s[0] * b[2],
444
+ s[0] * b[1] - s[1] * b[0]
445
+ ], w = [
446
+ b[0] * y + D[0] * E + s[0] * k * (1 - y),
447
+ b[1] * y + D[1] * E + s[1] * k * (1 - y),
448
+ b[2] * y + D[2] * E + s[2] * k * (1 - y)
449
+ ], L = (90 - e) * Math.PI / 180, x = Math.cos(L), S = Math.sin(L), v = x * w[0] + S * s[0], I = x * w[1] + S * s[1], C = x * w[2] + S * s[2], B = Math.sqrt(v * v + I * I + C * C);
450
+ return B < 1e-10 ? { nx: 0, ny: 0, nz: 1 } : { nx: v / B, ny: I / B, nz: C / B };
451
+ }
452
+ function Ft(e, t, n = {}) {
453
+ if (!(e != null && e.length) || !(t != null && t.length)) return [];
454
+ const r = /* @__PURE__ */ new Map();
455
+ for (const i of t) {
456
+ const a = i.hole_id != null ? `${i.hole_id}`.trim().toLowerCase() : "";
457
+ a && (r.has(a) || r.set(a, []), r.get(a).push(i));
458
+ }
459
+ for (const [, i] of r)
460
+ i.sort((a, c) => Number(a.md) - Number(c.md));
461
+ const o = [];
462
+ for (const i of e) {
463
+ const a = i.hole_id != null ? `${i.hole_id}`.trim().toLowerCase() : "";
464
+ if (!a) continue;
465
+ const c = r.get(a);
466
+ if (!c || c.length === 0) continue;
467
+ const l = i.depth != null ? Number(i.depth) : i.mid != null ? Number(i.mid) : null;
468
+ if (!Number.isFinite(l)) continue;
469
+ const s = wt(c, l);
470
+ if (!s) continue;
471
+ const { x: u, y: p, z: m, dx: h, dy: d, dz: g } = s;
472
+ let N, O, b;
473
+ const A = i.alpha != null ? Number(i.alpha) : null, y = i.beta != null ? Number(i.beta) : null;
474
+ if (Number.isFinite(A)) {
475
+ const E = Number.isFinite(y) ? y : 0, k = xt(A, E, { dx: h, dy: d, dz: g }, n);
476
+ N = k.nx, O = k.ny, b = k.nz;
477
+ } else {
478
+ const E = i.dip != null ? Number(i.dip) : null, k = i.azimuth != null ? Number(i.azimuth) : null;
479
+ if (!Number.isFinite(E) || !Number.isFinite(k)) continue;
480
+ const D = E * Math.PI / 180, w = k * Math.PI / 180;
481
+ N = Math.sin(w) * Math.sin(D), O = Math.cos(w) * Math.sin(D), b = Math.cos(D);
482
+ }
483
+ o.push({ ...i, x: u, y: p, z: m, nx: N, ny: O, nz: b });
484
+ }
485
+ return o;
486
+ }
487
+ const vt = "baselode", Fr = vt, Ct = [
488
+ "#8b1e3f",
489
+ "#2563eb",
490
+ "#16a34a",
491
+ "#f59e0b",
492
+ "#7c3aed",
493
+ "#0ea5e9",
494
+ "#ef4444",
495
+ "#10b981",
496
+ "#f97316",
497
+ "#8b5cf6"
498
+ ], M = {
499
+ bg: "#ffffff",
500
+ panel: "#f8fafc",
501
+ ink: "#1e293b",
502
+ ink_soft: "#64748b",
503
+ grid: "#e8e8e8",
504
+ line: "#d0d0d0",
505
+ accent: "#f59e0b",
506
+ accent_2: "#fcd34d",
507
+ muted_1: "#94a3b8",
508
+ muted_2: "#cbd5e1",
509
+ muted_3: "#e2e8f0",
510
+ primary: "#8b1e3f",
511
+ primary_2: "#a8324f"
512
+ }, ye = {
513
+ layout: {
514
+ paper_bgcolor: M.bg,
515
+ plot_bgcolor: M.bg,
516
+ colorway: Ct,
517
+ font: {
518
+ family: "Inter, system-ui, sans-serif",
519
+ size: 12,
520
+ color: M.ink
521
+ },
522
+ title: {
523
+ font: { size: 14, color: M.ink },
524
+ x: 0.05
525
+ },
526
+ hovermode: "x unified",
527
+ hoverlabel: {
528
+ bgcolor: M.bg,
529
+ bordercolor: M.line,
530
+ font: { size: 12, color: M.ink }
531
+ },
532
+ legend: {
533
+ bgcolor: "rgba(255,255,255,0.9)",
534
+ bordercolor: M.muted_3,
535
+ borderwidth: 1,
536
+ font: { size: 11, color: M.ink },
537
+ orientation: "h",
538
+ yanchor: "bottom",
539
+ y: 1.02,
540
+ xanchor: "left",
541
+ x: 0
542
+ },
543
+ xaxis: {
544
+ showline: !0,
545
+ linewidth: 1,
546
+ linecolor: M.line,
547
+ mirror: !1,
548
+ ticks: "outside",
549
+ tickwidth: 1,
550
+ tickcolor: M.line,
551
+ ticklen: 4,
552
+ showgrid: !0,
553
+ gridcolor: M.grid,
554
+ gridwidth: 1,
555
+ zeroline: !1,
556
+ title_font: { color: M.ink, size: 12 },
557
+ tickfont: { color: M.ink_soft, size: 10 }
558
+ },
559
+ yaxis: {
560
+ showline: !0,
561
+ linewidth: 1,
562
+ linecolor: M.line,
563
+ mirror: !1,
564
+ ticks: "outside",
565
+ tickwidth: 1,
566
+ tickcolor: M.line,
567
+ ticklen: 4,
568
+ showgrid: !0,
569
+ gridcolor: M.grid,
570
+ gridwidth: 1,
571
+ zeroline: !1,
572
+ title_font: { color: M.ink, size: 12 },
573
+ tickfont: { color: M.ink_soft, size: 10 }
574
+ },
575
+ modebar: {
576
+ remove: ["select2d", "lasso2d", "autoScale2d"]
577
+ },
578
+ bargap: 0.18,
579
+ bargroupgap: 0.08
580
+ },
581
+ data: {
582
+ scatter: [{
583
+ mode: "lines+markers",
584
+ line: { width: 2, color: M.primary },
585
+ marker: {
586
+ size: 7,
587
+ color: M.primary_2,
588
+ line: { width: 1.5, color: M.bg }
589
+ }
590
+ }],
591
+ bar: [{
592
+ marker: {
593
+ color: M.primary,
594
+ line: { color: M.bg, width: 0 }
595
+ }
596
+ }],
597
+ histogram: [{
598
+ marker: {
599
+ color: M.primary,
600
+ line: { color: M.bg, width: 0 }
601
+ }
602
+ }],
603
+ box: [{
604
+ fillcolor: M.accent,
605
+ line: { color: M.ink, width: 1.5 },
606
+ marker: { color: M.ink }
607
+ }],
608
+ violin: [{
609
+ fillcolor: M.accent,
610
+ line: { color: M.ink, width: 1.5 },
611
+ marker: { color: M.ink }
612
+ }],
613
+ heatmap: [{
614
+ colorscale: [
615
+ [0, "#ffffff"],
616
+ [0.2, "#f1f5f9"],
617
+ [0.4, "#cbd5e1"],
618
+ [0.6, "#94a3b8"],
619
+ [0.8, "#475569"],
620
+ [1, "#1e293b"]
621
+ ],
622
+ colorbar: {
623
+ outlinecolor: M.line,
624
+ tickcolor: M.line,
625
+ tickfont: { color: M.ink_soft }
626
+ }
627
+ }],
628
+ contour: [{
629
+ colorscale: [
630
+ [0, "#ffffff"],
631
+ [0.25, "#fef3c7"],
632
+ [0.5, "#f59e0b"],
633
+ [0.75, "#92400e"],
634
+ [1, "#1e293b"]
635
+ ],
636
+ colorbar: {
637
+ outlinecolor: M.line,
638
+ tickcolor: M.line,
639
+ tickfont: { color: M.ink_soft }
640
+ }
641
+ }]
642
+ }
643
+ }, vr = ye, _ = {
644
+ bg: "#1b1b1f",
645
+ panel: "#25252a",
646
+ ink: "#f0f0e4",
647
+ ink_soft: "#c8c8b8",
648
+ grid: "#2a2a26",
649
+ line: "#3a3a34",
650
+ accent: "#ffffbb",
651
+ accent_2: "#f3ef9b",
652
+ muted_1: "#8a8a80",
653
+ muted_2: "#5e5e56",
654
+ muted_3: "#3a3a34"
655
+ }, Cr = "baselode-dark", Ir = {
656
+ layout: {
657
+ font: {
658
+ family: "Inter, Arial, sans-serif",
659
+ color: _.ink,
660
+ size: 14
661
+ },
662
+ title: {
663
+ x: 0.02,
664
+ xanchor: "left",
665
+ font: {
666
+ family: "Inter, Arial, sans-serif",
667
+ size: 22,
668
+ color: _.ink
669
+ }
670
+ },
671
+ paper_bgcolor: _.bg,
672
+ plot_bgcolor: _.bg,
673
+ colorway: [
674
+ _.ink,
675
+ _.accent,
676
+ _.muted_1,
677
+ _.accent_2,
678
+ _.muted_2,
679
+ _.muted_3
680
+ ],
681
+ margin: { l: 70, r: 30, t: 70, b: 60 },
682
+ hovermode: "x unified",
683
+ hoverlabel: {
684
+ bgcolor: _.panel,
685
+ bordercolor: _.accent,
686
+ font: {
687
+ family: "Inter, Arial, sans-serif",
688
+ color: _.ink,
689
+ size: 13
690
+ }
691
+ },
692
+ legend: {
693
+ bgcolor: "rgba(37,37,42,0.88)",
694
+ bordercolor: _.line,
695
+ borderwidth: 1,
696
+ font: {
697
+ family: "Inter, Arial, sans-serif",
698
+ color: _.ink,
699
+ size: 12
700
+ },
701
+ orientation: "h",
702
+ yanchor: "bottom",
703
+ y: 1.02,
704
+ xanchor: "left",
705
+ x: 0
706
+ },
707
+ xaxis: {
708
+ showline: !1,
709
+ ticks: "outside",
710
+ tickwidth: 1,
711
+ tickcolor: _.muted_1,
712
+ ticklen: 6,
713
+ showgrid: !0,
714
+ gridcolor: _.grid,
715
+ gridwidth: 1,
716
+ zeroline: !1,
717
+ title_font: { color: _.ink },
718
+ tickfont: { color: _.ink_soft }
719
+ },
720
+ yaxis: {
721
+ showline: !1,
722
+ ticks: "outside",
723
+ tickwidth: 1,
724
+ tickcolor: _.muted_1,
725
+ ticklen: 6,
726
+ showgrid: !0,
727
+ gridcolor: _.grid,
728
+ gridwidth: 1,
729
+ zeroline: !1,
730
+ title_font: { color: _.ink },
731
+ tickfont: { color: _.ink_soft }
732
+ },
733
+ bargap: 0.18,
734
+ bargroupgap: 0.08
735
+ },
736
+ data: {
737
+ scatter: [{
738
+ mode: "lines+markers",
739
+ line: { width: 2.5, color: _.ink },
740
+ marker: {
741
+ size: 7,
742
+ color: _.ink,
743
+ line: { width: 1.5, color: _.bg }
744
+ }
745
+ }],
746
+ bar: [{
747
+ marker: {
748
+ color: _.ink,
749
+ line: { color: _.bg, width: 0 }
750
+ }
751
+ }],
752
+ histogram: [{
753
+ marker: {
754
+ color: _.ink,
755
+ line: { color: _.bg, width: 0 }
756
+ }
757
+ }],
758
+ box: [{
759
+ fillcolor: _.accent,
760
+ line: { color: _.ink, width: 1.5 },
761
+ marker: { color: _.ink }
762
+ }],
763
+ violin: [{
764
+ fillcolor: _.accent,
765
+ line: { color: _.ink, width: 1.5 },
766
+ marker: { color: _.ink }
767
+ }],
768
+ heatmap: [{
769
+ colorscale: [
770
+ [0, "#1b1b1f"],
771
+ [0.2, "#2e2e28"],
772
+ [0.4, "#5e5e50"],
773
+ [0.6, "#c8c89a"],
774
+ [0.8, "#f3ef9b"],
775
+ [1, "#ffffbb"]
776
+ ],
777
+ colorbar: {
778
+ outlinecolor: _.ink,
779
+ tickcolor: _.ink,
780
+ tickfont: { color: _.ink_soft }
781
+ }
782
+ }],
783
+ contour: [{
784
+ colorscale: [
785
+ [0, "#1b1b1f"],
786
+ [0.25, "#2e2e28"],
787
+ [0.5, "#6b6b50"],
788
+ [0.75, "#f3ef9b"],
789
+ [1, "#ffffbb"]
790
+ ],
791
+ colorbar: {
792
+ outlinecolor: _.ink,
793
+ tickcolor: _.ink,
794
+ tickfont: { color: _.ink_soft }
795
+ }
796
+ }]
797
+ }
798
+ }, It = "#7f7f7f", te = {
799
+ Au: "#FFD700",
800
+ // gold
801
+ Ag: "#C0C0C0",
802
+ // silver
803
+ Cu: "#B87333",
804
+ // copper / orange-brown
805
+ Fe: "#8B4513",
806
+ // iron / rusty brown
807
+ Ni: "#4CAF50",
808
+ // nickel / green
809
+ Zn: "#78909C",
810
+ // zinc / blue-grey
811
+ Pb: "#607D8B",
812
+ // lead / slate
813
+ Mo: "#9C27B0",
814
+ // molybdenite / purple
815
+ Co: "#2196F3",
816
+ // cobalt / blue
817
+ Li: "#FF5722",
818
+ // lithium / deep orange
819
+ Mn: "#795548",
820
+ // manganese / brown
821
+ Cr: "#009688",
822
+ // chromium / teal
823
+ V: "#673AB7",
824
+ // vanadium / deep purple
825
+ W: "#FF9800",
826
+ // tungsten / amber
827
+ Sn: "#9E9E9E",
828
+ // tin / medium grey
829
+ Ti: "#00BCD4",
830
+ // titanium / cyan
831
+ Al: "#FFEB3B",
832
+ // aluminium / yellow
833
+ U: "#8BC34A"
834
+ // uranium / lime green
835
+ }, Tt = {
836
+ // Sedimentary
837
+ shale: "#607D8B",
838
+ mudstone: "#78909C",
839
+ siltstone: "#90A4AE",
840
+ sandstone: "#F5CBA7",
841
+ limestone: "#B0BEC5",
842
+ dolomite: "#CFD8DC",
843
+ conglomerate: "#D7CCC8",
844
+ coal: "#212121",
845
+ // Iron-formation
846
+ BIF: "#8B4513",
847
+ ironstone: "#A0522D",
848
+ // Igneous – intrusive
849
+ granite: "#EF9A9A",
850
+ granodiorite: "#F48FB1",
851
+ diorite: "#CE93D8",
852
+ gabbro: "#546E7A",
853
+ peridotite: "#33691E",
854
+ pegmatite: "#FFF9C4",
855
+ // Igneous – extrusive / volcanic
856
+ basalt: "#37474F",
857
+ andesite: "#78909C",
858
+ rhyolite: "#FFCCBC",
859
+ dacite: "#FFAB91",
860
+ tuff: "#D7CCC8",
861
+ breccia: "#BCAAA4",
862
+ // Metamorphic
863
+ schist: "#80CBC4",
864
+ gneiss: "#4DB6AC",
865
+ quartzite: "#E0F7FA",
866
+ marble: "#F5F5F5",
867
+ slate: "#455A64",
868
+ phyllite: "#80DEEA",
869
+ // Other
870
+ quartz: "#ECEFF1",
871
+ calcite: "#F9FBE7",
872
+ vein: "#FFFFFF",
873
+ unknown: "#9E9E9E"
874
+ }, re = {
875
+ commodity: te,
876
+ lithology: Tt
877
+ };
878
+ function Bt(e, t, n = It) {
879
+ if (!t || e == null) return n;
880
+ const r = String(e).trim();
881
+ if (Object.prototype.hasOwnProperty.call(t, r)) return t[r];
882
+ const o = r.toLowerCase();
883
+ for (const [i, a] of Object.entries(t))
884
+ if (String(i).trim().toLowerCase() === o) return a;
885
+ return n;
886
+ }
887
+ function Pt(e) {
888
+ if (e == null) return {};
889
+ if (typeof e == "string") {
890
+ const t = e.trim().toLowerCase();
891
+ if (Object.prototype.hasOwnProperty.call(re, t))
892
+ return re[t];
893
+ const n = Object.keys(re).sort().join(", ");
894
+ throw new RangeError(
895
+ `Unknown built-in colour map '${e}'. Available maps: ${n}`
896
+ );
897
+ }
898
+ if (typeof e == "object" && Object.getPrototypeOf(e) === Object.prototype) return e;
899
+ throw new TypeError(
900
+ `colourMap must be null, a string, or a plain object; got ${Array.isArray(e) ? "Array" : Object.prototype.toString.call(e)}`
901
+ );
902
+ }
903
+ const Rt = "#8b1e3f", Vt = "#a8324f";
904
+ function Ht(e) {
905
+ if (!e) return null;
906
+ const t = e.split(/[_\-/\s]+/);
907
+ for (const n of t) {
908
+ if (Object.prototype.hasOwnProperty.call(te, n))
909
+ return te[n];
910
+ const r = n.toLowerCase();
911
+ for (const [o, i] of Object.entries(te))
912
+ if (o.toLowerCase() === r) return i;
913
+ }
914
+ return null;
915
+ }
916
+ const Gt = "#6b7280", jt = { l: 42, r: 4, t: 4, b: 30 }, Oe = 10, ke = 12;
917
+ function Ae(e) {
918
+ return e ? typeof e == "string" ? { text: e } : e : {};
919
+ }
920
+ function Pe(e = {}) {
921
+ const t = Ae(e.xaxis && e.xaxis.title), n = Ae(e.yaxis && e.yaxis.title);
922
+ return {
923
+ ...e,
924
+ margin: jt,
925
+ autosize: !0,
926
+ width: void 0,
927
+ xaxis: {
928
+ ...e.xaxis || {},
929
+ tickfont: {
930
+ ...e.xaxis && e.xaxis.tickfont || {},
931
+ size: Oe
932
+ },
933
+ title: {
934
+ ...t,
935
+ font: { ...t.font || {}, size: ke }
936
+ }
937
+ },
938
+ yaxis: {
939
+ ...e.yaxis || {},
940
+ automargin: !0,
941
+ tickfont: {
942
+ ...e.yaxis && e.yaxis.tickfont || {},
943
+ size: Oe
944
+ },
945
+ title: {
946
+ ...n,
947
+ font: { ...n.font || {}, size: ke }
948
+ }
949
+ }
950
+ };
951
+ }
952
+ function Tr(e, t) {
953
+ var r;
954
+ if (!e || !t) return !1;
955
+ const n = e.points || [];
956
+ for (let o = 0; o < n.length; o += 1) {
957
+ const i = (r = n[o]) == null ? void 0 : r[t];
958
+ if (i != null && (typeof i == "number" && Number.isFinite(i) || typeof i == "string" && i.trim() !== ""))
959
+ return !0;
960
+ }
961
+ return !1;
962
+ }
963
+ function Br(e, t, n) {
964
+ if (!e || !t) return [];
965
+ const r = (e == null ? void 0 : e.points) || [], o = [], i = /* @__PURE__ */ new Set();
966
+ return r.forEach((a) => {
967
+ let c = Number(
968
+ a.from ?? a.samp_from ?? a.sample_from ?? a.fromdepth ?? a.from_depth ?? a.depth_from
969
+ ), l = Number(
970
+ a.to ?? a.samp_to ?? a.sample_to ?? a.todepth ?? a.to_depth ?? a.depth_to
971
+ );
972
+ if (!Number.isFinite(c) || !Number.isFinite(l)) {
973
+ const h = Number(a.depth ?? a.md);
974
+ Number.isFinite(h) && (c = h, l = h);
975
+ }
976
+ const s = a == null ? void 0 : a[t];
977
+ if (!Number.isFinite(c) || !Number.isFinite(l) || l < c || s == null || s === "" || n && typeof s == "string" && /^(nan|null|none)$/i.test(s.trim())) return;
978
+ const u = `${t}:${c}-${l}:${String(s)}`;
979
+ if (i.has(u)) return;
980
+ i.add(u);
981
+ const p = (c + l) / 2, m = n ? s : Number(s);
982
+ !n && !Number.isFinite(m) || o.push({
983
+ z: p,
984
+ val: m,
985
+ from: c,
986
+ to: l,
987
+ errorPlus: l - p,
988
+ errorMinus: p - c
989
+ });
990
+ }), o.sort((a, c) => c.z - a.z);
991
+ }
992
+ function Ut(e, t, n, r) {
993
+ if (!e.length) return { data: [], layout: {} };
994
+ const o = e.filter((m) => Number.isFinite(m == null ? void 0 : m.from) && Number.isFinite(m == null ? void 0 : m.to) && m.to > m.from).map((m) => ({ ...m, category: `${(m == null ? void 0 : m.val) ?? ""}`.trim() })).filter((m) => m.category !== "" && !/^(nan|null|none)$/i.test(m.category)).sort((m, h) => m.from - h.from || m.to - h.to);
995
+ if (!o.length) return { data: [], layout: {} };
996
+ const i = Pt(n), a = [
997
+ "#1f77b4",
998
+ // blue
999
+ "#ff7f0e",
1000
+ // orange
1001
+ "#2ca02c",
1002
+ // green
1003
+ "#d62728",
1004
+ // red
1005
+ "#9467bd",
1006
+ // purple
1007
+ "#17becf",
1008
+ // cyan
1009
+ "#bcbd22",
1010
+ // olive
1011
+ "#e377c2",
1012
+ // pink
1013
+ "#8c564b",
1014
+ // brown
1015
+ "#393b79",
1016
+ // indigo
1017
+ "#e6550d",
1018
+ // deep orange
1019
+ "#31a354",
1020
+ // deep green
1021
+ "#756bb1",
1022
+ // violet
1023
+ "#636363"
1024
+ // dark gray
1025
+ ], c = [...new Set(o.map((m) => m.category))];
1026
+ function l(m, h) {
1027
+ if (i && Object.keys(i).length > 0) {
1028
+ const d = Bt(m, i, null);
1029
+ if (d !== null) return d;
1030
+ }
1031
+ return a[h % a.length];
1032
+ }
1033
+ const s = new Map(
1034
+ c.map((m, h) => [m, l(m, h)])
1035
+ );
1036
+ return { data: c.map((m) => {
1037
+ const h = o.filter((d) => d.category === m);
1038
+ return {
1039
+ type: "bar",
1040
+ x: h.map(() => 0.5),
1041
+ y: h.map((d) => d.to - d.from),
1042
+ base: h.map((d) => d.from),
1043
+ width: 1,
1044
+ marker: { color: s.get(m), line: { width: 0 } },
1045
+ name: m,
1046
+ showlegend: !1,
1047
+ customdata: h.map((d) => [d.from, d.to]),
1048
+ hovertemplate: `${t}: ${m}<br>from: %{customdata[0]:.3f} to: %{customdata[1]:.3f}<extra></extra>`
1049
+ };
1050
+ }), layout: Pe({
1051
+ barmode: "overlay",
1052
+ bargap: 0,
1053
+ xaxis: { range: [0, 1], visible: !1, fixedrange: !0 },
1054
+ yaxis: { title: "Depth (m)", autorange: "reversed", zeroline: !1 },
1055
+ showlegend: !1,
1056
+ title: t || void 0,
1057
+ template: r !== void 0 ? r : ye
1058
+ }) };
1059
+ }
1060
+ function Yt(e, t, n, r, o) {
1061
+ if (!e.length) return { data: [], layout: {} };
1062
+ const i = n === "bar", a = n === "markers", c = n === "line", l = r || Rt, s = r || Vt, u = {
1063
+ x: e.map((d) => d.val),
1064
+ y: e.map((d) => d.z),
1065
+ hovertemplate: `${t}: %{x}<br>from: %{customdata[0]:.3f} to: %{customdata[1]:.3f}<extra></extra>`,
1066
+ customdata: e.map((d) => [Math.min(d.from, d.to), Math.max(d.from, d.to)])
1067
+ }, p = {
1068
+ type: "data",
1069
+ symmetric: !1,
1070
+ array: e.map((d) => d.errorPlus),
1071
+ arrayminus: e.map((d) => d.errorMinus),
1072
+ thickness: 1.5,
1073
+ width: 2,
1074
+ color: Gt
1075
+ };
1076
+ return { data: [i ? {
1077
+ ...u,
1078
+ type: "bar",
1079
+ orientation: "h",
1080
+ marker: { color: l },
1081
+ error_y: p
1082
+ } : {
1083
+ ...u,
1084
+ type: "scatter",
1085
+ mode: a ? "markers" : c ? "lines" : "lines+markers",
1086
+ line: { color: l, width: 2 },
1087
+ marker: { size: 7, color: s },
1088
+ error_y: c ? void 0 : p
1089
+ }], layout: Pe({
1090
+ xaxis: { title: t, zeroline: !1 },
1091
+ yaxis: { title: "Depth (m)", autorange: "reversed", zeroline: !1 },
1092
+ barmode: "overlay",
1093
+ showlegend: !1,
1094
+ template: o !== void 0 ? o : ye
1095
+ }) };
1096
+ }
1097
+ function $t({ points: e, isCategorical: t, property: n, chartType: r, colourMap: o, template: i }) {
1098
+ if (!e || !e.length || !n) return { data: [], layout: {} };
1099
+ if (t || r === "categorical")
1100
+ return Ut(e, n, o, i);
1101
+ const a = Ht(n);
1102
+ return Yt(e, n, r, a, i);
1103
+ }
1104
+ function Pr(e = [], {
1105
+ fromCol: t = "from",
1106
+ toCol: n = "to",
1107
+ categoryCol: r = "geology_code",
1108
+ colourMap: o = null,
1109
+ template: i = void 0
1110
+ } = {}) {
1111
+ const a = [];
1112
+ return e.forEach((c) => {
1113
+ const l = Number(c == null ? void 0 : c[t]), s = Number(c == null ? void 0 : c[n]), u = c == null ? void 0 : c[r];
1114
+ if (!Number.isFinite(l) || !Number.isFinite(s) || s <= l || u == null || `${u}`.trim() === "") return;
1115
+ const p = (l + s) / 2;
1116
+ a.push({
1117
+ z: p,
1118
+ val: `${u}`,
1119
+ from: l,
1120
+ to: s,
1121
+ errorPlus: s - p,
1122
+ errorMinus: p - l
1123
+ });
1124
+ }), a.sort((c, l) => l.z - c.z), $t({
1125
+ points: a,
1126
+ isCategorical: !0,
1127
+ property: r,
1128
+ chartType: "categorical",
1129
+ colourMap: o,
1130
+ template: i
1131
+ });
1132
+ }
1133
+ const Xt = [
1134
+ "#313695",
1135
+ "#4575b4",
1136
+ "#74add1",
1137
+ "#abd9e9",
1138
+ "#e0f3f8",
1139
+ "#fee090",
1140
+ "#fdae61",
1141
+ "#f46d43",
1142
+ "#d73027",
1143
+ "#a50026"
1144
+ ];
1145
+ function qt(e = [], t = Xt) {
1146
+ const n = e.filter((s) => Number.isFinite(s));
1147
+ if (!n.length)
1148
+ return {
1149
+ min: null,
1150
+ max: null,
1151
+ step: null,
1152
+ bins: [],
1153
+ colors: t
1154
+ };
1155
+ const r = n.slice().sort((s, u) => s - u), o = r[0], i = r[r.length - 1], a = t.length;
1156
+ if (i === o) {
1157
+ const s = t.map((u, p) => ({
1158
+ index: p,
1159
+ min: o,
1160
+ max: i,
1161
+ label: `${o}`
1162
+ }));
1163
+ return {
1164
+ min: o,
1165
+ max: i,
1166
+ step: 0,
1167
+ bins: s,
1168
+ colors: t
1169
+ };
1170
+ }
1171
+ const c = t.map((s, u) => {
1172
+ const p = u / a, m = (u + 1) / a, h = Math.floor(p * r.length), d = Math.min(r.length - 1, Math.floor(m * r.length)), g = r[h], N = u === a - 1 ? i : r[d];
1173
+ return {
1174
+ index: u,
1175
+ min: g,
1176
+ max: N,
1177
+ label: Zt(g, N)
1178
+ };
1179
+ }), l = (i - o) / a;
1180
+ return {
1181
+ min: o,
1182
+ max: i,
1183
+ step: l,
1184
+ bins: c,
1185
+ colors: t
1186
+ };
1187
+ }
1188
+ function Zt(e, t) {
1189
+ const n = (r) => Number.isFinite(r) ? Math.abs(r) >= 1e3 ? r.toFixed(0) : Math.abs(r) >= 10 ? r.toFixed(1) : Math.abs(r) >= 0.1 ? r.toFixed(2) : r.toFixed(3) : "n/a";
1190
+ return `${n(e)} – ${n(t)}`;
1191
+ }
1192
+ function Re(e, t) {
1193
+ if (!Number.isFinite(e) || !t || !Array.isArray(t.bins) || !t.bins.length)
1194
+ return -1;
1195
+ if (t.max === t.min)
1196
+ return e === t.min ? 0 : -1;
1197
+ for (let n = 0; n < t.bins.length; n += 1) {
1198
+ const r = t.bins[n];
1199
+ if (e >= r.min && (e <= r.max || n === t.bins.length - 1))
1200
+ return n;
1201
+ }
1202
+ return -1;
1203
+ }
1204
+ function Wt(e, t, n = "#8b1e3f") {
1205
+ const r = Re(e, t);
1206
+ return r < 0 ? n : t.colors[r] || n;
1207
+ }
1208
+ function j(e) {
1209
+ e.selectables = [
1210
+ ...e.blocks,
1211
+ ...e.drillMeshes,
1212
+ ...e.structuralMeshes
1213
+ ];
1214
+ }
1215
+ const Kt = {
1216
+ bedding: "#2563eb",
1217
+ foliation: "#16a34a",
1218
+ joint: "#9333ea",
1219
+ fault: "#dc2626",
1220
+ vein: "#f59e0b",
1221
+ "shear zone": "#0ea5e9",
1222
+ "fault zone": "#ef4444"
1223
+ };
1224
+ function Jt(e, t) {
1225
+ const n = t || Kt, r = (e || "").toLowerCase().trim(), o = n[r] || "#888888";
1226
+ return new f.Color(o).getHex();
1227
+ }
1228
+ function Qt(e, t) {
1229
+ const n = e * Math.PI / 180, r = t * Math.PI / 180;
1230
+ return new f.Vector3(
1231
+ Math.sin(r) * Math.sin(n),
1232
+ // East component
1233
+ Math.cos(r) * Math.sin(n),
1234
+ // North component
1235
+ Math.cos(n)
1236
+ // Up component
1237
+ ).normalize();
1238
+ }
1239
+ function en(e, t = {}) {
1240
+ const {
1241
+ radius: n = 5,
1242
+ discThickness: r = 0.2,
1243
+ opacity: o = 0.7,
1244
+ segments: i = 32,
1245
+ colorMap: a = null
1246
+ } = t, c = new f.Group(), l = new f.Vector3(0, 1, 0);
1247
+ for (const s of e) {
1248
+ const u = s.x != null ? s.x : s.easting != null ? s.easting : null, p = s.y != null ? s.y : s.northing != null ? s.northing : null, m = s.z != null ? s.z : s.elevation != null ? s.elevation : null;
1249
+ if (u == null || p == null || m == null || !Number.isFinite(u) || !Number.isFinite(p) || !Number.isFinite(m)) continue;
1250
+ const h = s[K] != null ? Number(s[K]) : null, d = s[W] != null ? Number(s[W]) : null;
1251
+ let g;
1252
+ if (s.nx != null && Number.isFinite(s.nx) && s.ny != null && Number.isFinite(s.ny) && s.nz != null && Number.isFinite(s.nz))
1253
+ g = new f.Vector3(s.nx, s.ny, s.nz).normalize();
1254
+ else {
1255
+ if (h == null || d == null || !Number.isFinite(h) || !Number.isFinite(d)) continue;
1256
+ g = Qt(h, d);
1257
+ }
1258
+ const N = new f.CylinderGeometry(n, n, r, i, 1, !1), O = new f.MeshStandardMaterial({
1259
+ color: Jt(s.structure_type, a),
1260
+ transparent: !0,
1261
+ opacity: o,
1262
+ side: f.DoubleSide
1263
+ }), b = new f.Mesh(N, O);
1264
+ b.position.set(u, p, m), b.quaternion.setFromUnitVectors(l, g), b.userData = {
1265
+ type: "structure",
1266
+ hole_id: s.hole_id,
1267
+ depth: s.depth ?? s.mid,
1268
+ structure_type: s.structure_type,
1269
+ dip: h,
1270
+ azimuth: d,
1271
+ comments: s.comments
1272
+ }, c.add(b);
1273
+ }
1274
+ return c;
1275
+ }
1276
+ function tn(e, t, n, r = {}) {
1277
+ if (!e.scene || (Ve(e), !(t != null && t.length) || !(n != null && n.length))) return;
1278
+ const { maxDiscs: o = 3e3 } = r;
1279
+ let i = t;
1280
+ if (i.length > o) {
1281
+ const l = i.length / o, s = [];
1282
+ for (let u = 0; u < o; u++)
1283
+ s.push(i[Math.floor(u * l)]);
1284
+ i = s;
1285
+ }
1286
+ const a = n.flatMap((l) => (l.points || []).map((s) => ({ ...s, hole_id: l.id }))), c = Ft(i, a, r);
1287
+ c.length && (e.structuralGroup = en(c, r), e.scene.add(e.structuralGroup), e.structuralGroup.traverse((l) => {
1288
+ l.isMesh && e.structuralMeshes.push(l);
1289
+ }), j(e));
1290
+ }
1291
+ function Ve(e) {
1292
+ e.structuralGroup && (e.scene.remove(e.structuralGroup), e.structuralGroup.traverse((t) => {
1293
+ t.isMesh && (t.geometry.dispose(), t.material.dispose());
1294
+ }), e.structuralGroup = null), e.structuralMeshes = [], j(e);
1295
+ }
1296
+ function nn(e, t) {
1297
+ e.structuralGroup && (e.structuralGroup.visible = !!t);
1298
+ }
1299
+ let rn = 0;
1300
+ function on(e) {
1301
+ let t, n, r, o;
1302
+ if ("width" in e || "height" in e || "x" in e && !("maxX" in e)) {
1303
+ const i = Number(e.x ?? 0), a = Number(e.y ?? 0), c = Number(e.width ?? 0), l = Number(e.height ?? 0);
1304
+ t = i, n = a, r = i + c, o = a + l;
1305
+ } else
1306
+ t = Number(e.minX), n = Number(e.minY), r = Number(e.maxX), o = Number(e.maxY);
1307
+ if (r - t <= 0)
1308
+ throw new Error(
1309
+ `Invalid raster bounds: width must be positive (got minX=${t}, maxX=${r})`
1310
+ );
1311
+ if (o - n <= 0)
1312
+ throw new Error(
1313
+ `Invalid raster bounds: height must be positive (got minY=${n}, maxY=${o})`
1314
+ );
1315
+ return { minX: t, minY: n, maxX: r, maxY: o };
1316
+ }
1317
+ function sn(e) {
1318
+ if (e.type === "texture")
1319
+ return Promise.resolve(e.texture);
1320
+ let t, n = !1;
1321
+ if (e.type === "url")
1322
+ t = e.url;
1323
+ else if (e.type === "file")
1324
+ t = URL.createObjectURL(e.file), n = !0;
1325
+ else
1326
+ return Promise.reject(
1327
+ new Error(`Unsupported raster source type: "${e.type}"`)
1328
+ );
1329
+ return new Promise((r, o) => {
1330
+ new f.TextureLoader().load(
1331
+ t,
1332
+ (a) => {
1333
+ n && URL.revokeObjectURL(t), r(a);
1334
+ },
1335
+ void 0,
1336
+ (a) => {
1337
+ n && URL.revokeObjectURL(t), o(
1338
+ new Error(
1339
+ `Failed to load raster texture from "${t}": ${(a == null ? void 0 : a.message) ?? a}`
1340
+ )
1341
+ );
1342
+ }
1343
+ );
1344
+ });
1345
+ }
1346
+ async function Rr(e) {
1347
+ const { source: t, bounds: n, elevation: r = 0, visible: o = !0, renderOrder: i = 0 } = e, a = e.id ?? `raster-overlay-${++rn}`, c = e.name ?? a;
1348
+ let l = e.opacity ?? 1;
1349
+ if ((l < 0 || l > 1) && (console.warn(
1350
+ `[baselode] raster overlay "${a}": opacity ${l} is outside [0, 1] — clamped`
1351
+ ), l = Math.max(0, Math.min(1, l))), !t) throw new Error("raster overlay: options.source is required");
1352
+ if (!n) throw new Error("raster overlay: options.bounds is required");
1353
+ const s = on(n), { minX: u, minY: p, maxX: m, maxY: h } = s, d = m - u, g = h - p, N = (u + m) / 2, O = (p + h) / 2, b = await sn(t), A = new f.PlaneGeometry(d, g), y = new f.MeshBasicMaterial({
1354
+ map: b,
1355
+ transparent: !0,
1356
+ opacity: l,
1357
+ side: f.DoubleSide,
1358
+ depthWrite: !1
1359
+ }), E = new f.Mesh(A, y);
1360
+ return E.position.set(N, O, r), E.renderOrder = i, E.visible = o, { id: a, name: c, mesh: E, texture: b, bounds: s, elevation: r, opacity: l, visible: o };
1361
+ }
1362
+ function an(e, t) {
1363
+ e.scene && (e.rasterOverlays.has(t.id) && _e(e, t.id), e.rasterOverlays.set(t.id, t), e.scene.add(t.mesh));
1364
+ }
1365
+ function _e(e, t) {
1366
+ var r;
1367
+ const n = e.rasterOverlays.get(t);
1368
+ n && ((r = e.scene) == null || r.remove(n.mesh), n.mesh.geometry.dispose(), n.mesh.material.dispose(), n.texture && n.texture.dispose(), e.rasterOverlays.delete(t));
1369
+ }
1370
+ function ln(e, t, n) {
1371
+ const r = e.rasterOverlays.get(t);
1372
+ if (!r) return;
1373
+ const o = Math.max(0, Math.min(1, Number(n)));
1374
+ r.opacity = o, r.mesh.material.opacity = o, r.mesh.material.needsUpdate = !0;
1375
+ }
1376
+ function cn(e, t, n) {
1377
+ const r = e.rasterOverlays.get(t);
1378
+ r && (r.visible = !!n, r.mesh.visible = r.visible);
1379
+ }
1380
+ function un(e, t, n) {
1381
+ const r = e.rasterOverlays.get(t);
1382
+ r && (r.elevation = Number(n), r.mesh.position.setZ(r.elevation));
1383
+ }
1384
+ function mn(e, t) {
1385
+ return e.rasterOverlays.get(t);
1386
+ }
1387
+ function dn(e) {
1388
+ return Array.from(e.rasterOverlays.values());
1389
+ }
1390
+ function fn(e) {
1391
+ for (const t of [...e.rasterOverlays.keys()])
1392
+ _e(e, t);
1393
+ }
1394
+ function Me(e) {
1395
+ var n, r, o, i, a, c, l, s, u;
1396
+ if (!e) return "";
1397
+ const t = (p) => Number.isFinite(p) ? p.toFixed(3) : "nan";
1398
+ return [
1399
+ t((n = e.camera) == null ? void 0 : n.x),
1400
+ t((r = e.camera) == null ? void 0 : r.y),
1401
+ t((o = e.camera) == null ? void 0 : o.z),
1402
+ t((i = e.target) == null ? void 0 : i.x),
1403
+ t((a = e.target) == null ? void 0 : a.y),
1404
+ t((c = e.target) == null ? void 0 : c.z),
1405
+ t((l = e.up) == null ? void 0 : l.x),
1406
+ t((s = e.up) == null ? void 0 : s.y),
1407
+ t((u = e.up) == null ? void 0 : u.z)
1408
+ ].join("|");
1409
+ }
1410
+ function He(e) {
1411
+ return !e.camera || !e.controls ? null : {
1412
+ camera: {
1413
+ x: e.camera.position.x,
1414
+ y: e.camera.position.y,
1415
+ z: e.camera.position.z
1416
+ },
1417
+ target: {
1418
+ x: e.controls.target.x,
1419
+ y: e.controls.target.y,
1420
+ z: e.controls.target.z
1421
+ },
1422
+ up: {
1423
+ x: e.camera.up.x,
1424
+ y: e.camera.up.y,
1425
+ z: e.camera.up.z
1426
+ }
1427
+ };
1428
+ }
1429
+ function hn(e, t) {
1430
+ if (!e.camera || !e.controls || !t) return !1;
1431
+ const n = t.camera || {}, r = t.target || {}, o = t.up || {};
1432
+ return [n.x, n.y, n.z, r.x, r.y, r.z, o.x, o.y, o.z].every(Number.isFinite) ? (e.camera.position.set(n.x, n.y, n.z), e.controls.target.set(r.x, r.y, r.z), e.camera.up.set(o.x, o.y, o.z), e.camera.lookAt(r.x, r.y, r.z), e.controls.update(), e._lastViewSignature = Me(t), !0) : !1;
1433
+ }
1434
+ function bn(e) {
1435
+ if (!e.viewChangeHandler) return;
1436
+ const t = Date.now();
1437
+ if (t - e._lastViewEmitMs < 250) return;
1438
+ const n = He(e);
1439
+ if (!n) return;
1440
+ const r = Me(n);
1441
+ r !== e._lastViewSignature && (e._lastViewSignature = r, e._lastViewEmitMs = t, e.viewChangeHandler(n));
1442
+ }
1443
+ function Ee(e, { minX: t, maxX: n, minY: r, maxY: o, minZ: i, maxZ: a }) {
1444
+ const c = (t + n) / 2, l = (r + o) / 2, s = (i + a) / 2, u = n - t, p = o - r, m = a - i, d = Math.max(u, p, m, 1) * 2;
1445
+ e.controls.target.set(c, l, s), e.camera.position.set(c + d, l + d, s + d), e.camera.lookAt(c, l, s), e.controls.update();
1446
+ }
1447
+ function pn(e, t = 1e3) {
1448
+ !e.camera || !e.controls || (e.controls.target.set(0, 0, 0), e.camera.position.set(t, t, t), e.camera.lookAt(0, 0, 0), e.controls.update());
1449
+ }
1450
+ function gn(e, t = 2e3) {
1451
+ !e.camera || !e.controls || (e.controls.target.set(0, 0, 0), e.camera.position.set(0, 0, t), e.camera.up.set(0, 1, 0), e.camera.lookAt(0, 0, 0), e.controls.update());
1452
+ }
1453
+ function yn(e, t = 0, n = 0) {
1454
+ e.controls && typeof e.controls.pan == "function" && (e.controls.pan(t, n), e.controls.update());
1455
+ }
1456
+ function _n(e, t = 1.1) {
1457
+ !e.controls || typeof e.controls.dollyIn != "function" || typeof e.controls.dollyOut != "function" || (t > 1 ? e.controls.dollyOut(t) : e.controls.dollyIn(1 / t), e.controls.update());
1458
+ }
1459
+ function Mn(e, t = 1.2) {
1460
+ if (!e.lastBounds) return;
1461
+ const {
1462
+ minX: n,
1463
+ maxX: r,
1464
+ minY: o,
1465
+ maxY: i,
1466
+ minZ: a,
1467
+ maxZ: c
1468
+ } = e.lastBounds, l = (r - n) * t, s = (i - o) * t, u = (c - a) * t, p = (n + r) / 2, m = (o + i) / 2, h = (a + c) / 2, g = Math.max(l, s, u, 1) * 2;
1469
+ e.controls.target.set(p, m, h), e.camera.position.set(p + g, m + g, h + g), e.camera.lookAt(p, m, h), e.controls.update();
1470
+ }
1471
+ const En = 1, zn = 120;
1472
+ function Nn(e, t) {
1473
+ if (!e.camera || !e.controls || !Number.isFinite(t)) return !1;
1474
+ const n = Math.min(zn, Math.max(En, t)), r = e.controls.target, o = e.camera.position.distanceTo(r), i = e.camera.fov * Math.PI / 180, a = 2 * o * Math.tan(i / 2), c = n * Math.PI / 180, l = a / (2 * Math.tan(c / 2)), s = e.camera.position.clone().sub(r).normalize();
1475
+ return e.camera.position.copy(r).addScaledVector(s, l), e.camera.fov = n, e.camera.updateProjectionMatrix(), e.controls.update(), !0;
1476
+ }
1477
+ function On(e, t = "orbit") {
1478
+ if (e.controlMode = t === "fly" ? "fly" : "orbit", e.controlMode === "fly")
1479
+ e.controls && (e.controls.enabled = !1), e.flyControls && (e.flyControls.enabled = !0);
1480
+ else if (e.flyControls && (e.flyControls.enabled = !1), e.controls) {
1481
+ e.controls.enabled = !0, e.camera.getWorldDirection(e._tmpDir);
1482
+ const n = e.camera.position.clone().addScaledVector(e._tmpDir, 10);
1483
+ e.controls.target.copy(n), e.controls.update();
1484
+ }
1485
+ }
1486
+ const T = "#9ca3af";
1487
+ function Le(e, t) {
1488
+ const n = Number(e == null ? void 0 : e.md), r = Number(t == null ? void 0 : t.md);
1489
+ if (!Number.isFinite(n) || !Number.isFinite(r)) return null;
1490
+ const o = Math.min(n, r), i = Math.max(n, r);
1491
+ return i <= o ? null : { segStart: o, segEnd: i };
1492
+ }
1493
+ function kn(e, t, n) {
1494
+ let r = 0, o = 0;
1495
+ for (let a = 0; a < e.length; a += 1) {
1496
+ const c = e[a], l = Number(c == null ? void 0 : c.from), s = Number(c == null ? void 0 : c.to), u = Number(c == null ? void 0 : c.value);
1497
+ if (!Number.isFinite(l) || !Number.isFinite(s) || !Number.isFinite(u) || s <= l) continue;
1498
+ const p = Math.max(t, l), h = Math.min(n, s) - p;
1499
+ h <= 0 || (r += u * h, o += h);
1500
+ }
1501
+ if (o <= 0) return null;
1502
+ const i = r / o;
1503
+ return Number.isFinite(i) ? i : null;
1504
+ }
1505
+ function An(e, t) {
1506
+ if (!Number.isFinite(e)) return new f.Color(T);
1507
+ if (Re(e, t) < 0) return new f.Color(T);
1508
+ const r = Wt(e, t, T);
1509
+ return new f.Color(r);
1510
+ }
1511
+ function Ln(e) {
1512
+ if (!e || !String(e).trim()) return T;
1513
+ const t = Ge(String(e).toLowerCase().trim());
1514
+ return "#" + new f.Color().setHSL(t, 0.7, 0.5).getHexString();
1515
+ }
1516
+ function Dn(e = {}) {
1517
+ return {
1518
+ preserveView: !!e.preserveView,
1519
+ assayIntervalsByHole: e.assayIntervalsByHole || null,
1520
+ selectedAssayVariable: e.selectedAssayVariable || "",
1521
+ isCategoricalVariable: !!e.isCategoricalVariable
1522
+ };
1523
+ }
1524
+ function Sn(e, t) {
1525
+ if (!e || !t) return [];
1526
+ const n = [];
1527
+ return Object.values(e).forEach((r) => {
1528
+ (r || []).forEach((o) => {
1529
+ const i = Number(o == null ? void 0 : o.value);
1530
+ Number.isFinite(i) && n.push(i);
1531
+ });
1532
+ }), n;
1533
+ }
1534
+ function oe(e) {
1535
+ return {
1536
+ holeId: e.id,
1537
+ project: e.project
1538
+ };
1539
+ }
1540
+ function wn(e) {
1541
+ return `${e ?? ""}`.trim().toLowerCase();
1542
+ }
1543
+ function xn(e, t) {
1544
+ const n = `${e ?? ""}:${t ?? 0}`, r = Ge(n), o = (t ?? 0) % 14 / 14, i = (r * 0.15 + o * 0.85) % 1, a = new f.Color();
1545
+ return a.setHSL(i, 1, 0.5), a;
1546
+ }
1547
+ function Ge(e) {
1548
+ const t = `${e ?? ""}`;
1549
+ let n = 2166136261;
1550
+ for (let r = 0; r < t.length; r += 1)
1551
+ n ^= t.charCodeAt(r), n = Math.imul(n, 16777619);
1552
+ return (n >>> 0) / 4294967295;
1553
+ }
1554
+ function Fn(e, t, n) {
1555
+ let r = null, o = 0;
1556
+ for (const i of e) {
1557
+ const a = Number(i == null ? void 0 : i.from), c = Number(i == null ? void 0 : i.to);
1558
+ if (!Number.isFinite(a) || !Number.isFinite(c)) continue;
1559
+ const l = Math.min(n, c) - Math.max(t, a);
1560
+ l > o && (o = l, r = i == null ? void 0 : i.value);
1561
+ }
1562
+ return r;
1563
+ }
1564
+ function vn(e, t) {
1565
+ if (!t || !e) return [];
1566
+ const n = e.id || e.holeId;
1567
+ if (!n) return [];
1568
+ const r = t[n];
1569
+ if (Array.isArray(r) && r.length) return r;
1570
+ const o = wn(n);
1571
+ if (o) {
1572
+ const i = t[o];
1573
+ if (Array.isArray(i) && i.length) return i;
1574
+ }
1575
+ return [];
1576
+ }
1577
+ function Cn({ selectedAssayVariable: e, assayIntervals: t, assayScale: n, holeId: r, segmentIndex: o, p1: i, p2: a, isCategorical: c }) {
1578
+ if (!e)
1579
+ return xn(r, o);
1580
+ if (e === "__HAS_ASSAY__") {
1581
+ if (!(t != null && t.length)) return new f.Color(T);
1582
+ const u = Le(i, a);
1583
+ return u ? t.some((m) => {
1584
+ const h = Number(m == null ? void 0 : m.from), d = Number(m == null ? void 0 : m.to);
1585
+ if (!Number.isFinite(h) || !Number.isFinite(d)) return !1;
1586
+ const g = Math.max(u.segStart, h);
1587
+ return Math.min(u.segEnd, d) > g;
1588
+ }) ? new f.Color("#ff8c42") : new f.Color(T) : new f.Color(T);
1589
+ }
1590
+ if (!(t != null && t.length)) return new f.Color(T);
1591
+ const l = Le(i, a);
1592
+ if (!l) return new f.Color(T);
1593
+ if (c) {
1594
+ const u = Fn(t, l.segStart, l.segEnd);
1595
+ return new f.Color(Ln(u));
1596
+ }
1597
+ const s = kn(t, l.segStart, l.segEnd);
1598
+ return An(s, n);
1599
+ }
1600
+ function In(e, t, n = {}) {
1601
+ if (!e.scene || (je(e), !t || t.length === 0)) return;
1602
+ const { preserveView: r, assayIntervalsByHole: o, selectedAssayVariable: i, isCategoricalVariable: a } = Dn(n), c = a ? [] : Sn(o, i), l = qt(c);
1603
+ let s = 1 / 0, u = -1 / 0, p = 1 / 0, m = -1 / 0, h = 1 / 0, d = -1 / 0;
1604
+ const g = new f.Vector3(), N = new f.Vector3(0, 1, 0);
1605
+ t.forEach((O, b) => {
1606
+ const y = b * 137.5 % 360 / 360, E = new f.Color().setHSL(y, 0.75, 0.55), k = (O.points || []).map((L) => {
1607
+ s = Math.min(s, L.x), u = Math.max(u, L.x), p = Math.min(p, L.y), m = Math.max(m, L.y), h = Math.min(h, L.z), d = Math.max(d, L.z);
1608
+ const x = new f.Vector3(L.x, L.y, L.z);
1609
+ return x.md = L.md, x;
1610
+ });
1611
+ if (k.length < 2) {
1612
+ if (k.length === 1) {
1613
+ const L = new f.SphereGeometry(5, 12, 12), x = new f.MeshLambertMaterial({
1614
+ color: E,
1615
+ emissive: E,
1616
+ emissiveIntensity: 0.2
1617
+ }), S = new f.Mesh(L, x);
1618
+ S.position.copy(k[0]), S.userData = oe(O), e.scene.add(S), e.drillLines.push(S), e.drillMeshes.push(S);
1619
+ }
1620
+ return;
1621
+ }
1622
+ const D = new f.Group();
1623
+ D.userData = oe(O);
1624
+ const w = i ? vn(O, o) : [];
1625
+ for (let L = 0; L < k.length - 1; L += 1) {
1626
+ const x = k[L], S = k[L + 1], v = g.subVectors(S, x), I = v.length();
1627
+ if (I <= 1e-3) continue;
1628
+ const C = 2.2, B = new f.CylinderGeometry(C, C, I, 6, 1, !0), P = Cn({
1629
+ selectedAssayVariable: i,
1630
+ assayIntervals: w,
1631
+ assayScale: l,
1632
+ holeId: O.id,
1633
+ segmentIndex: L,
1634
+ p1: x,
1635
+ p2: S,
1636
+ isCategorical: a
1637
+ }), z = new f.MeshLambertMaterial({
1638
+ color: P,
1639
+ flatShading: !0,
1640
+ emissive: P,
1641
+ emissiveIntensity: 0.15
1642
+ }), F = new f.Mesh(B, z);
1643
+ F.position.copy(x.clone().addScaledVector(v, 0.5)), F.quaternion.setFromUnitVectors(N, v.clone().normalize()), F.userData = oe(O), D.add(F), e.drillMeshes.push(F);
1644
+ }
1645
+ e.scene.add(D), e.drillLines.push(D);
1646
+ }), e.camera && e.controls && (e.lastBounds = { minX: s, maxX: u, minY: p, maxY: m, minZ: h, maxZ: d }, r || Ee(e, { minX: s, maxX: u, minY: p, maxY: m, minZ: h, maxZ: d })), j(e);
1647
+ }
1648
+ function je(e) {
1649
+ e.drillLines.forEach((t) => {
1650
+ e.scene.remove(t), t.isGroup ? t.traverse((n) => {
1651
+ n.isMesh && (n.geometry.dispose(), n.material.dispose());
1652
+ }) : t.isMesh && (t.geometry.dispose(), t.material.dispose());
1653
+ }), e.drillLines = [], e.drillMeshes = [], j(e);
1654
+ }
1655
+ const Tn = 20, Bn = 15, Pn = "#00bcd4";
1656
+ function Rn(e = {}) {
1657
+ return {
1658
+ panelWidth: e.panelWidth != null ? Number(e.panelWidth) : Tn,
1659
+ lateralOffset: e.lateralOffset != null ? Number(e.lateralOffset) : Bn,
1660
+ color: e.color || Pn,
1661
+ valueMin: e.valueMin != null ? Number(e.valueMin) : null,
1662
+ valueMax: e.valueMax != null ? Number(e.valueMax) : null
1663
+ };
1664
+ }
1665
+ function Vr(e) {
1666
+ if (!e || e.length < 2) return null;
1667
+ let t = -1 / 0, n = 1 / 0;
1668
+ for (const o of e)
1669
+ o.z > t && (t = o.z), o.z < n && (n = o.z);
1670
+ const r = t - n;
1671
+ return r < 1e-3 ? null : { topZ: t, botZ: n, height: r };
1672
+ }
1673
+ function Vn(e, t, n, r, o, i, a) {
1674
+ if (!Array.isArray(e) || !Array.isArray(t)) return [];
1675
+ const c = Math.min(e.length, t.length), l = [];
1676
+ for (let b = 0; b < c; b++)
1677
+ Number.isFinite(e[b]) && Number.isFinite(t[b]) && l.push({ d: e[b], v: t[b] });
1678
+ if (l.length < 2) return [];
1679
+ const s = a != null && a > 0 ? a : null, u = s != null ? 0 : Math.min(...l.map((b) => b.d)), m = (s ?? Math.max(...l.map((b) => b.d))) - u || 1, h = Math.min(...l.map((b) => b.v)), d = Math.max(...l.map((b) => b.v)), g = o ?? h, O = (i ?? d) - g || 1;
1680
+ return l.map(({ d: b, v: A }) => {
1681
+ const y = (b - u) / m, E = Math.max(0, Math.min(1, (A - g) / O)), k = -n / 2 + E * n, D = y * r;
1682
+ return new f.Vector3(k, D, 0.01);
1683
+ });
1684
+ }
1685
+ function Hn(e, t) {
1686
+ const n = e.length;
1687
+ if (n < 2) return null;
1688
+ const r = [], o = [];
1689
+ let i = 0;
1690
+ for (let c = 0; c < n - 1; c++) {
1691
+ const l = e[c], s = e[c + 1], u = s.x - l.x, p = s.y - l.y, m = Math.sqrt(u * u + p * p);
1692
+ if (m < 1e-6) continue;
1693
+ const h = -p / m * t, d = u / m * t, g = 0.01;
1694
+ r.push(
1695
+ l.x + h,
1696
+ l.y + d,
1697
+ g,
1698
+ l.x - h,
1699
+ l.y - d,
1700
+ g,
1701
+ s.x + h,
1702
+ s.y + d,
1703
+ g,
1704
+ s.x - h,
1705
+ s.y - d,
1706
+ g
1707
+ ), o.push(i, i + 1, i + 2, i + 1, i + 3, i + 2), i += 4;
1708
+ }
1709
+ if (r.length === 0) return null;
1710
+ const a = new f.BufferGeometry();
1711
+ return a.setAttribute("position", new f.Float32BufferAttribute(r, 3)), a.setIndex(o), a;
1712
+ }
1713
+ function Gn(e, t) {
1714
+ const n = e.points || [];
1715
+ if (n.length < 2) return null;
1716
+ const r = n[0], o = n[n.length - 1], i = new f.Vector3(
1717
+ o.x - r.x,
1718
+ o.y - r.y,
1719
+ o.z - r.z
1720
+ ), a = i.length();
1721
+ if (a < 1e-3) return null;
1722
+ const c = i.clone().normalize(), l = Rn(t.options), { panelWidth: s, lateralOffset: u, color: p, valueMin: m, valueMax: h } = l, d = new f.Vector3(0, 0, 1);
1723
+ let g = new f.Vector3().crossVectors(c, d);
1724
+ g.lengthSq() < 1e-6 ? g.set(1, 0, 0) : g.normalize();
1725
+ const N = new f.Vector3().crossVectors(g, c).normalize(), O = new f.Vector3(r.x, r.y, r.z).addScaledVector(g, u), b = new f.Matrix4().makeBasis(g, c, N), A = new f.Quaternion().setFromRotationMatrix(b), y = n.map((v) => v.md).filter(Number.isFinite), E = y.length > 0 ? Math.max(...y) : a, k = Vn(
1726
+ t.depths,
1727
+ t.values,
1728
+ s,
1729
+ a,
1730
+ m,
1731
+ h,
1732
+ E
1733
+ );
1734
+ if (k.length < 2) return null;
1735
+ const D = new f.Group();
1736
+ D.userData = { holeId: e.id, isStripLog: !0 };
1737
+ const w = s * 0.025, L = Hn(k, w);
1738
+ if (!L) return null;
1739
+ const x = new f.MeshBasicMaterial({
1740
+ color: new f.Color(p),
1741
+ side: f.DoubleSide
1742
+ }), S = new f.Mesh(L, x);
1743
+ return S.position.copy(O), S.quaternion.copy(A), D.add(S), D;
1744
+ }
1745
+ function jn(e, t, n) {
1746
+ if (!e.scene || (ce(e), !n || n.length === 0) || !t || t.length === 0) return;
1747
+ const r = /* @__PURE__ */ new Map();
1748
+ t.forEach((o) => {
1749
+ o.id != null && r.set(o.id, o);
1750
+ }), n.forEach((o) => {
1751
+ const i = r.get(o.holeId);
1752
+ if (!i) return;
1753
+ const a = Gn(i, o);
1754
+ a && (e.scene.add(a), e.stripLogGroups.push(a));
1755
+ });
1756
+ }
1757
+ function ce(e) {
1758
+ e.stripLogGroups && (e.stripLogGroups.forEach((t) => {
1759
+ e.scene && e.scene.remove(t), t.traverse((n) => {
1760
+ n.geometry && n.geometry.dispose(), n.material && n.material.dispose();
1761
+ });
1762
+ }), e.stripLogGroups = []);
1763
+ }
1764
+ const De = "#ffffbb", Un = 2, Yn = 1.5, $n = 1;
1765
+ function Xn(e) {
1766
+ const { renderer: t, scene: n, camera: r, container: o } = e;
1767
+ if (!t || !n || !r) return;
1768
+ const i = (o == null ? void 0 : o.clientWidth) || t.domElement.clientWidth || 1, a = (o == null ? void 0 : o.clientHeight) || t.domElement.clientHeight || 1, c = new lt(t), l = new ct(n, r);
1769
+ c.addPass(l);
1770
+ const s = new f.Vector2(i, a), u = new ut(s, n, r);
1771
+ u.visibleEdgeColor.set(De), u.hiddenEdgeColor.set(De), u.edgeStrength = Un, u.edgeThickness = Yn, u.edgeGlow = $n, u.pulsePeriod = 0, u.selectedObjects = [], c.addPass(u), c.setSize(i, a), e._composer = c, e._outlinePass = u;
1772
+ }
1773
+ function qn(e, t, n) {
1774
+ !e._composer || !e._outlinePass || (e._composer.setSize(t, n), e._outlinePass.resolution.set(t, n));
1775
+ }
1776
+ function Z(e, t) {
1777
+ e._outlinePass && (e._outlinePass.selectedObjects = t ? [t] : [], e._selectedObject = t || null);
1778
+ }
1779
+ function Se(e) {
1780
+ e._composer && (e._composer.dispose(), e._composer = null), e._outlinePass = null, e._selectedObject = null, e.selectables = [];
1781
+ }
1782
+ const Zn = [
1783
+ { normal: [1, 0, 0], neibDir: [1, 0, 0], verts: [[1, -1, -1], [1, 1, -1], [1, 1, 1], [1, -1, 1]] },
1784
+ { normal: [-1, 0, 0], neibDir: [-1, 0, 0], verts: [[-1, -1, 1], [-1, 1, 1], [-1, 1, -1], [-1, -1, -1]] },
1785
+ { normal: [0, 1, 0], neibDir: [0, 1, 0], verts: [[-1, 1, 1], [1, 1, 1], [1, 1, -1], [-1, 1, -1]] },
1786
+ { normal: [0, -1, 0], neibDir: [0, -1, 0], verts: [[1, -1, 1], [-1, -1, 1], [-1, -1, -1], [1, -1, -1]] },
1787
+ { normal: [0, 0, 1], neibDir: [0, 0, 1], verts: [[-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]] },
1788
+ { normal: [0, 0, -1], neibDir: [0, 0, -1], verts: [[1, -1, -1], [-1, -1, -1], [-1, 1, -1], [1, 1, -1]] }
1789
+ ];
1790
+ function Wn(e, t, n, r, o = {}) {
1791
+ if (!e.scene || (Ue(e), !t || !n || !r)) return;
1792
+ const { autoCenter: i = !0, opacity: a = 1 } = o;
1793
+ let c = 1 / 0, l = -1 / 0, s = 1 / 0, u = -1 / 0, p = 1 / 0, m = -1 / 0;
1794
+ t.forEach((z) => {
1795
+ const F = Number(z.x ?? z.center_x ?? 0), R = Number(z.y ?? z.center_y ?? 0), Y = Number(z.z ?? z.center_z ?? 0), $ = Number(z.dx ?? z.size_x ?? 1), X = Number(z.dy ?? z.size_y ?? 1), q = Number(z.dz ?? z.size_z ?? 1);
1796
+ c = Math.min(c, F - $ / 2), l = Math.max(l, F + $ / 2), s = Math.min(s, R - X / 2), u = Math.max(u, R + X / 2), p = Math.min(p, Y - q / 2), m = Math.max(m, Y + q / 2);
1797
+ });
1798
+ let h = 0, d = 0, g = 0;
1799
+ o.offset ? (h = Number(o.offset.x ?? 0), d = Number(o.offset.y ?? 0), g = Number(o.offset.z ?? 0)) : i && (h = -((c + l) / 2), d = -((s + u) / 2), g = -((p + m) / 2));
1800
+ const N = c + h, O = l + h, b = s + d, A = u + d, y = p + g, E = m + g, k = (z, F, R) => `${Math.round(z)},${Math.round(F)},${Math.round(R)}`, D = new Set(
1801
+ t.map((z) => k(Number(z.x ?? 0), Number(z.y ?? 0), Number(z.z ?? 0)))
1802
+ ), w = [], L = [], x = [], S = [], v = [];
1803
+ let I = 0;
1804
+ if (t.forEach((z) => {
1805
+ const F = Number(z.x ?? z.center_x ?? 0), R = Number(z.y ?? z.center_y ?? 0), Y = Number(z.z ?? z.center_z ?? 0), $ = Number(z.dx ?? z.size_x ?? 1), X = Number(z.dy ?? z.size_y ?? 1), q = Number(z.dz ?? z.size_z ?? 1), $e = F + h, Xe = R + d, qe = Y + g, Ze = St(z[n], r, f), { r: We, g: Ke, b: Je } = Ze;
1806
+ Zn.forEach((V) => {
1807
+ const Qe = F + V.neibDir[0] * $, et = R + V.neibDir[1] * X, tt = Y + V.neibDir[2] * q;
1808
+ if (D.has(k(Qe, et, tt))) return;
1809
+ const U = I;
1810
+ V.verts.forEach(([nt, rt, ot]) => {
1811
+ w.push($e + nt * $ / 2, Xe + rt * X / 2, qe + ot * q / 2), L.push(V.normal[0], V.normal[1], V.normal[2]), x.push(We, Ke, Je), I++;
1812
+ }), S.push(U, U + 1, U + 2, U, U + 2, U + 3), v.push(z);
1813
+ });
1814
+ }), w.length === 0) return;
1815
+ const C = new f.BufferGeometry();
1816
+ C.setAttribute("position", new f.Float32BufferAttribute(w, 3)), C.setAttribute("normal", new f.Float32BufferAttribute(L, 3)), C.setAttribute("color", new f.Float32BufferAttribute(x, 3)), C.setIndex(S);
1817
+ const B = new f.MeshLambertMaterial({
1818
+ vertexColors: !0,
1819
+ transparent: a < 1,
1820
+ opacity: a,
1821
+ side: f.DoubleSide
1822
+ }), P = new f.Mesh(C, B);
1823
+ P.userData._isMergedBlocks = !0, P.userData._quadToBlock = v, P.userData._offset = { x: h, y: d, z: g }, e.scene.add(P), e.blocks.push(P), j(e), e.camera && e.controls && (e.lastBounds = { minX: N, maxX: O, minY: b, maxY: A, minZ: y, maxZ: E }, Ee(e, { minX: N, maxX: O, minY: b, maxY: A, minZ: y, maxZ: E }));
1824
+ }
1825
+ function Ue(e) {
1826
+ var t;
1827
+ e.blocks.forEach((n) => {
1828
+ e.scene.remove(n), n.geometry.dispose(), n.material.dispose();
1829
+ }), e.blocks = [], e._blockHighlightMesh && ((t = e.scene) == null || t.remove(e._blockHighlightMesh), e._blockHighlightMesh.geometry.dispose(), e._blockHighlightMesh.material.dispose(), e._blockHighlightMesh = null), j(e);
1830
+ }
1831
+ function Kn(e, t) {
1832
+ const n = Math.max(0, Math.min(1, Number(t)));
1833
+ e.blocks.forEach((r) => {
1834
+ r.material && (r.material.opacity = n, r.material.transparent = n < 1, r.material.needsUpdate = !0);
1835
+ });
1836
+ }
1837
+ function Jn(e, t, n) {
1838
+ const r = (n == null ? void 0 : n.x) ?? 0, o = (n == null ? void 0 : n.y) ?? 0, i = (n == null ? void 0 : n.z) ?? 0, a = Number(t.x ?? t.center_x ?? 0) + r, c = Number(t.y ?? t.center_y ?? 0) + o, l = Number(t.z ?? t.center_z ?? 0) + i, s = Number(t.dx ?? t.size_x ?? 1), u = Number(t.dy ?? t.size_y ?? 1), p = Number(t.dz ?? t.size_z ?? 1);
1839
+ if (!e._blockHighlightMesh) {
1840
+ const m = new f.BoxGeometry(1, 1, 1), h = new f.MeshBasicMaterial({ transparent: !0, opacity: 0, depthWrite: !1 });
1841
+ e._blockHighlightMesh = new f.Mesh(m, h), e.scene.add(e._blockHighlightMesh);
1842
+ }
1843
+ return e._blockHighlightMesh.position.set(a, c, l), e._blockHighlightMesh.scale.set(s, u, p), e._blockHighlightMesh;
1844
+ }
1845
+ function Ye(e) {
1846
+ var o, i;
1847
+ if (!e._outlinePass || e.selectables.length === 0) {
1848
+ e._outlinePass && Z(e, null);
1849
+ return;
1850
+ }
1851
+ const t = e.raycaster.intersectObjects(e.selectables, !0);
1852
+ if (t.length === 0) {
1853
+ Z(e, null);
1854
+ return;
1855
+ }
1856
+ const n = t[0], r = n.object;
1857
+ if ((o = r == null ? void 0 : r.userData) != null && o._isMergedBlocks) {
1858
+ const a = Math.floor(n.faceIndex / 2), c = (i = r.userData._quadToBlock) == null ? void 0 : i[a];
1859
+ if (c) {
1860
+ Z(e, Jn(e, c, r.userData._offset));
1861
+ return;
1862
+ }
1863
+ }
1864
+ Z(e, r);
1865
+ }
1866
+ function Qn(e) {
1867
+ const t = e.renderer;
1868
+ t && (e.handleCanvasClick = (n) => {
1869
+ var h, d, g, N, O, b, A;
1870
+ if (n.button !== 0) return;
1871
+ if ((h = e.gizmo) != null && h.domElement) {
1872
+ const y = e.gizmo.domElement.getBoundingClientRect();
1873
+ if (n.clientX >= y.left && n.clientX <= y.right && n.clientY >= y.top && n.clientY <= y.bottom)
1874
+ return;
1875
+ }
1876
+ const r = t.domElement.getBoundingClientRect(), o = n.clientX - r.left, i = n.clientY - r.top;
1877
+ if (e.pointer.x = o / r.width * 2 - 1, e.pointer.y = -(i / r.height * 2) + 1, e.raycaster.setFromCamera(e.pointer, e.camera), Ye(e), e.blocks.length > 0) {
1878
+ const y = e.raycaster.intersectObjects(e.blocks, !1);
1879
+ if (y.length > 0) {
1880
+ const E = y[0], k = E.object;
1881
+ if ((d = k == null ? void 0 : k.userData) != null && d._isMergedBlocks && e.blockClickHandler) {
1882
+ const D = Math.floor(E.faceIndex / 2), w = k.userData._quadToBlock[D];
1883
+ w && e.blockClickHandler(w);
1884
+ }
1885
+ return;
1886
+ }
1887
+ }
1888
+ const a = e.raycaster.intersectObjects(e.drillMeshes, !0), c = e.raycaster.intersectObjects(e.structuralMeshes, !0), l = ((g = a[0]) == null ? void 0 : g.distance) ?? 1 / 0;
1889
+ if ((((N = c[0]) == null ? void 0 : N.distance) ?? 1 / 0) < l && c.length > 0) {
1890
+ const y = c[0].object;
1891
+ e.drillholeClickHandler && e.drillholeClickHandler({ type: "structure", ...y.userData });
1892
+ return;
1893
+ }
1894
+ if (a.length === 0) return;
1895
+ let u = a[0].object;
1896
+ for (; u && u.parent && !((O = u.userData) != null && O.holeId); )
1897
+ u = u.parent;
1898
+ const p = (b = u == null ? void 0 : u.userData) == null ? void 0 : b.holeId, m = (A = u == null ? void 0 : u.userData) == null ? void 0 : A.project;
1899
+ p && e.drillholeClickHandler && e.drillholeClickHandler({ holeId: p, project: m });
1900
+ }, t.domElement.addEventListener("click", e.handleCanvasClick));
1901
+ }
1902
+ class Hr {
1903
+ constructor() {
1904
+ this.container = null, this.scene = null, this.camera = null, this.renderer = null, this.controls = null, this.flyControls = null, this.gizmo = null, this.blocks = [], this.drillLines = [], this.drillMeshes = [], this.structuralGroup = null, this.structuralMeshes = [], this.stripLogGroups = [], this.frameId = null, this.clock = new f.Clock(), this.handleCanvasClick = null, this.raycaster = new f.Raycaster(), this.pointer = new f.Vector2(), this.drillholeClickHandler = null, this.blockClickHandler = null, this.controlMode = "orbit", this._tmpDir = new f.Vector3(), this.viewChangeHandler = null, this._lastViewSignature = "", this._lastViewEmitMs = 0, this.selectables = [], this._selectedObject = null, this._composer = null, this._blockHighlightMesh = null, this._outlinePass = null, this.rasterOverlays = /* @__PURE__ */ new Map();
1905
+ }
1906
+ init(t) {
1907
+ if (!t) return;
1908
+ this.container = t;
1909
+ const n = t.clientWidth, r = t.clientHeight;
1910
+ this.scene = new f.Scene(), this.scene.background = new f.Color(16777215), this.camera = new f.PerspectiveCamera(28, n / r, 1e-3, 1e7), this.camera.up.set(0, 0, 1), this.camera.position.set(50, 50, 50), this.camera.lookAt(0, 0, 0), this.renderer = new f.WebGLRenderer({ antialias: !0 }), this.renderer.setSize(n, r), this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.autoClear = !1, t.appendChild(this.renderer.domElement);
1911
+ const o = new f.AmbientLight(16777215, 1.2);
1912
+ this.scene.add(o);
1913
+ const i = new f.DirectionalLight(16777215, 1.5);
1914
+ i.position.set(10, 10, 5), this.scene.add(i);
1915
+ const a = new f.AxesHelper(20);
1916
+ this.scene.add(a), this.controls = new it(this.camera, this.renderer.domElement), this.controls.enableDamping = !1, this.controls.screenSpacePanning = !0, this.controls.enableZoom = !0, this.controls.zoomSpeed = 10, this.controls.minDistance = 1e-4, this.controls.maxDistance = 5e6, this.controls.mouseButtons = {
1917
+ LEFT: f.MOUSE.PAN,
1918
+ MIDDLE: f.MOUSE.DOLLY,
1919
+ RIGHT: f.MOUSE.ROTATE
1920
+ }, this.controls.touches = {
1921
+ ONE: f.TOUCH.ROTATE,
1922
+ TWO: f.TOUCH.DOLLY_PAN
1923
+ }, this.controls.maxPolarAngle = Math.PI, this.flyControls = new st(this.camera, this.renderer.domElement), this.flyControls.movementSpeed = 2e3, this.flyControls.rollSpeed = Math.PI / 12, this.flyControls.dragToLook = !0, this.flyControls.enabled = !1, this.gizmo = new at(this.camera, this.renderer, {
1924
+ container: this.container,
1925
+ placement: "top-right",
1926
+ size: 110,
1927
+ offset: { top: 12, right: 12 },
1928
+ animated: !0,
1929
+ speed: 1.5
1930
+ }), this.gizmo.attachControls(this.controls), Qn(this), this._wheelRelay = (l) => {
1931
+ l.target !== this.renderer.domElement && (l.preventDefault(), this.renderer.domElement.dispatchEvent(new WheelEvent("wheel", {
1932
+ clientX: l.clientX,
1933
+ clientY: l.clientY,
1934
+ deltaX: l.deltaX,
1935
+ deltaY: l.deltaY,
1936
+ deltaZ: l.deltaZ,
1937
+ deltaMode: l.deltaMode,
1938
+ ctrlKey: l.ctrlKey,
1939
+ shiftKey: l.shiftKey,
1940
+ altKey: l.altKey,
1941
+ bubbles: !1
1942
+ })));
1943
+ }, this.container.addEventListener("wheel", this._wheelRelay, { passive: !1 }), Xn(this);
1944
+ const c = () => {
1945
+ var s;
1946
+ this.frameId = requestAnimationFrame(c);
1947
+ const l = this.clock.getDelta();
1948
+ this.renderer.clear(), this.controlMode === "fly" && ((s = this.flyControls) != null && s.enabled) ? this.flyControls.update(l) : this.controls && this.controls.update(), this._emitViewChangeIfNeeded(), this._composer ? this._composer.render(l) : this.renderer.render(this.scene, this.camera), this.gizmo && this.gizmo.render();
1949
+ };
1950
+ c();
1951
+ }
1952
+ resize() {
1953
+ if (!this.container || !this.camera || !this.renderer) return;
1954
+ const t = this.container.clientWidth, n = this.container.clientHeight;
1955
+ this.camera.aspect = t / n, this.camera.updateProjectionMatrix(), this.renderer.setSize(t, n), this.gizmo && this.gizmo.update(), qn(this, t, n);
1956
+ }
1957
+ dispose() {
1958
+ this.frameId && cancelAnimationFrame(this.frameId), this.renderer && this.handleCanvasClick && this.renderer.domElement.removeEventListener("click", this.handleCanvasClick), this.gizmo && (this.gizmo.dispose(), this.gizmo = null), this.viewChangeHandler = null, Ue(this), je(this), ce(this), Ve(this), fn(this), Se(this), this.container && this._wheelRelay && this.container.removeEventListener("wheel", this._wheelRelay), this.controls && this.controls.dispose(), this.flyControls && this.flyControls.dispose(), this.renderer && (this.renderer.dispose(), this.container && this.renderer.domElement && this.container.removeChild(this.renderer.domElement));
1959
+ }
1960
+ // ---------------------------------------------------------------------------
1961
+ // Data renderers — delegate to domain modules
1962
+ // ---------------------------------------------------------------------------
1963
+ setDrillholes(t, n = {}) {
1964
+ In(this, t, n);
1965
+ }
1966
+ /**
1967
+ * Add floating 2D strip log panels beside drillholes in the 3D scene.
1968
+ * Each panel is a flat rectangle offset from the hole collar, depth-registered
1969
+ * to the hole's vertical extent and containing a line graph of numeric data.
1970
+ *
1971
+ * @param {Array<object>} holes - Hole objects (same array as passed to setDrillholes)
1972
+ * @param {Array<object>} stripLogs - Strip log definitions. Each must contain:
1973
+ * - `holeId` {string} — must match a hole id
1974
+ * - `depths` {number[]} — downhole depth positions for each sample
1975
+ * - `values` {number[]} — numeric value at each depth
1976
+ * - `options` {object} — optional: panelWidth, lateralOffset, color, valueMin, valueMax
1977
+ */
1978
+ setStripLogs(t, n) {
1979
+ jn(this, t, n);
1980
+ }
1981
+ /**
1982
+ * Remove all strip log panels from the scene and free GPU resources.
1983
+ */
1984
+ clearStripLogs() {
1985
+ ce(this);
1986
+ }
1987
+ /**
1988
+ * Render block model data as a single merged mesh of exterior faces only.
1989
+ * @param {Array<Object>} data - Block rows (canonical column names)
1990
+ * @param {string} selectedProperty - Attribute column used for colouring
1991
+ * @param {Object} stats - Property statistics
1992
+ * @param {Object} [options]
1993
+ */
1994
+ setBlocks(t, n, r, o = {}) {
1995
+ Wn(this, t, n, r, o);
1996
+ }
1997
+ /**
1998
+ * Update the opacity of all currently rendered blocks.
1999
+ * @param {number} opacity - New opacity value between 0 and 1
2000
+ */
2001
+ setBlockOpacity(t) {
2002
+ Kn(this, t);
2003
+ }
2004
+ setStructuralDiscs(t, n, r = {}) {
2005
+ tn(this, t, n, r);
2006
+ }
2007
+ setStructuralDiscsVisible(t) {
2008
+ nn(this, t);
2009
+ }
2010
+ // ---------------------------------------------------------------------------
2011
+ // Click handlers
2012
+ // ---------------------------------------------------------------------------
2013
+ setDrillholeClickHandler(t) {
2014
+ this.drillholeClickHandler = t;
2015
+ }
2016
+ /**
2017
+ * Register a click handler for block selection.
2018
+ * @param {Function|null} handler - Callback ``(blockData) => void``, or null to clear
2019
+ */
2020
+ setBlockClickHandler(t) {
2021
+ this.blockClickHandler = typeof t == "function" ? t : null;
2022
+ }
2023
+ // ---------------------------------------------------------------------------
2024
+ // Camera controls — delegate to baselode3dCameraControls
2025
+ // ---------------------------------------------------------------------------
2026
+ setViewChangeHandler(t) {
2027
+ this.viewChangeHandler = typeof t == "function" ? t : null;
2028
+ }
2029
+ getViewState() {
2030
+ return He(this);
2031
+ }
2032
+ setViewState(t) {
2033
+ return hn(this, t);
2034
+ }
2035
+ _buildViewSignature(t) {
2036
+ return Me(t);
2037
+ }
2038
+ _emitViewChangeIfNeeded() {
2039
+ bn(this);
2040
+ }
2041
+ _fitCameraToBounds({ minX: t, maxX: n, minY: r, maxY: o, minZ: i, maxZ: a }) {
2042
+ Ee(this, { minX: t, maxX: n, minY: r, maxY: o, minZ: i, maxZ: a });
2043
+ }
2044
+ recenterCameraToOrigin(t = 1e3) {
2045
+ pn(this, t);
2046
+ }
2047
+ lookDown(t = 2e3) {
2048
+ gn(this, t);
2049
+ }
2050
+ pan(t = 0, n = 0) {
2051
+ yn(this, t, n);
2052
+ }
2053
+ dolly(t = 1.1) {
2054
+ _n(this, t);
2055
+ }
2056
+ focusOnLastBounds(t = 1.2) {
2057
+ Mn(this, t);
2058
+ }
2059
+ /**
2060
+ * Change the camera field-of-view while keeping the visible scene the same apparent size.
2061
+ * @param {number} fovDeg - Desired FOV in degrees
2062
+ */
2063
+ setCameraFov(t) {
2064
+ Nn(this, t);
2065
+ }
2066
+ /**
2067
+ * Set the scene background colour.
2068
+ * @param {'white'|'black'} colour
2069
+ */
2070
+ setBackground(t) {
2071
+ this.scene && (this.scene.background = new f.Color(t === "black" ? 0 : 16777215));
2072
+ }
2073
+ setControlMode(t = "orbit") {
2074
+ On(this, t);
2075
+ }
2076
+ // ---------------------------------------------------------------------------
2077
+ // Selection glow public API
2078
+ // ---------------------------------------------------------------------------
2079
+ _syncSelectables() {
2080
+ j(this);
2081
+ }
2082
+ /**
2083
+ * Register the objects that are candidates for click-select glow.
2084
+ * @param {THREE.Object3D[]} objects
2085
+ */
2086
+ setSelectableObjects(t) {
2087
+ this.selectables = Array.isArray(t) ? t.slice() : [];
2088
+ }
2089
+ /**
2090
+ * Programmatically select an object (or pass null to clear).
2091
+ * @param {THREE.Object3D|null} object
2092
+ */
2093
+ selectObject(t) {
2094
+ Z(this, t || null);
2095
+ }
2096
+ /**
2097
+ * Return the currently selected object, or null if nothing is selected.
2098
+ * @returns {THREE.Object3D|null}
2099
+ */
2100
+ getSelectedObject() {
2101
+ return this._selectedObject || null;
2102
+ }
2103
+ /**
2104
+ * Dispose the effect composer and all GPU resources used by the selection glow.
2105
+ */
2106
+ disposeGlow() {
2107
+ Se(this);
2108
+ }
2109
+ /** @private */
2110
+ _updateSelectionFromPointer() {
2111
+ Ye(this);
2112
+ }
2113
+ // ---------------------------------------------------------------------------
2114
+ // Raster overlay API — delegate to rasterOverlayScene
2115
+ // ---------------------------------------------------------------------------
2116
+ /**
2117
+ * Add a raster overlay layer (created with createRasterOverlay) to the scene.
2118
+ * @param {object} layer - Layer descriptor returned by createRasterOverlay()
2119
+ */
2120
+ addRasterOverlay(t) {
2121
+ an(this, t);
2122
+ }
2123
+ /**
2124
+ * Remove a raster overlay from the scene and dispose its GPU resources.
2125
+ * @param {string} id - Overlay id
2126
+ */
2127
+ removeRasterOverlay(t) {
2128
+ _e(this, t);
2129
+ }
2130
+ /**
2131
+ * Set the opacity of a raster overlay at runtime.
2132
+ * @param {string} id - Overlay id
2133
+ * @param {number} opacity - New opacity [0, 1]
2134
+ */
2135
+ setRasterOverlayOpacity(t, n) {
2136
+ ln(this, t, n);
2137
+ }
2138
+ /**
2139
+ * Show or hide a raster overlay.
2140
+ * @param {string} id - Overlay id
2141
+ * @param {boolean} visible
2142
+ */
2143
+ setRasterOverlayVisibility(t, n) {
2144
+ cn(this, t, n);
2145
+ }
2146
+ /**
2147
+ * Update the elevation (Z position) of a raster overlay.
2148
+ * @param {string} id - Overlay id
2149
+ * @param {number} elevation
2150
+ */
2151
+ setRasterOverlayElevation(t, n) {
2152
+ un(this, t, n);
2153
+ }
2154
+ /**
2155
+ * Return a raster overlay by id, or undefined if not found.
2156
+ * @param {string} id
2157
+ * @returns {object|undefined}
2158
+ */
2159
+ getRasterOverlay(t) {
2160
+ return mn(this, t);
2161
+ }
2162
+ /**
2163
+ * Return all raster overlay layers in insertion order.
2164
+ * @returns {object[]}
2165
+ */
2166
+ listRasterOverlays() {
2167
+ return dn(this);
2168
+ }
2169
+ }
2170
+ export {
2171
+ be as $,
2172
+ W as A,
2173
+ Mr as B,
2174
+ Er as C,
2175
+ ge as D,
2176
+ fe as E,
2177
+ ne as F,
2178
+ Ce as G,
2179
+ H,
2180
+ Nr as I,
2181
+ M as J,
2182
+ vr as K,
2183
+ ue as L,
2184
+ pe as M,
2185
+ he as N,
2186
+ Fr as O,
2187
+ xe as P,
2188
+ vt as Q,
2189
+ ve as R,
2190
+ re as S,
2191
+ Q as T,
2192
+ Hr as U,
2193
+ ze as V,
2194
+ dt as W,
2195
+ yt as X,
2196
+ Nt as Y,
2197
+ te as Z,
2198
+ Mt as _,
2199
+ me as a,
2200
+ Or as a$,
2201
+ ar as a0,
2202
+ we as a1,
2203
+ hr as a2,
2204
+ ht as a3,
2205
+ dr as a4,
2206
+ mr as a5,
2207
+ _t as a6,
2208
+ ee as a7,
2209
+ Gt as a8,
2210
+ G as a9,
2211
+ Me as aA,
2212
+ xr as aB,
2213
+ Lt as aC,
2214
+ fn as aD,
2215
+ ce as aE,
2216
+ Ft as aF,
2217
+ Rr as aG,
2218
+ Lr as aH,
2219
+ Qt as aI,
2220
+ _n as aJ,
2221
+ bn as aK,
2222
+ Dt as aL,
2223
+ Ee as aM,
2224
+ Mn as aN,
2225
+ wr as aO,
2226
+ Ln as aP,
2227
+ St as aQ,
2228
+ Bt as aR,
2229
+ Re as aS,
2230
+ Wt as aT,
2231
+ Vr as aU,
2232
+ mn as aV,
2233
+ He as aW,
2234
+ wt as aX,
2235
+ dn as aY,
2236
+ Sr as aZ,
2237
+ kr as a_,
2238
+ It as aa,
2239
+ zn as ab,
2240
+ En as ac,
2241
+ pr as ad,
2242
+ Ne as ae,
2243
+ lr as af,
2244
+ Tt as ag,
2245
+ cr as ah,
2246
+ Rt as ai,
2247
+ Vt as aj,
2248
+ bt as ak,
2249
+ pt as al,
2250
+ gt as am,
2251
+ Pn as an,
2252
+ Bn as ao,
2253
+ Tn as ap,
2254
+ ur as aq,
2255
+ ft as ar,
2256
+ fr as as,
2257
+ an as at,
2258
+ xt as au,
2259
+ Pr as av,
2260
+ qt as aw,
2261
+ Gn as ax,
2262
+ Vn as ay,
2263
+ en as az,
2264
+ K as b,
2265
+ gn as b0,
2266
+ At as b1,
2267
+ on as b2,
2268
+ Rn as b3,
2269
+ yn as b4,
2270
+ Dr as b5,
2271
+ pn as b6,
2272
+ _e as b7,
2273
+ Pt as b8,
2274
+ On as b9,
2275
+ Nn as ba,
2276
+ un as bb,
2277
+ ln as bc,
2278
+ cn as bd,
2279
+ jn as be,
2280
+ hn as bf,
2281
+ Et as bg,
2282
+ Ar as c,
2283
+ de as d,
2284
+ Ie as e,
2285
+ br as f,
2286
+ ye as g,
2287
+ le as h,
2288
+ ae as i,
2289
+ J as j,
2290
+ Ot as k,
2291
+ $t as l,
2292
+ zt as m,
2293
+ Tr as n,
2294
+ Br as o,
2295
+ Fe as p,
2296
+ Xt as q,
2297
+ Ct as r,
2298
+ _ as s,
2299
+ Ir as t,
2300
+ Cr as u,
2301
+ _r as v,
2302
+ se as w,
2303
+ gr as x,
2304
+ yr as y,
2305
+ zr as z
2306
+ };
2307
+ //# sourceMappingURL=baselode3dScene-qMfVRKxK.js.map