baselode 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/baselode.js CHANGED
@@ -1,107 +1,107 @@
1
1
  import W from "papaparse";
2
- import { jsx as G, jsxs as Ce } from "react/jsx-runtime";
3
- import { useRef as ot, useState as Z, useEffect as oe, useMemo as ve } from "react";
4
- import xe from "plotly.js-dist-min";
5
- import * as g from "three";
6
- import { OrbitControls as It } from "three/examples/jsm/controls/OrbitControls";
7
- import { FlyControls as At } from "three/examples/jsm/controls/FlyControls";
8
- import { ViewportGizmo as Et } from "three-viewport-gizmo";
9
- const b = "hole_id", Q = "latitude", ee = "longitude", he = "elevation", D = "azimuth", L = "dip", $ = "from", F = "to", we = "mid", ne = "project_id", ie = "easting", se = "northing", it = "crs", R = "depth", st = "alpha", at = "beta", St = "strike", Gn = {
2
+ import { jsx as L, jsxs as Q } from "react/jsx-runtime";
3
+ import { useRef as lt, useState as K, useEffect as ae, useMemo as ke } from "react";
4
+ import Ce from "plotly.js-dist-min";
5
+ import * as N from "three";
6
+ import { OrbitControls as Ot } from "three/examples/jsm/controls/OrbitControls";
7
+ import { FlyControls as Vt } from "three/examples/jsm/controls/FlyControls";
8
+ import { ViewportGizmo as wt } from "three-viewport-gizmo";
9
+ const E = "hole_id", te = "latitude", ne = "longitude", ge = "elevation", j = "azimuth", B = "dip", X = "from", G = "to", Re = "mid", se = "project_id", ce = "easting", ue = "northing", at = "crs", Y = "depth", ct = "alpha", ut = "beta", $t = "strike", hr = {
10
10
  // A unique hole identifier across the entire dataset and all future data sets
11
- [b]: "string",
11
+ [E]: "string",
12
12
  // The hole ID from the original collar source
13
13
  datasource_hole_id: "string",
14
14
  // The project ID or project code from the original collar source, if available
15
- [ne]: "string",
15
+ [se]: "string",
16
16
  // The latitude of the collar, in decimal degrees (WGS84)
17
- [Q]: "number",
17
+ [te]: "number",
18
18
  // The longitude of the collar, in decimal degrees (WGS84)
19
- [ee]: "number",
19
+ [ne]: "number",
20
20
  // The elevation of the collar, in meters above sea level (WGS84)
21
- [he]: "number",
21
+ [ge]: "number",
22
22
  // The easting coordinate of the collar, in meters (projected CRS)
23
- [ie]: "number",
23
+ [ce]: "number",
24
24
  // The northing coordinate of the collar, in meters (projected CRS)
25
- [se]: "number",
25
+ [ue]: "number",
26
26
  // The coordinate reference system of the collar coordinates for easting/northing, as an EPSG code or proj string
27
- [it]: "string"
28
- }, Xn = {
27
+ [at]: "string"
28
+ }, pr = {
29
29
  // The unique hole id that maps to the collar and any other data tables
30
- [b]: "string",
30
+ [E]: "string",
31
31
  // The depth along the hole where the survey measurement was taken / started
32
- [R]: "number",
32
+ [Y]: "number",
33
33
  // The depth along the hole where the survey measurement ended, if applicable (some surveys are point measurements and may not have a 'to' depth)
34
- [F]: "number",
34
+ [G]: "number",
35
35
  // The azimuth of the hole at the survey depth, in degrees from north
36
- [D]: "number",
36
+ [j]: "number",
37
37
  // The dip of the hole at the survey depth, in degrees from horizontal (negative values indicate downward inclination)
38
- [L]: "number"
39
- }, qn = {
38
+ [B]: "number"
39
+ }, br = {
40
40
  // The unique hole id that maps to the collar and any other data tables
41
- [b]: "string",
41
+ [E]: "string",
42
42
  // The depth along the hole where the assay interval starts
43
- [$]: "number",
43
+ [X]: "number",
44
44
  // The depth along the hole where the assay interval ends
45
- [F]: "number",
45
+ [G]: "number",
46
46
  // The midpoint depth of the assay interval
47
- [we]: "number"
47
+ [Re]: "number"
48
48
  // assay value columns are variable and not standardized here.
49
49
  // Assays may be flattened (one column per assay type) or long (one row per assay type with an additional 'assay_type' column)
50
- }, Wn = {
51
- [b]: "string",
52
- [R]: "number",
53
- [L]: "number",
54
- [D]: "number",
55
- [st]: "number",
56
- [at]: "number",
50
+ }, yr = {
51
+ [E]: "string",
52
+ [Y]: "number",
53
+ [B]: "number",
54
+ [j]: "number",
55
+ [ct]: "number",
56
+ [ut]: "number",
57
57
  comments: "string"
58
- }, vt = {
59
- [b]: ["hole_id", "holeid", "hole id", "hole-id"],
58
+ }, Rt = {
59
+ [E]: ["hole_id", "holeid", "hole id", "hole-id"],
60
60
  datasource_hole_id: ["datasource_hole_id", "datasourceholeid", "datasource hole id", "datasource-hole-id", "company_hole_id", "companyholeid", "company hole id", "company-hole-id"],
61
- [ne]: ["project_id", "projectid", "project id", "project-id", "project_code", "projectcode", "project code", "project-code", "companyId", "company_id", "companyid", "company id", "company-id", "dataset", "project"],
62
- [Q]: ["latitude", "lat"],
63
- [ee]: ["longitude", "lon"],
64
- [he]: ["elevation", "rl", "elev", "z"],
65
- [ie]: ["easting", "x"],
66
- [se]: ["northing", "y"],
67
- [it]: ["crs", "epsg", "projection"],
68
- [$]: ["from", "depth_from", "from_depth", "samp_from", "sample_from", "sampfrom", "fromdepth"],
69
- [F]: ["to", "depth_to", "to_depth", "samp_to", "sample_to", "sampto", "todepth"],
70
- [D]: ["azimuth", "az", "dip_direction", "dipdir", "dip direction", "dipdrn", "dipdirection", "dip_dir", "computed_plane_azimuth", "calc_dipdir", "calc_dipdir_deg", "dipdrn", "dipdir_calc", "dipdirect_calc"],
71
- [L]: ["dip", "computed_plane_dip", "calc_dip", "calc_dip_deg", "dip_calc"],
72
- [st]: ["alpha", "alpha_angle", "alpha_angle_deg", "alpha_2"],
73
- [at]: ["beta", "beta_angle", "beta_angle_deg", "beta_2"],
74
- [R]: ["depth", "survey_depth", "surveydepth"],
75
- [St]: ["strike", "str"]
76
- }, lt = {};
77
- for (const [e, t] of Object.entries(vt))
61
+ [se]: ["project_id", "projectid", "project id", "project-id", "project_code", "projectcode", "project code", "project-code", "companyId", "company_id", "companyid", "company id", "company-id", "dataset", "project"],
62
+ [te]: ["latitude", "lat"],
63
+ [ne]: ["longitude", "lon"],
64
+ [ge]: ["elevation", "rl", "elev", "z"],
65
+ [ce]: ["easting", "x"],
66
+ [ue]: ["northing", "y"],
67
+ [at]: ["crs", "epsg", "projection"],
68
+ [X]: ["from", "depth_from", "from_depth", "samp_from", "sample_from", "sampfrom", "fromdepth"],
69
+ [G]: ["to", "depth_to", "to_depth", "samp_to", "sample_to", "sampto", "todepth"],
70
+ [j]: ["azimuth", "az", "dip_direction", "dipdir", "dip direction", "dipdrn", "dipdirection", "dip_dir", "computed_plane_azimuth", "calc_dipdir", "calc_dipdir_deg", "dipdrn", "dipdir_calc", "dipdirect_calc"],
71
+ [B]: ["dip", "computed_plane_dip", "calc_dip", "calc_dip_deg", "dip_calc"],
72
+ [ct]: ["alpha", "alpha_angle", "alpha_angle_deg", "alpha_2"],
73
+ [ut]: ["beta", "beta_angle", "beta_angle_deg", "beta_2"],
74
+ [Y]: ["depth", "survey_depth", "surveydepth"],
75
+ [$t]: ["strike", "str"]
76
+ }, mt = {};
77
+ for (const [e, t] of Object.entries(Rt))
78
78
  for (const n of t) {
79
79
  const r = n.toLowerCase().trim();
80
- lt[r] = e;
80
+ mt[r] = e;
81
81
  }
82
- function ze(e) {
82
+ function Ie(e) {
83
83
  return (e || "").toString().trim().toLowerCase().replace(/\s+/g, "_");
84
84
  }
85
- function ue(e, t = null, n = null) {
86
- const r = { ...lt };
85
+ function pe(e, t = null, n = null) {
86
+ const r = { ...mt };
87
87
  if (n) {
88
88
  for (const [s, i] of Object.entries(n))
89
89
  if (s != null && i != null) {
90
- const a = ze(s), u = ze(i);
91
- r[a] = u;
90
+ const c = Ie(s), u = Ie(i);
91
+ r[c] = u;
92
92
  }
93
93
  }
94
94
  const o = {};
95
95
  for (const [s, i] of Object.entries(e)) {
96
- const a = ze(s), u = r[a] || a;
96
+ const c = Ie(s), u = r[c] || c;
97
97
  o[u] = i;
98
98
  }
99
99
  return o;
100
100
  }
101
- function Zn(e, t = null, n = null) {
102
- return e.map((r) => ue(r, t, n));
101
+ function gr(e, t = null, n = null) {
102
+ return e.map((r) => pe(r, t, n));
103
103
  }
104
- const Pt = /* @__PURE__ */ new Set([
104
+ const Ht = /* @__PURE__ */ new Set([
105
105
  "hole_id",
106
106
  "holeid",
107
107
  "id",
@@ -133,34 +133,34 @@ const Pt = /* @__PURE__ */ new Set([
133
133
  "todepth",
134
134
  "comment",
135
135
  "z"
136
- ]), Oe = "[baselode:data]";
137
- function Tt(e, t = "Unknown error") {
136
+ ]), Ve = "[baselode:data]";
137
+ function jt(e, t = "Unknown error") {
138
138
  if (e instanceof Error) return e;
139
139
  const n = typeof e == "string" && e.trim() ? e : t;
140
140
  return new Error(n);
141
141
  }
142
142
  function w(e, t, n = "Operation failed") {
143
- const r = Tt(t, n), o = new Error(`${e}: ${r.message}`);
143
+ const r = jt(t, n), o = new Error(`${e}: ${r.message}`);
144
144
  return o.cause = r, o;
145
145
  }
146
- function Kn(e, t) {
146
+ function _r(e, t) {
147
147
  if (t !== void 0) {
148
- console.warn(`${Oe} ${e}`, t);
148
+ console.warn(`${Ve} ${e}`, t);
149
149
  return;
150
150
  }
151
- console.warn(`${Oe} ${e}`);
151
+ console.warn(`${Ve} ${e}`);
152
152
  }
153
- function Jn(e) {
154
- console.info(`${Oe} ${e}`);
153
+ function xr(e) {
154
+ console.info(`${Ve} ${e}`);
155
155
  }
156
- const Ee = (e, t = null) => ue(e, null, t);
157
- function Dt(e) {
158
- return { holeId: e[b] };
156
+ const Se = (e, t = null) => pe(e, null, t);
157
+ function Bt(e) {
158
+ return { holeId: e[E] };
159
159
  }
160
- function ct(e, t = null) {
161
- const n = e[b], r = n !== void 0 ? `${n}`.trim() : "";
160
+ function dt(e, t = null) {
161
+ const n = e[E], r = n !== void 0 ? `${n}`.trim() : "";
162
162
  if (!r) return null;
163
- const o = e[ne] || e.project || e.project_code, s = Number(e[$]), i = Number(e[F]);
163
+ const o = e[se] || e.project || e.project_code, s = Number(e[X]), i = Number(e[G]);
164
164
  return !Number.isFinite(s) || !Number.isFinite(i) || i <= s ? null : {
165
165
  holeId: r,
166
166
  project: o,
@@ -169,22 +169,22 @@ function ct(e, t = null) {
169
169
  ...e
170
170
  };
171
171
  }
172
- function ut(e, t) {
172
+ function ft(e, t) {
173
173
  var o;
174
174
  const n = t.sort((s, i) => s.from - i.from), r = [];
175
175
  return n.forEach((s) => {
176
- const { from: i, to: a, project: u, ...c } = s, l = {
176
+ const { from: i, to: c, project: u, ...l } = s, a = {
177
177
  z: i,
178
178
  from: i,
179
- to: a,
180
- [b]: e,
181
- [ne]: u,
182
- ...c
179
+ to: c,
180
+ [E]: e,
181
+ [se]: u,
182
+ ...l
183
183
  };
184
- r.push(l), r.push({ ...l, z: a });
184
+ r.push(a), r.push({ ...a, z: c });
185
185
  }), { id: e, project: (o = n[0]) == null ? void 0 : o.project, points: r };
186
186
  }
187
- function Qn(e, t = null) {
187
+ function Nr(e, t = null) {
188
188
  return new Promise((n, r) => {
189
189
  const o = /* @__PURE__ */ new Set();
190
190
  W.parse(e, {
@@ -192,18 +192,18 @@ function Qn(e, t = null) {
192
192
  dynamicTyping: !0,
193
193
  skipEmptyLines: !0,
194
194
  step: (s) => {
195
- const a = Ee(s.data, t)[b];
196
- a !== void 0 && `${a}`.trim() !== "" && o.add(`${a}`.trim());
195
+ const c = Se(s.data, t)[E];
196
+ c !== void 0 && `${c}`.trim() !== "" && o.add(`${c}`.trim());
197
197
  },
198
198
  complete: () => n(Array.from(o)),
199
199
  error: (s) => r(w("parseAssayHoleIds", s))
200
200
  });
201
201
  });
202
202
  }
203
- function Lt(e) {
204
- return Object.entries(e || {}).some(([t, n]) => !(Pt.has(t) || n == null || typeof n == "string" && n.trim() === ""));
203
+ function Gt(e) {
204
+ return Object.entries(e || {}).some(([t, n]) => !(Ht.has(t) || n == null || typeof n == "string" && n.trim() === ""));
205
205
  }
206
- function Ot(e, t = null) {
206
+ function Ut(e, t = null) {
207
207
  return new Promise((n, r) => {
208
208
  const o = /* @__PURE__ */ new Map();
209
209
  W.parse(e, {
@@ -211,13 +211,13 @@ function Ot(e, t = null) {
211
211
  dynamicTyping: !0,
212
212
  skipEmptyLines: !0,
213
213
  step: (s) => {
214
- const i = Ee(s.data, t);
215
- if (!Lt(i)) return;
216
- const u = Dt(i).holeId;
214
+ const i = Se(s.data, t);
215
+ if (!Gt(i)) return;
216
+ const u = Bt(i).holeId;
217
217
  if (u !== void 0 && `${u}`.trim() !== "") {
218
- const c = `${u}`.trim();
219
- o.has(c) || o.set(c, {
220
- holeId: c
218
+ const l = `${u}`.trim();
219
+ o.has(l) || o.set(l, {
220
+ holeId: l
221
221
  });
222
222
  }
223
223
  },
@@ -226,35 +226,35 @@ function Ot(e, t = null) {
226
226
  });
227
227
  });
228
228
  }
229
- function kt(e, t, n = null, r = null) {
229
+ function Yt(e, t, n = null, r = null) {
230
230
  return new Promise((o, s) => {
231
231
  const i = `${t}`.trim();
232
232
  if (!i) {
233
233
  s(w("parseAssayHole", new Error("Missing hole id")));
234
234
  return;
235
235
  }
236
- const a = [];
236
+ const c = [];
237
237
  W.parse(e, {
238
238
  header: !0,
239
239
  dynamicTyping: !0,
240
240
  skipEmptyLines: !0,
241
241
  step: (u) => {
242
- const c = Ee(u.data, r), l = ct(c, r);
243
- l && `${l.holeId}`.trim() === i && a.push(l);
242
+ const l = Se(u.data, r), a = dt(l, r);
243
+ a && `${a.holeId}`.trim() === i && c.push(a);
244
244
  },
245
245
  complete: () => {
246
- if (!a.length) {
246
+ if (!c.length) {
247
247
  o(null);
248
248
  return;
249
249
  }
250
- const u = ut(i, a);
250
+ const u = ft(i, c);
251
251
  o(u);
252
252
  },
253
253
  error: (u) => s(w("parseAssayHole", u))
254
254
  });
255
255
  });
256
256
  }
257
- function Ft(e, t = null, n = null) {
257
+ function qt(e, t = null, n = null) {
258
258
  return new Promise((r, o) => {
259
259
  W.parse(e, {
260
260
  header: !0,
@@ -263,23 +263,23 @@ function Ft(e, t = null, n = null) {
263
263
  complete: (s) => {
264
264
  const i = /* @__PURE__ */ new Map();
265
265
  s.data.forEach((u) => {
266
- const c = Ee(u, n), l = ct(c, n);
267
- l && (i.has(l.holeId) || i.set(l.holeId, []), i.get(l.holeId).push(l));
266
+ const l = Se(u, n), a = dt(l, n);
267
+ a && (i.has(a.holeId) || i.set(a.holeId, []), i.get(a.holeId).push(a));
268
268
  });
269
- const a = Array.from(i.entries()).map(([u, c]) => ut(u, c));
270
- r({ holes: a });
269
+ const c = Array.from(i.entries()).map(([u, l]) => ft(u, l));
270
+ r({ holes: c });
271
271
  },
272
272
  error: (s) => o(w("parseAssaysCSV", s))
273
273
  });
274
274
  });
275
275
  }
276
- function er(e = {}) {
276
+ function zr(e = {}) {
277
277
  const t = {};
278
278
  return Object.entries(e || {}).forEach(([n, r]) => {
279
- n && (t[ze(n)] = r);
279
+ n && (t[Ie(n)] = r);
280
280
  }), t;
281
281
  }
282
- function tr(e = {}, t = [], n) {
282
+ function Mr(e = {}, t = [], n) {
283
283
  for (const r of t) {
284
284
  const o = e[r];
285
285
  if (o != null && `${o}`.trim() !== "")
@@ -287,8 +287,8 @@ function tr(e = {}, t = [], n) {
287
287
  }
288
288
  return n;
289
289
  }
290
- const wt = 4;
291
- function dt(e = [], t = "") {
290
+ const Xt = 4;
291
+ function ht(e = [], t = "") {
292
292
  if (!e.length) return [];
293
293
  if (!t) return e;
294
294
  const n = e.findIndex((s) => s === t);
@@ -296,7 +296,7 @@ function dt(e = [], t = "") {
296
296
  const r = e[n], o = e.filter((s, i) => i !== n);
297
297
  return [r, ...o];
298
298
  }
299
- function Ne({
299
+ function Ae({
300
300
  property: e = "",
301
301
  chartType: t = "",
302
302
  categoricalProps: n = [],
@@ -305,18 +305,18 @@ function Ne({
305
305
  } = {}) {
306
306
  return e ? r.includes(e) ? "comment" : n.includes(e) ? "categorical" : e === "dip" ? "tadpole" : !t || t === "categorical" || t === "comment" || t === "tadpole" ? o : t : t || o;
307
307
  }
308
- function mt({
308
+ function pt({
309
309
  holeIds: e = [],
310
310
  focusedHoleId: t = "",
311
- plotCount: n = wt,
311
+ plotCount: n = Xt,
312
312
  defaultProp: r = "",
313
313
  categoricalProps: o = [],
314
314
  commentProps: s = [],
315
315
  numericDefaultChartType: i = "markers+line"
316
316
  } = {}) {
317
- const a = dt(e, t);
318
- return Array.from({ length: n }).map((u, c) => {
319
- const l = a[c] || e[c] || "", d = Ne({
317
+ const c = ht(e, t);
318
+ return Array.from({ length: n }).map((u, l) => {
319
+ const a = c[l] || e[l] || "", m = Ae({
320
320
  property: r,
321
321
  chartType: "",
322
322
  categoricalProps: o,
@@ -324,30 +324,30 @@ function mt({
324
324
  numericDefaultChartType: i
325
325
  });
326
326
  return {
327
- holeId: l,
327
+ holeId: a,
328
328
  property: r,
329
- chartType: d
329
+ chartType: m
330
330
  };
331
331
  });
332
332
  }
333
- const ye = "numeric", _e = "categorical", pe = "comment", Me = "hidden", ke = "tadpole", Be = {
334
- [ye]: [
333
+ const xe = "numeric", Me = "categorical", _e = "comment", ve = "hidden", we = "tadpole", Xe = {
334
+ [xe]: [
335
335
  { value: "bar", label: "Bars" },
336
336
  { value: "markers", label: "Markers" },
337
337
  { value: "markers+line", label: "Markers + Line" },
338
338
  { value: "line", label: "Line only" }
339
339
  ],
340
- [_e]: [
340
+ [Me]: [
341
341
  { value: "categorical", label: "Categorical bands" }
342
342
  ],
343
- [pe]: [
343
+ [_e]: [
344
344
  { value: "comment", label: "Comments" }
345
345
  ],
346
- [ke]: [
346
+ [we]: [
347
347
  { value: "tadpole", label: "Tadpole" }
348
348
  ],
349
- [Me]: []
350
- }, Ge = /* @__PURE__ */ new Set([
349
+ [ve]: []
350
+ }, Ze = /* @__PURE__ */ new Set([
351
351
  // Hole identifiers
352
352
  "hole_id",
353
353
  "holeid",
@@ -402,7 +402,7 @@ const ye = "numeric", _e = "categorical", pe = "comment", Me = "hidden", ke = "t
402
402
  "data_source",
403
403
  "_hole_key",
404
404
  "_hole_id_key"
405
- ]), Vt = /* @__PURE__ */ new Set([
405
+ ]), Zt = /* @__PURE__ */ new Set([
406
406
  "comments",
407
407
  "comment",
408
408
  "notes",
@@ -414,50 +414,50 @@ const ye = "numeric", _e = "categorical", pe = "comment", Me = "hidden", ke = "t
414
414
  "struct_comment",
415
415
  "structcomment"
416
416
  ]);
417
- function Rt(e) {
417
+ function Wt(e) {
418
418
  if (!(e != null && e.length))
419
419
  return { byType: {}, numericCols: [], categoricalCols: [], commentCols: [] };
420
420
  const t = new Set(e.flatMap((r) => Object.keys(r || {}))), n = {};
421
421
  for (const r of t) {
422
422
  const o = r.toLowerCase().trim();
423
- if (Ge.has(o) || Ge.has(r)) {
424
- n[r] = Me;
423
+ if (Ze.has(o) || Ze.has(r)) {
424
+ n[r] = ve;
425
425
  continue;
426
426
  }
427
- if (Vt.has(o)) {
428
- const a = e.some((u) => {
429
- const c = u[r];
430
- return c != null && String(c).trim() !== "" && String(c) !== "null";
427
+ if (Zt.has(o)) {
428
+ const c = e.some((u) => {
429
+ const l = u[r];
430
+ return l != null && String(l).trim() !== "" && String(l) !== "null";
431
431
  });
432
- n[r] = a ? pe : Me;
432
+ n[r] = c ? _e : ve;
433
433
  continue;
434
434
  }
435
435
  let s = !1, i = !1;
436
- for (const a of e) {
437
- const u = a[r];
436
+ for (const c of e) {
437
+ const u = c[r];
438
438
  if (!(u == null || typeof u == "string" && u.trim() === "") && (i = !0, typeof u == "number" && Number.isFinite(u))) {
439
439
  s = !0;
440
440
  break;
441
441
  }
442
442
  }
443
- i ? s ? n[r] = ye : n[r] = _e : n[r] = Me;
443
+ i ? s ? n[r] = xe : n[r] = Me : n[r] = ve;
444
444
  }
445
445
  return {
446
446
  byType: n,
447
- numericCols: Object.entries(n).filter(([, r]) => r === ye).map(([r]) => r),
448
- categoricalCols: Object.entries(n).filter(([, r]) => r === _e).map(([r]) => r),
449
- commentCols: Object.entries(n).filter(([, r]) => r === pe).map(([r]) => r)
447
+ numericCols: Object.entries(n).filter(([, r]) => r === xe).map(([r]) => r),
448
+ categoricalCols: Object.entries(n).filter(([, r]) => r === Me).map(([r]) => r),
449
+ commentCols: Object.entries(n).filter(([, r]) => r === _e).map(([r]) => r)
450
450
  };
451
451
  }
452
- function Ve(e) {
453
- return Be[e] ?? Be[ye];
452
+ function He(e) {
453
+ return Xe[e] ?? Xe[xe];
454
454
  }
455
- function nr(e) {
456
- const t = Ve(e);
457
- return t.length ? e === ye ? "line" : t[0].value : "markers+line";
455
+ function Cr(e) {
456
+ const t = He(e);
457
+ return t.length ? e === xe ? "line" : t[0].value : "markers+line";
458
458
  }
459
- function Ie(e = []) {
460
- const t = e.flatMap((a) => a.points || []), { numericCols: n, categoricalCols: r, commentCols: o, byType: s } = Rt(t), i = n[0] || r[0] || "";
459
+ function Ee(e = []) {
460
+ const t = e.flatMap((c) => c.points || []), { numericCols: n, categoricalCols: r, commentCols: o, byType: s } = Wt(t), i = n[0] || r[0] || "";
461
461
  return {
462
462
  numericProps: n,
463
463
  categoricalProps: r,
@@ -466,16 +466,16 @@ function Ie(e = []) {
466
466
  defaultProp: i
467
467
  };
468
468
  }
469
- async function $t(e, t = null) {
470
- return await Ot(e);
469
+ async function Kt(e, t = null) {
470
+ return await Ut(e);
471
471
  }
472
- async function Ht(e, t, n = null) {
473
- return await kt(e, t);
472
+ async function Jt(e, t, n = null) {
473
+ return await Yt(e, t);
474
474
  }
475
- function jt(e = [], t = "") {
475
+ function Qt(e = [], t = "") {
476
476
  if (!e.length) return null;
477
- const { numericProps: n, categoricalProps: r, commentProps: o, columnMeta: s, defaultProp: i } = Ie(e), a = e.map((c) => c.id || c.holeId).filter(Boolean), u = mt({
478
- holeIds: a,
477
+ const { numericProps: n, categoricalProps: r, commentProps: o, columnMeta: s, defaultProp: i } = Ee(e), c = e.map((l) => l.id || l.holeId).filter(Boolean), u = pt({
478
+ holeIds: c,
479
479
  focusedHoleId: t,
480
480
  plotCount: 4,
481
481
  defaultProp: i,
@@ -493,145 +493,145 @@ function jt(e = [], t = "") {
493
493
  traceConfigs: u
494
494
  };
495
495
  }
496
- async function rr(e, t = "", n = null) {
497
- const { holes: r } = await Ft(e, n), o = jt(r, t);
496
+ async function Ir(e, t = "", n = null) {
497
+ const { holes: r } = await qt(e, n), o = Qt(r, t);
498
498
  if (!o) throw new Error("No valid assay intervals found.");
499
499
  return o;
500
500
  }
501
- function or(e, t = null) {
501
+ function Ar(e, t = null) {
502
502
  return new Promise((n, r) => {
503
503
  W.parse(e, {
504
504
  header: !0,
505
505
  dynamicTyping: !0,
506
506
  skipEmptyLines: !0,
507
507
  complete: (o) => {
508
- const s = o.data.map((i) => Ut(i, t)).filter((i) => i[b] && Number.isFinite(i[R]) && Number.isFinite(i[L]) && Number.isFinite(i[D]));
508
+ const s = o.data.map((i) => en(i, t)).filter((i) => i[E] && Number.isFinite(i[Y]) && Number.isFinite(i[B]) && Number.isFinite(i[j]));
509
509
  n(s);
510
510
  },
511
511
  error: (o) => r(w("parseSurveyCSV", o))
512
512
  });
513
513
  });
514
514
  }
515
- function Ut(e, t = null) {
516
- const n = ue(e, null, t), r = n[b], o = n[ne] || n.project || n.project_code, s = fe(n[Q]), i = fe(n[ee]), a = fe(n[R]), u = fe(n[L]), c = fe(n[D]), l = fe(n.maxdepth);
515
+ function en(e, t = null) {
516
+ const n = pe(e, null, t), r = n[E], o = n[se] || n.project || n.project_code, s = ye(n[te]), i = ye(n[ne]), c = ye(n[Y]), u = ye(n[B]), l = ye(n[j]), a = ye(n.maxdepth);
517
517
  return {
518
518
  raw: n,
519
- [b]: r,
520
- [ne]: o,
521
- [Q]: s,
522
- [ee]: i,
523
- [R]: a,
524
- [L]: u,
525
- [D]: c,
526
- maxdepth: l,
519
+ [E]: r,
520
+ [se]: o,
521
+ [te]: s,
522
+ [ne]: i,
523
+ [Y]: c,
524
+ [B]: u,
525
+ [j]: l,
526
+ maxdepth: a,
527
527
  // Legacy field names for backwards compatibility
528
528
  project_code: o,
529
529
  latitude: s,
530
530
  longitude: i,
531
- surveydepth: a
531
+ surveydepth: c
532
532
  };
533
533
  }
534
- const fe = (e) => {
534
+ const ye = (e) => {
535
535
  const t = Number(e);
536
536
  return Number.isFinite(t) ? t : void 0;
537
537
  };
538
- function ir(e, t) {
539
- var c, l, d, m;
538
+ function vr(e, t) {
539
+ var l, a, m, d;
540
540
  const n = /* @__PURE__ */ new Map();
541
541
  e.forEach((f) => {
542
- const p = (f[b] || f.holeId || f.id || "").toString().trim();
543
- if (!p) return;
544
- const y = p.toLowerCase();
545
- n.has(y) || n.set(y, f);
542
+ const b = (f[E] || f.holeId || f.id || "").toString().trim();
543
+ if (!b) return;
544
+ const p = b.toLowerCase();
545
+ n.has(p) || n.set(p, f);
546
546
  });
547
- const r = ((c = e[0]) == null ? void 0 : c.lat) ?? ((l = e[0]) == null ? void 0 : l[Q]) ?? 0, o = ((d = e[0]) == null ? void 0 : d.lng) ?? ((m = e[0]) == null ? void 0 : m[ee]) ?? 0, s = 111132, i = 111320 * Math.cos(r * Math.PI / 180), a = /* @__PURE__ */ new Map();
547
+ const r = ((l = e[0]) == null ? void 0 : l.lat) ?? ((a = e[0]) == null ? void 0 : a[te]) ?? 0, o = ((m = e[0]) == null ? void 0 : m.lng) ?? ((d = e[0]) == null ? void 0 : d[ne]) ?? 0, s = 111132, i = 111320 * Math.cos(r * Math.PI / 180), c = /* @__PURE__ */ new Map();
548
548
  t.forEach((f) => {
549
- const p = (f[b] || "").toString().trim();
550
- if (!p) return;
551
- const y = p.toLowerCase();
552
- a.has(y) || a.set(y, []), a.get(y).push(f);
549
+ const b = (f[E] || "").toString().trim();
550
+ if (!b) return;
551
+ const p = b.toLowerCase();
552
+ c.has(p) || c.set(p, []), c.get(p).push(f);
553
553
  });
554
554
  const u = [];
555
- return a.forEach((f, p) => {
556
- const y = n.get(p);
557
- if (!y) return;
558
- const h = f.filter((T) => Number.isFinite(T[R] ?? T.surveydepth)).sort((T, B) => (T[R] ?? T.surveydepth) - (B[R] ?? B.surveydepth));
555
+ return c.forEach((f, b) => {
556
+ const p = n.get(b);
557
+ if (!p) return;
558
+ const h = f.filter((T) => Number.isFinite(T[Y] ?? T.surveydepth)).sort((T, R) => (T[Y] ?? T.surveydepth) - (R[Y] ?? R.surveydepth));
559
559
  if (!h.length) return;
560
- const z = y.lat ?? y[Q], C = y.lng ?? y[ee], E = 111132, H = 111320 * Math.cos(z * Math.PI / 180), A = (C - o) * i, j = (z - r) * s, P = [];
561
- let N = 0, V = 0, Y = 0;
560
+ const _ = p.lat ?? p[te], y = p.lng ?? p[ne], I = 111132, z = 111320 * Math.cos(_ * Math.PI / 180), x = (y - o) * i, D = (_ - r) * s, S = [];
561
+ let M = 0, O = 0, $ = 0;
562
562
  for (let T = 0; T < h.length; T += 1) {
563
- const B = h[T], q = h[T - 1], M = B[R] ?? B.surveydepth, _ = B[D] ?? B.azimuth, I = B[L] ?? B.dip;
563
+ const R = h[T], q = h[T - 1], A = R[Y] ?? R.surveydepth, v = R[j] ?? R.azimuth, P = R[B] ?? R.dip;
564
564
  if (!q) {
565
- P.push({
566
- x: A + N,
567
- y: j + V,
565
+ S.push({
566
+ x: x + M,
567
+ y: D + O,
568
568
  z: 0,
569
- md: M,
570
- azimuth: _,
571
- dip: I
569
+ md: A,
570
+ azimuth: v,
571
+ dip: P
572
572
  });
573
573
  continue;
574
574
  }
575
- const S = q[R] ?? q.surveydepth, x = q[D] ?? q.azimuth, O = q[L] ?? q.dip, k = M - S;
576
- if (k <= 0) continue;
577
- const v = Xe(O), U = Xe(I), X = Fe(x), le = Fe(_), ge = Math.acos(
578
- Math.sin(v) * Math.sin(U) * Math.cos(X - le) + Math.cos(v) * Math.cos(U)
579
- ), de = ge > 1e-6 ? 2 / ge * Math.tan(ge / 2) : 1, Se = 0.5 * k * (Math.sin(v) * Math.cos(X) + Math.sin(U) * Math.cos(le)) * de, me = 0.5 * k * (Math.sin(v) * Math.sin(X) + Math.sin(U) * Math.sin(le)) * de, Mt = 0.5 * k * (Math.cos(v) + Math.cos(U)) * de;
580
- N += Se, V += me, Y += Mt, P.push({
581
- x: A + N,
582
- y: j + V,
583
- z: -Y,
575
+ const g = q[Y] ?? q.surveydepth, C = q[j] ?? q.azimuth, F = q[B] ?? q.dip, V = A - g;
576
+ if (V <= 0) continue;
577
+ const k = We(F), H = We(P), U = $e(C), re = $e(v), de = Math.acos(
578
+ Math.sin(k) * Math.sin(H) * Math.cos(U - re) + Math.cos(k) * Math.cos(H)
579
+ ), ie = de > 1e-6 ? 2 / de * Math.tan(de / 2) : 1, Ne = 0.5 * V * (Math.sin(k) * Math.cos(U) + Math.sin(H) * Math.cos(re)) * ie, le = 0.5 * V * (Math.sin(k) * Math.sin(U) + Math.sin(H) * Math.sin(re)) * ie, Pe = 0.5 * V * (Math.cos(k) + Math.cos(H)) * ie;
580
+ M += Ne, O += le, $ += Pe, S.push({
581
+ x: x + M,
582
+ y: D + O,
583
+ z: -$,
584
584
  // render with z up; depth down
585
- md: M,
586
- azimuth: _,
587
- dip: I
585
+ md: A,
586
+ azimuth: v,
587
+ dip: P
588
588
  });
589
589
  }
590
- const re = P.map((T) => ({
590
+ const Z = S.map((T) => ({
591
591
  ...T,
592
- lat: z + T.y / E,
593
- lng: C + T.x / H
592
+ lat: _ + T.y / I,
593
+ lng: y + T.x / z
594
594
  }));
595
595
  u.push({
596
- id: y[b] || y.holeId || p,
597
- project: y[ne] || y.project_id || y.project || "",
598
- points: re,
599
- collar: y
596
+ id: p[E] || p.holeId || b,
597
+ project: p[se] || p.project_id || p.project || "",
598
+ points: Z,
599
+ collar: p
600
600
  });
601
601
  }), u;
602
602
  }
603
- const Fe = (e) => e * Math.PI / 180, Xe = (e) => {
603
+ const $e = (e) => e * Math.PI / 180, We = (e) => {
604
604
  const t = Number(e), n = 90 + (Number.isFinite(t) ? t : 0), r = Math.min(180, Math.max(0, n));
605
- return Fe(r);
605
+ return $e(r);
606
606
  };
607
- function J(e, t = void 0) {
607
+ function ee(e, t = void 0) {
608
608
  const n = Number(e);
609
609
  return Number.isFinite(n) ? n : t;
610
610
  }
611
- function qe(e) {
611
+ function Ke(e) {
612
612
  return e == null ? "" : `${e}`.trim();
613
613
  }
614
- function Ae(e = [], t = null) {
615
- const n = t || "hole_id", o = [n, "hole_id", "holeId", "id"].find((s) => e.some((i) => qe(i == null ? void 0 : i[s])));
614
+ function De(e = [], t = null) {
615
+ const n = t || "hole_id", o = [n, "hole_id", "holeId", "id"].find((s) => e.some((i) => Ke(i == null ? void 0 : i[s])));
616
616
  if (!o)
617
617
  throw w("canonicalizeHoleIdRows", new Error(`hole id column '${n}' not found`));
618
618
  return {
619
619
  aliasCol: o,
620
620
  rows: e.map((s) => ({
621
621
  ...s,
622
- hole_id: qe(s == null ? void 0 : s[o])
622
+ hole_id: Ke(s == null ? void 0 : s[o])
623
623
  }))
624
624
  };
625
625
  }
626
- function We(e) {
626
+ function Je(e) {
627
627
  return Number(e) * Math.PI / 180;
628
628
  }
629
- function Pe(e, t) {
630
- const n = We(e), r = We(t), o = Math.cos(r) * Math.sin(n), s = Math.cos(r) * Math.cos(n), i = Math.sin(r) * -1;
629
+ function Le(e, t) {
630
+ const n = Je(e), r = Je(t), o = Math.cos(r) * Math.sin(n), s = Math.cos(r) * Math.cos(n), i = Math.sin(r) * -1;
631
631
  return { ca: o, cb: s, cc: i };
632
632
  }
633
- function Yt(e, t, n, r, o, s = "minimum_curvature") {
634
- const i = Pe(t, n), a = Pe(r, o);
633
+ function tn(e, t, n, r, o, s = "minimum_curvature") {
634
+ const i = Le(t, n), c = Le(r, o);
635
635
  if (s === "tangential")
636
636
  return {
637
637
  dx: e * i.ca,
@@ -641,126 +641,126 @@ function Yt(e, t, n, r, o, s = "minimum_curvature") {
641
641
  dip: n
642
642
  };
643
643
  if (s === "balanced_tangential") {
644
- const d = 0.5 * (t + r), m = 0.5 * (n + o), f = Pe(d, m);
644
+ const m = 0.5 * (t + r), d = 0.5 * (n + o), f = Le(m, d);
645
645
  return {
646
646
  dx: e * f.ca,
647
647
  dy: e * f.cb,
648
648
  dz: e * f.cc,
649
- azimuth: d,
650
- dip: m
649
+ azimuth: m,
650
+ dip: d
651
651
  };
652
652
  }
653
- const u = i.ca * a.ca + i.cb * a.cb + i.cc * a.cc, c = Math.acos(Math.max(-1, Math.min(1, u))), l = c > 1e-6 ? 2 * Math.tan(c / 2) / c : 1;
653
+ const u = i.ca * c.ca + i.cb * c.cb + i.cc * c.cc, l = Math.acos(Math.max(-1, Math.min(1, u))), a = l > 1e-6 ? 2 * Math.tan(l / 2) / l : 1;
654
654
  return {
655
- dx: 0.5 * e * (i.ca + a.ca) * l,
656
- dy: 0.5 * e * (i.cb + a.cb) * l,
657
- dz: 0.5 * e * (i.cc + a.cc) * l,
655
+ dx: 0.5 * e * (i.ca + c.ca) * a,
656
+ dy: 0.5 * e * (i.cb + c.cb) * a,
657
+ dz: 0.5 * e * (i.cc + c.cc) * a,
658
658
  azimuth: r,
659
659
  dip: o
660
660
  };
661
661
  }
662
- function Re(e = [], t = [], n = {}) {
662
+ function je(e = [], t = [], n = {}) {
663
663
  const {
664
664
  step: r = 1,
665
665
  holeIdCol: o = null,
666
666
  method: s = "minimum_curvature"
667
- } = n, i = Number.isFinite(Number(r)) && Number(r) > 0 ? Number(r) : 1, a = Ae(e, o), u = Ae(t, o || a.aliasCol);
668
- if (!a.rows.length || !u.rows.length) return [];
669
- const c = /* @__PURE__ */ new Map();
670
- a.rows.forEach((m) => {
671
- !m.hole_id || c.has(m.hole_id) || c.set(m.hole_id, m);
672
- });
667
+ } = n, i = Number.isFinite(Number(r)) && Number(r) > 0 ? Number(r) : 1, c = De(e, o), u = De(t, o || c.aliasCol);
668
+ if (!c.rows.length || !u.rows.length) return [];
673
669
  const l = /* @__PURE__ */ new Map();
674
- u.rows.forEach((m) => {
675
- m.hole_id && (l.has(m.hole_id) || l.set(m.hole_id, []), l.get(m.hole_id).push(m));
670
+ c.rows.forEach((d) => {
671
+ !d.hole_id || l.has(d.hole_id) || l.set(d.hole_id, d);
676
672
  });
677
- const d = [];
678
- return l.forEach((m, f) => {
679
- const p = c.get(f);
680
- if (!p) return;
681
- const y = [...m].map((P) => ({
682
- ...P,
683
- from: J(P.from),
684
- azimuth: J(P.azimuth),
685
- dip: J(P.dip)
686
- })).filter((P) => Number.isFinite(P.from) && Number.isFinite(P.azimuth) && Number.isFinite(P.dip)).sort((P, N) => P.from - N.from);
687
- if (!y.length) return;
688
- let h = J(p.x, 0), z = J(p.y, 0), C = J(p.z, 0), E = y[0].from;
689
- const H = y[0].azimuth, A = y[0].dip, j = {
673
+ const a = /* @__PURE__ */ new Map();
674
+ u.rows.forEach((d) => {
675
+ d.hole_id && (a.has(d.hole_id) || a.set(d.hole_id, []), a.get(d.hole_id).push(d));
676
+ });
677
+ const m = [];
678
+ return a.forEach((d, f) => {
679
+ const b = l.get(f);
680
+ if (!b) return;
681
+ const p = [...d].map((S) => ({
682
+ ...S,
683
+ from: ee(S.from),
684
+ azimuth: ee(S.azimuth),
685
+ dip: ee(S.dip)
686
+ })).filter((S) => Number.isFinite(S.from) && Number.isFinite(S.azimuth) && Number.isFinite(S.dip)).sort((S, M) => S.from - M.from);
687
+ if (!p.length) return;
688
+ let h = ee(b.x, 0), _ = ee(b.y, 0), y = ee(b.z, 0), I = p[0].from;
689
+ const z = p[0].azimuth, x = p[0].dip, D = {
690
690
  hole_id: f,
691
- md: E,
691
+ md: I,
692
692
  x: h,
693
- y: z,
694
- z: C,
695
- azimuth: H,
696
- dip: A
693
+ y: _,
694
+ z: y,
695
+ azimuth: z,
696
+ dip: x
697
697
  };
698
- a.aliasCol !== "hole_id" && p[a.aliasCol] !== void 0 && (j[a.aliasCol] = p[a.aliasCol]), d.push(j);
699
- for (let P = 0; P < y.length - 1; P += 1) {
700
- const N = y[P], V = y[P + 1], Y = N.from, T = V.from - Y;
698
+ c.aliasCol !== "hole_id" && b[c.aliasCol] !== void 0 && (D[c.aliasCol] = b[c.aliasCol]), m.push(D);
699
+ for (let S = 0; S < p.length - 1; S += 1) {
700
+ const M = p[S], O = p[S + 1], $ = M.from, T = O.from - $;
701
701
  if (T <= 0) continue;
702
- const B = Math.max(1, Math.ceil(T / i)), q = T / B;
703
- for (let M = 0; M < B; M += 1) {
704
- E += q;
705
- const _ = (E - Y) / T, I = N.azimuth + _ * (V.azimuth - N.azimuth), S = N.dip + _ * (V.dip - N.dip), x = Yt(q, N.azimuth, N.dip, V.azimuth, V.dip, s);
706
- h += x.dx, z += x.dy, C += x.dz;
707
- const O = {
702
+ const R = Math.max(1, Math.ceil(T / i)), q = T / R;
703
+ for (let A = 0; A < R; A += 1) {
704
+ I += q;
705
+ const v = (I - $) / T, P = M.azimuth + v * (O.azimuth - M.azimuth), g = M.dip + v * (O.dip - M.dip), C = tn(q, M.azimuth, M.dip, O.azimuth, O.dip, s);
706
+ h += C.dx, _ += C.dy, y += C.dz;
707
+ const F = {
708
708
  hole_id: f,
709
- md: E,
709
+ md: I,
710
710
  x: h,
711
- y: z,
712
- z: C,
713
- azimuth: s === "minimum_curvature" ? I : x.azimuth,
714
- dip: s === "minimum_curvature" ? S : x.dip
711
+ y: _,
712
+ z: y,
713
+ azimuth: s === "minimum_curvature" ? P : C.azimuth,
714
+ dip: s === "minimum_curvature" ? g : C.dip
715
715
  };
716
- a.aliasCol !== "hole_id" && p[a.aliasCol] !== void 0 && (O[a.aliasCol] = p[a.aliasCol]), d.push(O);
716
+ c.aliasCol !== "hole_id" && b[c.aliasCol] !== void 0 && (F[c.aliasCol] = b[c.aliasCol]), m.push(F);
717
717
  }
718
718
  }
719
- }), d;
719
+ }), m;
720
720
  }
721
- function Bt(e, t, n = {}) {
722
- return Re(e, t, { ...n, method: "minimum_curvature" });
721
+ function nn(e, t, n = {}) {
722
+ return je(e, t, { ...n, method: "minimum_curvature" });
723
723
  }
724
- function sr(e, t, n = {}) {
725
- return Re(e, t, { ...n, method: "tangential" });
724
+ function Er(e, t, n = {}) {
725
+ return je(e, t, { ...n, method: "tangential" });
726
726
  }
727
- function ar(e, t, n = {}) {
728
- return Re(e, t, { ...n, method: "balanced_tangential" });
727
+ function Dr(e, t, n = {}) {
728
+ return je(e, t, { ...n, method: "balanced_tangential" });
729
729
  }
730
- function lr(e, t, n = {}) {
731
- return Bt(e, t, n);
730
+ function Sr(e, t, n = {}) {
731
+ return nn(e, t, n);
732
732
  }
733
- function Gt(e, t) {
733
+ function rn(e, t) {
734
734
  if (!e.length || !Number.isFinite(t)) return null;
735
735
  let n = null, r = 1 / 0;
736
736
  for (let o = 0; o < e.length; o += 1) {
737
- const s = e[o], i = J(s.md);
737
+ const s = e[o], i = ee(s.md);
738
738
  if (!Number.isFinite(i)) continue;
739
- const a = Math.abs(i - t);
740
- a < r && (r = a, n = s);
739
+ const c = Math.abs(i - t);
740
+ c < r && (r = c, n = s);
741
741
  }
742
742
  return n;
743
743
  }
744
- function cr(e = [], t = [], n = {}) {
745
- const r = n.holeIdCol || "hole_id", o = Ae(e, r), s = Ae(t, r);
744
+ function Pr(e = [], t = [], n = {}) {
745
+ const r = n.holeIdCol || "hole_id", o = De(e, r), s = De(t, r);
746
746
  if (!o.rows.length || !s.rows.length) return [...o.rows];
747
747
  const i = /* @__PURE__ */ new Map();
748
- return s.rows.forEach((a) => {
749
- a.hole_id && (i.has(a.hole_id) || i.set(a.hole_id, []), i.get(a.hole_id).push(a));
750
- }), i.forEach((a, u) => {
751
- i.set(u, [...a].sort((c, l) => J(c.md, 0) - J(l.md, 0)));
752
- }), o.rows.map((a) => {
753
- const u = J(a.from), c = J(a.to), l = Number.isFinite(u) && Number.isFinite(c) ? 0.5 * (u + c) : void 0;
754
- if (!a.hole_id || !Number.isFinite(l)) return { ...a };
755
- const d = Gt(i.get(a.hole_id) || [], l);
756
- if (!d) return { ...a };
757
- const m = { ...a };
748
+ return s.rows.forEach((c) => {
749
+ c.hole_id && (i.has(c.hole_id) || i.set(c.hole_id, []), i.get(c.hole_id).push(c));
750
+ }), i.forEach((c, u) => {
751
+ i.set(u, [...c].sort((l, a) => ee(l.md, 0) - ee(a.md, 0)));
752
+ }), o.rows.map((c) => {
753
+ const u = ee(c.from), l = ee(c.to), a = Number.isFinite(u) && Number.isFinite(l) ? 0.5 * (u + l) : void 0;
754
+ if (!c.hole_id || !Number.isFinite(a)) return { ...c };
755
+ const m = rn(i.get(c.hole_id) || [], a);
756
+ if (!m) return { ...c };
757
+ const d = { ...c };
758
758
  return ["md", "x", "y", "z", "azimuth", "dip"].forEach((f) => {
759
- d[f] !== void 0 && (Object.prototype.hasOwnProperty.call(m, f) ? m[`${f}_trace`] = d[f] : m[f] = d[f]);
760
- }), m;
759
+ m[f] !== void 0 && (Object.prototype.hasOwnProperty.call(d, f) ? d[`${f}_trace`] = m[f] : d[f] = m[f]);
760
+ }), d;
761
761
  });
762
762
  }
763
- function ur(e, t = null) {
763
+ function kr(e, t = null) {
764
764
  return new Promise((n, r) => {
765
765
  W.parse(e, {
766
766
  header: !0,
@@ -768,24 +768,24 @@ function ur(e, t = null) {
768
768
  skipEmptyLines: !0,
769
769
  complete: (o) => {
770
770
  const s = /* @__PURE__ */ new Map();
771
- o.data.forEach((a, u) => {
772
- const c = ue(a, null, t), l = c[b], d = l !== void 0 ? `${l}`.trim() : "", m = c[ie] ?? c.x, f = c[se] ?? c.y, p = c[he] ?? c.z, y = c.order ?? u;
773
- !d || m === null || m === void 0 || f === null || f === void 0 || p === null || p === void 0 || (s.has(d) || s.set(d, []), s.get(d).push({
774
- ...c,
775
- holeId: d,
776
- order: y,
777
- x: Number(m) ?? 0,
771
+ o.data.forEach((c, u) => {
772
+ const l = pe(c, null, t), a = l[E], m = a !== void 0 ? `${a}`.trim() : "", d = l[ce] ?? l.x, f = l[ue] ?? l.y, b = l[ge] ?? l.z, p = l.order ?? u;
773
+ !m || d === null || d === void 0 || f === null || f === void 0 || b === null || b === void 0 || (s.has(m) || s.set(m, []), s.get(m).push({
774
+ ...l,
775
+ holeId: m,
776
+ order: p,
777
+ x: Number(d) ?? 0,
778
778
  y: Number(f) ?? 0,
779
- z: Number(p) ?? 0
779
+ z: Number(b) ?? 0
780
780
  }));
781
781
  });
782
- const i = Array.from(s.entries()).map(([a, u]) => ({
783
- id: a,
784
- points: u.sort((c, l) => c.order - l.order).map((c) => ({
785
- ...c,
786
- x: Number(c.x) || 0,
787
- y: Number(c.y) || 0,
788
- z: Number(c.z) || 0
782
+ const i = Array.from(s.entries()).map(([c, u]) => ({
783
+ id: c,
784
+ points: u.sort((l, a) => l.order - a.order).map((l) => ({
785
+ ...l,
786
+ x: Number(l.x) || 0,
787
+ y: Number(l.y) || 0,
788
+ z: Number(l.z) || 0
789
789
  }))
790
790
  }));
791
791
  n({ holes: i });
@@ -794,25 +794,25 @@ function ur(e, t = null) {
794
794
  });
795
795
  });
796
796
  }
797
- function be(e) {
797
+ function ze(e) {
798
798
  return e ? Array.isArray(e) ? [...e] : [] : [];
799
799
  }
800
- function K(e) {
800
+ function J(e) {
801
801
  const t = Number(e);
802
802
  return Number.isFinite(t) ? t : void 0;
803
803
  }
804
- function ft(e = [], t = []) {
804
+ function bt(e = [], t = []) {
805
805
  const n = [...e];
806
806
  return n.sort((r, o) => {
807
807
  for (let s = 0; s < t.length; s += 1) {
808
- const i = t[s], a = r == null ? void 0 : r[i], u = o == null ? void 0 : o[i];
809
- if (a !== u)
810
- return a == null ? 1 : u == null ? -1 : typeof a == "number" && typeof u == "number" ? a - u : `${a}`.localeCompare(`${u}`);
808
+ const i = t[s], c = r == null ? void 0 : r[i], u = o == null ? void 0 : o[i];
809
+ if (c !== u)
810
+ return c == null ? 1 : u == null ? -1 : typeof c == "number" && typeof u == "number" ? c - u : `${c}`.localeCompare(`${u}`);
811
811
  }
812
812
  return 0;
813
813
  }), n;
814
814
  }
815
- function Xt(e, t = {}) {
815
+ function on(e, t = {}) {
816
816
  return new Promise((n, r) => {
817
817
  W.parse(e, {
818
818
  header: !0,
@@ -824,10 +824,10 @@ function Xt(e, t = {}) {
824
824
  });
825
825
  });
826
826
  }
827
- function qt(e = [], t = null, n = null) {
828
- return e.map((r) => ue(r, t, n));
827
+ function sn(e = [], t = null, n = null) {
828
+ return e.map((r) => pe(r, t, n));
829
829
  }
830
- async function $e(e, t = {}) {
830
+ async function Be(e, t = {}) {
831
831
  const {
832
832
  kind: n = "csv",
833
833
  columnMap: r = null,
@@ -836,107 +836,107 @@ async function $e(e, t = {}) {
836
836
  } = t;
837
837
  let i;
838
838
  if (Array.isArray(e))
839
- i = be(e);
839
+ i = ze(e);
840
840
  else if (n === "csv")
841
- i = await Xt(e, s);
841
+ i = await on(e, s);
842
842
  else throw n === "parquet" || n === "sql" ? w("loadTable", new Error(`Unsupported kind in JS runtime: ${n}`)) : w("loadTable", new Error(`Unsupported kind: ${n}`));
843
- return qt(i, r, o);
843
+ return sn(i, r, o);
844
844
  }
845
- async function dr(e, t = {}) {
845
+ async function Lr(e, t = {}) {
846
846
  const {
847
847
  crs: n = null,
848
848
  sourceColumnMap: r = null,
849
849
  keepAll: o = !0,
850
850
  ...s
851
- } = t, i = await $e(e, { ...s, sourceColumnMap: r });
852
- if (!i.some((m) => b in m))
853
- throw w("loadCollars", new Error(`Collar table missing column: ${b}`));
854
- const u = i.some((m) => ie in m && se in m), c = i.some((m) => Q in m && ee in m);
855
- if (!u && !c)
851
+ } = t, i = await Be(e, { ...s, sourceColumnMap: r });
852
+ if (!i.some((d) => E in d))
853
+ throw w("loadCollars", new Error(`Collar table missing column: ${E}`));
854
+ const u = i.some((d) => ce in d && ue in d), l = i.some((d) => te in d && ne in d);
855
+ if (!u && !l)
856
856
  throw w("loadCollars", new Error("Collar table missing coordinate columns (need easting/northing or latitude/longitude)"));
857
- const l = i.map((m) => {
858
- const f = { ...m };
859
- if (b in f) {
860
- const p = f[b];
861
- f[b] = p == null ? "" : `${p}`.trim();
857
+ const a = i.map((d) => {
858
+ const f = { ...d };
859
+ if (E in f) {
860
+ const b = f[E];
861
+ f[E] = b == null ? "" : `${b}`.trim();
862
862
  }
863
- return Q in f && (f[Q] = K(f[Q])), ee in f && (f[ee] = K(f[ee])), he in f && (f[he] = K(f[he])), ie in f && (f[ie] = K(f[ie])), se in f && (f[se] = K(f[se])), !("datasource_hole_id" in f) && b in f && (f.datasource_hole_id = f[b]), f;
863
+ return te in f && (f[te] = J(f[te])), ne in f && (f[ne] = J(f[ne])), ge in f && (f[ge] = J(f[ge])), ce in f && (f[ce] = J(f[ce])), ue in f && (f[ue] = J(f[ue])), !("datasource_hole_id" in f) && E in f && (f.datasource_hole_id = f[E]), f;
864
864
  });
865
- if (!l.every((m) => !(!m[b] || c && (!Number.isFinite(m[Q]) || !Number.isFinite(m[ee])) || u && !c && (!Number.isFinite(m[ie]) || !Number.isFinite(m[se])))))
865
+ if (!a.every((d) => !(!d[E] || l && (!Number.isFinite(d[te]) || !Number.isFinite(d[ne])) || u && !l && (!Number.isFinite(d[ce]) || !Number.isFinite(d[ue])))))
866
866
  throw w("loadCollars", new Error("Collar table has missing required values"));
867
- return l;
867
+ return a;
868
868
  }
869
- async function mr(e, t = {}) {
869
+ async function Tr(e, t = {}) {
870
870
  const {
871
871
  sourceColumnMap: n = null,
872
872
  keepAll: r = !0,
873
873
  ...o
874
- } = t, s = await $e(e, { ...o, sourceColumnMap: n }), i = [b, R, D, L];
875
- for (const c of i)
876
- if (!s.some((d) => c in d))
877
- throw w("loadSurveys", new Error(`Survey table missing column: ${c}`));
878
- const a = s.map((c) => {
879
- const l = { ...c };
880
- if (b in l) {
881
- const d = l[b];
882
- l[b] = d == null ? "" : `${d}`.trim();
874
+ } = t, s = await Be(e, { ...o, sourceColumnMap: n }), i = [E, Y, j, B];
875
+ for (const l of i)
876
+ if (!s.some((m) => l in m))
877
+ throw w("loadSurveys", new Error(`Survey table missing column: ${l}`));
878
+ const c = s.map((l) => {
879
+ const a = { ...l };
880
+ if (E in a) {
881
+ const m = a[E];
882
+ a[E] = m == null ? "" : `${m}`.trim();
883
883
  }
884
- return R in l && (l[R] = K(l[R])), F in l && (l[F] = K(l[F])), D in l && (l[D] = K(l[D])), L in l && (l[L] = K(l[L])), l;
884
+ return Y in a && (a[Y] = J(a[Y])), G in a && (a[G] = J(a[G])), j in a && (a[j] = J(a[j])), B in a && (a[B] = J(a[B])), a;
885
885
  });
886
- if (!a.every((c) => !(!c[b] || !Number.isFinite(c[R]) || !Number.isFinite(c[D]) || !Number.isFinite(c[L]))))
886
+ if (!c.every((l) => !(!l[E] || !Number.isFinite(l[Y]) || !Number.isFinite(l[j]) || !Number.isFinite(l[B]))))
887
887
  throw w("loadSurveys", new Error("Survey table has missing required values"));
888
- return ft(a, [b, R]);
888
+ return bt(c, [E, Y]);
889
889
  }
890
- async function fr(e, t = {}) {
890
+ async function Fr(e, t = {}) {
891
891
  const {
892
892
  sourceColumnMap: n = null,
893
893
  keepAll: r = !0,
894
894
  ...o
895
- } = t, s = await $e(e, { ...o, sourceColumnMap: n }), i = [b, $, F];
896
- for (const c of i)
897
- if (!s.some((d) => c in d))
898
- throw w("loadAssays", new Error(`Assay table missing column: ${c}`));
899
- const a = s.map((c) => {
900
- const l = { ...c };
901
- if (b in l) {
902
- const d = l[b];
903
- l[b] = d == null ? "" : `${d}`.trim();
895
+ } = t, s = await Be(e, { ...o, sourceColumnMap: n }), i = [E, X, G];
896
+ for (const l of i)
897
+ if (!s.some((m) => l in m))
898
+ throw w("loadAssays", new Error(`Assay table missing column: ${l}`));
899
+ const c = s.map((l) => {
900
+ const a = { ...l };
901
+ if (E in a) {
902
+ const m = a[E];
903
+ a[E] = m == null ? "" : `${m}`.trim();
904
904
  }
905
- return $ in l && (l[$] = K(l[$])), F in l && (l[F] = K(l[F])), $ in l && F in l && Number.isFinite(l[$]) && Number.isFinite(l[F]) && (l[we] = 0.5 * (l[$] + l[F])), l;
905
+ return X in a && (a[X] = J(a[X])), G in a && (a[G] = J(a[G])), X in a && G in a && Number.isFinite(a[X]) && Number.isFinite(a[G]) && (a[Re] = 0.5 * (a[X] + a[G])), a;
906
906
  });
907
- if (!a.every((c) => !(!c[b] || !Number.isFinite(c[$]) || !Number.isFinite(c[F]))))
907
+ if (!c.every((l) => !(!l[E] || !Number.isFinite(l[X]) || !Number.isFinite(l[G]))))
908
908
  throw w("loadAssays", new Error("Assay table has missing required values"));
909
- return ft(a, [b, $, F]);
909
+ return bt(c, [E, X, G]);
910
910
  }
911
- function hr(e = [], t = [], n = {}) {
912
- const r = Array.isArray(n.onCols) && n.onCols.length ? n.onCols : [b];
911
+ function Or(e = [], t = [], n = {}) {
912
+ const r = Array.isArray(n.onCols) && n.onCols.length ? n.onCols : [E];
913
913
  if (!t.length) return [...e];
914
- const o = (i) => r.map((a) => `${(i == null ? void 0 : i[a]) ?? ""}`).join("|"), s = /* @__PURE__ */ new Map();
914
+ const o = (i) => r.map((c) => `${(i == null ? void 0 : i[c]) ?? ""}`).join("|"), s = /* @__PURE__ */ new Map();
915
915
  return t.forEach((i) => {
916
916
  s.set(o(i), i);
917
917
  }), e.map((i) => {
918
- const a = s.get(o(i));
919
- if (!a) return { ...i };
918
+ const c = s.get(o(i));
919
+ if (!c) return { ...i };
920
920
  const u = { ...i };
921
- return Object.entries(a).forEach(([c, l]) => {
922
- r.includes(c) || (Object.prototype.hasOwnProperty.call(u, c) ? u[`${c}_trace`] = l : u[c] = l);
921
+ return Object.entries(c).forEach(([l, a]) => {
922
+ r.includes(l) || (Object.prototype.hasOwnProperty.call(u, l) ? u[`${l}_trace`] = a : u[l] = a);
923
923
  }), u;
924
924
  });
925
925
  }
926
- function pr(e = [], t = null) {
927
- return t == null ? [...e] : e.length ? e.some((r) => ne in r) ? e.filter((r) => (r == null ? void 0 : r[ne]) === t) : [...e] : [];
926
+ function Vr(e = [], t = null) {
927
+ return t == null ? [...e] : e.length ? e.some((r) => se in r) ? e.filter((r) => (r == null ? void 0 : r[se]) === t) : [...e] : [];
928
928
  }
929
- function yr(e = [], t = []) {
929
+ function wr(e = [], t = []) {
930
930
  return e.map((n) => {
931
931
  const r = { ...n };
932
932
  return t.forEach((o) => {
933
933
  if (!(o in r)) return;
934
- const s = K(r[o]);
934
+ const s = J(r[o]);
935
935
  r[o] = s;
936
936
  }), r;
937
937
  });
938
938
  }
939
- function gr({
939
+ function $r({
940
940
  collars: e = [],
941
941
  surveys: t = [],
942
942
  assays: n = [],
@@ -944,25 +944,46 @@ function gr({
944
944
  metadata: o = {}
945
945
  } = {}) {
946
946
  return {
947
- collars: be(e),
948
- surveys: be(t),
949
- assays: be(n),
950
- structures: be(r),
947
+ collars: ze(e),
948
+ surveys: ze(t),
949
+ assays: ze(n),
950
+ structures: ze(r),
951
951
  metadata: o || {}
952
952
  };
953
953
  }
954
- function br(e) {
954
+ const yt = ["x", "y", "z", "dx", "dy", "dz"], ln = {
955
+ x: ["x", "easting", "center_x", "xc", "xcentre", "xcenter", "x_centre", "x_center", "cx"],
956
+ y: ["y", "northing", "center_y", "yc", "ycentre", "ycenter", "y_centre", "y_center", "cy"],
957
+ z: ["z", "elevation", "center_z", "zc", "zcentre", "zcenter", "z_centre", "z_center", "cz"],
958
+ dx: ["dx", "size_x", "sx", "sizex", "dim_x", "block_size_x"],
959
+ dy: ["dy", "size_y", "sy", "sizey", "dim_y", "block_size_y"],
960
+ dz: ["dz", "size_z", "sz", "sizez", "dim_z", "block_size_z"]
961
+ }, gt = {};
962
+ Object.entries(ln).forEach(([e, t]) => {
963
+ t.forEach((n) => {
964
+ gt[n.toLowerCase()] = e;
965
+ });
966
+ });
967
+ function an(e) {
968
+ const t = {};
969
+ return Object.entries(e).forEach(([n, r]) => {
970
+ const o = gt[n.toLowerCase().trim()] || n;
971
+ t[o] = r;
972
+ }), t;
973
+ }
974
+ function Rr(e) {
955
975
  return new Promise((t, n) => {
956
976
  W.parse(e, {
957
977
  header: !0,
958
978
  dynamicTyping: !0,
979
+ skipEmptyLines: !0,
959
980
  complete: (r) => {
960
- const o = r.data.filter(
961
- (a) => a.center_x !== null && a.center_y !== null && a.center_z !== null
962
- ), s = ["center_x", "center_y", "center_z", "size_x", "size_y", "size_z"], i = Object.keys(o[0] || {}).filter(
963
- (a) => !s.includes(a)
981
+ const s = (r.data || []).map(an).filter(
982
+ (c) => c.x !== null && c.y !== null && c.z !== null
983
+ ), i = Object.keys(s[0] || {}).filter(
984
+ (c) => !yt.includes(c)
964
985
  );
965
- t({ data: o, properties: i });
986
+ t({ data: s, properties: i });
966
987
  },
967
988
  error: (r) => {
968
989
  n(w("parseBlockModelCSV", r));
@@ -970,73 +991,106 @@ function br(e) {
970
991
  });
971
992
  });
972
993
  }
973
- function _r(e, t) {
994
+ function Hr(e) {
995
+ if (typeof e == "string")
996
+ try {
997
+ return JSON.parse(e);
998
+ } catch (t) {
999
+ throw w("loadBlockModelMetadata", t);
1000
+ }
1001
+ if (e && typeof e == "object") return e;
1002
+ throw w("loadBlockModelMetadata", new Error("Invalid metadata source"));
1003
+ }
1004
+ function cn(e, t) {
974
1005
  const n = e.map((s) => s[t]).filter((s) => s != null);
975
- if (n.every((s) => typeof s == "number")) {
1006
+ if (n.length > 0 && n.every((s) => typeof s == "number")) {
976
1007
  const s = Math.min(...n), i = Math.max(...n);
977
1008
  return { type: "numeric", min: s, max: i, values: n };
978
1009
  }
979
1010
  return { type: "categorical", categories: [...new Set(n)], values: n };
980
1011
  }
981
- function Wt(e, t, n) {
1012
+ function jr(e) {
1013
+ if (!e || e.length === 0) return {};
1014
+ const t = Object.keys(e[0]).filter(
1015
+ (r) => !yt.includes(r)
1016
+ ), n = {};
1017
+ return t.forEach((r) => {
1018
+ n[r] = cn(e, r);
1019
+ }), n;
1020
+ }
1021
+ function un(e, t) {
1022
+ return !t || typeof t != "object" ? e : e.filter(
1023
+ (n) => Object.entries(t).every(([r, o]) => {
1024
+ const s = n[r];
1025
+ return o == null ? !0 : typeof o != "object" || Array.isArray(o) ? s === o : !("gt" in o && !(s > o.gt) || "gte" in o && !(s >= o.gte) || "lt" in o && !(s < o.lt) || "lte" in o && !(s <= o.lte) || "eq" in o && s !== o.eq || "ne" in o && s === o.ne || "in" in o && !o.in.includes(s));
1026
+ })
1027
+ );
1028
+ }
1029
+ function Br(e, t = null) {
1030
+ return (t ? un(e, t) : e).reduce((r, o) => {
1031
+ const s = Number(o.dx) || 0, i = Number(o.dy) || 0, c = Number(o.dz) || 0;
1032
+ return r + s * i * c;
1033
+ }, 0);
1034
+ }
1035
+ function mn(e, t, n) {
982
1036
  if (!t) return new n.Color("#888888");
983
1037
  if (t.type === "numeric") {
984
- const s = t.max - t.min, a = (1 - (s === 0 ? 0.5 : (e - t.min) / s)) * 240;
985
- return new n.Color().setHSL(a / 360, 0.8, 0.5);
1038
+ const s = t.max - t.min, c = (1 - (s === 0 ? 0.5 : (e - t.min) / s)) * 240;
1039
+ return new n.Color().setHSL(c / 360, 0.8, 0.5);
986
1040
  }
987
1041
  const o = t.categories.indexOf(e) / Math.max(t.categories.length, 1) * 360;
988
1042
  return new n.Color().setHSL(o / 360, 0.7, 0.5);
989
1043
  }
990
- const He = (e, t = null) => ue(e, null, t);
991
- function Zt(e) {
1044
+ const Ge = (e, t = null) => pe(e, null, t);
1045
+ function dn(e) {
992
1046
  if (!e.length) return null;
993
- const t = e[0], n = $ in t && F in t, r = R in t && !n;
1047
+ const t = e[0], n = X in t && G in t, r = Y in t && !n;
994
1048
  return n ? "interval" : r ? "point" : null;
995
1049
  }
996
- function te(e) {
1050
+ function oe(e) {
997
1051
  const t = Number(e);
998
1052
  return Number.isFinite(t) ? t : null;
999
1053
  }
1000
- function ht(e) {
1001
- const t = e[b] !== void 0 ? `${e[b]}`.trim() : "";
1054
+ function _t(e) {
1055
+ const t = e[E] !== void 0 ? `${e[E]}`.trim() : "";
1002
1056
  if (!t) return null;
1003
- const n = te(e[R]);
1057
+ const n = oe(e[Y]);
1004
1058
  return n === null ? null : {
1005
- [b]: t,
1006
- [R]: n,
1007
- [L]: te(e[L]),
1008
- [D]: te(e[D]),
1059
+ [E]: t,
1060
+ [Y]: n,
1061
+ [B]: oe(e[B]),
1062
+ [j]: oe(e[j]),
1009
1063
  comments: e.comments != null ? `${e.comments}` : null,
1010
1064
  ...e
1011
1065
  };
1012
1066
  }
1013
- function pt(e) {
1014
- const t = e[b] !== void 0 ? `${e[b]}`.trim() : "";
1067
+ function xt(e) {
1068
+ const t = e[E] !== void 0 ? `${e[E]}`.trim() : "";
1015
1069
  if (!t) return null;
1016
- const n = te(e[$]), r = te(e[F]);
1070
+ const n = oe(e[X]), r = oe(e[G]);
1017
1071
  if (n === null || r === null || r <= n) return null;
1018
1072
  const o = 0.5 * (n + r);
1019
1073
  return {
1020
- [b]: t,
1021
- [$]: n,
1022
- [F]: r,
1074
+ [E]: t,
1075
+ [X]: n,
1076
+ [G]: r,
1023
1077
  mid: o,
1024
- [L]: te(e[L]),
1025
- [D]: te(e[D]),
1078
+ [B]: oe(e[B]),
1079
+ [j]: oe(e[j]),
1026
1080
  classification: e.classification != null ? `${e.classification}` : null,
1027
1081
  comments: e.comments != null ? `${e.comments}` : null,
1028
1082
  ...e
1029
1083
  };
1030
1084
  }
1031
- function xr(e) {
1085
+ function Gr(e) {
1032
1086
  const t = [], n = [];
1033
1087
  for (const r of e) {
1034
- const o = [], s = te(r[L]), i = te(r[D]);
1088
+ const o = [], s = oe(r[B]), i = oe(r[j]);
1035
1089
  s !== null && (s < 0 || s > 90) && o.push(`dip ${s} out of range [0, 90]`), i !== null && (i < 0 || i >= 360) && o.push(`azimuth ${i} out of range [0, 360)`), o.length ? n.push({ row: r, message: o.join("; ") }) : t.push(r);
1036
1090
  }
1037
1091
  return { valid: t, errors: n };
1038
1092
  }
1039
- function Cr(e, t = null) {
1093
+ function Ur(e, t = null) {
1040
1094
  return new Promise((n, r) => {
1041
1095
  const o = {
1042
1096
  header: !0,
@@ -1044,9 +1098,9 @@ function Cr(e, t = null) {
1044
1098
  skipEmptyLines: !0,
1045
1099
  complete: (s) => {
1046
1100
  const i = [];
1047
- for (const a of s.data) {
1048
- const u = He(a, t), c = ht(u);
1049
- c && i.push(c);
1101
+ for (const c of s.data) {
1102
+ const u = Ge(c, t), l = _t(u);
1103
+ l && i.push(l);
1050
1104
  }
1051
1105
  n(i);
1052
1106
  },
@@ -1056,7 +1110,7 @@ function Cr(e, t = null) {
1056
1110
  `) ? W.parse(e, o) : W.parse(e, o);
1057
1111
  });
1058
1112
  }
1059
- function zr(e, t = null) {
1113
+ function Yr(e, t = null) {
1060
1114
  return new Promise((n, r) => {
1061
1115
  W.parse(e, {
1062
1116
  header: !0,
@@ -1065,7 +1119,7 @@ function zr(e, t = null) {
1065
1119
  complete: (o) => {
1066
1120
  const s = [];
1067
1121
  for (const i of o.data) {
1068
- const a = He(i, t), u = pt(a);
1122
+ const c = Ge(i, t), u = xt(c);
1069
1123
  u && s.push(u);
1070
1124
  }
1071
1125
  n(s);
@@ -1074,7 +1128,7 @@ function zr(e, t = null) {
1074
1128
  });
1075
1129
  });
1076
1130
  }
1077
- function Kt(e, t = b) {
1131
+ function fn(e, t = E) {
1078
1132
  const n = /* @__PURE__ */ new Map();
1079
1133
  for (const r of e) {
1080
1134
  const o = r[t] != null ? String(r[t]).trim() : "";
@@ -1082,14 +1136,14 @@ function Kt(e, t = b) {
1082
1136
  }
1083
1137
  return Array.from(n.values());
1084
1138
  }
1085
- function Jt(e, t = null) {
1139
+ function hn(e, t = null) {
1086
1140
  return new Promise((n, r) => {
1087
1141
  W.parse(e, {
1088
1142
  header: !0,
1089
1143
  dynamicTyping: !0,
1090
1144
  skipEmptyLines: !0,
1091
1145
  complete: (o) => {
1092
- const s = o.data.map((u) => He(u, t)), i = Zt(s);
1146
+ const s = o.data.map((u) => Ge(u, t)), i = dn(s);
1093
1147
  if (!i) {
1094
1148
  r(w(
1095
1149
  "parseStructuralCSV",
@@ -1097,18 +1151,18 @@ function Jt(e, t = null) {
1097
1151
  ));
1098
1152
  return;
1099
1153
  }
1100
- const a = [];
1154
+ const c = [];
1101
1155
  for (const u of s) {
1102
- const c = i === "interval" ? pt(u) : ht(u);
1103
- c && a.push(c);
1156
+ const l = i === "interval" ? xt(u) : _t(u);
1157
+ l && c.push(l);
1104
1158
  }
1105
- n({ schema: i, rows: a });
1159
+ n({ schema: i, rows: c });
1106
1160
  },
1107
1161
  error: (o) => r(w("parseStructuralCSV", o))
1108
1162
  });
1109
1163
  });
1110
1164
  }
1111
- function Qt(e) {
1165
+ function pn(e) {
1112
1166
  return new Promise((t) => {
1113
1167
  W.parse(e, {
1114
1168
  header: !0,
@@ -1117,85 +1171,183 @@ function Qt(e) {
1117
1171
  complete: (n) => {
1118
1172
  const r = /* @__PURE__ */ new Map();
1119
1173
  for (const s of n.data) {
1120
- const i = ue(s), a = i[b] != null ? `${i[b]}`.trim() : "";
1121
- if (!a) continue;
1122
- const u = Number(i[$]), c = Number(i[F]);
1123
- if (!Number.isFinite(u) || !Number.isFinite(c) || c <= u) continue;
1124
- const l = (u + c) / 2, { [L]: d, [D]: m, ...f } = i, p = {
1174
+ const i = pe(s), c = i[E] != null ? `${i[E]}`.trim() : "";
1175
+ if (!c) continue;
1176
+ const u = Number(i[X]), l = Number(i[G]);
1177
+ if (!Number.isFinite(u) || !Number.isFinite(l) || l <= u) continue;
1178
+ const a = (u + l) / 2, { [B]: m, [j]: d, ...f } = i, b = {
1125
1179
  ...f,
1126
- [b]: a,
1127
- [$]: u,
1128
- [F]: c,
1129
- [we]: l,
1130
- [R]: l,
1180
+ [E]: c,
1181
+ [X]: u,
1182
+ [G]: l,
1183
+ [Re]: a,
1184
+ [Y]: a,
1131
1185
  // unified depth field for y-axis rendering
1132
1186
  _source: "assay"
1133
1187
  };
1134
- r.has(a) || r.set(a, []), r.get(a).push(p);
1188
+ r.has(c) || r.set(c, []), r.get(c).push(b);
1135
1189
  }
1136
1190
  const o = Array.from(r.entries()).map(([s, i]) => ({
1137
1191
  holeId: s,
1138
- points: i.sort((a, u) => a[$] - u[$])
1192
+ points: i.sort((c, u) => c[X] - u[X])
1139
1193
  }));
1140
1194
  t(o);
1141
1195
  }
1142
1196
  });
1143
1197
  });
1144
1198
  }
1145
- async function Nr({ assayCsv: e, structuralCsv: t } = {}) {
1199
+ async function qr({ assayCsv: e, structuralCsv: t } = {}) {
1146
1200
  const [n, r] = await Promise.all([
1147
- e ? Qt(e) : Promise.resolve([]),
1148
- t ? Jt(t).then(
1149
- ({ rows: s }) => Kt(s.map((i) => ({ ...i, _source: "structural" })))
1201
+ e ? pn(e) : Promise.resolve([]),
1202
+ t ? hn(t).then(
1203
+ ({ rows: s }) => fn(s.map((i) => ({ ...i, _source: "structural" })))
1150
1204
  ) : Promise.resolve([])
1151
1205
  ]), o = new Map(n.map((s) => [s.holeId, { ...s, points: [...s.points] }]));
1152
1206
  for (const s of r) {
1153
1207
  const i = s.holeId;
1154
1208
  if (i)
1155
1209
  if (o.has(i)) {
1156
- const a = o.get(i);
1157
- o.set(i, { ...a, points: [...a.points, ...s.points || []] });
1210
+ const c = o.get(i);
1211
+ o.set(i, { ...c, points: [...c.points, ...s.points || []] });
1158
1212
  } else
1159
1213
  o.set(i, s);
1160
1214
  }
1161
1215
  return { holes: Array.from(o.values()) };
1162
1216
  }
1163
- const Ze = "#8b1e3f", en = "#a8324f", tn = "#6b7280", nn = { l: 4, r: 4, t: 4, b: 4 }, Ke = 10, Je = 12;
1164
- function Qe(e) {
1217
+ function bn(e, t) {
1218
+ if (!e || e.length === 0 || !Number.isFinite(t)) return null;
1219
+ const n = e.length;
1220
+ if (n === 1) {
1221
+ const y = e[0];
1222
+ return { x: Number(y.x), y: Number(y.y), z: Number(y.z), dx: 0, dy: 0, dz: -1 };
1223
+ }
1224
+ let r = -1;
1225
+ for (let y = 0; y < n - 1; y++) {
1226
+ const I = Number(e[y].md), z = Number(e[y + 1].md);
1227
+ if (t >= I && t <= z) {
1228
+ r = y;
1229
+ break;
1230
+ }
1231
+ }
1232
+ let o, s, i;
1233
+ if (r === -1) {
1234
+ t < Number(e[0].md) ? (o = e[0], s = e[1]) : (o = e[n - 2], s = e[n - 1]);
1235
+ const y = Number(o.md), z = Number(s.md) - y;
1236
+ i = z > 0 ? (t - y) / z : t < y ? 0 : 1;
1237
+ } else {
1238
+ o = e[r], s = e[r + 1];
1239
+ const y = Number(o.md), z = Number(s.md) - y;
1240
+ i = z > 0 ? (t - y) / z : 0;
1241
+ }
1242
+ const c = Number(o.x) + i * (Number(s.x) - Number(o.x)), u = Number(o.y) + i * (Number(s.y) - Number(o.y)), l = Number(o.z) + i * (Number(s.z) - Number(o.z));
1243
+ let a, m, d;
1244
+ const f = Number(o.azimuth), b = Number(o.dip), p = Number(s.azimuth), h = Number(s.dip);
1245
+ if (Number.isFinite(f) && Number.isFinite(b)) {
1246
+ const y = Number.isFinite(p) && Number.isFinite(h) ? f + i * (p - f) : f, I = Number.isFinite(p) && Number.isFinite(h) ? b + i * (h - b) : b, z = y * Math.PI / 180, x = I * Math.PI / 180;
1247
+ a = Math.cos(x) * Math.sin(z), m = Math.cos(x) * Math.cos(z), d = -Math.sin(x);
1248
+ } else {
1249
+ const y = Number(s.x) - Number(o.x), I = Number(s.y) - Number(o.y), z = Number(s.z) - Number(o.z), x = Math.sqrt(y * y + I * I + z * z);
1250
+ if (x < 1e-10) return { x: c, y: u, z: l, dx: 0, dy: 0, dz: -1 };
1251
+ a = y / x, m = I / x, d = z / x;
1252
+ }
1253
+ const _ = Math.sqrt(a * a + m * m + d * d);
1254
+ return _ < 1e-10 ? { x: c, y: u, z: l, dx: 0, dy: 0, dz: -1 } : { x: c, y: u, z: l, dx: a / _, dy: m / _, dz: d / _ };
1255
+ }
1256
+ function yn(e, t, n, r = {}) {
1257
+ const { betaZeroAxis: o = "B", betaHandedness: s = 1 } = r, { dx: i, dy: c, dz: u } = n, l = [i, c, u];
1258
+ let a = [0, 0, 1];
1259
+ const m = l[0] * a[0] + l[1] * a[1] + l[2] * a[2];
1260
+ Math.abs(m) > 0.99 && (a = [0, 1, 0]);
1261
+ const d = [
1262
+ a[1] * l[2] - a[2] * l[1],
1263
+ a[2] * l[0] - a[0] * l[2],
1264
+ a[0] * l[1] - a[1] * l[0]
1265
+ ], f = Math.sqrt(d[0] ** 2 + d[1] ** 2 + d[2] ** 2), b = f > 1e-10 ? [d[0] / f, d[1] / f, d[2] / f] : [1, 0, 0], p = [
1266
+ l[1] * b[2] - l[2] * b[1],
1267
+ l[2] * b[0] - l[0] * b[2],
1268
+ l[0] * b[1] - l[1] * b[0]
1269
+ ], h = Math.sqrt(p[0] ** 2 + p[1] ** 2 + p[2] ** 2), _ = h > 1e-10 ? [p[0] / h, p[1] / h, p[2] / h] : [0, 1, 0], y = o === "R" ? b : _, I = t * Math.PI / 180 * s, z = Math.cos(I), x = Math.sin(I), D = y[0] * l[0] + y[1] * l[1] + y[2] * l[2], S = [
1270
+ l[1] * y[2] - l[2] * y[1],
1271
+ l[2] * y[0] - l[0] * y[2],
1272
+ l[0] * y[1] - l[1] * y[0]
1273
+ ], M = [
1274
+ y[0] * z + S[0] * x + l[0] * D * (1 - z),
1275
+ y[1] * z + S[1] * x + l[1] * D * (1 - z),
1276
+ y[2] * z + S[2] * x + l[2] * D * (1 - z)
1277
+ ], O = (90 - e) * Math.PI / 180, $ = Math.cos(O), Z = Math.sin(O), T = $ * M[0] + Z * l[0], R = $ * M[1] + Z * l[1], q = $ * M[2] + Z * l[2], A = Math.sqrt(T * T + R * R + q * q);
1278
+ return A < 1e-10 ? { nx: 0, ny: 0, nz: 1 } : { nx: T / A, ny: R / A, nz: q / A };
1279
+ }
1280
+ function gn(e, t, n = {}) {
1281
+ if (!(e != null && e.length) || !(t != null && t.length)) return [];
1282
+ const r = /* @__PURE__ */ new Map();
1283
+ for (const s of t) {
1284
+ const i = s.hole_id != null ? `${s.hole_id}`.trim().toLowerCase() : "";
1285
+ i && (r.has(i) || r.set(i, []), r.get(i).push(s));
1286
+ }
1287
+ for (const [, s] of r)
1288
+ s.sort((i, c) => Number(i.md) - Number(c.md));
1289
+ const o = [];
1290
+ for (const s of e) {
1291
+ const i = s.hole_id != null ? `${s.hole_id}`.trim().toLowerCase() : "";
1292
+ if (!i) continue;
1293
+ const c = r.get(i);
1294
+ if (!c || c.length === 0) continue;
1295
+ const u = s.depth != null ? Number(s.depth) : s.mid != null ? Number(s.mid) : null;
1296
+ if (!Number.isFinite(u)) continue;
1297
+ const l = bn(c, u);
1298
+ if (!l) continue;
1299
+ const { x: a, y: m, z: d, dx: f, dy: b, dz: p } = l;
1300
+ let h, _, y;
1301
+ const I = s.alpha != null ? Number(s.alpha) : null, z = s.beta != null ? Number(s.beta) : null;
1302
+ if (Number.isFinite(I)) {
1303
+ const x = Number.isFinite(z) ? z : 0, D = yn(I, x, { dx: f, dy: b, dz: p }, n);
1304
+ h = D.nx, _ = D.ny, y = D.nz;
1305
+ } else {
1306
+ const x = s.dip != null ? Number(s.dip) : null, D = s.azimuth != null ? Number(s.azimuth) : null;
1307
+ if (!Number.isFinite(x) || !Number.isFinite(D)) continue;
1308
+ const S = x * Math.PI / 180, M = D * Math.PI / 180;
1309
+ h = Math.sin(M) * Math.sin(S), _ = Math.cos(M) * Math.sin(S), y = Math.cos(S);
1310
+ }
1311
+ o.push({ ...s, x: a, y: m, z: d, nx: h, ny: _, nz: y });
1312
+ }
1313
+ return o;
1314
+ }
1315
+ const Qe = "#8b1e3f", _n = "#a8324f", xn = "#6b7280", Nn = { l: 4, r: 4, t: 4, b: 4 }, et = 10, tt = 12;
1316
+ function nt(e) {
1165
1317
  return e ? typeof e == "string" ? { text: e } : e : {};
1166
1318
  }
1167
- function yt(e = {}) {
1168
- const t = Qe(e.xaxis && e.xaxis.title), n = Qe(e.yaxis && e.yaxis.title);
1319
+ function Nt(e = {}) {
1320
+ const t = nt(e.xaxis && e.xaxis.title), n = nt(e.yaxis && e.yaxis.title);
1169
1321
  return {
1170
1322
  ...e,
1171
- margin: nn,
1323
+ margin: Nn,
1172
1324
  autosize: !0,
1173
1325
  width: void 0,
1174
1326
  xaxis: {
1175
1327
  ...e.xaxis || {},
1176
1328
  tickfont: {
1177
1329
  ...e.xaxis && e.xaxis.tickfont || {},
1178
- size: Ke
1330
+ size: et
1179
1331
  },
1180
1332
  title: {
1181
1333
  ...t,
1182
- font: { ...t.font || {}, size: Je }
1334
+ font: { ...t.font || {}, size: tt }
1183
1335
  }
1184
1336
  },
1185
1337
  yaxis: {
1186
1338
  ...e.yaxis || {},
1187
1339
  tickfont: {
1188
1340
  ...e.yaxis && e.yaxis.tickfont || {},
1189
- size: Ke
1341
+ size: et
1190
1342
  },
1191
1343
  title: {
1192
1344
  ...n,
1193
- font: { ...n.font || {}, size: Je }
1345
+ font: { ...n.font || {}, size: tt }
1194
1346
  }
1195
1347
  }
1196
1348
  };
1197
1349
  }
1198
- function rn(e, t) {
1350
+ function zn(e, t) {
1199
1351
  var r;
1200
1352
  if (!e || !t) return !1;
1201
1353
  const n = e.points || [];
@@ -1206,115 +1358,115 @@ function rn(e, t) {
1206
1358
  }
1207
1359
  return !1;
1208
1360
  }
1209
- function on(e, t, n) {
1361
+ function Mn(e, t, n) {
1210
1362
  if (!e || !t) return [];
1211
1363
  const r = (e == null ? void 0 : e.points) || [], o = [], s = /* @__PURE__ */ new Set();
1212
1364
  return r.forEach((i) => {
1213
- let a = Number(
1365
+ let c = Number(
1214
1366
  i.from ?? i.samp_from ?? i.sample_from ?? i.fromdepth ?? i.from_depth ?? i.depth_from
1215
1367
  ), u = Number(
1216
1368
  i.to ?? i.samp_to ?? i.sample_to ?? i.todepth ?? i.to_depth ?? i.depth_to
1217
1369
  );
1218
- if (!Number.isFinite(a) || !Number.isFinite(u)) {
1370
+ if (!Number.isFinite(c) || !Number.isFinite(u)) {
1219
1371
  const f = Number(i.depth ?? i.md);
1220
- Number.isFinite(f) && (a = f, u = f);
1372
+ Number.isFinite(f) && (c = f, u = f);
1221
1373
  }
1222
- const c = i == null ? void 0 : i[t];
1223
- if (!Number.isFinite(a) || !Number.isFinite(u) || u < a || c == null || c === "" || n && typeof c == "string" && /^(nan|null|none)$/i.test(c.trim())) return;
1224
- const l = `${t}:${a}-${u}`;
1225
- if (s.has(l)) return;
1226
- s.add(l);
1227
- const d = (a + u) / 2, m = n ? c : Number(c);
1228
- !n && !Number.isFinite(m) || o.push({
1229
- z: d,
1230
- val: m,
1231
- from: a,
1374
+ const l = i == null ? void 0 : i[t];
1375
+ if (!Number.isFinite(c) || !Number.isFinite(u) || u < c || l == null || l === "" || n && typeof l == "string" && /^(nan|null|none)$/i.test(l.trim())) return;
1376
+ const a = `${t}:${c}-${u}`;
1377
+ if (s.has(a)) return;
1378
+ s.add(a);
1379
+ const m = (c + u) / 2, d = n ? l : Number(l);
1380
+ !n && !Number.isFinite(d) || o.push({
1381
+ z: m,
1382
+ val: d,
1383
+ from: c,
1232
1384
  to: u,
1233
- errorPlus: u - d,
1234
- errorMinus: d - a
1385
+ errorPlus: u - m,
1386
+ errorMinus: m - c
1235
1387
  });
1236
- }), o.sort((i, a) => a.z - i.z);
1388
+ }), o.sort((i, c) => c.z - i.z);
1237
1389
  }
1238
- function sn(e, t) {
1390
+ function Cn(e, t) {
1239
1391
  if (!e.length) return { data: [], layout: {} };
1240
- const n = [...e].sort((l, d) => d.z - l.z), r = [];
1241
- for (let l = 0; l < n.length; l += 1) {
1242
- const d = n[l], m = n[l + 1], f = d.z, p = m ? m.z : d.z - 20;
1243
- if (p === f) continue;
1244
- const y = d.val == null ? "" : String(d.val).trim();
1245
- !y || /^(nan|null|none)$/i.test(y) || r.push({ y0: f, y1: p, category: y, fromVal: d.from, toVal: d.to });
1392
+ const n = [...e].sort((a, m) => m.z - a.z), r = [];
1393
+ for (let a = 0; a < n.length; a += 1) {
1394
+ const m = n[a], d = n[a + 1], f = m.z, b = d ? d.z : m.z - 20;
1395
+ if (b === f) continue;
1396
+ const p = m.val == null ? "" : String(m.val).trim();
1397
+ !p || /^(nan|null|none)$/i.test(p) || r.push({ y0: f, y1: b, category: p, fromVal: m.from, toVal: m.to });
1246
1398
  }
1247
- const o = ["#4e79a7", "#f28e2b", "#e15759", "#76b7b2", "#59a14f", "#edc948", "#b07aa1", "#ff9da7", "#9c755f", "#bab0ac", "#d4a6c8", "#86bcb6"], s = [...new Set(r.map((l) => l.category))], i = Object.fromEntries(
1248
- s.map((l, d) => [l, o[d % o.length]])
1249
- ), a = r.map((l) => ({
1399
+ const o = ["#4e79a7", "#f28e2b", "#e15759", "#76b7b2", "#59a14f", "#edc948", "#b07aa1", "#ff9da7", "#9c755f", "#bab0ac", "#d4a6c8", "#86bcb6"], s = [...new Set(r.map((a) => a.category))], i = Object.fromEntries(
1400
+ s.map((a, m) => [a, o[m % o.length]])
1401
+ ), c = r.map((a) => ({
1250
1402
  type: "rect",
1251
1403
  xref: "x",
1252
1404
  yref: "y",
1253
1405
  x0: 0,
1254
1406
  x1: 1,
1255
- y0: l.y0,
1256
- y1: l.y1,
1257
- fillcolor: i[l.category],
1407
+ y0: a.y0,
1408
+ y1: a.y1,
1409
+ fillcolor: i[a.category],
1258
1410
  line: { width: 0 }
1259
1411
  }));
1260
1412
  return { data: [{
1261
1413
  x: r.map(() => 0.5),
1262
- y: r.map((l) => (l.y0 + l.y1) / 2),
1414
+ y: r.map((a) => (a.y0 + a.y1) / 2),
1263
1415
  mode: "text",
1264
- text: r.map((l) => l.category),
1416
+ text: r.map((a) => a.category),
1265
1417
  textposition: "middle center",
1266
1418
  showlegend: !1,
1267
1419
  hoverinfo: "text",
1268
- customdata: r.map((l) => [Math.min(l.fromVal, l.toVal), Math.max(l.fromVal, l.toVal)]),
1420
+ customdata: r.map((a) => [Math.min(a.fromVal, a.toVal), Math.max(a.fromVal, a.toVal)]),
1269
1421
  hovertemplate: "Category: %{text}<br>from: %{customdata[0]} to: %{customdata[1]}<extra></extra>"
1270
- }], layout: yt({
1422
+ }], layout: Nt({
1271
1423
  xaxis: { range: [0, 1], visible: !1, fixedrange: !0 },
1272
1424
  yaxis: { title: "Depth (m)", autorange: "reversed", zeroline: !1 },
1273
- shapes: a,
1425
+ shapes: c,
1274
1426
  showlegend: !1,
1275
1427
  title: t || void 0
1276
1428
  }) };
1277
1429
  }
1278
- function an(e, t, n) {
1430
+ function In(e, t, n) {
1279
1431
  if (!e.length) return { data: [], layout: {} };
1280
1432
  const r = n === "bar", o = n === "markers", s = n === "line", i = {
1281
- x: e.map((l) => l.val),
1282
- y: e.map((l) => l.z),
1433
+ x: e.map((a) => a.val),
1434
+ y: e.map((a) => a.z),
1283
1435
  hovertemplate: `${t}: %{x}<br>from: %{customdata[0]} to: %{customdata[1]}<extra></extra>`,
1284
- customdata: e.map((l) => [Math.min(l.from, l.to), Math.max(l.from, l.to)])
1285
- }, a = {
1436
+ customdata: e.map((a) => [Math.min(a.from, a.to), Math.max(a.from, a.to)])
1437
+ }, c = {
1286
1438
  type: "data",
1287
1439
  symmetric: !1,
1288
- array: e.map((l) => l.errorPlus),
1289
- arrayminus: e.map((l) => l.errorMinus),
1440
+ array: e.map((a) => a.errorPlus),
1441
+ arrayminus: e.map((a) => a.errorMinus),
1290
1442
  thickness: 1.5,
1291
1443
  width: 2,
1292
- color: tn
1444
+ color: xn
1293
1445
  };
1294
1446
  return { data: [r ? {
1295
1447
  ...i,
1296
1448
  type: "bar",
1297
1449
  orientation: "h",
1298
- marker: { color: Ze },
1299
- error_y: a
1450
+ marker: { color: Qe },
1451
+ error_y: c
1300
1452
  } : {
1301
1453
  ...i,
1302
1454
  type: "scatter",
1303
1455
  mode: o ? "markers" : s ? "lines" : "lines+markers",
1304
- line: { color: Ze, width: 2 },
1305
- marker: { size: 7, color: en },
1306
- error_y: s ? void 0 : a
1307
- }], layout: yt({
1456
+ line: { color: Qe, width: 2 },
1457
+ marker: { size: 7, color: _n },
1458
+ error_y: s ? void 0 : c
1459
+ }], layout: Nt({
1308
1460
  xaxis: { title: t, zeroline: !1 },
1309
1461
  yaxis: { title: "Depth (m)", autorange: "reversed", zeroline: !1 },
1310
1462
  barmode: "overlay",
1311
1463
  showlegend: !1
1312
1464
  }) };
1313
1465
  }
1314
- function ln({ points: e, isCategorical: t, property: n, chartType: r }) {
1315
- return !e || !e.length || !n ? { data: [], layout: {} } : t || r === "categorical" ? sn(e, n) : an(e, n, r);
1466
+ function An({ points: e, isCategorical: t, property: n, chartType: r }) {
1467
+ return !e || !e.length || !n ? { data: [], layout: {} } : t || r === "categorical" ? Cn(e, n) : In(e, n, r);
1316
1468
  }
1317
- const gt = [
1469
+ const zt = [
1318
1470
  "#0f172a",
1319
1471
  "#1e3a5f",
1320
1472
  "#7c3aed",
@@ -1325,24 +1477,24 @@ const gt = [
1325
1477
  "#db2777",
1326
1478
  "#65a30d",
1327
1479
  "#9333ea"
1328
- ], cn = { l: 4, r: 4, t: 4, b: 4 }, et = 10, tt = 12;
1329
- function bt(e = {}) {
1480
+ ], vn = { l: 4, r: 4, t: 4, b: 4 }, rt = 10, ot = 12;
1481
+ function Mt(e = {}) {
1330
1482
  return {
1331
1483
  ...e,
1332
- margin: cn,
1484
+ margin: vn,
1333
1485
  autosize: !0,
1334
1486
  width: void 0,
1335
1487
  xaxis: {
1336
1488
  ...e.xaxis || {},
1337
1489
  tickfont: {
1338
1490
  ...e.xaxis && e.xaxis.tickfont || {},
1339
- size: et
1491
+ size: rt
1340
1492
  },
1341
1493
  title: {
1342
1494
  ...e.xaxis && e.xaxis.title || {},
1343
1495
  font: {
1344
1496
  ...e.xaxis && e.xaxis.title && e.xaxis.title.font || {},
1345
- size: tt
1497
+ size: ot
1346
1498
  }
1347
1499
  }
1348
1500
  },
@@ -1350,66 +1502,66 @@ function bt(e = {}) {
1350
1502
  ...e.yaxis || {},
1351
1503
  tickfont: {
1352
1504
  ...e.yaxis && e.yaxis.tickfont || {},
1353
- size: et
1505
+ size: rt
1354
1506
  },
1355
1507
  title: {
1356
1508
  ...e.yaxis && e.yaxis.title || {},
1357
1509
  font: {
1358
1510
  ...e.yaxis && e.yaxis.title && e.yaxis.title.font || {},
1359
- size: tt
1511
+ size: ot
1360
1512
  }
1361
1513
  }
1362
1514
  }
1363
1515
  };
1364
1516
  }
1365
- function un(e, {
1517
+ function En(e, {
1366
1518
  tailScale: t = 5,
1367
1519
  colorBy: n = null,
1368
- palette: r = gt,
1369
- depthCol: o = R,
1370
- dipCol: s = L,
1371
- azCol: i = D
1520
+ palette: r = zt,
1521
+ depthCol: o = Y,
1522
+ dipCol: s = B,
1523
+ azCol: i = j
1372
1524
  } = {}) {
1373
- const a = e.filter(
1374
- (p) => p[o] != null && p[s] != null && p[i] != null
1525
+ const c = e.filter(
1526
+ (b) => b[o] != null && b[s] != null && b[i] != null
1375
1527
  );
1376
- if (!a.length)
1528
+ if (!c.length)
1377
1529
  return { data: [], layout: {} };
1378
1530
  const u = {};
1379
- n && [...new Set(a.map((y) => y[n]).filter((y) => y != null))].sort().forEach((y, h) => {
1380
- u[y] = r[h % r.length];
1531
+ n && [...new Set(c.map((p) => p[n]).filter((p) => p != null))].sort().forEach((p, h) => {
1532
+ u[p] = r[h % r.length];
1381
1533
  });
1382
- const c = /* @__PURE__ */ new Map(), l = [];
1383
- for (const p of a) {
1384
- const y = Number(p[o]), h = Number(p[s]), z = Number(p[i]), C = n ? p[n] ?? "_default" : "_default", E = n ? u[C] ?? "#0f172a" : "#0f172a";
1385
- c.has(C) || c.set(C, { xs: [], ys: [], dips: [], azs: [], color: E });
1386
- const H = c.get(C);
1387
- H.xs.push(h), H.ys.push(y), H.dips.push(h), H.azs.push(z);
1388
- const A = z * Math.PI / 180, j = t * (Math.abs(h) / 90), P = Math.sin(A) * j, N = Math.cos(A) * j;
1389
- l.push({
1534
+ const l = /* @__PURE__ */ new Map(), a = [];
1535
+ for (const b of c) {
1536
+ const p = Number(b[o]), h = Number(b[s]), _ = Number(b[i]), y = n ? b[n] ?? "_default" : "_default", I = n ? u[y] ?? "#0f172a" : "#0f172a";
1537
+ l.has(y) || l.set(y, { xs: [], ys: [], dips: [], azs: [], color: I });
1538
+ const z = l.get(y);
1539
+ z.xs.push(h), z.ys.push(p), z.dips.push(h), z.azs.push(_);
1540
+ const x = _ * Math.PI / 180, D = t * (Math.abs(h) / 90), S = Math.sin(x) * D, M = Math.cos(x) * D;
1541
+ a.push({
1390
1542
  type: "line",
1391
1543
  x0: h,
1392
- y0: y,
1393
- x1: h + P,
1394
- y1: y + N,
1395
- line: { color: E, width: 2 }
1544
+ y0: p,
1545
+ x1: h + S,
1546
+ y1: p + M,
1547
+ line: { color: I, width: 2 }
1396
1548
  });
1397
1549
  }
1398
- const d = [], m = n && c.size > 1;
1399
- for (const [p, y] of c.entries())
1400
- d.push({
1550
+ const m = [], d = n && l.size > 1;
1551
+ for (const [b, p] of l.entries())
1552
+ m.push({
1401
1553
  type: "scatter",
1402
- x: y.xs,
1403
- y: y.ys,
1554
+ x: p.xs,
1555
+ y: p.ys,
1404
1556
  mode: "markers",
1405
- name: p !== "_default" ? String(p) : void 0,
1406
- marker: { size: 8, color: y.color },
1407
- showlegend: m && p !== "_default",
1408
- customdata: y.dips.map((h, z) => [h, y.azs[z]]),
1557
+ name: b !== "_default" ? String(b) : void 0,
1558
+ marker: { size: 8, color: p.color },
1559
+ showlegend: d && b !== "_default",
1560
+ customdata: p.dips.map((h, _) => [h, p.azs[_]]),
1409
1561
  hovertemplate: "Depth: %{y}<br>Dip: %{customdata[0]}<br>Az: %{customdata[1]}<extra></extra>"
1410
1562
  });
1411
- return { data: d, layout: {
1412
- shapes: l,
1563
+ return { data: m, layout: {
1564
+ shapes: a,
1413
1565
  height: 400,
1414
1566
  margin: { l: 40, r: 10, t: 10, b: 40 },
1415
1567
  xaxis: {
@@ -1420,46 +1572,46 @@ function un(e, {
1420
1572
  tickvals: [-90, -60, -30, 0, 30, 60, 90]
1421
1573
  },
1422
1574
  yaxis: { title: "Depth (m)", autorange: "reversed" },
1423
- showlegend: !!m
1575
+ showlegend: !!d
1424
1576
  } };
1425
1577
  }
1426
- function Mr(e, {
1578
+ function Xr(e, {
1427
1579
  labelCol: t = "structure_type",
1428
- palette: n = gt,
1429
- fromCol: r = $,
1430
- toCol: o = F
1580
+ palette: n = zt,
1581
+ fromCol: r = X,
1582
+ toCol: o = G
1431
1583
  } = {}) {
1432
- const s = e.filter((d) => d[r] != null && d[o] != null && Number(d[o]) > Number(d[r])).filter((d) => {
1433
- const m = d[t];
1434
- if (m == null) return !1;
1435
- const f = String(m).trim();
1584
+ const s = e.filter((m) => m[r] != null && m[o] != null && Number(m[o]) > Number(m[r])).filter((m) => {
1585
+ const d = m[t];
1586
+ if (d == null) return !1;
1587
+ const f = String(d).trim();
1436
1588
  return f !== "" && !/^(nan|null|none)$/i.test(f);
1437
- }).map((d) => ({ from: Number(d[r]), to: Number(d[o]), label: String(d[t]).trim() })).sort((d, m) => d.from - m.from);
1589
+ }).map((m) => ({ from: Number(m[r]), to: Number(m[o]), label: String(m[t]).trim() })).sort((m, d) => m.from - d.from);
1438
1590
  if (!s.length)
1439
1591
  return { data: [], layout: {} };
1440
- const i = [], a = [], u = [];
1441
- return s.forEach((d, m) => {
1592
+ const i = [], c = [], u = [];
1593
+ return s.forEach((m, d) => {
1442
1594
  i.push({
1443
1595
  type: "rect",
1444
1596
  xref: "x",
1445
1597
  yref: "y",
1446
1598
  x0: 0,
1447
1599
  x1: 1,
1448
- y0: d.from,
1449
- y1: d.to,
1450
- fillcolor: n[m % n.length],
1600
+ y0: m.from,
1601
+ y1: m.to,
1602
+ fillcolor: n[d % n.length],
1451
1603
  line: { width: 0 }
1452
- }), a.push(0.5 * (d.from + d.to)), u.push(d.label);
1604
+ }), c.push(0.5 * (m.from + m.to)), u.push(m.label);
1453
1605
  }), { data: [{
1454
1606
  type: "scatter",
1455
1607
  x: Array(u.length).fill(0.5),
1456
- y: a,
1608
+ y: c,
1457
1609
  mode: "text",
1458
1610
  text: u,
1459
1611
  textposition: "middle center",
1460
1612
  showlegend: !1,
1461
1613
  hoverinfo: "text"
1462
- }], layout: bt({
1614
+ }], layout: Mt({
1463
1615
  shapes: i,
1464
1616
  height: 400,
1465
1617
  xaxis: { range: [0, 1], visible: !1, fixedrange: !0 },
@@ -1467,7 +1619,7 @@ function Mr(e, {
1467
1619
  showlegend: !1
1468
1620
  }) };
1469
1621
  }
1470
- function dn(e, t) {
1622
+ function Dn(e, t) {
1471
1623
  if (!e) return "";
1472
1624
  const n = String(e).trim().split(/\s+/), r = [];
1473
1625
  let o = "";
@@ -1475,25 +1627,25 @@ function dn(e, t) {
1475
1627
  o && o.length + 1 + s.length > t ? (r.push(o), o = s) : o = o ? `${o} ${s}` : s;
1476
1628
  return o && r.push(o), r.join("<br>");
1477
1629
  }
1478
- function mn(e, {
1630
+ function Sn(e, {
1479
1631
  commentCol: t = "comments",
1480
- fromCol: n = $,
1481
- toCol: r = F,
1632
+ fromCol: n = X,
1633
+ toCol: r = G,
1482
1634
  bgColor: o = "#f1f5f9",
1483
1635
  borderColor: s = "#cbd5e1",
1484
1636
  textColor: i = "#1e293b",
1485
- charsPerLine: a = 18
1637
+ charsPerLine: c = 18
1486
1638
  } = {}) {
1487
1639
  const u = e.filter((h) => h[n] != null && h[r] != null && Number(h[r]) > Number(h[n])).map((h) => {
1488
- const z = h[t], C = z != null && String(z).trim() !== "" && String(z) !== "null" ? String(z).trim() : "";
1489
- return { from: Number(h[n]), to: Number(h[r]), comment: C };
1490
- }).sort((h, z) => h.from - z.from);
1640
+ const _ = h[t], y = _ != null && String(_).trim() !== "" && String(_) !== "null" ? String(_).trim() : "";
1641
+ return { from: Number(h[n]), to: Number(h[r]), comment: y };
1642
+ }).sort((h, _) => h.from - _.from);
1491
1643
  if (!u.length)
1492
1644
  return { data: [], layout: {} };
1493
- const c = [], l = [], d = [], m = [], f = [];
1645
+ const l = [], a = [], m = [], d = [], f = [];
1494
1646
  for (const h of u) {
1495
- const z = 0.5 * (h.from + h.to), C = !!h.comment;
1496
- c.push({
1647
+ const _ = 0.5 * (h.from + h.to), y = !!h.comment;
1648
+ l.push({
1497
1649
  type: "rect",
1498
1650
  xref: "x",
1499
1651
  yref: "y",
@@ -1501,149 +1653,149 @@ function mn(e, {
1501
1653
  x1: 1,
1502
1654
  y0: h.from,
1503
1655
  y1: h.to,
1504
- fillcolor: C ? o : "rgba(0,0,0,0)",
1656
+ fillcolor: y ? o : "rgba(0,0,0,0)",
1505
1657
  line: { color: s, width: 1 }
1506
- }), C && (l.push(0.5), d.push(z), m.push(dn(h.comment, a)), f.push(`${h.from}–${h.to} m: ${h.comment}`));
1658
+ }), y && (a.push(0.5), m.push(_), d.push(Dn(h.comment, c)), f.push(`${h.from}–${h.to} m: ${h.comment}`));
1507
1659
  }
1508
- return { data: l.length ? [{
1660
+ return { data: a.length ? [{
1509
1661
  type: "scatter",
1510
- x: l,
1511
- y: d,
1662
+ x: a,
1663
+ y: m,
1512
1664
  mode: "text",
1513
- text: m,
1665
+ text: d,
1514
1666
  textposition: "middle center",
1515
1667
  textfont: { color: i, size: 10 },
1516
1668
  hovertext: f,
1517
1669
  hoverinfo: "text",
1518
1670
  showlegend: !1
1519
- }] : [], layout: bt({
1520
- shapes: c,
1671
+ }] : [], layout: Mt({
1672
+ shapes: l,
1521
1673
  height: 400,
1522
1674
  xaxis: { range: [0, 1], visible: !1, fixedrange: !0 },
1523
1675
  yaxis: { title: "Depth (m)", autorange: "reversed" },
1524
1676
  showlegend: !1
1525
1677
  }) };
1526
1678
  }
1527
- function Ir(e, {
1679
+ function Zr(e, {
1528
1680
  symbolSize: t = 10,
1529
1681
  xCol: n = "easting",
1530
1682
  yCol: r = "northing"
1531
1683
  } = {}) {
1532
- const o = e[n] != null ? Number(e[n]) : null, s = e[r] != null ? Number(e[r]) : null, i = e[L] != null ? Number(e[L]) : null, a = e[D] != null ? Number(e[D]) : null;
1533
- if (o === null || s === null || i === null || a === null) return null;
1534
- const u = (a - 90 + 360) % 360, c = u * Math.PI / 180, l = a * Math.PI / 180, d = t * Math.sin(c), m = t * Math.cos(c), f = t * 0.4 * (i / 90), p = f * Math.sin(l), y = f * Math.cos(l);
1684
+ const o = e[n] != null ? Number(e[n]) : null, s = e[r] != null ? Number(e[r]) : null, i = e[B] != null ? Number(e[B]) : null, c = e[j] != null ? Number(e[j]) : null;
1685
+ if (o === null || s === null || i === null || c === null) return null;
1686
+ const u = (c - 90 + 360) % 360, l = u * Math.PI / 180, a = c * Math.PI / 180, m = t * Math.sin(l), d = t * Math.cos(l), f = t * 0.4 * (i / 90), b = f * Math.sin(a), p = f * Math.cos(a);
1535
1687
  return {
1536
1688
  strike: u,
1537
1689
  dipValue: i,
1538
1690
  x: o,
1539
1691
  y: s,
1540
- strikeX0: o - d,
1541
- strikeY0: s - m,
1542
- strikeX1: o + d,
1543
- strikeY1: s + m,
1544
- tickX1: o + p,
1545
- tickY1: s + y
1692
+ strikeX0: o - m,
1693
+ strikeY0: s - d,
1694
+ strikeX1: o + m,
1695
+ strikeY1: s + d,
1696
+ tickX1: o + b,
1697
+ tickY1: s + p
1546
1698
  };
1547
1699
  }
1548
- const _t = "markers+line";
1549
- function fn(e, t) {
1700
+ const Ct = "markers+line";
1701
+ function Pn(e, t) {
1550
1702
  var r;
1551
- const n = Ve(e);
1552
- return n.some((o) => o.value === t) ? t : ((r = n[0]) == null ? void 0 : r.value) || _t;
1553
- }
1554
- function Ar({ config: e, graph: t, holeOptions: n = [], propertyOptions: r = [], onConfigChange: o }) {
1555
- const s = ot(null), i = t == null ? void 0 : t.hole, a = (t == null ? void 0 : t.points) || [], u = (e == null ? void 0 : e.property) || "", c = (e == null ? void 0 : e.chartType) || _t, l = (e == null ? void 0 : e.holeId) || "", d = (t == null ? void 0 : t.displayType) || (t != null && t.isComment ? pe : t != null && t.isCategorical ? _e : ye), m = Ve(d), f = fn(d, c), [p, y] = Z("");
1556
- return oe(() => {
1557
- const h = d === pe, z = d === ke;
1558
- if (!i || !u || !h && !z && a.length === 0) return;
1559
- const C = s.current;
1560
- if (!C) return;
1561
- let E;
1703
+ const n = He(e);
1704
+ return n.some((o) => o.value === t) ? t : ((r = n[0]) == null ? void 0 : r.value) || Ct;
1705
+ }
1706
+ function Wr({ config: e, graph: t, holeOptions: n = [], propertyOptions: r = [], onConfigChange: o }) {
1707
+ const s = lt(null), i = t == null ? void 0 : t.hole, c = (t == null ? void 0 : t.points) || [], u = (e == null ? void 0 : e.property) || "", l = (e == null ? void 0 : e.chartType) || Ct, a = (e == null ? void 0 : e.holeId) || "", m = (t == null ? void 0 : t.displayType) || (t != null && t.isComment ? _e : t != null && t.isCategorical ? Me : xe), d = He(m), f = Pn(m, l), [b, p] = K("");
1708
+ return ae(() => {
1709
+ const h = m === _e, _ = m === we;
1710
+ if (!i || !u || !h && !_ && c.length === 0) return;
1711
+ const y = s.current;
1712
+ if (!y) return;
1713
+ let I;
1562
1714
  try {
1563
- h ? E = mn(a, { commentCol: u, fromCol: "from", toCol: "to" }) : z ? E = un(a) : E = ln({
1564
- points: a,
1565
- isCategorical: d === _e,
1715
+ h ? I = Sn(c, { commentCol: u, fromCol: "from", toCol: "to" }) : _ ? I = En(c) : I = An({
1716
+ points: c,
1717
+ isCategorical: m === Me,
1566
1718
  property: u,
1567
1719
  chartType: f
1568
1720
  });
1569
- } catch (A) {
1570
- console.error("Plot build error", A), y((A == null ? void 0 : A.message) || "Plot build error");
1721
+ } catch (x) {
1722
+ console.error("Plot build error", x), p((x == null ? void 0 : x.message) || "Plot build error");
1571
1723
  return;
1572
1724
  }
1573
- if ((!(E != null && E.data) || E.data.length === 0) && !h)
1725
+ if ((!(I != null && I.data) || I.data.length === 0) && !h)
1574
1726
  return;
1575
- const H = {
1727
+ const z = {
1576
1728
  displayModeBar: !0,
1577
1729
  responsive: !0,
1578
1730
  useResizeHandler: !0,
1579
1731
  modeBarButtonsToRemove: ["select2d", "lasso2d", "zoom2d", "zoomIn2d", "zoomOut2d", "autoScale2d"]
1580
1732
  };
1581
1733
  try {
1582
- y(""), xe.react(C, E.data, E.layout, H), requestAnimationFrame(() => {
1583
- C && C.parentElement && xe.Plots.resize(C);
1734
+ p(""), Ce.react(y, I.data, I.layout, z), requestAnimationFrame(() => {
1735
+ y && y.parentElement && Ce.Plots.resize(y);
1584
1736
  });
1585
- } catch (A) {
1586
- console.error("Plot render error", A), y((A == null ? void 0 : A.message) || "Plot render error");
1737
+ } catch (x) {
1738
+ console.error("Plot render error", x), p((x == null ? void 0 : x.message) || "Plot render error");
1587
1739
  }
1588
1740
  return () => {
1589
- if (C)
1741
+ if (y)
1590
1742
  try {
1591
- xe.purge(C);
1592
- } catch (A) {
1593
- console.warn("Plot purge error", A);
1743
+ Ce.purge(y);
1744
+ } catch (x) {
1745
+ console.warn("Plot purge error", x);
1594
1746
  }
1595
1747
  };
1596
- }, [i, u, f, d, a]), oe(() => {
1748
+ }, [i, u, f, m, c]), ae(() => {
1597
1749
  const h = s.current;
1598
1750
  if (!h || typeof ResizeObserver > "u") return;
1599
- const z = new ResizeObserver(() => {
1751
+ const _ = new ResizeObserver(() => {
1600
1752
  try {
1601
- h && h.data && xe.Plots.resize(h);
1602
- } catch (C) {
1603
- console.warn("Plot resize error", C);
1753
+ h && h.data && Ce.Plots.resize(h);
1754
+ } catch (y) {
1755
+ console.warn("Plot resize error", y);
1604
1756
  }
1605
1757
  });
1606
- return z.observe(h), () => z.disconnect();
1607
- }, []), !i || !u ? /* @__PURE__ */ G("div", { className: "plot-card empty", children: /* @__PURE__ */ G("div", { className: "placeholder", children: e != null && e.holeId ? t != null && t.loading ? `Loading ${e.holeId}...` : "Select a property" : "Loading demo data..." }) }) : d !== pe && d !== ke && a.length === 0 ? /* @__PURE__ */ G("div", { className: "plot-card empty", children: /* @__PURE__ */ G("div", { className: "placeholder", children: "No data" }) }) : p ? /* @__PURE__ */ G("div", { className: "plot-card empty", children: /* @__PURE__ */ Ce("div", { className: "placeholder", children: [
1758
+ return _.observe(h), () => _.disconnect();
1759
+ }, []), !i || !u ? /* @__PURE__ */ L("div", { className: "plot-card empty", children: /* @__PURE__ */ L("div", { className: "placeholder", children: e != null && e.holeId ? t != null && t.loading ? `Loading ${e.holeId}...` : "Select a property" : "Loading demo data..." }) }) : m !== _e && m !== we && c.length === 0 ? /* @__PURE__ */ L("div", { className: "plot-card empty", children: /* @__PURE__ */ L("div", { className: "placeholder", children: "No data" }) }) : b ? /* @__PURE__ */ L("div", { className: "plot-card empty", children: /* @__PURE__ */ Q("div", { className: "placeholder", children: [
1608
1760
  "Plot error: ",
1609
- p
1610
- ] }) }) : /* @__PURE__ */ Ce("div", { className: "plot-card", children: [
1611
- /* @__PURE__ */ G("div", { className: "plot-title", children: /* @__PURE__ */ G(
1761
+ b
1762
+ ] }) }) : /* @__PURE__ */ Q("div", { className: "plot-card", children: [
1763
+ /* @__PURE__ */ L("div", { className: "plot-title", children: /* @__PURE__ */ L(
1612
1764
  "select",
1613
1765
  {
1614
1766
  className: "plot-select",
1615
- value: l,
1767
+ value: a,
1616
1768
  onChange: (h) => o && o({ holeId: h.target.value }),
1617
1769
  children: n.map((h) => {
1618
- const z = typeof h == "string" ? h : h.holeId, C = typeof h == "string" ? h : h.label || h.holeId;
1619
- return /* @__PURE__ */ G("option", { value: z, children: C }, z);
1770
+ const _ = typeof h == "string" ? h : h.holeId, y = typeof h == "string" ? h : h.label || h.holeId;
1771
+ return /* @__PURE__ */ L("option", { value: _, children: y }, _);
1620
1772
  })
1621
1773
  }
1622
1774
  ) }),
1623
- /* @__PURE__ */ Ce("div", { className: "plot-controls column", children: [
1624
- r.length > 0 && /* @__PURE__ */ G(
1775
+ /* @__PURE__ */ Q("div", { className: "plot-controls column", children: [
1776
+ r.length > 0 && /* @__PURE__ */ L(
1625
1777
  "select",
1626
1778
  {
1627
1779
  className: "plot-select",
1628
1780
  value: u,
1629
1781
  onChange: (h) => o && o({ property: h.target.value }),
1630
- children: r.map((h) => /* @__PURE__ */ G("option", { value: h, children: h }, h))
1782
+ children: r.map((h) => /* @__PURE__ */ L("option", { value: h, children: h }, h))
1631
1783
  }
1632
1784
  ),
1633
- m.length > 1 && /* @__PURE__ */ G(
1785
+ d.length > 1 && /* @__PURE__ */ L(
1634
1786
  "select",
1635
1787
  {
1636
1788
  className: "plot-select",
1637
1789
  value: f,
1638
1790
  onChange: (h) => o && o({ chartType: h.target.value }),
1639
- children: m.map((h) => /* @__PURE__ */ G("option", { value: h.value, children: h.label }, h.value))
1791
+ children: d.map((h) => /* @__PURE__ */ L("option", { value: h.value, children: h.label }, h.value))
1640
1792
  }
1641
1793
  )
1642
1794
  ] }),
1643
- /* @__PURE__ */ G("div", { className: "plotly-chart", ref: s })
1795
+ /* @__PURE__ */ L("div", { className: "plotly-chart", ref: s })
1644
1796
  ] });
1645
1797
  }
1646
- function nt(e, t) {
1798
+ function st(e, t) {
1647
1799
  if (!(t != null && t.length)) return e;
1648
1800
  const n = new Map(e.map((r) => [r.id || r.holeId, { ...r }]));
1649
1801
  for (const r of t) {
@@ -1657,157 +1809,157 @@ function nt(e, t) {
1657
1809
  }
1658
1810
  return Array.from(n.values());
1659
1811
  }
1660
- function hn(e, t) {
1812
+ function kn(e, t) {
1661
1813
  if (!e || !t) return [];
1662
1814
  const n = /* @__PURE__ */ new Set(), r = [];
1663
1815
  for (const o of e.points || []) {
1664
1816
  const s = Number(o.from ?? o.samp_from ?? o.depth_from ?? o.from_depth), i = Number(o.to ?? o.samp_to ?? o.depth_to ?? o.to_depth);
1665
1817
  if (!Number.isFinite(s) || !Number.isFinite(i) || i <= s) continue;
1666
- const a = `${s}-${i}`;
1667
- n.has(a) || (n.add(a), r.push({ from: s, to: i, [t]: o[t] ?? "" }));
1818
+ const c = `${s}-${i}`;
1819
+ n.has(c) || (n.add(c), r.push({ from: s, to: i, [t]: o[t] ?? "" }));
1668
1820
  }
1669
1821
  return r;
1670
1822
  }
1671
- function Er({
1823
+ function Kr({
1672
1824
  initialFocusedHoleId: e = "",
1673
1825
  sourceFile: t = null,
1674
1826
  extraHoles: n = [],
1675
1827
  plotCount: r = 4
1676
1828
  } = {}) {
1677
- const [o, s] = Z([]), [i, a] = Z([]), [u, c] = Z([]), [l, d] = Z([]), [m, f] = Z([]), [p, y] = Z({}), [h, z] = Z(""), [C, E] = Z([]), [H, A] = Z(""), [j, P] = Z(e || ""), [N, V] = Z([]), Y = ot(null);
1678
- oe(() => {
1679
- !t || Y.current === t || (Y.current = t, $t(t).then((M) => {
1680
- if (!M) return;
1681
- const _ = Array.from(new Map(M.map((I) => [I.holeId, I])).values());
1682
- a(_), E(mt({
1683
- holeIds: _.map((I) => I.holeId),
1684
- focusedHoleId: j,
1829
+ const [o, s] = K([]), [i, c] = K([]), [u, l] = K([]), [a, m] = K([]), [d, f] = K([]), [b, p] = K({}), [h, _] = K(""), [y, I] = K([]), [z, x] = K(""), [D, S] = K(e || ""), [M, O] = K([]), $ = lt(null);
1830
+ ae(() => {
1831
+ !t || $.current === t || ($.current = t, Kt(t).then((A) => {
1832
+ if (!A) return;
1833
+ const v = Array.from(new Map(A.map((P) => [P.holeId, P])).values());
1834
+ c(v), I(pt({
1835
+ holeIds: v.map((P) => P.holeId),
1836
+ focusedHoleId: D,
1685
1837
  plotCount: r,
1686
1838
  defaultProp: "",
1687
- categoricalProps: l,
1688
- commentProps: m,
1839
+ categoricalProps: a,
1840
+ commentProps: d,
1689
1841
  numericDefaultChartType: "markers+line"
1690
1842
  }));
1691
- }).catch((M) => {
1692
- console.info("Assay metadata load skipped:", M.message);
1843
+ }).catch((A) => {
1844
+ console.info("Assay metadata load skipped:", A.message);
1693
1845
  }));
1694
- }, [t, j, r, l, m]), oe(() => {
1846
+ }, [t, D, r, a, d]), ae(() => {
1695
1847
  if (!(n != null && n.length)) return;
1696
- const M = n.map((_) => ({ holeId: _.id || _.holeId })).filter((_) => _.holeId);
1697
- a((_) => {
1698
- const I = new Set(_.map((x) => x.holeId)), S = M.filter((x) => !I.has(x.holeId));
1699
- return S.length ? [..._, ...S] : _;
1848
+ const A = n.map((v) => ({ holeId: v.id || v.holeId })).filter((v) => v.holeId);
1849
+ c((v) => {
1850
+ const P = new Set(v.map((C) => C.holeId)), g = A.filter((C) => !P.has(C.holeId));
1851
+ return g.length ? [...v, ...g] : v;
1700
1852
  });
1701
- }, [n]), oe(() => {
1702
- A((M) => M && M.startsWith("Loading data for hole") ? M : "");
1703
- }, [C]), oe(() => {
1853
+ }, [n]), ae(() => {
1854
+ x((A) => A && A.startsWith("Loading data for hole") ? A : "");
1855
+ }, [y]), ae(() => {
1704
1856
  if (!i.length) {
1705
- E([]);
1857
+ I([]);
1706
1858
  return;
1707
1859
  }
1708
- const M = dt(i.map((_) => _.holeId), j);
1709
- E((_) => Array.from({ length: r }).map((S, x) => {
1710
- var X;
1711
- const O = _[x] || {}, k = i.some((le) => le.holeId === O.holeId) ? O.holeId : M[x] || ((X = i[x]) == null ? void 0 : X.holeId) || "", v = O.property || h, U = Ne({
1712
- property: v,
1713
- chartType: O.chartType,
1714
- categoricalProps: l,
1715
- commentProps: m,
1860
+ const A = ht(i.map((v) => v.holeId), D);
1861
+ I((v) => Array.from({ length: r }).map((g, C) => {
1862
+ var U;
1863
+ const F = v[C] || {}, V = i.some((re) => re.holeId === F.holeId) ? F.holeId : A[C] || ((U = i[C]) == null ? void 0 : U.holeId) || "", k = F.property || h, H = Ae({
1864
+ property: k,
1865
+ chartType: F.chartType,
1866
+ categoricalProps: a,
1867
+ commentProps: d,
1716
1868
  numericDefaultChartType: "markers+line"
1717
1869
  });
1718
- return { holeId: k, property: v, chartType: U };
1870
+ return { holeId: V, property: k, chartType: H };
1719
1871
  }));
1720
- }, [i, j, h, l, m, r]), oe(() => {
1872
+ }, [i, D, h, a, d, r]), ae(() => {
1721
1873
  if (!t) return;
1722
- C.map((_) => _.holeId).filter(Boolean).forEach((_) => {
1723
- const I = o.some((x) => (x.id || x.holeId) === _), S = N.includes(_);
1724
- I || S || (V((x) => [...x, _]), Ht(t, _).then((x) => {
1725
- V((O) => O.filter((k) => k !== _)), x && s((O) => {
1726
- const k = nt(
1727
- [...O.filter((U) => (U.id || U.holeId) !== _), x],
1874
+ y.map((v) => v.holeId).filter(Boolean).forEach((v) => {
1875
+ const P = o.some((C) => (C.id || C.holeId) === v), g = M.includes(v);
1876
+ P || g || (O((C) => [...C, v]), Jt(t, v).then((C) => {
1877
+ O((F) => F.filter((V) => V !== v)), C && s((F) => {
1878
+ const V = st(
1879
+ [...F.filter((H) => (H.id || H.holeId) !== v), C],
1728
1880
  n
1729
- ), v = Ie(k);
1730
- return c(v.numericProps), d(v.categoricalProps), f(v.commentProps), y(v.columnMeta), !h && v.defaultProp && (z(v.defaultProp), E((U) => U.map((X) => ({
1731
- ...X,
1732
- property: X.property || v.defaultProp,
1733
- chartType: Ne({
1734
- property: X.property || v.defaultProp,
1735
- chartType: X.chartType,
1736
- categoricalProps: v.categoricalProps,
1737
- commentProps: v.commentProps,
1881
+ ), k = Ee(V);
1882
+ return l(k.numericProps), m(k.categoricalProps), f(k.commentProps), p(k.columnMeta), !h && k.defaultProp && (_(k.defaultProp), I((H) => H.map((U) => ({
1883
+ ...U,
1884
+ property: U.property || k.defaultProp,
1885
+ chartType: Ae({
1886
+ property: U.property || k.defaultProp,
1887
+ chartType: U.chartType,
1888
+ categoricalProps: k.categoricalProps,
1889
+ commentProps: k.commentProps,
1738
1890
  numericDefaultChartType: "markers+line"
1739
1891
  })
1740
- })))), k;
1892
+ })))), V;
1741
1893
  });
1742
- }).catch((x) => {
1743
- console.error(x), V((O) => O.filter((k) => k !== _)), A(x.message || `Error loading hole ${_}`);
1894
+ }).catch((C) => {
1895
+ console.error(C), O((F) => F.filter((V) => V !== v)), x(C.message || `Error loading hole ${v}`);
1744
1896
  }));
1745
1897
  });
1746
- }, [C, t, o, N, h, n]), oe(() => {
1747
- n != null && n.length && s((M) => {
1748
- if (!M.length) {
1749
- const S = Ie(n);
1750
- return c(S.numericProps), d(S.categoricalProps), f(S.commentProps), y(S.columnMeta), !h && S.defaultProp && z(S.defaultProp), n;
1898
+ }, [y, t, o, M, h, n]), ae(() => {
1899
+ n != null && n.length && s((A) => {
1900
+ if (!A.length) {
1901
+ const g = Ee(n);
1902
+ return l(g.numericProps), m(g.categoricalProps), f(g.commentProps), p(g.columnMeta), !h && g.defaultProp && _(g.defaultProp), n;
1751
1903
  }
1752
- const _ = nt(M, n), I = Ie(_);
1753
- return c(I.numericProps), d(I.categoricalProps), f(I.commentProps), y(I.columnMeta), !h && I.defaultProp && z(I.defaultProp), _;
1904
+ const v = st(A, n), P = Ee(v);
1905
+ return l(P.numericProps), m(P.categoricalProps), f(P.commentProps), p(P.columnMeta), !h && P.defaultProp && _(P.defaultProp), v;
1754
1906
  });
1755
1907
  }, [n]);
1756
- const re = ve(
1757
- () => [...u, ...l, ...m],
1758
- [u, l, m]
1759
- ), T = ve(
1760
- () => i.map((M) => ({ holeId: M.holeId, label: M.holeId })).sort((M, _) => M.label.localeCompare(_.label)),
1908
+ const Z = ke(
1909
+ () => [...u, ...a, ...d],
1910
+ [u, a, d]
1911
+ ), T = ke(
1912
+ () => i.map((A) => ({ holeId: A.holeId, label: A.holeId })).sort((A, v) => A.label.localeCompare(v.label)),
1761
1913
  [i]
1762
- ), B = ve(() => {
1763
- const M = [...u, ...l, ...m];
1764
- return Array.from({ length: r }).map((_, I) => {
1765
- const S = C[I] || {}, x = o.find((me) => (me.id || me.holeId) === S.holeId) || null, O = x ? M.filter((me) => rn(x, me)) : M;
1766
- let k = S.property || h;
1767
- x && !O.includes(k) && (k = O[0] || k);
1768
- const v = m.includes(k), U = !v && l.includes(k), X = !v && !U && k === "dip", le = v ? "comment" : X ? "tadpole" : U ? "categorical" : "numeric", ge = X ? "tadpole" : S.chartType || (v ? "comment" : U ? "categorical" : "markers+line"), de = S.holeId || (x == null ? void 0 : x.id) || (x == null ? void 0 : x.holeId) || "", Se = X ? (x == null ? void 0 : x.points) || [] : v ? hn(x, k) : on(x, k, U);
1914
+ ), R = ke(() => {
1915
+ const A = [...u, ...a, ...d];
1916
+ return Array.from({ length: r }).map((v, P) => {
1917
+ const g = y[P] || {}, C = o.find((le) => (le.id || le.holeId) === g.holeId) || null, F = C ? A.filter((le) => zn(C, le)) : A;
1918
+ let V = g.property || h;
1919
+ C && !F.includes(V) && (V = F[0] || V);
1920
+ const k = d.includes(V), H = !k && a.includes(V), U = !k && !H && V === "dip", re = k ? "comment" : U ? "tadpole" : H ? "categorical" : "numeric", de = U ? "tadpole" : g.chartType || (k ? "comment" : H ? "categorical" : "markers+line"), ie = g.holeId || (C == null ? void 0 : C.id) || (C == null ? void 0 : C.holeId) || "", Ne = U ? (C == null ? void 0 : C.points) || [] : k ? kn(C, V) : Mn(C, V, H);
1769
1921
  return {
1770
- config: { holeId: de, property: k, chartType: ge },
1771
- hole: x,
1772
- loading: N.includes(S.holeId),
1773
- isCategorical: U,
1774
- isComment: v,
1775
- isTadpole: X,
1776
- displayType: le,
1777
- points: Se,
1778
- propertyOptions: O,
1779
- label: de
1922
+ config: { holeId: ie, property: V, chartType: de },
1923
+ hole: C,
1924
+ loading: M.includes(g.holeId),
1925
+ isCategorical: H,
1926
+ isComment: k,
1927
+ isTadpole: U,
1928
+ displayType: re,
1929
+ points: Ne,
1930
+ propertyOptions: F,
1931
+ label: ie
1780
1932
  };
1781
1933
  });
1782
- }, [C, o, h, l, m, N, r, u]), q = (M, _) => {
1783
- E((I) => {
1784
- const S = [...I], O = { ...S[M] || {}, ..._ };
1785
- return _.property && (O.chartType = Ne({
1786
- property: _.property,
1787
- chartType: O.chartType,
1788
- categoricalProps: l,
1789
- commentProps: m,
1934
+ }, [y, o, h, a, d, M, r, u]), q = (A, v) => {
1935
+ I((P) => {
1936
+ const g = [...P], F = { ...g[A] || {}, ...v };
1937
+ return v.property && (F.chartType = Ae({
1938
+ property: v.property,
1939
+ chartType: F.chartType,
1940
+ categoricalProps: a,
1941
+ commentProps: d,
1790
1942
  numericDefaultChartType: "markers+line"
1791
- })), S[M] = O, S;
1943
+ })), g[A] = F, g;
1792
1944
  });
1793
1945
  };
1794
1946
  return {
1795
- error: H,
1796
- focusedHoleId: j,
1797
- setFocusedHoleId: P,
1798
- setError: A,
1947
+ error: z,
1948
+ focusedHoleId: D,
1949
+ setFocusedHoleId: S,
1950
+ setError: x,
1799
1951
  holeCount: i.length,
1800
1952
  numericProps: u,
1801
- categoricalProps: l,
1802
- commentProps: m,
1803
- columnMeta: p,
1804
- propertyOptions: re,
1953
+ categoricalProps: a,
1954
+ commentProps: d,
1955
+ columnMeta: b,
1956
+ propertyOptions: Z,
1805
1957
  labeledHoleOptions: T,
1806
- traceGraphs: B,
1958
+ traceGraphs: R,
1807
1959
  handleConfigChange: q
1808
1960
  };
1809
1961
  }
1810
- const pn = [
1962
+ const Ln = [
1811
1963
  "#313695",
1812
1964
  "#4575b4",
1813
1965
  "#74add1",
@@ -1819,8 +1971,8 @@ const pn = [
1819
1971
  "#d73027",
1820
1972
  "#a50026"
1821
1973
  ];
1822
- function yn(e = [], t = pn) {
1823
- const n = e.filter((c) => Number.isFinite(c));
1974
+ function Tn(e = [], t = Ln) {
1975
+ const n = e.filter((l) => Number.isFinite(l));
1824
1976
  if (!n.length)
1825
1977
  return {
1826
1978
  min: null,
@@ -1829,10 +1981,10 @@ function yn(e = [], t = pn) {
1829
1981
  bins: [],
1830
1982
  colors: t
1831
1983
  };
1832
- const r = n.slice().sort((c, l) => c - l), o = r[0], s = r[r.length - 1], i = t.length;
1984
+ const r = n.slice().sort((l, a) => l - a), o = r[0], s = r[r.length - 1], i = t.length;
1833
1985
  if (s === o) {
1834
- const c = t.map((l, d) => ({
1835
- index: d,
1986
+ const l = t.map((a, m) => ({
1987
+ index: m,
1836
1988
  min: o,
1837
1989
  max: s,
1838
1990
  label: `${o}`
@@ -1841,32 +1993,32 @@ function yn(e = [], t = pn) {
1841
1993
  min: o,
1842
1994
  max: s,
1843
1995
  step: 0,
1844
- bins: c,
1996
+ bins: l,
1845
1997
  colors: t
1846
1998
  };
1847
1999
  }
1848
- const a = t.map((c, l) => {
1849
- const d = l / i, m = (l + 1) / i, f = Math.floor(d * r.length), p = Math.min(r.length - 1, Math.floor(m * r.length)), y = r[f], h = l === i - 1 ? s : r[p];
2000
+ const c = t.map((l, a) => {
2001
+ const m = a / i, d = (a + 1) / i, f = Math.floor(m * r.length), b = Math.min(r.length - 1, Math.floor(d * r.length)), p = r[f], h = a === i - 1 ? s : r[b];
1850
2002
  return {
1851
- index: l,
1852
- min: y,
2003
+ index: a,
2004
+ min: p,
1853
2005
  max: h,
1854
- label: gn(y, h)
2006
+ label: Fn(p, h)
1855
2007
  };
1856
2008
  }), u = (s - o) / i;
1857
2009
  return {
1858
2010
  min: o,
1859
2011
  max: s,
1860
2012
  step: u,
1861
- bins: a,
2013
+ bins: c,
1862
2014
  colors: t
1863
2015
  };
1864
2016
  }
1865
- function gn(e, t) {
2017
+ function Fn(e, t) {
1866
2018
  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";
1867
2019
  return `${n(e)} – ${n(t)}`;
1868
2020
  }
1869
- function xt(e, t) {
2021
+ function It(e, t) {
1870
2022
  if (!Number.isFinite(e) || !t || !Array.isArray(t.bins) || !t.bins.length)
1871
2023
  return -1;
1872
2024
  if (t.max === t.min)
@@ -1878,18 +2030,18 @@ function xt(e, t) {
1878
2030
  }
1879
2031
  return -1;
1880
2032
  }
1881
- function bn(e, t, n = "#8b1e3f") {
1882
- const r = xt(e, t);
2033
+ function On(e, t, n = "#8b1e3f") {
2034
+ const r = It(e, t);
1883
2035
  return r < 0 ? n : t.colors[r] || n;
1884
2036
  }
1885
- function Ct(e) {
2037
+ function At(e) {
1886
2038
  return Array.isArray(e) ? e : [];
1887
2039
  }
1888
2040
  function Te(e) {
1889
2041
  const t = Number(e);
1890
2042
  return Number.isFinite(t) ? t : void 0;
1891
2043
  }
1892
- function zt(e = {}) {
2044
+ function vt(e = {}) {
1893
2045
  return {
1894
2046
  ...e,
1895
2047
  x: Te(e.x),
@@ -1897,24 +2049,24 @@ function zt(e = {}) {
1897
2049
  z: Te(e.z)
1898
2050
  };
1899
2051
  }
1900
- function _n(e = [], t = [0, 0], n = 0) {
1901
- const [r, o] = t, s = Number(n) * Math.PI / 180, i = Math.cos(s), a = Math.sin(s);
1902
- return Ct(e).map(zt).map((u) => {
2052
+ function Vn(e = [], t = [0, 0], n = 0) {
2053
+ const [r, o] = t, s = Number(n) * Math.PI / 180, i = Math.cos(s), c = Math.sin(s);
2054
+ return At(e).map(vt).map((u) => {
1903
2055
  if (!Number.isFinite(u.x) || !Number.isFinite(u.y)) return { ...u };
1904
- const c = u.x - r, l = u.y - o;
2056
+ const l = u.x - r, a = u.y - o;
1905
2057
  return {
1906
2058
  ...u,
1907
- along: c * a + l * i,
1908
- across: c * i - l * a
2059
+ along: l * c + a * i,
2060
+ across: l * i - a * c
1909
2061
  };
1910
2062
  });
1911
2063
  }
1912
- function xn(e = [], t = [0, 0], n = 0, r = 50) {
1913
- const o = _n(e, t, n), s = 0.5 * Number(r || 0);
2064
+ function wn(e = [], t = [0, 0], n = 0, r = 50) {
2065
+ const o = Vn(e, t, n), s = 0.5 * Number(r || 0);
1914
2066
  return !Number.isFinite(s) || s <= 0 ? o : o.filter((i) => Number.isFinite(i.across) && Math.abs(i.across) <= s);
1915
2067
  }
1916
- function Sr(e = [], t = null, n = null) {
1917
- let r = Ct(e).map(zt);
2068
+ function Jr(e = [], t = null, n = null) {
2069
+ let r = At(e).map(vt);
1918
2070
  if (Array.isArray(t) && t.length === 2) {
1919
2071
  const [o, s] = t;
1920
2072
  r = r.filter((i) => Number.isFinite(i.z) && i.z <= Number(o) && i.z >= Number(s));
@@ -1924,46 +2076,46 @@ function Sr(e = [], t = null, n = null) {
1924
2076
  color_value: o == null ? void 0 : o[n]
1925
2077
  }))), r;
1926
2078
  }
1927
- function vr(e = [], t = [0, 0], n = 0, r = 50, o = null) {
1928
- let s = xn(e, t, n, r);
2079
+ function Qr(e = [], t = [0, 0], n = 0, r = 50, o = null) {
2080
+ let s = wn(e, t, n, r);
1929
2081
  return o && (s = s.map((i) => ({
1930
2082
  ...i,
1931
2083
  color_value: i == null ? void 0 : i[o]
1932
2084
  }))), s;
1933
2085
  }
1934
- function je(e) {
2086
+ function Ue(e) {
1935
2087
  return Array.isArray(e) ? e : [];
1936
2088
  }
1937
- function Ue(e = {}) {
2089
+ function Ye(e = {}) {
1938
2090
  return e.hole_id ?? e.holeId ?? e.id;
1939
2091
  }
1940
- function ce(e, t = void 0) {
2092
+ function he(e, t = void 0) {
1941
2093
  const n = Number(e);
1942
2094
  return Number.isFinite(n) ? n : t;
1943
2095
  }
1944
- function Pr(e = [], t = null) {
2096
+ function eo(e = [], t = null) {
1945
2097
  const n = /* @__PURE__ */ new Map();
1946
- je(e).forEach((o) => {
1947
- const s = Ue(o);
2098
+ Ue(e).forEach((o) => {
2099
+ const s = Ye(o);
1948
2100
  if (s == null || `${s}`.trim() === "") return;
1949
2101
  const i = `${s}`;
1950
2102
  n.has(i) || n.set(i, []), n.get(i).push(o);
1951
2103
  });
1952
2104
  const r = [];
1953
2105
  return n.forEach((o, s) => {
1954
- const i = [...o].sort((u, c) => ce(u.md, 0) - ce(c.md, 0)), a = {
2106
+ const i = [...o].sort((u, l) => he(u.md, 0) - he(l.md, 0)), c = {
1955
2107
  hole_id: s,
1956
- x: i.map((u) => ce(u.x, 0)),
1957
- y: i.map((u) => ce(u.y, 0)),
1958
- z: i.map((u) => ce(u.z, 0)),
2108
+ x: i.map((u) => he(u.x, 0)),
2109
+ y: i.map((u) => he(u.y, 0)),
2110
+ z: i.map((u) => he(u.z, 0)),
1959
2111
  color: null
1960
2112
  };
1961
- t && (a.color = i.map((u) => u == null ? void 0 : u[t])), r.push(a);
2113
+ t && (c.color = i.map((u) => u == null ? void 0 : u[t])), r.push(c);
1962
2114
  }), r;
1963
2115
  }
1964
- function Tr(e = [], t = 1, n = null) {
1965
- return je(e).map((r) => ({
1966
- hole_id: Ue(r),
2116
+ function to(e = [], t = 1, n = null) {
2117
+ return Ue(e).map((r) => ({
2118
+ hole_id: Ye(r),
1967
2119
  from: r == null ? void 0 : r.from,
1968
2120
  to: r == null ? void 0 : r.to,
1969
2121
  radius: t,
@@ -1971,14 +2123,14 @@ function Tr(e = [], t = 1, n = null) {
1971
2123
  value: n ? r == null ? void 0 : r[n] : null
1972
2124
  }));
1973
2125
  }
1974
- function Dr(e = [], t = null) {
1975
- return t ? je(e).filter((n) => Object.prototype.hasOwnProperty.call(n || {}, t)).map((n) => ({
1976
- hole_id: Ue(n),
2126
+ function no(e = [], t = null) {
2127
+ return t ? Ue(e).filter((n) => Object.prototype.hasOwnProperty.call(n || {}, t)).map((n) => ({
2128
+ hole_id: Ye(n),
1977
2129
  label: n == null ? void 0 : n[t],
1978
- depth: 0.5 * (ce(n == null ? void 0 : n.from, 0) + ce(n == null ? void 0 : n.to, 0))
2130
+ depth: 0.5 * (he(n == null ? void 0 : n.from, 0) + he(n == null ? void 0 : n.to, 0))
1979
2131
  })) : [];
1980
2132
  }
1981
- const Cn = {
2133
+ const $n = {
1982
2134
  bedding: "#2563eb",
1983
2135
  foliation: "#16a34a",
1984
2136
  joint: "#9333ea",
@@ -1987,13 +2139,13 @@ const Cn = {
1987
2139
  "shear zone": "#0ea5e9",
1988
2140
  "fault zone": "#ef4444"
1989
2141
  };
1990
- function zn(e, t) {
1991
- const n = t || Cn, r = (e || "").toLowerCase().trim(), o = n[r] || "#888888";
1992
- return new g.Color(o).getHex();
2142
+ function Rn(e, t) {
2143
+ const n = t || $n, r = (e || "").toLowerCase().trim(), o = n[r] || "#888888";
2144
+ return new N.Color(o).getHex();
1993
2145
  }
1994
- function Nn(e, t) {
2146
+ function Hn(e, t) {
1995
2147
  const n = e * Math.PI / 180, r = t * Math.PI / 180;
1996
- return new g.Vector3(
2148
+ return new N.Vector3(
1997
2149
  Math.sin(r) * Math.sin(n),
1998
2150
  // East component
1999
2151
  Math.cos(r) * Math.sin(n),
@@ -2002,52 +2154,60 @@ function Nn(e, t) {
2002
2154
  // Up component
2003
2155
  ).normalize();
2004
2156
  }
2005
- function Lr(e, t = {}) {
2157
+ function jn(e, t = {}) {
2006
2158
  const {
2007
2159
  radius: n = 5,
2008
2160
  discThickness: r = 0.2,
2009
2161
  opacity: o = 0.7,
2010
2162
  segments: s = 32,
2011
2163
  colorMap: i = null
2012
- } = t, a = new g.Group(), u = new g.Vector3(0, 1, 0);
2013
- for (const c of e) {
2014
- const l = c.x != null ? c.x : c.easting != null ? c.easting : null, d = c.y != null ? c.y : c.northing != null ? c.northing : null, m = c.z != null ? c.z : c.elevation != null ? c.elevation : null, f = c[L] != null ? Number(c[L]) : null, p = c[D] != null ? Number(c[D]) : null;
2015
- if (l == null || d == null || m == null || f == null || p == null || !Number.isFinite(l) || !Number.isFinite(d) || !Number.isFinite(m) || !Number.isFinite(f) || !Number.isFinite(p)) continue;
2016
- const y = Nn(f, p), h = new g.CylinderGeometry(n, n, r, s, 1, !1), z = new g.MeshStandardMaterial({
2017
- color: zn(c.structure_type, i),
2164
+ } = t, c = new N.Group(), u = new N.Vector3(0, 1, 0);
2165
+ for (const l of e) {
2166
+ const a = l.x != null ? l.x : l.easting != null ? l.easting : null, m = l.y != null ? l.y : l.northing != null ? l.northing : null, d = l.z != null ? l.z : l.elevation != null ? l.elevation : null;
2167
+ if (a == null || m == null || d == null || !Number.isFinite(a) || !Number.isFinite(m) || !Number.isFinite(d)) continue;
2168
+ const f = l[B] != null ? Number(l[B]) : null, b = l[j] != null ? Number(l[j]) : null;
2169
+ let p;
2170
+ if (l.nx != null && Number.isFinite(l.nx) && l.ny != null && Number.isFinite(l.ny) && l.nz != null && Number.isFinite(l.nz))
2171
+ p = new N.Vector3(l.nx, l.ny, l.nz).normalize();
2172
+ else {
2173
+ if (f == null || b == null || !Number.isFinite(f) || !Number.isFinite(b)) continue;
2174
+ p = Hn(f, b);
2175
+ }
2176
+ const h = new N.CylinderGeometry(n, n, r, s, 1, !1), _ = new N.MeshStandardMaterial({
2177
+ color: Rn(l.structure_type, i),
2018
2178
  transparent: !0,
2019
2179
  opacity: o,
2020
- side: g.DoubleSide
2021
- }), C = new g.Mesh(h, z);
2022
- C.position.set(l, d, m), C.quaternion.setFromUnitVectors(u, y), C.userData = {
2180
+ side: N.DoubleSide
2181
+ }), y = new N.Mesh(h, _);
2182
+ y.position.set(a, m, d), y.quaternion.setFromUnitVectors(u, p), y.userData = {
2023
2183
  type: "structure",
2024
- hole_id: c.hole_id,
2025
- depth: c.depth ?? c.mid,
2026
- structure_type: c.structure_type,
2184
+ hole_id: l.hole_id,
2185
+ depth: l.depth ?? l.mid,
2186
+ structure_type: l.structure_type,
2027
2187
  dip: f,
2028
- azimuth: p,
2029
- comments: c.comments
2030
- }, a.add(C);
2188
+ azimuth: b,
2189
+ comments: l.comments
2190
+ }, c.add(y);
2031
2191
  }
2032
- return a;
2192
+ return c;
2033
2193
  }
2034
- function Ye(e) {
2035
- var n, r, o, s, i, a, u, c, l;
2194
+ function qe(e) {
2195
+ var n, r, o, s, i, c, u, l, a;
2036
2196
  if (!e) return "";
2037
- const t = (d) => Number.isFinite(d) ? d.toFixed(3) : "nan";
2197
+ const t = (m) => Number.isFinite(m) ? m.toFixed(3) : "nan";
2038
2198
  return [
2039
2199
  t((n = e.camera) == null ? void 0 : n.x),
2040
2200
  t((r = e.camera) == null ? void 0 : r.y),
2041
2201
  t((o = e.camera) == null ? void 0 : o.z),
2042
2202
  t((s = e.target) == null ? void 0 : s.x),
2043
2203
  t((i = e.target) == null ? void 0 : i.y),
2044
- t((a = e.target) == null ? void 0 : a.z),
2204
+ t((c = e.target) == null ? void 0 : c.z),
2045
2205
  t((u = e.up) == null ? void 0 : u.x),
2046
- t((c = e.up) == null ? void 0 : c.y),
2047
- t((l = e.up) == null ? void 0 : l.z)
2206
+ t((l = e.up) == null ? void 0 : l.y),
2207
+ t((a = e.up) == null ? void 0 : a.z)
2048
2208
  ].join("|");
2049
2209
  }
2050
- function Nt(e) {
2210
+ function Et(e) {
2051
2211
  return !e.camera || !e.controls ? null : {
2052
2212
  camera: {
2053
2213
  x: e.camera.position.x,
@@ -2066,37 +2226,37 @@ function Nt(e) {
2066
2226
  }
2067
2227
  };
2068
2228
  }
2069
- function Mn(e, t) {
2229
+ function Bn(e, t) {
2070
2230
  if (!e.camera || !e.controls || !t) return !1;
2071
2231
  const n = t.camera || {}, r = t.target || {}, o = t.up || {};
2072
- 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 = Ye(t), !0) : !1;
2232
+ 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 = qe(t), !0) : !1;
2073
2233
  }
2074
- function In(e) {
2234
+ function Gn(e) {
2075
2235
  if (!e.viewChangeHandler) return;
2076
2236
  const t = Date.now();
2077
2237
  if (t - e._lastViewEmitMs < 250) return;
2078
- const n = Nt(e);
2238
+ const n = Et(e);
2079
2239
  if (!n) return;
2080
- const r = Ye(n);
2240
+ const r = qe(n);
2081
2241
  r !== e._lastViewSignature && (e._lastViewSignature = r, e._lastViewEmitMs = t, e.viewChangeHandler(n));
2082
2242
  }
2083
- function De(e, { minX: t, maxX: n, minY: r, maxY: o, minZ: s, maxZ: i }) {
2084
- const a = (t + n) / 2, u = (r + o) / 2, c = (s + i) / 2, l = n - t, d = o - r, m = i - s, p = Math.max(l, d, m, 1) * 2;
2085
- e.controls.target.set(a, u, c), e.camera.position.set(a + p, u + p, c + p), e.camera.lookAt(a, u, c), e.controls.update();
2243
+ function Fe(e, { minX: t, maxX: n, minY: r, maxY: o, minZ: s, maxZ: i }) {
2244
+ const c = (t + n) / 2, u = (r + o) / 2, l = (s + i) / 2, a = n - t, m = o - r, d = i - s, b = Math.max(a, m, d, 1) * 2;
2245
+ e.controls.target.set(c, u, l), e.camera.position.set(c + b, u + b, l + b), e.camera.lookAt(c, u, l), e.controls.update();
2086
2246
  }
2087
- function An(e, t = 1e3) {
2247
+ function Un(e, t = 1e3) {
2088
2248
  !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());
2089
2249
  }
2090
- function En(e, t = 2e3) {
2250
+ function Yn(e, t = 2e3) {
2091
2251
  !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());
2092
2252
  }
2093
- function Sn(e, t = 0, n = 0) {
2253
+ function qn(e, t = 0, n = 0) {
2094
2254
  e.controls && typeof e.controls.pan == "function" && (e.controls.pan(t, n), e.controls.update());
2095
2255
  }
2096
- function vn(e, t = 1.1) {
2256
+ function Xn(e, t = 1.1) {
2097
2257
  !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());
2098
2258
  }
2099
- function Pn(e, t = 1.2) {
2259
+ function Zn(e, t = 1.2) {
2100
2260
  if (!e.lastBounds) return;
2101
2261
  const {
2102
2262
  minX: n,
@@ -2104,11 +2264,17 @@ function Pn(e, t = 1.2) {
2104
2264
  minY: o,
2105
2265
  maxY: s,
2106
2266
  minZ: i,
2107
- maxZ: a
2108
- } = e.lastBounds, u = (r - n) * t, c = (s - o) * t, l = (a - i) * t, d = (n + r) / 2, m = (o + s) / 2, f = (i + a) / 2, y = Math.max(u, c, l, 1) * 2;
2109
- e.controls.target.set(d, m, f), e.camera.position.set(d + y, m + y, f + y), e.camera.lookAt(d, m, f), e.controls.update();
2267
+ maxZ: c
2268
+ } = e.lastBounds, u = (r - n) * t, l = (s - o) * t, a = (c - i) * t, m = (n + r) / 2, d = (o + s) / 2, f = (i + c) / 2, p = Math.max(u, l, a, 1) * 2;
2269
+ e.controls.target.set(m, d, f), e.camera.position.set(m + p, d + p, f + p), e.camera.lookAt(m, d, f), e.controls.update();
2110
2270
  }
2111
- function Tn(e, t = "orbit") {
2271
+ const Wn = 1, Kn = 120;
2272
+ function Jn(e, t) {
2273
+ if (!e.camera || !e.controls || !Number.isFinite(t)) return !1;
2274
+ const n = Math.min(Kn, Math.max(Wn, t)), r = e.controls.target, o = e.camera.position.distanceTo(r), s = e.camera.fov * Math.PI / 180, i = 2 * o * Math.tan(s / 2), c = n * Math.PI / 180, u = i / (2 * Math.tan(c / 2)), l = e.camera.position.clone().sub(r).normalize();
2275
+ return e.camera.position.copy(r).addScaledVector(l, u), e.camera.fov = n, e.camera.updateProjectionMatrix(), e.controls.update(), !0;
2276
+ }
2277
+ function Qn(e, t = "orbit") {
2112
2278
  if (e.controlMode = t === "fly" ? "fly" : "orbit", e.controlMode === "fly")
2113
2279
  e.controls && (e.controls.enabled = !1), e.flyControls && (e.flyControls.enabled = !0);
2114
2280
  else if (e.flyControls && (e.flyControls.enabled = !1), e.controls) {
@@ -2117,39 +2283,39 @@ function Tn(e, t = "orbit") {
2117
2283
  e.controls.target.copy(n), e.controls.update();
2118
2284
  }
2119
2285
  }
2120
- const ae = "#9ca3af";
2121
- function rt(e, t) {
2286
+ const me = "#9ca3af";
2287
+ function it(e, t) {
2122
2288
  const n = Number(e == null ? void 0 : e.md), r = Number(t == null ? void 0 : t.md);
2123
2289
  if (!Number.isFinite(n) || !Number.isFinite(r)) return null;
2124
2290
  const o = Math.min(n, r), s = Math.max(n, r);
2125
2291
  return s <= o ? null : { segStart: o, segEnd: s };
2126
2292
  }
2127
- function Dn(e, t, n) {
2293
+ function er(e, t, n) {
2128
2294
  let r = 0, o = 0;
2129
2295
  for (let i = 0; i < e.length; i += 1) {
2130
- const a = e[i], u = Number(a == null ? void 0 : a.from), c = Number(a == null ? void 0 : a.to), l = Number(a == null ? void 0 : a.value);
2131
- if (!Number.isFinite(u) || !Number.isFinite(c) || !Number.isFinite(l) || c <= u) continue;
2132
- const d = Math.max(t, u), f = Math.min(n, c) - d;
2133
- f <= 0 || (r += l * f, o += f);
2296
+ const c = e[i], u = Number(c == null ? void 0 : c.from), l = Number(c == null ? void 0 : c.to), a = Number(c == null ? void 0 : c.value);
2297
+ if (!Number.isFinite(u) || !Number.isFinite(l) || !Number.isFinite(a) || l <= u) continue;
2298
+ const m = Math.max(t, u), f = Math.min(n, l) - m;
2299
+ f <= 0 || (r += a * f, o += f);
2134
2300
  }
2135
2301
  if (o <= 0) return null;
2136
2302
  const s = r / o;
2137
2303
  return Number.isFinite(s) ? s : null;
2138
2304
  }
2139
- function Ln(e, t) {
2140
- if (!Number.isFinite(e)) return new g.Color(ae);
2141
- if (xt(e, t) < 0) return new g.Color(ae);
2142
- const r = bn(e, t, ae);
2143
- return new g.Color(r);
2305
+ function tr(e, t) {
2306
+ if (!Number.isFinite(e)) return new N.Color(me);
2307
+ if (It(e, t) < 0) return new N.Color(me);
2308
+ const r = On(e, t, me);
2309
+ return new N.Color(r);
2144
2310
  }
2145
- function On(e = {}) {
2311
+ function nr(e = {}) {
2146
2312
  return {
2147
2313
  preserveView: !!e.preserveView,
2148
2314
  assayIntervalsByHole: e.assayIntervalsByHole || null,
2149
2315
  selectedAssayVariable: e.selectedAssayVariable || ""
2150
2316
  };
2151
2317
  }
2152
- function kn(e, t) {
2318
+ function rr(e, t) {
2153
2319
  if (!e || !t) return [];
2154
2320
  const n = [];
2155
2321
  return Object.values(e).forEach((r) => {
@@ -2159,34 +2325,34 @@ function kn(e, t) {
2159
2325
  });
2160
2326
  }), n;
2161
2327
  }
2162
- function Le(e) {
2328
+ function Oe(e) {
2163
2329
  return {
2164
2330
  holeId: e.id,
2165
2331
  project: e.project
2166
2332
  };
2167
2333
  }
2168
- class Or {
2334
+ class ro {
2169
2335
  constructor() {
2170
- 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.frameId = null, this.clock = new g.Clock(), this.handleCanvasClick = null, this.raycaster = new g.Raycaster(), this.pointer = new g.Vector2(), this.drillholeClickHandler = null, this.controlMode = "orbit", this._tmpDir = new g.Vector3(), this.viewChangeHandler = null, this._lastViewSignature = "", this._lastViewEmitMs = 0;
2336
+ 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.frameId = null, this.clock = new N.Clock(), this.handleCanvasClick = null, this.raycaster = new N.Raycaster(), this.pointer = new N.Vector2(), this.drillholeClickHandler = null, this.blockClickHandler = null, this.controlMode = "orbit", this._tmpDir = new N.Vector3(), this.viewChangeHandler = null, this._lastViewSignature = "", this._lastViewEmitMs = 0;
2171
2337
  }
2172
2338
  init(t) {
2173
2339
  if (!t) return;
2174
2340
  this.container = t;
2175
2341
  const n = t.clientWidth, r = t.clientHeight;
2176
- this.scene = new g.Scene(), this.scene.background = new g.Color(16777215), this.camera = new g.PerspectiveCamera(28, n / r, 1e-3, 1e5), this.camera.up.set(0, 0, 1), this.camera.position.set(50, 50, 50), this.camera.lookAt(0, 0, 0), this.renderer = new g.WebGLRenderer({ antialias: !0 }), this.renderer.setSize(n, r), this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.autoClear = !1, t.appendChild(this.renderer.domElement);
2177
- const o = new g.AmbientLight(16777215, 0.5);
2342
+ this.scene = new N.Scene(), this.scene.background = new N.Color(16777215), this.camera = new N.PerspectiveCamera(28, n / r, 1e-3, 1e5), this.camera.up.set(0, 0, 1), this.camera.position.set(50, 50, 50), this.camera.lookAt(0, 0, 0), this.renderer = new N.WebGLRenderer({ antialias: !0 }), this.renderer.setSize(n, r), this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.autoClear = !1, t.appendChild(this.renderer.domElement);
2343
+ const o = new N.AmbientLight(16777215, 0.5);
2178
2344
  this.scene.add(o);
2179
- const s = new g.DirectionalLight(16777215, 0.6);
2345
+ const s = new N.DirectionalLight(16777215, 0.6);
2180
2346
  s.position.set(10, 10, 5), this.scene.add(s);
2181
- const i = new g.AxesHelper(20);
2182
- this.scene.add(i), this.controls = new It(this.camera, this.renderer.domElement), this.controls.enableDamping = !1, this.controls.screenSpacePanning = !0, this.controls.enableZoom = !0, this.controls.zoomSpeed = 1.2, this.controls.minDistance = 3e-3, this.controls.maxDistance = 4e4, this.controls.mouseButtons = {
2183
- LEFT: g.MOUSE.PAN,
2184
- MIDDLE: g.MOUSE.DOLLY,
2185
- RIGHT: g.MOUSE.ROTATE
2347
+ const i = new N.AxesHelper(20);
2348
+ this.scene.add(i), this.controls = new Ot(this.camera, this.renderer.domElement), this.controls.enableDamping = !1, this.controls.screenSpacePanning = !0, this.controls.enableZoom = !0, this.controls.zoomSpeed = 1.2, this.controls.minDistance = 3e-3, this.controls.maxDistance = 4e4, this.controls.mouseButtons = {
2349
+ LEFT: N.MOUSE.PAN,
2350
+ MIDDLE: N.MOUSE.DOLLY,
2351
+ RIGHT: N.MOUSE.ROTATE
2186
2352
  }, this.controls.touches = {
2187
- ONE: g.TOUCH.ROTATE,
2188
- TWO: g.TOUCH.PAN
2189
- }, this.controls.maxPolarAngle = Math.PI, this.flyControls = new At(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 Et(this.camera, this.renderer, {
2353
+ ONE: N.TOUCH.ROTATE,
2354
+ TWO: N.TOUCH.PAN
2355
+ }, this.controls.maxPolarAngle = Math.PI, this.flyControls = new Vt(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 wt(this.camera, this.renderer, {
2190
2356
  container: this.container,
2191
2357
  placement: "top-right",
2192
2358
  size: 110,
@@ -2194,48 +2360,63 @@ class Or {
2194
2360
  animated: !0,
2195
2361
  speed: 1.5
2196
2362
  }), this.gizmo.attachControls(this.controls), this._attachCanvasClickHandler();
2197
- const a = () => {
2198
- var c;
2199
- this.frameId = requestAnimationFrame(a);
2363
+ const c = () => {
2364
+ var l;
2365
+ this.frameId = requestAnimationFrame(c);
2200
2366
  const u = this.clock.getDelta();
2201
- this.renderer.clear(), this.controlMode === "fly" && ((c = this.flyControls) != null && c.enabled) ? this.flyControls.update(u) : this.controls && this.controls.update(), this._emitViewChangeIfNeeded(), this.renderer.render(this.scene, this.camera), this.gizmo && this.gizmo.render();
2367
+ this.renderer.clear(), this.controlMode === "fly" && ((l = this.flyControls) != null && l.enabled) ? this.flyControls.update(u) : this.controls && this.controls.update(), this._emitViewChangeIfNeeded(), this.renderer.render(this.scene, this.camera), this.gizmo && this.gizmo.render();
2202
2368
  };
2203
- a();
2369
+ c();
2204
2370
  }
2205
2371
  setViewChangeHandler(t) {
2206
2372
  this.viewChangeHandler = typeof t == "function" ? t : null;
2207
2373
  }
2208
2374
  getViewState() {
2209
- return Nt(this);
2375
+ return Et(this);
2210
2376
  }
2211
2377
  setViewState(t) {
2212
- return Mn(this, t);
2378
+ return Bn(this, t);
2213
2379
  }
2214
2380
  _buildViewSignature(t) {
2215
- return Ye(t);
2381
+ return qe(t);
2216
2382
  }
2217
2383
  _emitViewChangeIfNeeded() {
2218
- In(this);
2384
+ Gn(this);
2219
2385
  }
2220
2386
  _attachCanvasClickHandler() {
2221
2387
  const t = this.renderer;
2222
2388
  t && (this.handleCanvasClick = (n) => {
2223
- var l, d, m, f;
2389
+ var f, b, p, h, _, y, I;
2224
2390
  if (n.button !== 0) return;
2225
- if ((l = this.gizmo) != null && l.domElement) {
2226
- const p = this.gizmo.domElement.getBoundingClientRect();
2227
- if (n.clientX >= p.left && n.clientX <= p.right && n.clientY >= p.top && n.clientY <= p.bottom)
2391
+ if ((f = this.gizmo) != null && f.domElement) {
2392
+ const z = this.gizmo.domElement.getBoundingClientRect();
2393
+ if (n.clientX >= z.left && n.clientX <= z.right && n.clientY >= z.top && n.clientY <= z.bottom)
2228
2394
  return;
2229
2395
  }
2230
2396
  const r = t.domElement.getBoundingClientRect(), o = n.clientX - r.left, s = n.clientY - r.top;
2231
- this.pointer.x = o / r.width * 2 - 1, this.pointer.y = -(s / r.height * 2) + 1, this.raycaster.setFromCamera(this.pointer, this.camera);
2232
- const i = this.raycaster.intersectObjects(this.drillMeshes, !0);
2397
+ if (this.pointer.x = o / r.width * 2 - 1, this.pointer.y = -(s / r.height * 2) + 1, this.raycaster.setFromCamera(this.pointer, this.camera), this.blocks.length > 0) {
2398
+ const z = this.raycaster.intersectObjects(this.blocks, !1);
2399
+ if (z.length > 0) {
2400
+ const x = z[0], D = x.object;
2401
+ if ((b = D == null ? void 0 : D.userData) != null && b._isMergedBlocks && this.blockClickHandler) {
2402
+ const S = Math.floor(x.faceIndex / 2), M = D.userData._quadToBlock[S];
2403
+ M && this.blockClickHandler(M);
2404
+ }
2405
+ return;
2406
+ }
2407
+ }
2408
+ const i = this.raycaster.intersectObjects(this.drillMeshes, !0), c = this.raycaster.intersectObjects(this.structuralMeshes, !0), u = ((p = i[0]) == null ? void 0 : p.distance) ?? 1 / 0;
2409
+ if ((((h = c[0]) == null ? void 0 : h.distance) ?? 1 / 0) < u && c.length > 0) {
2410
+ const z = c[0].object;
2411
+ this.drillholeClickHandler && this.drillholeClickHandler({ type: "structure", ...z.userData });
2412
+ return;
2413
+ }
2233
2414
  if (i.length === 0) return;
2234
2415
  let a = i[0].object;
2235
- for (; a && a.parent && !((d = a.userData) != null && d.holeId); )
2416
+ for (; a && a.parent && !((_ = a.userData) != null && _.holeId); )
2236
2417
  a = a.parent;
2237
- const u = (m = a == null ? void 0 : a.userData) == null ? void 0 : m.holeId, c = (f = a == null ? void 0 : a.userData) == null ? void 0 : f.project;
2238
- u && this.drillholeClickHandler && this.drillholeClickHandler({ holeId: u, project: c });
2418
+ const m = (y = a == null ? void 0 : a.userData) == null ? void 0 : y.holeId, d = (I = a == null ? void 0 : a.userData) == null ? void 0 : I.project;
2419
+ m && this.drillholeClickHandler && this.drillholeClickHandler({ holeId: m, project: d });
2239
2420
  }, t.domElement.addEventListener("click", this.handleCanvasClick));
2240
2421
  }
2241
2422
  resize() {
@@ -2243,93 +2424,153 @@ class Or {
2243
2424
  const t = this.container.clientWidth, n = this.container.clientHeight;
2244
2425
  this.camera.aspect = t / n, this.camera.updateProjectionMatrix(), this.renderer.setSize(t, n), this.gizmo && this.gizmo.update();
2245
2426
  }
2246
- setBlocks(t, n, r) {
2427
+ /**
2428
+ * Render block model data as a single merged mesh of exterior faces only.
2429
+ *
2430
+ * Adjacent blocks' shared faces are skipped so there are no coincident
2431
+ * polygons and therefore no z-fighting. Vertex colours are used so the
2432
+ * entire model is a single draw call.
2433
+ *
2434
+ * Accepts rows with canonical column names ``x``, ``y``, ``z``, ``dx``,
2435
+ * ``dy``, ``dz`` (produced by :func:`parseBlockModelCSV`).
2436
+ *
2437
+ * @param {Array<Object>} data - Block rows (canonical column names)
2438
+ * @param {string} selectedProperty - Attribute column used for colouring
2439
+ * @param {Object} stats - Property statistics (from :func:`calculatePropertyStats`)
2440
+ * @param {Object} [options]
2441
+ * @param {Object} [options.offset] - Optional ``{x, y, z}`` translation applied
2442
+ * to all block centres before rendering. When omitted the scene defaults to
2443
+ * auto-centering by shifting the extent centre to the origin.
2444
+ * @param {number} [options.opacity=1.0] - Initial material opacity (0–1)
2445
+ * @param {boolean} [options.autoCenter=true] - If true and no offset is
2446
+ * supplied, translate block centres so the extent centre sits at the origin.
2447
+ */
2448
+ setBlocks(t, n, r, o = {}) {
2247
2449
  if (!this.scene || (this._clearBlocks(), !t || !n || !r)) return;
2248
- let o = 1 / 0, s = -1 / 0, i = 1 / 0, a = -1 / 0, u = 1 / 0, c = -1 / 0;
2249
- t.forEach((l) => {
2250
- const {
2251
- center_x: d = 0,
2252
- center_y: m = 0,
2253
- center_z: f = 0,
2254
- size_x: p = 1,
2255
- size_y: y = 1,
2256
- size_z: h = 1
2257
- } = l;
2258
- o = Math.min(o, d - p / 2), s = Math.max(s, d + p / 2), i = Math.min(i, m - y / 2), a = Math.max(a, m + y / 2), u = Math.min(u, f - h / 2), c = Math.max(c, f + h / 2);
2259
- const z = new g.BoxGeometry(p, y, h), C = Wt(l[n], r, g), E = new g.MeshStandardMaterial({
2260
- color: C,
2261
- transparent: !0,
2262
- opacity: 0.7,
2263
- side: g.DoubleSide
2264
- }), H = new g.Mesh(z, E);
2265
- H.position.set(d, m, f), this.scene.add(H), this.blocks.push(H);
2266
- }), this.camera && this.controls && (this.lastBounds = { minX: o, maxX: s, minY: i, maxY: a, minZ: u, maxZ: c }, De(this, { minX: o, maxX: s, minY: i, maxY: a, minZ: u, maxZ: c }));
2450
+ const { autoCenter: s = !0, opacity: i = 1 } = o;
2451
+ let c = 1 / 0, u = -1 / 0, l = 1 / 0, a = -1 / 0, m = 1 / 0, d = -1 / 0;
2452
+ t.forEach((g) => {
2453
+ const C = Number(g.x ?? g.center_x ?? 0), F = Number(g.y ?? g.center_y ?? 0), V = Number(g.z ?? g.center_z ?? 0), k = Number(g.dx ?? g.size_x ?? 1), H = Number(g.dy ?? g.size_y ?? 1), U = Number(g.dz ?? g.size_z ?? 1);
2454
+ c = Math.min(c, C - k / 2), u = Math.max(u, C + k / 2), l = Math.min(l, F - H / 2), a = Math.max(a, F + H / 2), m = Math.min(m, V - U / 2), d = Math.max(d, V + U / 2);
2455
+ });
2456
+ let f = 0, b = 0, p = 0;
2457
+ o.offset ? (f = Number(o.offset.x ?? 0), b = Number(o.offset.y ?? 0), p = Number(o.offset.z ?? 0)) : s && (f = -((c + u) / 2), b = -((l + a) / 2), p = -((m + d) / 2));
2458
+ const h = c + f, _ = u + f, y = l + b, I = a + b, z = m + p, x = d + p, D = (g, C, F) => `${Math.round(g)},${Math.round(C)},${Math.round(F)}`, S = new Set(
2459
+ t.map((g) => D(Number(g.x ?? 0), Number(g.y ?? 0), Number(g.z ?? 0)))
2460
+ ), M = [
2461
+ { normal: [1, 0, 0], neibDir: [1, 0, 0], verts: [[1, -1, -1], [1, 1, -1], [1, 1, 1], [1, -1, 1]] },
2462
+ { normal: [-1, 0, 0], neibDir: [-1, 0, 0], verts: [[-1, -1, 1], [-1, 1, 1], [-1, 1, -1], [-1, -1, -1]] },
2463
+ { normal: [0, 1, 0], neibDir: [0, 1, 0], verts: [[-1, 1, 1], [1, 1, 1], [1, 1, -1], [-1, 1, -1]] },
2464
+ { normal: [0, -1, 0], neibDir: [0, -1, 0], verts: [[1, -1, 1], [-1, -1, 1], [-1, -1, -1], [1, -1, -1]] },
2465
+ { normal: [0, 0, 1], neibDir: [0, 0, 1], verts: [[-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]] },
2466
+ { normal: [0, 0, -1], neibDir: [0, 0, -1], verts: [[1, -1, -1], [-1, -1, -1], [-1, 1, -1], [1, 1, -1]] }
2467
+ ], O = [], $ = [], Z = [], T = [], R = [];
2468
+ let q = 0;
2469
+ if (t.forEach((g) => {
2470
+ const C = Number(g.x ?? g.center_x ?? 0), F = Number(g.y ?? g.center_y ?? 0), V = Number(g.z ?? g.center_z ?? 0), k = Number(g.dx ?? g.size_x ?? 1), H = Number(g.dy ?? g.size_y ?? 1), U = Number(g.dz ?? g.size_z ?? 1), re = C + f, de = F + b, ie = V + p, Ne = mn(g[n], r, N), { r: le, g: Pe, b: Dt } = Ne;
2471
+ M.forEach((fe) => {
2472
+ const St = C + fe.neibDir[0] * k, Pt = F + fe.neibDir[1] * H, kt = V + fe.neibDir[2] * U;
2473
+ if (S.has(D(St, Pt, kt))) return;
2474
+ const be = q;
2475
+ fe.verts.forEach(([Lt, Tt, Ft]) => {
2476
+ O.push(re + Lt * k / 2, de + Tt * H / 2, ie + Ft * U / 2), $.push(fe.normal[0], fe.normal[1], fe.normal[2]), Z.push(le, Pe, Dt), q++;
2477
+ }), T.push(be, be + 1, be + 2, be, be + 2, be + 3), R.push(g);
2478
+ });
2479
+ }), O.length === 0) return;
2480
+ const A = new N.BufferGeometry();
2481
+ A.setAttribute("position", new N.Float32BufferAttribute(O, 3)), A.setAttribute("normal", new N.Float32BufferAttribute($, 3)), A.setAttribute("color", new N.Float32BufferAttribute(Z, 3)), A.setIndex(T);
2482
+ const v = new N.MeshLambertMaterial({
2483
+ vertexColors: !0,
2484
+ transparent: i < 1,
2485
+ opacity: i,
2486
+ side: N.DoubleSide
2487
+ // safe — all interior faces are already removed
2488
+ }), P = new N.Mesh(A, v);
2489
+ P.userData._isMergedBlocks = !0, P.userData._quadToBlock = R, this.scene.add(P), this.blocks.push(P), this.camera && this.controls && (this.lastBounds = { minX: h, maxX: _, minY: y, maxY: I, minZ: z, maxZ: x }, Fe(this, { minX: h, maxX: _, minY: y, maxY: I, minZ: z, maxZ: x }));
2490
+ }
2491
+ /**
2492
+ * Update the opacity of all currently rendered blocks.
2493
+ * @param {number} opacity - New opacity value between 0 (transparent) and 1 (opaque)
2494
+ */
2495
+ setBlockOpacity(t) {
2496
+ const n = Math.max(0, Math.min(1, Number(t)));
2497
+ this.blocks.forEach((r) => {
2498
+ r.material && (r.material.opacity = n, r.material.transparent = n < 1, r.material.needsUpdate = !0);
2499
+ });
2500
+ }
2501
+ /**
2502
+ * Register a click handler for block selection.
2503
+ * The handler is called with the full block row data when a block is clicked.
2504
+ * @param {Function|null} handler - Callback ``(blockData) => void``, or null to clear
2505
+ */
2506
+ setBlockClickHandler(t) {
2507
+ this.blockClickHandler = typeof t == "function" ? t : null;
2267
2508
  }
2268
2509
  setDrillholes(t, n = {}) {
2269
2510
  if (!this.scene || (this._clearDrillholes(), !t || t.length === 0)) return;
2270
- const { preserveView: r, assayIntervalsByHole: o, selectedAssayVariable: s } = On(n), i = kn(o, s), a = yn(i);
2271
- let u = 1 / 0, c = -1 / 0, l = 1 / 0, d = -1 / 0, m = 1 / 0, f = -1 / 0;
2272
- const p = new g.Vector3(), y = new g.Vector3(0, 1, 0);
2273
- t.forEach((h, z) => {
2274
- const E = z * 137.5 % 360 / 360, H = new g.Color().setHSL(E, 0.75, 0.55), A = (h.points || []).map((N) => {
2275
- u = Math.min(u, N.x), c = Math.max(c, N.x), l = Math.min(l, N.y), d = Math.max(d, N.y), m = Math.min(m, N.z), f = Math.max(f, N.z);
2276
- const V = new g.Vector3(N.x, N.y, N.z);
2277
- return V.md = N.md, V;
2511
+ const { preserveView: r, assayIntervalsByHole: o, selectedAssayVariable: s } = nr(n), i = rr(o, s), c = Tn(i);
2512
+ let u = 1 / 0, l = -1 / 0, a = 1 / 0, m = -1 / 0, d = 1 / 0, f = -1 / 0;
2513
+ const b = new N.Vector3(), p = new N.Vector3(0, 1, 0);
2514
+ t.forEach((h, _) => {
2515
+ const I = _ * 137.5 % 360 / 360, z = new N.Color().setHSL(I, 0.75, 0.55), x = (h.points || []).map((M) => {
2516
+ u = Math.min(u, M.x), l = Math.max(l, M.x), a = Math.min(a, M.y), m = Math.max(m, M.y), d = Math.min(d, M.z), f = Math.max(f, M.z);
2517
+ const O = new N.Vector3(M.x, M.y, M.z);
2518
+ return O.md = M.md, O;
2278
2519
  });
2279
- if (A.length < 2) {
2280
- if (A.length === 1) {
2281
- const N = new g.SphereGeometry(5, 12, 12), V = new g.MeshLambertMaterial({
2282
- color: H,
2283
- emissive: H,
2520
+ if (x.length < 2) {
2521
+ if (x.length === 1) {
2522
+ const M = new N.SphereGeometry(5, 12, 12), O = new N.MeshLambertMaterial({
2523
+ color: z,
2524
+ emissive: z,
2284
2525
  emissiveIntensity: 0.2
2285
- }), Y = new g.Mesh(N, V);
2286
- Y.position.copy(A[0]), Y.userData = Le(h), this.scene.add(Y), this.drillLines.push(Y), this.drillMeshes.push(Y);
2526
+ }), $ = new N.Mesh(M, O);
2527
+ $.position.copy(x[0]), $.userData = Oe(h), this.scene.add($), this.drillLines.push($), this.drillMeshes.push($);
2287
2528
  }
2288
2529
  return;
2289
2530
  }
2290
- const j = new g.Group();
2291
- j.userData = Le(h);
2292
- const P = s ? this._resolveAssayIntervalsForHole(h, o) : [];
2293
- for (let N = 0; N < A.length - 1; N += 1) {
2294
- const V = A[N], Y = A[N + 1], re = p.subVectors(Y, V), T = re.length();
2531
+ const D = new N.Group();
2532
+ D.userData = Oe(h);
2533
+ const S = s ? this._resolveAssayIntervalsForHole(h, o) : [];
2534
+ for (let M = 0; M < x.length - 1; M += 1) {
2535
+ const O = x[M], $ = x[M + 1], Z = b.subVectors($, O), T = Z.length();
2295
2536
  if (T <= 1e-3) continue;
2296
- const B = 2.2, q = new g.CylinderGeometry(B, B, T, 6, 1, !0), M = this._getSegmentColor({
2537
+ const R = 2.2, q = new N.CylinderGeometry(R, R, T, 6, 1, !0), A = this._getSegmentColor({
2297
2538
  selectedAssayVariable: s,
2298
- assayIntervals: P,
2299
- assayScale: a,
2539
+ assayIntervals: S,
2540
+ assayScale: c,
2300
2541
  holeId: h.id,
2301
- segmentIndex: N,
2302
- p1: V,
2303
- p2: Y
2304
- }), _ = new g.MeshLambertMaterial({
2305
- color: M,
2542
+ segmentIndex: M,
2543
+ p1: O,
2544
+ p2: $
2545
+ }), v = new N.MeshLambertMaterial({
2546
+ color: A,
2306
2547
  flatShading: !0,
2307
- emissive: M,
2548
+ emissive: A,
2308
2549
  emissiveIntensity: 0.15
2309
- }), I = new g.Mesh(q, _);
2310
- I.position.copy(V.clone().addScaledVector(re, 0.5)), I.quaternion.setFromUnitVectors(y, re.clone().normalize()), I.userData = Le(h), j.add(I), this.drillMeshes.push(I);
2550
+ }), P = new N.Mesh(q, v);
2551
+ P.position.copy(O.clone().addScaledVector(Z, 0.5)), P.quaternion.setFromUnitVectors(p, Z.clone().normalize()), P.userData = Oe(h), D.add(P), this.drillMeshes.push(P);
2311
2552
  }
2312
- this.scene.add(j), this.drillLines.push(j);
2313
- }), this.camera && this.controls && (this.lastBounds = { minX: u, maxX: c, minY: l, maxY: d, minZ: m, maxZ: f }, r || De(this, { minX: u, maxX: c, minY: l, maxY: d, minZ: m, maxZ: f }));
2553
+ this.scene.add(D), this.drillLines.push(D);
2554
+ }), this.camera && this.controls && (this.lastBounds = { minX: u, maxX: l, minY: a, maxY: m, minZ: d, maxZ: f }, r || Fe(this, { minX: u, maxX: l, minY: a, maxY: m, minZ: d, maxZ: f }));
2314
2555
  }
2315
- _getSegmentColor({ selectedAssayVariable: t, assayIntervals: n, assayScale: r, holeId: o, segmentIndex: s, p1: i, p2: a }) {
2556
+ _getSegmentColor({ selectedAssayVariable: t, assayIntervals: n, assayScale: r, holeId: o, segmentIndex: s, p1: i, p2: c }) {
2316
2557
  if (!t)
2317
- return wn(o, s);
2558
+ return sr(o, s);
2318
2559
  if (t === "__HAS_ASSAY__") {
2319
- if (!(n != null && n.length)) return new g.Color(ae);
2320
- const l = rt(i, a);
2321
- return l ? n.some((m) => {
2322
- const f = Number(m == null ? void 0 : m.from), p = Number(m == null ? void 0 : m.to);
2323
- if (!Number.isFinite(f) || !Number.isFinite(p)) return !1;
2324
- const y = Math.max(l.segStart, f);
2325
- return Math.min(l.segEnd, p) > y;
2326
- }) ? new g.Color("#ff8c42") : new g.Color(ae) : new g.Color(ae);
2560
+ if (!(n != null && n.length)) return new N.Color(me);
2561
+ const a = it(i, c);
2562
+ return a ? n.some((d) => {
2563
+ const f = Number(d == null ? void 0 : d.from), b = Number(d == null ? void 0 : d.to);
2564
+ if (!Number.isFinite(f) || !Number.isFinite(b)) return !1;
2565
+ const p = Math.max(a.segStart, f);
2566
+ return Math.min(a.segEnd, b) > p;
2567
+ }) ? new N.Color("#ff8c42") : new N.Color(me) : new N.Color(me);
2327
2568
  }
2328
- if (!(n != null && n.length)) return new g.Color(ae);
2329
- const u = rt(i, a);
2330
- if (!u) return new g.Color(ae);
2331
- const c = Dn(n, u.segStart, u.segEnd);
2332
- return Ln(c, r);
2569
+ if (!(n != null && n.length)) return new N.Color(me);
2570
+ const u = it(i, c);
2571
+ if (!u) return new N.Color(me);
2572
+ const l = er(n, u.segStart, u.segEnd);
2573
+ return tr(l, r);
2333
2574
  }
2334
2575
  _resolveAssayIntervalsForHole(t, n) {
2335
2576
  if (!n || !t) return [];
@@ -2337,7 +2578,7 @@ class Or {
2337
2578
  if (!r) return [];
2338
2579
  const o = n[r];
2339
2580
  if (Array.isArray(o) && o.length) return o;
2340
- const s = Fn(r);
2581
+ const s = or(r);
2341
2582
  if (s) {
2342
2583
  const i = n[s];
2343
2584
  if (Array.isArray(i) && i.length) return i;
@@ -2345,28 +2586,59 @@ class Or {
2345
2586
  return [];
2346
2587
  }
2347
2588
  _fitCameraToBounds({ minX: t, maxX: n, minY: r, maxY: o, minZ: s, maxZ: i }) {
2348
- De(this, { minX: t, maxX: n, minY: r, maxY: o, minZ: s, maxZ: i });
2589
+ Fe(this, { minX: t, maxX: n, minY: r, maxY: o, minZ: s, maxZ: i });
2349
2590
  }
2350
2591
  recenterCameraToOrigin(t = 1e3) {
2351
- An(this, t);
2592
+ Un(this, t);
2352
2593
  }
2353
2594
  lookDown(t = 2e3) {
2354
- En(this, t);
2595
+ Yn(this, t);
2355
2596
  }
2356
2597
  pan(t = 0, n = 0) {
2357
- Sn(this, t, n);
2598
+ qn(this, t, n);
2358
2599
  }
2359
2600
  dolly(t = 1.1) {
2360
- vn(this, t);
2601
+ Xn(this, t);
2361
2602
  }
2362
2603
  focusOnLastBounds(t = 1.2) {
2363
- Pn(this, t);
2604
+ Zn(this, t);
2364
2605
  }
2365
2606
  _clearBlocks() {
2366
2607
  this.blocks.forEach((t) => {
2367
2608
  this.scene.remove(t), t.geometry.dispose(), t.material.dispose();
2368
2609
  }), this.blocks = [];
2369
2610
  }
2611
+ setStructuralDiscs(t, n, r = {}) {
2612
+ if (!this.scene || (this._clearStructuralDiscs(), !(t != null && t.length) || !(n != null && n.length))) return;
2613
+ const { maxDiscs: o = 3e3 } = r;
2614
+ let s = t;
2615
+ if (s.length > o) {
2616
+ const u = s.length / o, l = [];
2617
+ for (let a = 0; a < o; a++)
2618
+ l.push(s[Math.floor(a * u)]);
2619
+ s = l;
2620
+ }
2621
+ const i = n.flatMap((u) => (u.points || []).map((l) => ({ ...l, hole_id: u.id }))), c = gn(s, i, r);
2622
+ c.length && (this.structuralGroup = jn(c, r), this.scene.add(this.structuralGroup), this.structuralGroup.traverse((u) => {
2623
+ u.isMesh && this.structuralMeshes.push(u);
2624
+ }));
2625
+ }
2626
+ /**
2627
+ * Change the camera field-of-view while keeping the visible scene the same apparent size.
2628
+ * FOV is clamped to [FOV_MIN_DEG, FOV_MAX_DEG]. Delegates to setFov in baselode3dCameraControls.
2629
+ * @param {number} fovDeg - Desired FOV in degrees
2630
+ */
2631
+ setCameraFov(t) {
2632
+ Jn(this, t);
2633
+ }
2634
+ setStructuralDiscsVisible(t) {
2635
+ this.structuralGroup && (this.structuralGroup.visible = !!t);
2636
+ }
2637
+ _clearStructuralDiscs() {
2638
+ this.structuralGroup && (this.scene.remove(this.structuralGroup), this.structuralGroup.traverse((t) => {
2639
+ t.isMesh && (t.geometry.dispose(), t.material.dispose());
2640
+ }), this.structuralGroup = null), this.structuralMeshes = [];
2641
+ }
2370
2642
  _clearDrillholes() {
2371
2643
  this.drillLines.forEach((t) => {
2372
2644
  this.scene.remove(t), t.isGroup ? t.traverse((n) => {
@@ -2375,30 +2647,30 @@ class Or {
2375
2647
  }), this.drillLines = [], this.drillMeshes = [];
2376
2648
  }
2377
2649
  dispose() {
2378
- 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, this._clearBlocks(), this._clearDrillholes(), 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));
2650
+ 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, this._clearBlocks(), this._clearDrillholes(), this._clearStructuralDiscs(), 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));
2379
2651
  }
2380
2652
  setDrillholeClickHandler(t) {
2381
2653
  this.drillholeClickHandler = t;
2382
2654
  }
2383
2655
  setControlMode(t = "orbit") {
2384
- Tn(this, t);
2656
+ Qn(this, t);
2385
2657
  }
2386
2658
  }
2387
- function Fn(e) {
2659
+ function or(e) {
2388
2660
  return `${e ?? ""}`.trim().toLowerCase();
2389
2661
  }
2390
- function wn(e, t) {
2391
- const n = `${e ?? ""}:${t ?? 0}`, r = Vn(n), o = (t ?? 0) % 14 / 14, s = (r * 0.15 + o * 0.85) % 1, i = new g.Color();
2662
+ function sr(e, t) {
2663
+ const n = `${e ?? ""}:${t ?? 0}`, r = ir(n), o = (t ?? 0) % 14 / 14, s = (r * 0.15 + o * 0.85) % 1, i = new N.Color();
2392
2664
  return i.setHSL(s, 1, 0.5), i;
2393
2665
  }
2394
- function Vn(e) {
2666
+ function ir(e) {
2395
2667
  const t = `${e ?? ""}`;
2396
2668
  let n = 2166136261;
2397
2669
  for (let r = 0; r < t.length; r += 1)
2398
2670
  n ^= t.charCodeAt(r), n = Math.imul(n, 16777619);
2399
2671
  return (n >>> 0) / 4294967295;
2400
2672
  }
2401
- function kr({
2673
+ function oo({
2402
2674
  controlMode: e = "orbit",
2403
2675
  onToggleFly: t = () => {
2404
2676
  },
@@ -2409,128 +2681,225 @@ function kr({
2409
2681
  onFit: o = () => {
2410
2682
  }
2411
2683
  }) {
2412
- return /* @__PURE__ */ Ce("div", { className: "baselode-3d-controls", children: [
2413
- /* @__PURE__ */ G("button", { type: "button", className: "ghost-button", onClick: n, children: "Recenter to (0,0,0)" }),
2414
- /* @__PURE__ */ G("button", { type: "button", className: "ghost-button", onClick: r, children: "Look down" }),
2415
- /* @__PURE__ */ G("button", { type: "button", className: "ghost-button", onClick: o, children: "Fit to scene" }),
2416
- /* @__PURE__ */ G("button", { type: "button", className: "ghost-button", onClick: t, children: e === "orbit" ? "Enable fly controls" : "Disable fly controls" })
2684
+ return /* @__PURE__ */ Q("div", { className: "baselode-3d-controls", children: [
2685
+ /* @__PURE__ */ L("button", { type: "button", className: "ghost-button", onClick: n, children: "Recenter to (0,0,0)" }),
2686
+ /* @__PURE__ */ L("button", { type: "button", className: "ghost-button", onClick: r, children: "Look down" }),
2687
+ /* @__PURE__ */ L("button", { type: "button", className: "ghost-button", onClick: o, children: "Fit to scene" }),
2688
+ /* @__PURE__ */ L("button", { type: "button", className: "ghost-button", onClick: t, children: e === "orbit" ? "Enable fly controls" : "Disable fly controls" })
2689
+ ] });
2690
+ }
2691
+ function so({
2692
+ properties: e = [],
2693
+ selectedProperty: t = "",
2694
+ onPropertyChange: n = () => {
2695
+ },
2696
+ opacity: r = 0.85,
2697
+ onOpacityChange: o = () => {
2698
+ },
2699
+ propertyStats: s = null,
2700
+ clickedBlock: i = null,
2701
+ onPopupClose: c = () => {
2702
+ }
2703
+ }) {
2704
+ var u, l;
2705
+ return /* @__PURE__ */ Q("div", { className: "bm-widget", children: [
2706
+ /* @__PURE__ */ L("label", { className: "bm-widget__label", htmlFor: "bm-property-select", children: "Color by" }),
2707
+ /* @__PURE__ */ Q(
2708
+ "select",
2709
+ {
2710
+ id: "bm-property-select",
2711
+ className: "bm-widget__select",
2712
+ value: t,
2713
+ onChange: (a) => n(a.target.value),
2714
+ children: [
2715
+ e.length === 0 && /* @__PURE__ */ L("option", { value: "", children: "— no attributes —" }),
2716
+ e.map((a) => /* @__PURE__ */ L("option", { value: a, children: a }, a))
2717
+ ]
2718
+ }
2719
+ ),
2720
+ s && s.type === "numeric" && /* @__PURE__ */ Q("div", { className: "bm-widget__scale", children: [
2721
+ /* @__PURE__ */ L("span", { className: "bm-widget__scale-label bm-widget__scale-label--min", children: ((u = s.min) == null ? void 0 : u.toFixed(2)) ?? "—" }),
2722
+ /* @__PURE__ */ L("div", { className: "bm-widget__scale-bar" }),
2723
+ /* @__PURE__ */ L("span", { className: "bm-widget__scale-label bm-widget__scale-label--max", children: ((l = s.max) == null ? void 0 : l.toFixed(2)) ?? "—" })
2724
+ ] }),
2725
+ s && s.type === "categorical" && /* @__PURE__ */ L("div", { className: "bm-widget__categories", children: (s.categories || []).map((a, m) => {
2726
+ const d = Math.round(m / Math.max(s.categories.length, 1) * 360);
2727
+ return /* @__PURE__ */ L(
2728
+ "span",
2729
+ {
2730
+ className: "bm-widget__category-chip",
2731
+ style: { background: `hsl(${d},70%,50%)` },
2732
+ children: a
2733
+ },
2734
+ a
2735
+ );
2736
+ }) }),
2737
+ /* @__PURE__ */ Q("label", { className: "bm-widget__label", htmlFor: "bm-opacity-slider", children: [
2738
+ "Opacity (",
2739
+ Math.round(r * 100),
2740
+ "%)"
2741
+ ] }),
2742
+ /* @__PURE__ */ L(
2743
+ "input",
2744
+ {
2745
+ id: "bm-opacity-slider",
2746
+ type: "range",
2747
+ className: "bm-widget__slider",
2748
+ min: "0",
2749
+ max: "1",
2750
+ step: "0.01",
2751
+ value: r,
2752
+ onChange: (a) => o(parseFloat(a.target.value))
2753
+ }
2754
+ ),
2755
+ i && /* @__PURE__ */ Q("div", { className: "bm-widget__popup", children: [
2756
+ /* @__PURE__ */ Q("div", { className: "bm-widget__popup-header", children: [
2757
+ /* @__PURE__ */ L("span", { children: "Block attributes" }),
2758
+ /* @__PURE__ */ L(
2759
+ "button",
2760
+ {
2761
+ type: "button",
2762
+ className: "bm-widget__popup-close",
2763
+ onClick: c,
2764
+ "aria-label": "Close",
2765
+ children: "×"
2766
+ }
2767
+ )
2768
+ ] }),
2769
+ /* @__PURE__ */ L("table", { className: "bm-widget__popup-table", children: /* @__PURE__ */ L("tbody", { children: Object.entries(i).map(([a, m]) => /* @__PURE__ */ Q("tr", { children: [
2770
+ /* @__PURE__ */ L("th", { children: a }),
2771
+ /* @__PURE__ */ L("td", { children: m == null ? "—" : String(m) })
2772
+ ] }, a)) }) })
2773
+ ] })
2417
2774
  ] });
2418
2775
  }
2419
2776
  export {
2420
- pn as ASSAY_COLOR_PALETTE_10,
2421
- Pt as ASSAY_NON_VALUE_FIELDS,
2422
- D as AZIMUTH,
2423
- qn as BASELODE_DATA_MODEL_DRILL_ASSAY,
2424
- Gn as BASELODE_DATA_MODEL_DRILL_COLLAR,
2425
- Xn as BASELODE_DATA_MODEL_DRILL_SURVEY,
2426
- Wn as BASELODE_DATA_MODEL_STRUCTURAL_POINT,
2427
- kr as Baselode3DControls,
2428
- Or as Baselode3DScene,
2429
- Be as CHART_OPTIONS,
2430
- Vt as COMMENT_COLUMN_NAMES,
2431
- it as CRS,
2432
- vt as DEFAULT_COLUMN_MAP,
2433
- R as DEPTH,
2434
- L as DIP,
2435
- _e as DISPLAY_CATEGORICAL,
2436
- pe as DISPLAY_COMMENT,
2437
- Me as DISPLAY_HIDDEN,
2438
- ye as DISPLAY_NUMERIC,
2439
- ke as DISPLAY_TADPOLE,
2440
- ie as EASTING,
2441
- he as ELEVATION,
2442
- tn as ERROR_COLOR,
2443
- $ as FROM,
2444
- Ge as HIDDEN_COLUMNS,
2445
- b as HOLE_ID,
2446
- Q as LATITUDE,
2447
- ee as LONGITUDE,
2448
- we as MID,
2449
- se as NORTHING,
2450
- Ze as NUMERIC_LINE_COLOR,
2451
- en as NUMERIC_MARKER_COLOR,
2452
- ne as PROJECT_ID,
2453
- St as STRIKE,
2454
- F as TO,
2455
- Ar as TracePlot,
2456
- Dr as annotationsFromIntervals,
2457
- gr as assembleDataset,
2458
- cr as attachAssayPositions,
2459
- ar as balancedTangentialDesurvey,
2460
- jt as buildAssayState,
2461
- mn as buildCommentsConfig,
2462
- yn as buildEqualRangeColorScale,
2463
- on as buildIntervalPoints,
2464
- ln as buildPlotConfig,
2465
- Ir as buildStrikeDipSymbol,
2466
- Lr as buildStructuralDiscs,
2467
- Mr as buildStructuralStripConfig,
2468
- un as buildTadpoleConfig,
2469
- lr as buildTraces,
2470
- Ye as buildViewSignature,
2471
- _r as calculatePropertyStats,
2472
- Rt as classifyColumns,
2473
- yr as coerceNumeric,
2474
- nr as defaultChartType,
2475
- Ie as deriveAssayProps,
2476
- ir as desurveyTraces,
2477
- Nn as dipAzimuthToNormal,
2478
- vn as dolly,
2479
- In as emitViewChangeIfNeeded,
2480
- pr as filterByProject,
2481
- De as fitCameraToBounds,
2482
- Pn as focusOnLastBounds,
2483
- Ve as getChartOptions,
2484
- Wt as getColorForValue,
2485
- xt as getEqualRangeBinIndex,
2486
- bn as getEqualRangeColor,
2487
- Nt as getViewState,
2488
- Kt as groupRowsByHole,
2489
- rn as holeHasData,
2490
- Tr as intervalsAsTubes,
2491
- hr as joinAssaysToTraces,
2492
- rr as loadAssayFile,
2493
- Ht as loadAssayHole,
2494
- $t as loadAssayMetadata,
2495
- fr as loadAssays,
2496
- dr as loadCollars,
2497
- mr as loadSurveys,
2498
- $e as loadTable,
2499
- Jn as logDataInfo,
2500
- Kn as logDataWarning,
2501
- En as lookDown,
2502
- Bt as minimumCurvatureDesurvey,
2503
- er as normalizeCsvRow,
2504
- ze as normalizeFieldName,
2505
- Sn as pan,
2506
- Qt as parseAssayCsvTextToHoles,
2507
- kt as parseAssayHole,
2508
- Qn as parseAssayHoleIds,
2509
- Ot as parseAssayHoleIdsWithAssays,
2510
- Ft as parseAssaysCSV,
2511
- br as parseBlockModelCSV,
2512
- ur as parseDrillholesCSV,
2513
- Jt as parseStructuralCSV,
2514
- zr as parseStructuralIntervalsCSV,
2515
- Cr as parseStructuralPointsCSV,
2516
- or as parseSurveyCSV,
2517
- Nr as parseUnifiedDataset,
2518
- tr as pickFirstPresent,
2519
- Sr as planView,
2520
- _n as projectTraceToSection,
2521
- An as recenterCameraToOrigin,
2522
- dt as reorderHoleIds,
2523
- vr as sectionView,
2524
- xn as sectionWindow,
2525
- Tn as setControlMode,
2526
- Mn as setViewState,
2527
- ue as standardizeColumns,
2528
- Zn as standardizeRowArray,
2529
- sr as tangentialDesurvey,
2530
- Tt as toError,
2531
- Pr as tracesAsSegments,
2532
- Er as useDrillholeTraceGrid,
2533
- xr as validateStructuralPoints,
2777
+ Ln as ASSAY_COLOR_PALETTE_10,
2778
+ Ht as ASSAY_NON_VALUE_FIELDS,
2779
+ j as AZIMUTH,
2780
+ br as BASELODE_DATA_MODEL_DRILL_ASSAY,
2781
+ hr as BASELODE_DATA_MODEL_DRILL_COLLAR,
2782
+ pr as BASELODE_DATA_MODEL_DRILL_SURVEY,
2783
+ yr as BASELODE_DATA_MODEL_STRUCTURAL_POINT,
2784
+ oo as Baselode3DControls,
2785
+ ro as Baselode3DScene,
2786
+ so as BlockModelWidget,
2787
+ Xe as CHART_OPTIONS,
2788
+ Zt as COMMENT_COLUMN_NAMES,
2789
+ at as CRS,
2790
+ Rt as DEFAULT_COLUMN_MAP,
2791
+ Y as DEPTH,
2792
+ B as DIP,
2793
+ Me as DISPLAY_CATEGORICAL,
2794
+ _e as DISPLAY_COMMENT,
2795
+ ve as DISPLAY_HIDDEN,
2796
+ xe as DISPLAY_NUMERIC,
2797
+ we as DISPLAY_TADPOLE,
2798
+ ce as EASTING,
2799
+ ge as ELEVATION,
2800
+ xn as ERROR_COLOR,
2801
+ Kn as FOV_MAX_DEG,
2802
+ Wn as FOV_MIN_DEG,
2803
+ X as FROM,
2804
+ Ze as HIDDEN_COLUMNS,
2805
+ E as HOLE_ID,
2806
+ te as LATITUDE,
2807
+ ne as LONGITUDE,
2808
+ Re as MID,
2809
+ ue as NORTHING,
2810
+ Qe as NUMERIC_LINE_COLOR,
2811
+ _n as NUMERIC_MARKER_COLOR,
2812
+ se as PROJECT_ID,
2813
+ $t as STRIKE,
2814
+ G as TO,
2815
+ Wr as TracePlot,
2816
+ yn as alphaBetaToNormal,
2817
+ no as annotationsFromIntervals,
2818
+ $r as assembleDataset,
2819
+ Pr as attachAssayPositions,
2820
+ Dr as balancedTangentialDesurvey,
2821
+ Qt as buildAssayState,
2822
+ Sn as buildCommentsConfig,
2823
+ Tn as buildEqualRangeColorScale,
2824
+ Mn as buildIntervalPoints,
2825
+ An as buildPlotConfig,
2826
+ Zr as buildStrikeDipSymbol,
2827
+ jn as buildStructuralDiscs,
2828
+ Xr as buildStructuralStripConfig,
2829
+ En as buildTadpoleConfig,
2830
+ Sr as buildTraces,
2831
+ qe as buildViewSignature,
2832
+ Br as calculateBlockVolume,
2833
+ cn as calculatePropertyStats,
2834
+ Wt as classifyColumns,
2835
+ wr as coerceNumeric,
2836
+ gn as computeStructuralPositions,
2837
+ Cr as defaultChartType,
2838
+ Ee as deriveAssayProps,
2839
+ vr as desurveyTraces,
2840
+ Hn as dipAzimuthToNormal,
2841
+ Xn as dolly,
2842
+ Gn as emitViewChangeIfNeeded,
2843
+ un as filterBlocks,
2844
+ Vr as filterByProject,
2845
+ Fe as fitCameraToBounds,
2846
+ Zn as focusOnLastBounds,
2847
+ jr as getBlockStats,
2848
+ He as getChartOptions,
2849
+ mn as getColorForValue,
2850
+ It as getEqualRangeBinIndex,
2851
+ On as getEqualRangeColor,
2852
+ Et as getViewState,
2853
+ fn as groupRowsByHole,
2854
+ zn as holeHasData,
2855
+ bn as interpolateTrace,
2856
+ to as intervalsAsTubes,
2857
+ Or as joinAssaysToTraces,
2858
+ Ir as loadAssayFile,
2859
+ Jt as loadAssayHole,
2860
+ Kt as loadAssayMetadata,
2861
+ Fr as loadAssays,
2862
+ Hr as loadBlockModelMetadata,
2863
+ Lr as loadCollars,
2864
+ Tr as loadSurveys,
2865
+ Be as loadTable,
2866
+ xr as logDataInfo,
2867
+ _r as logDataWarning,
2868
+ Yn as lookDown,
2869
+ nn as minimumCurvatureDesurvey,
2870
+ an as normalizeBlockRow,
2871
+ zr as normalizeCsvRow,
2872
+ Ie as normalizeFieldName,
2873
+ qn as pan,
2874
+ pn as parseAssayCsvTextToHoles,
2875
+ Yt as parseAssayHole,
2876
+ Nr as parseAssayHoleIds,
2877
+ Ut as parseAssayHoleIdsWithAssays,
2878
+ qt as parseAssaysCSV,
2879
+ Rr as parseBlockModelCSV,
2880
+ kr as parseDrillholesCSV,
2881
+ hn as parseStructuralCSV,
2882
+ Yr as parseStructuralIntervalsCSV,
2883
+ Ur as parseStructuralPointsCSV,
2884
+ Ar as parseSurveyCSV,
2885
+ qr as parseUnifiedDataset,
2886
+ Mr as pickFirstPresent,
2887
+ Jr as planView,
2888
+ Vn as projectTraceToSection,
2889
+ Un as recenterCameraToOrigin,
2890
+ ht as reorderHoleIds,
2891
+ Qr as sectionView,
2892
+ wn as sectionWindow,
2893
+ Qn as setControlMode,
2894
+ Jn as setFov,
2895
+ Bn as setViewState,
2896
+ pe as standardizeColumns,
2897
+ gr as standardizeRowArray,
2898
+ Er as tangentialDesurvey,
2899
+ jt as toError,
2900
+ eo as tracesAsSegments,
2901
+ Kr as useDrillholeTraceGrid,
2902
+ Gr as validateStructuralPoints,
2534
2903
  w as withDataErrorContext
2535
2904
  };
2536
2905
  //# sourceMappingURL=baselode.js.map