baselode 0.1.1 → 0.1.2

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,97 +1,107 @@
1
- import ee from "papaparse";
2
- import { jsx as k, jsxs as ae } from "react/jsx-runtime";
3
- import { useRef as rt, useState as W, useEffect as re, useMemo as ze } from "react";
4
- import me from "plotly.js-dist-min";
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
5
  import * as g from "three";
6
- import { OrbitControls as ot } from "three/examples/jsm/controls/OrbitControls";
7
- import { FlyControls as it } from "three/examples/jsm/controls/FlyControls";
8
- import { ViewportGizmo as st } from "three-viewport-gizmo";
9
- const x = "hole_id", q = "latitude", X = "longitude", oe = "elevation", j = "azimuth", B = "dip", $ = "from", H = "to", we = "mid", Z = "project_id", K = "easting", J = "northing", $e = "crs", V = "depth", cn = {
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 = {
10
10
  // A unique hole identifier across the entire dataset and all future data sets
11
- [x]: "string",
11
+ [b]: "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
- [Z]: "string",
15
+ [ne]: "string",
16
16
  // The latitude of the collar, in decimal degrees (WGS84)
17
- [q]: "number",
17
+ [Q]: "number",
18
18
  // The longitude of the collar, in decimal degrees (WGS84)
19
- [X]: "number",
19
+ [ee]: "number",
20
20
  // The elevation of the collar, in meters above sea level (WGS84)
21
- [oe]: "number",
21
+ [he]: "number",
22
22
  // The easting coordinate of the collar, in meters (projected CRS)
23
- [K]: "number",
23
+ [ie]: "number",
24
24
  // The northing coordinate of the collar, in meters (projected CRS)
25
- [J]: "number",
25
+ [se]: "number",
26
26
  // The coordinate reference system of the collar coordinates for easting/northing, as an EPSG code or proj string
27
- [$e]: "string"
28
- }, un = {
27
+ [it]: "string"
28
+ }, Xn = {
29
29
  // The unique hole id that maps to the collar and any other data tables
30
- [x]: "string",
30
+ [b]: "string",
31
31
  // The depth along the hole where the survey measurement was taken / started
32
- [V]: "number",
32
+ [R]: "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
- [H]: "number",
34
+ [F]: "number",
35
35
  // The azimuth of the hole at the survey depth, in degrees from north
36
- [j]: "number",
36
+ [D]: "number",
37
37
  // The dip of the hole at the survey depth, in degrees from horizontal (negative values indicate downward inclination)
38
- [B]: "number"
39
- }, dn = {
38
+ [L]: "number"
39
+ }, qn = {
40
40
  // The unique hole id that maps to the collar and any other data tables
41
- [x]: "string",
41
+ [b]: "string",
42
42
  // The depth along the hole where the assay interval starts
43
43
  [$]: "number",
44
44
  // The depth along the hole where the assay interval ends
45
- [H]: "number",
45
+ [F]: "number",
46
46
  // The midpoint depth of the assay interval
47
47
  [we]: "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
- }, at = {
51
- [x]: ["hole_id", "holeid", "hole id", "hole-id"],
50
+ }, Wn = {
51
+ [b]: "string",
52
+ [R]: "number",
53
+ [L]: "number",
54
+ [D]: "number",
55
+ [st]: "number",
56
+ [at]: "number",
57
+ comments: "string"
58
+ }, vt = {
59
+ [b]: ["hole_id", "holeid", "hole id", "hole-id"],
52
60
  datasource_hole_id: ["datasource_hole_id", "datasourceholeid", "datasource hole id", "datasource-hole-id", "company_hole_id", "companyholeid", "company hole id", "company-hole-id"],
53
- [Z]: ["project_id", "projectid", "project id", "project-id", "project_code", "projectcode", "project code", "project-code", "companyId", "company_id", "companyid", "company id", "company-id", "dataset", "project"],
54
- [q]: ["latitude", "lat"],
55
- [X]: ["longitude", "lon"],
56
- [oe]: ["elevation", "rl", "elev", "z"],
57
- [K]: ["easting", "x"],
58
- [J]: ["northing", "y"],
59
- [$e]: ["crs", "epsg", "projection"],
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"],
60
68
  [$]: ["from", "depth_from", "from_depth", "samp_from", "sample_from", "sampfrom", "fromdepth"],
61
- [H]: ["to", "depth_to", "to_depth", "samp_to", "sample_to", "sampto", "todepth"],
62
- [j]: ["azimuth", "az", "dipdir", "dip_direction"],
63
- [B]: ["dip"],
64
- declination: ["declination", "dec"],
65
- [V]: ["depth", "survey_depth", "surveydepth"]
66
- }, je = {};
67
- for (const [e, t] of Object.entries(at))
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))
68
78
  for (const n of t) {
69
79
  const r = n.toLowerCase().trim();
70
- je[r] = e;
80
+ lt[r] = e;
71
81
  }
72
- function fe(e) {
82
+ function ze(e) {
73
83
  return (e || "").toString().trim().toLowerCase().replace(/\s+/g, "_");
74
84
  }
75
- function ce(e, t = null, n = null) {
76
- const r = { ...je };
85
+ function ue(e, t = null, n = null) {
86
+ const r = { ...lt };
77
87
  if (n) {
78
88
  for (const [s, i] of Object.entries(n))
79
89
  if (s != null && i != null) {
80
- const a = fe(s), c = fe(i);
81
- r[a] = c;
90
+ const a = ze(s), u = ze(i);
91
+ r[a] = u;
82
92
  }
83
93
  }
84
94
  const o = {};
85
95
  for (const [s, i] of Object.entries(e)) {
86
- const a = fe(s), c = r[a] || a;
87
- o[c] = i;
96
+ const a = ze(s), u = r[a] || a;
97
+ o[u] = i;
88
98
  }
89
99
  return o;
90
100
  }
91
- function mn(e, t = null, n = null) {
92
- return e.map((r) => ce(r, t, n));
101
+ function Zn(e, t = null, n = null) {
102
+ return e.map((r) => ue(r, t, n));
93
103
  }
94
- const Be = /* @__PURE__ */ new Set([
104
+ const Pt = /* @__PURE__ */ new Set([
95
105
  "hole_id",
96
106
  "holeid",
97
107
  "id",
@@ -123,34 +133,34 @@ const Be = /* @__PURE__ */ new Set([
123
133
  "todepth",
124
134
  "comment",
125
135
  "z"
126
- ]), Ie = "[baselode:data]";
127
- function lt(e, t = "Unknown error") {
136
+ ]), Oe = "[baselode:data]";
137
+ function Tt(e, t = "Unknown error") {
128
138
  if (e instanceof Error) return e;
129
139
  const n = typeof e == "string" && e.trim() ? e : t;
130
140
  return new Error(n);
131
141
  }
132
- function P(e, t, n = "Operation failed") {
133
- const r = lt(t, n), o = new Error(`${e}: ${r.message}`);
142
+ function w(e, t, n = "Operation failed") {
143
+ const r = Tt(t, n), o = new Error(`${e}: ${r.message}`);
134
144
  return o.cause = r, o;
135
145
  }
136
- function fn(e, t) {
146
+ function Kn(e, t) {
137
147
  if (t !== void 0) {
138
- console.warn(`${Ie} ${e}`, t);
148
+ console.warn(`${Oe} ${e}`, t);
139
149
  return;
140
150
  }
141
- console.warn(`${Ie} ${e}`);
151
+ console.warn(`${Oe} ${e}`);
142
152
  }
143
- function hn(e) {
144
- console.info(`${Ie} ${e}`);
153
+ function Jn(e) {
154
+ console.info(`${Oe} ${e}`);
145
155
  }
146
- const ye = (e, t = null) => ce(e, null, t);
147
- function ct(e) {
148
- return { holeId: e[x] };
156
+ const Ee = (e, t = null) => ue(e, null, t);
157
+ function Dt(e) {
158
+ return { holeId: e[b] };
149
159
  }
150
- function Ue(e, t = null) {
151
- const n = e[x], r = n !== void 0 ? `${n}`.trim() : "";
160
+ function ct(e, t = null) {
161
+ const n = e[b], r = n !== void 0 ? `${n}`.trim() : "";
152
162
  if (!r) return null;
153
- const o = e[Z] || e.project || e.project_code, s = Number(e[$]), i = Number(e[H]);
163
+ const o = e[ne] || e.project || e.project_code, s = Number(e[$]), i = Number(e[F]);
154
164
  return !Number.isFinite(s) || !Number.isFinite(i) || i <= s ? null : {
155
165
  holeId: r,
156
166
  project: o,
@@ -159,117 +169,117 @@ function Ue(e, t = null) {
159
169
  ...e
160
170
  };
161
171
  }
162
- function Ye(e, t) {
172
+ function ut(e, t) {
163
173
  var o;
164
174
  const n = t.sort((s, i) => s.from - i.from), r = [];
165
175
  return n.forEach((s) => {
166
- const { from: i, to: a, project: c, ...l } = s, u = {
176
+ const { from: i, to: a, project: u, ...c } = s, l = {
167
177
  z: i,
168
178
  from: i,
169
179
  to: a,
170
- [x]: e,
171
- [Z]: c,
172
- ...l
180
+ [b]: e,
181
+ [ne]: u,
182
+ ...c
173
183
  };
174
- r.push(u), r.push({ ...u, z: a });
184
+ r.push(l), r.push({ ...l, z: a });
175
185
  }), { id: e, project: (o = n[0]) == null ? void 0 : o.project, points: r };
176
186
  }
177
- function pn(e, t = null) {
187
+ function Qn(e, t = null) {
178
188
  return new Promise((n, r) => {
179
189
  const o = /* @__PURE__ */ new Set();
180
- ee.parse(e, {
190
+ W.parse(e, {
181
191
  header: !0,
182
192
  dynamicTyping: !0,
183
193
  skipEmptyLines: !0,
184
194
  step: (s) => {
185
- const a = ye(s.data, t)[x];
195
+ const a = Ee(s.data, t)[b];
186
196
  a !== void 0 && `${a}`.trim() !== "" && o.add(`${a}`.trim());
187
197
  },
188
198
  complete: () => n(Array.from(o)),
189
- error: (s) => r(P("parseAssayHoleIds", s))
199
+ error: (s) => r(w("parseAssayHoleIds", s))
190
200
  });
191
201
  });
192
202
  }
193
- function ut(e) {
194
- return Object.entries(e || {}).some(([t, n]) => !(Be.has(t) || n == null || typeof n == "string" && n.trim() === ""));
203
+ function Lt(e) {
204
+ return Object.entries(e || {}).some(([t, n]) => !(Pt.has(t) || n == null || typeof n == "string" && n.trim() === ""));
195
205
  }
196
- function dt(e, t = null) {
206
+ function Ot(e, t = null) {
197
207
  return new Promise((n, r) => {
198
208
  const o = /* @__PURE__ */ new Map();
199
- ee.parse(e, {
209
+ W.parse(e, {
200
210
  header: !0,
201
211
  dynamicTyping: !0,
202
212
  skipEmptyLines: !0,
203
213
  step: (s) => {
204
- const i = ye(s.data, t);
205
- if (!ut(i)) return;
206
- const c = ct(i).holeId;
207
- if (c !== void 0 && `${c}`.trim() !== "") {
208
- const l = `${c}`.trim();
209
- o.has(l) || o.set(l, {
210
- holeId: l
214
+ const i = Ee(s.data, t);
215
+ if (!Lt(i)) return;
216
+ const u = Dt(i).holeId;
217
+ if (u !== void 0 && `${u}`.trim() !== "") {
218
+ const c = `${u}`.trim();
219
+ o.has(c) || o.set(c, {
220
+ holeId: c
211
221
  });
212
222
  }
213
223
  },
214
224
  complete: () => n(Array.from(o.values())),
215
- error: (s) => r(P("parseAssayHoleIdsWithAssays", s))
225
+ error: (s) => r(w("parseAssayHoleIdsWithAssays", s))
216
226
  });
217
227
  });
218
228
  }
219
- function mt(e, t, n = null, r = null) {
229
+ function kt(e, t, n = null, r = null) {
220
230
  return new Promise((o, s) => {
221
231
  const i = `${t}`.trim();
222
232
  if (!i) {
223
- s(P("parseAssayHole", new Error("Missing hole id")));
233
+ s(w("parseAssayHole", new Error("Missing hole id")));
224
234
  return;
225
235
  }
226
236
  const a = [];
227
- ee.parse(e, {
237
+ W.parse(e, {
228
238
  header: !0,
229
239
  dynamicTyping: !0,
230
240
  skipEmptyLines: !0,
231
- step: (c) => {
232
- const l = ye(c.data, r), u = Ue(l, r);
233
- u && `${u.holeId}`.trim() === i && a.push(u);
241
+ step: (u) => {
242
+ const c = Ee(u.data, r), l = ct(c, r);
243
+ l && `${l.holeId}`.trim() === i && a.push(l);
234
244
  },
235
245
  complete: () => {
236
246
  if (!a.length) {
237
247
  o(null);
238
248
  return;
239
249
  }
240
- const c = Ye(i, a);
241
- o(c);
250
+ const u = ut(i, a);
251
+ o(u);
242
252
  },
243
- error: (c) => s(P("parseAssayHole", c))
253
+ error: (u) => s(w("parseAssayHole", u))
244
254
  });
245
255
  });
246
256
  }
247
- function ft(e, t = null, n = null) {
257
+ function Ft(e, t = null, n = null) {
248
258
  return new Promise((r, o) => {
249
- ee.parse(e, {
259
+ W.parse(e, {
250
260
  header: !0,
251
261
  dynamicTyping: !0,
252
262
  skipEmptyLines: !0,
253
263
  complete: (s) => {
254
264
  const i = /* @__PURE__ */ new Map();
255
- s.data.forEach((c) => {
256
- const l = ye(c, n), u = Ue(l, n);
257
- u && (i.has(u.holeId) || i.set(u.holeId, []), i.get(u.holeId).push(u));
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));
258
268
  });
259
- const a = Array.from(i.entries()).map(([c, l]) => Ye(c, l));
269
+ const a = Array.from(i.entries()).map(([u, c]) => ut(u, c));
260
270
  r({ holes: a });
261
271
  },
262
- error: (s) => o(P("parseAssaysCSV", s))
272
+ error: (s) => o(w("parseAssaysCSV", s))
263
273
  });
264
274
  });
265
275
  }
266
- function yn(e = {}) {
276
+ function er(e = {}) {
267
277
  const t = {};
268
278
  return Object.entries(e || {}).forEach(([n, r]) => {
269
- n && (t[fe(n)] = r);
279
+ n && (t[ze(n)] = r);
270
280
  }), t;
271
281
  }
272
- function gn(e = {}, t = [], n) {
282
+ function tr(e = {}, t = [], n) {
273
283
  for (const r of t) {
274
284
  const o = e[r];
275
285
  if (o != null && `${o}`.trim() !== "")
@@ -277,8 +287,8 @@ function gn(e = {}, t = [], n) {
277
287
  }
278
288
  return n;
279
289
  }
280
- const ht = 4;
281
- function Ge(e = [], t = "") {
290
+ const wt = 4;
291
+ function dt(e = [], t = "") {
282
292
  if (!e.length) return [];
283
293
  if (!t) return e;
284
294
  const n = e.findIndex((s) => s === t);
@@ -286,115 +296,234 @@ function Ge(e = [], t = "") {
286
296
  const r = e[n], o = e.filter((s, i) => i !== n);
287
297
  return [r, ...o];
288
298
  }
289
- function he({
299
+ function Ne({
290
300
  property: e = "",
291
301
  chartType: t = "",
292
302
  categoricalProps: n = [],
293
- numericDefaultChartType: r = "markers+line"
303
+ commentProps: r = [],
304
+ numericDefaultChartType: o = "markers+line"
294
305
  } = {}) {
295
- return e ? n.includes(e) ? "categorical" : !t || t === "categorical" ? r : t : t || r;
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;
296
307
  }
297
- function qe({
308
+ function mt({
298
309
  holeIds: e = [],
299
310
  focusedHoleId: t = "",
300
- plotCount: n = ht,
311
+ plotCount: n = wt,
301
312
  defaultProp: r = "",
302
313
  categoricalProps: o = [],
303
- numericDefaultChartType: s = "markers+line"
314
+ commentProps: s = [],
315
+ numericDefaultChartType: i = "markers+line"
304
316
  } = {}) {
305
- const i = Ge(e, t);
306
- return Array.from({ length: n }).map((a, c) => {
307
- const l = i[c] || e[c] || "", u = he({
317
+ const a = dt(e, t);
318
+ return Array.from({ length: n }).map((u, c) => {
319
+ const l = a[c] || e[c] || "", d = Ne({
308
320
  property: r,
309
321
  chartType: "",
310
322
  categoricalProps: o,
311
- numericDefaultChartType: s
323
+ commentProps: s,
324
+ numericDefaultChartType: i
312
325
  });
313
326
  return {
314
327
  holeId: l,
315
328
  property: r,
316
- chartType: u
329
+ chartType: d
317
330
  };
318
331
  });
319
332
  }
320
- function Xe(e = []) {
321
- const t = e.flatMap((i) => i.points || []), n = /* @__PURE__ */ new Set();
322
- t.forEach((i) => {
323
- Object.keys(i || {}).forEach((a) => {
324
- Be.has(a) || n.add(a);
325
- });
326
- });
327
- const r = [], o = [];
328
- n.forEach((i) => {
329
- var l;
330
- let a = !1, c = !1;
331
- for (let u = 0; u < t.length; u += 1) {
332
- const m = (l = t[u]) == null ? void 0 : l[i];
333
- if (!(m == null || typeof m == "string" && m.trim() === "") && (c = !0, typeof m == "number" && Number.isFinite(m))) {
334
- a = !0;
333
+ const ye = "numeric", _e = "categorical", pe = "comment", Me = "hidden", ke = "tadpole", Be = {
334
+ [ye]: [
335
+ { value: "bar", label: "Bars" },
336
+ { value: "markers", label: "Markers" },
337
+ { value: "markers+line", label: "Markers + Line" },
338
+ { value: "line", label: "Line only" }
339
+ ],
340
+ [_e]: [
341
+ { value: "categorical", label: "Categorical bands" }
342
+ ],
343
+ [pe]: [
344
+ { value: "comment", label: "Comments" }
345
+ ],
346
+ [ke]: [
347
+ { value: "tadpole", label: "Tadpole" }
348
+ ],
349
+ [Me]: []
350
+ }, Ge = /* @__PURE__ */ new Set([
351
+ // Hole identifiers
352
+ "hole_id",
353
+ "holeid",
354
+ "id",
355
+ "holetype",
356
+ "datasource_hole_id",
357
+ "anumber",
358
+ "collarid",
359
+ "companyholeid",
360
+ "company_hole_id",
361
+ "company_id",
362
+ // Project codes
363
+ "project_id",
364
+ "project_code",
365
+ "project",
366
+ "projectcode",
367
+ "projectid",
368
+ // Geographic coordinates
369
+ "latitude",
370
+ "longitude",
371
+ "lat",
372
+ "lon",
373
+ "lng",
374
+ "easting",
375
+ "northing",
376
+ "x",
377
+ "y",
378
+ "z",
379
+ "elevation",
380
+ "elev",
381
+ "rl",
382
+ // Depth / interval columns
383
+ "from",
384
+ "to",
385
+ "mid",
386
+ "depth",
387
+ "md",
388
+ "samp_from",
389
+ "samp_to",
390
+ "sample_from",
391
+ "sample_to",
392
+ "depth_from",
393
+ "depth_to",
394
+ "fromdepth",
395
+ "todepth",
396
+ // Geometry / CRS
397
+ "shape",
398
+ "geometry",
399
+ "crs",
400
+ "epsg",
401
+ // Internal / synthetic columns
402
+ "data_source",
403
+ "_hole_key",
404
+ "_hole_id_key"
405
+ ]), Vt = /* @__PURE__ */ new Set([
406
+ "comments",
407
+ "comment",
408
+ "notes",
409
+ "note",
410
+ "description",
411
+ "remarks",
412
+ "remark",
413
+ "log_description",
414
+ "struct_comment",
415
+ "structcomment"
416
+ ]);
417
+ function Rt(e) {
418
+ if (!(e != null && e.length))
419
+ return { byType: {}, numericCols: [], categoricalCols: [], commentCols: [] };
420
+ const t = new Set(e.flatMap((r) => Object.keys(r || {}))), n = {};
421
+ for (const r of t) {
422
+ const o = r.toLowerCase().trim();
423
+ if (Ge.has(o) || Ge.has(r)) {
424
+ n[r] = Me;
425
+ continue;
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";
431
+ });
432
+ n[r] = a ? pe : Me;
433
+ continue;
434
+ }
435
+ let s = !1, i = !1;
436
+ for (const a of e) {
437
+ const u = a[r];
438
+ if (!(u == null || typeof u == "string" && u.trim() === "") && (i = !0, typeof u == "number" && Number.isFinite(u))) {
439
+ s = !0;
335
440
  break;
336
441
  }
337
442
  }
338
- a ? r.push(i) : c && o.push(i);
339
- });
340
- const s = r[0] || o[0] || "";
341
- return { numericProps: r, categoricalProps: o, defaultProp: s };
443
+ i ? s ? n[r] = ye : n[r] = _e : n[r] = Me;
444
+ }
445
+ return {
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)
450
+ };
451
+ }
452
+ function Ve(e) {
453
+ return Be[e] ?? Be[ye];
454
+ }
455
+ function nr(e) {
456
+ const t = Ve(e);
457
+ return t.length ? e === ye ? "line" : t[0].value : "markers+line";
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] || "";
461
+ return {
462
+ numericProps: n,
463
+ categoricalProps: r,
464
+ commentProps: o,
465
+ columnMeta: s,
466
+ defaultProp: i
467
+ };
342
468
  }
343
- async function pt(e, t = null) {
344
- return await dt(e);
469
+ async function $t(e, t = null) {
470
+ return await Ot(e);
345
471
  }
346
- async function yt(e, t, n = null) {
347
- return await mt(e, t);
472
+ async function Ht(e, t, n = null) {
473
+ return await kt(e, t);
348
474
  }
349
- function gt(e = [], t = "") {
475
+ function jt(e = [], t = "") {
350
476
  if (!e.length) return null;
351
- const { numericProps: n, categoricalProps: r, defaultProp: o } = Xe(e), s = e.map((a) => a.id || a.holeId).filter(Boolean), i = qe({
352
- holeIds: s,
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,
353
479
  focusedHoleId: t,
354
480
  plotCount: 4,
355
- defaultProp: o,
481
+ defaultProp: i,
356
482
  categoricalProps: r,
483
+ commentProps: o,
357
484
  numericDefaultChartType: "line"
358
485
  });
359
486
  return {
360
487
  holes: e,
361
488
  numericProps: n,
362
489
  categoricalProps: r,
363
- defaultProp: o,
364
- traceConfigs: i
490
+ commentProps: o,
491
+ columnMeta: s,
492
+ defaultProp: i,
493
+ traceConfigs: u
365
494
  };
366
495
  }
367
- async function bn(e, t = "", n = null) {
368
- const { holes: r } = await ft(e, n), o = gt(r, t);
496
+ async function rr(e, t = "", n = null) {
497
+ const { holes: r } = await Ft(e, n), o = jt(r, t);
369
498
  if (!o) throw new Error("No valid assay intervals found.");
370
499
  return o;
371
500
  }
372
- function Cn(e, t = null) {
501
+ function or(e, t = null) {
373
502
  return new Promise((n, r) => {
374
- ee.parse(e, {
503
+ W.parse(e, {
375
504
  header: !0,
376
505
  dynamicTyping: !0,
377
506
  skipEmptyLines: !0,
378
507
  complete: (o) => {
379
- const s = o.data.map((i) => bt(i, t)).filter((i) => i[x] && Number.isFinite(i[V]) && Number.isFinite(i[B]) && Number.isFinite(i[j]));
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]));
380
509
  n(s);
381
510
  },
382
- error: (o) => r(P("parseSurveyCSV", o))
511
+ error: (o) => r(w("parseSurveyCSV", o))
383
512
  });
384
513
  });
385
514
  }
386
- function bt(e, t = null) {
387
- const n = ce(e, null, t), r = n[x], o = n[Z] || n.project || n.project_code, s = ne(n[q]), i = ne(n[X]), a = ne(n[V]), c = ne(n[B]), l = ne(n[j]), u = ne(n.maxdepth);
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);
388
517
  return {
389
518
  raw: n,
390
- [x]: r,
391
- [Z]: o,
392
- [q]: s,
393
- [X]: i,
394
- [V]: a,
395
- [B]: c,
396
- [j]: l,
397
- maxdepth: u,
519
+ [b]: r,
520
+ [ne]: o,
521
+ [Q]: s,
522
+ [ee]: i,
523
+ [R]: a,
524
+ [L]: u,
525
+ [D]: c,
526
+ maxdepth: l,
398
527
  // Legacy field names for backwards compatibility
399
528
  project_code: o,
400
529
  latitude: s,
@@ -402,107 +531,107 @@ function bt(e, t = null) {
402
531
  surveydepth: a
403
532
  };
404
533
  }
405
- const ne = (e) => {
534
+ const fe = (e) => {
406
535
  const t = Number(e);
407
536
  return Number.isFinite(t) ? t : void 0;
408
537
  };
409
- function _n(e, t) {
410
- var l, u, m, f;
538
+ function ir(e, t) {
539
+ var c, l, d, m;
411
540
  const n = /* @__PURE__ */ new Map();
412
- e.forEach((d) => {
413
- const p = (d[x] || d.holeId || d.id || "").toString().trim();
541
+ e.forEach((f) => {
542
+ const p = (f[b] || f.holeId || f.id || "").toString().trim();
414
543
  if (!p) return;
415
544
  const y = p.toLowerCase();
416
- n.has(y) || n.set(y, d);
545
+ n.has(y) || n.set(y, f);
417
546
  });
418
- const r = ((l = e[0]) == null ? void 0 : l.lat) ?? ((u = e[0]) == null ? void 0 : u[q]) ?? 0, o = ((m = e[0]) == null ? void 0 : m.lng) ?? ((f = e[0]) == null ? void 0 : f[X]) ?? 0, s = 111132, i = 111320 * Math.cos(r * Math.PI / 180), a = /* @__PURE__ */ new Map();
419
- t.forEach((d) => {
420
- const p = (d[x] || "").toString().trim();
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();
548
+ t.forEach((f) => {
549
+ const p = (f[b] || "").toString().trim();
421
550
  if (!p) return;
422
551
  const y = p.toLowerCase();
423
- a.has(y) || a.set(y, []), a.get(y).push(d);
552
+ a.has(y) || a.set(y, []), a.get(y).push(f);
424
553
  });
425
- const c = [];
426
- return a.forEach((d, p) => {
554
+ const u = [];
555
+ return a.forEach((f, p) => {
427
556
  const y = n.get(p);
428
557
  if (!y) return;
429
- const h = d.filter((b) => Number.isFinite(b[V] ?? b.surveydepth)).sort((b, _) => (b[V] ?? b.surveydepth) - (_[V] ?? _.surveydepth));
558
+ const h = f.filter((T) => Number.isFinite(T[R] ?? T.surveydepth)).sort((T, B) => (T[R] ?? T.surveydepth) - (B[R] ?? B.surveydepth));
430
559
  if (!h.length) return;
431
- const A = y.lat ?? y[q], O = y.lng ?? y[X], F = 111132, D = 111320 * Math.cos(A * Math.PI / 180), R = (O - o) * i, w = (A - r) * s, I = [];
432
- let N = 0, z = 0, C = 0;
433
- for (let b = 0; b < h.length; b += 1) {
434
- const _ = h[b], M = h[b - 1], L = _[V] ?? _.surveydepth, v = _[j] ?? _.azimuth, T = _[B] ?? _.dip;
435
- if (!M) {
436
- I.push({
437
- x: R + N,
438
- y: w + z,
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;
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;
564
+ if (!q) {
565
+ P.push({
566
+ x: A + N,
567
+ y: j + V,
439
568
  z: 0,
440
- md: L,
441
- azimuth: v,
442
- dip: T
569
+ md: M,
570
+ azimuth: _,
571
+ dip: I
443
572
  });
444
573
  continue;
445
574
  }
446
- const S = M[V] ?? M.surveydepth, Y = M[j] ?? M.azimuth, ue = M[B] ?? M.dip, de = L - S;
447
- if (de <= 0) continue;
448
- const ie = Fe(ue), se = Fe(T), ge = Ee(Y), be = Ee(v), Ce = Math.acos(
449
- Math.sin(ie) * Math.sin(se) * Math.cos(ge - be) + Math.cos(ie) * Math.cos(se)
450
- ), _e = Ce > 1e-6 ? 2 / Ce * Math.tan(Ce / 2) : 1, et = 0.5 * de * (Math.sin(ie) * Math.cos(ge) + Math.sin(se) * Math.cos(be)) * _e, tt = 0.5 * de * (Math.sin(ie) * Math.sin(ge) + Math.sin(se) * Math.sin(be)) * _e, nt = 0.5 * de * (Math.cos(ie) + Math.cos(se)) * _e;
451
- N += et, z += tt, C += nt, I.push({
452
- x: R + N,
453
- y: w + z,
454
- z: -C,
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,
455
584
  // render with z up; depth down
456
- md: L,
457
- azimuth: v,
458
- dip: T
585
+ md: M,
586
+ azimuth: _,
587
+ dip: I
459
588
  });
460
589
  }
461
- const E = I.map((b) => ({
462
- ...b,
463
- lat: A + b.y / F,
464
- lng: O + b.x / D
590
+ const re = P.map((T) => ({
591
+ ...T,
592
+ lat: z + T.y / E,
593
+ lng: C + T.x / H
465
594
  }));
466
- c.push({
467
- id: y[x] || y.holeId || p,
468
- project: y[Z] || y.project_id || y.project || "",
469
- points: E,
595
+ u.push({
596
+ id: y[b] || y.holeId || p,
597
+ project: y[ne] || y.project_id || y.project || "",
598
+ points: re,
470
599
  collar: y
471
600
  });
472
- }), c;
601
+ }), u;
473
602
  }
474
- const Ee = (e) => e * Math.PI / 180, Fe = (e) => {
603
+ const Fe = (e) => e * Math.PI / 180, Xe = (e) => {
475
604
  const t = Number(e), n = 90 + (Number.isFinite(t) ? t : 0), r = Math.min(180, Math.max(0, n));
476
- return Ee(r);
605
+ return Fe(r);
477
606
  };
478
- function G(e, t = void 0) {
607
+ function J(e, t = void 0) {
479
608
  const n = Number(e);
480
609
  return Number.isFinite(n) ? n : t;
481
610
  }
482
- function Se(e) {
611
+ function qe(e) {
483
612
  return e == null ? "" : `${e}`.trim();
484
613
  }
485
- function pe(e = [], t = null) {
486
- const n = t || "hole_id", o = [n, "hole_id", "holeId", "id"].find((s) => e.some((i) => Se(i == null ? void 0 : i[s])));
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])));
487
616
  if (!o)
488
- throw P("canonicalizeHoleIdRows", new Error(`hole id column '${n}' not found`));
617
+ throw w("canonicalizeHoleIdRows", new Error(`hole id column '${n}' not found`));
489
618
  return {
490
619
  aliasCol: o,
491
620
  rows: e.map((s) => ({
492
621
  ...s,
493
- hole_id: Se(s == null ? void 0 : s[o])
622
+ hole_id: qe(s == null ? void 0 : s[o])
494
623
  }))
495
624
  };
496
625
  }
497
- function ke(e) {
626
+ function We(e) {
498
627
  return Number(e) * Math.PI / 180;
499
628
  }
500
- function xe(e, t) {
501
- const n = ke(e), r = ke(t), o = Math.cos(r) * Math.sin(n), s = Math.cos(r) * Math.cos(n), i = Math.sin(r) * -1;
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;
502
631
  return { ca: o, cb: s, cc: i };
503
632
  }
504
- function Ct(e, t, n, r, o, s = "minimum_curvature") {
505
- const i = xe(t, n), a = xe(r, o);
633
+ function Yt(e, t, n, r, o, s = "minimum_curvature") {
634
+ const i = Pe(t, n), a = Pe(r, o);
506
635
  if (s === "tangential")
507
636
  return {
508
637
  dx: e * i.ca,
@@ -512,193 +641,193 @@ function Ct(e, t, n, r, o, s = "minimum_curvature") {
512
641
  dip: n
513
642
  };
514
643
  if (s === "balanced_tangential") {
515
- const m = 0.5 * (t + r), f = 0.5 * (n + o), d = xe(m, f);
644
+ const d = 0.5 * (t + r), m = 0.5 * (n + o), f = Pe(d, m);
516
645
  return {
517
- dx: e * d.ca,
518
- dy: e * d.cb,
519
- dz: e * d.cc,
520
- azimuth: m,
521
- dip: f
646
+ dx: e * f.ca,
647
+ dy: e * f.cb,
648
+ dz: e * f.cc,
649
+ azimuth: d,
650
+ dip: m
522
651
  };
523
652
  }
524
- const c = i.ca * a.ca + i.cb * a.cb + i.cc * a.cc, l = Math.acos(Math.max(-1, Math.min(1, c))), u = l > 1e-6 ? 2 * Math.tan(l / 2) / l : 1;
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;
525
654
  return {
526
- dx: 0.5 * e * (i.ca + a.ca) * u,
527
- dy: 0.5 * e * (i.cb + a.cb) * u,
528
- dz: 0.5 * e * (i.cc + a.cc) * u,
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,
529
658
  azimuth: r,
530
659
  dip: o
531
660
  };
532
661
  }
533
- function ve(e = [], t = [], n = {}) {
662
+ function Re(e = [], t = [], n = {}) {
534
663
  const {
535
664
  step: r = 1,
536
665
  holeIdCol: o = null,
537
666
  method: s = "minimum_curvature"
538
- } = n, i = Number.isFinite(Number(r)) && Number(r) > 0 ? Number(r) : 1, a = pe(e, o), c = pe(t, o || a.aliasCol);
539
- if (!a.rows.length || !c.rows.length) return [];
540
- const l = /* @__PURE__ */ new Map();
541
- a.rows.forEach((f) => {
542
- !f.hole_id || l.has(f.hole_id) || l.set(f.hole_id, f);
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);
543
672
  });
544
- const u = /* @__PURE__ */ new Map();
545
- c.rows.forEach((f) => {
546
- f.hole_id && (u.has(f.hole_id) || u.set(f.hole_id, []), u.get(f.hole_id).push(f));
673
+ 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));
547
676
  });
548
- const m = [];
549
- return u.forEach((f, d) => {
550
- const p = l.get(d);
677
+ const d = [];
678
+ return l.forEach((m, f) => {
679
+ const p = c.get(f);
551
680
  if (!p) return;
552
- const y = [...f].map((I) => ({
553
- ...I,
554
- from: G(I.from),
555
- azimuth: G(I.azimuth),
556
- dip: G(I.dip)
557
- })).filter((I) => Number.isFinite(I.from) && Number.isFinite(I.azimuth) && Number.isFinite(I.dip)).sort((I, N) => I.from - N.from);
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);
558
687
  if (!y.length) return;
559
- let h = G(p.x, 0), A = G(p.y, 0), O = G(p.z, 0), F = y[0].from;
560
- const D = y[0].azimuth, R = y[0].dip, w = {
561
- hole_id: d,
562
- md: F,
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 = {
690
+ hole_id: f,
691
+ md: E,
563
692
  x: h,
564
- y: A,
565
- z: O,
566
- azimuth: D,
567
- dip: R
693
+ y: z,
694
+ z: C,
695
+ azimuth: H,
696
+ dip: A
568
697
  };
569
- a.aliasCol !== "hole_id" && p[a.aliasCol] !== void 0 && (w[a.aliasCol] = p[a.aliasCol]), m.push(w);
570
- for (let I = 0; I < y.length - 1; I += 1) {
571
- const N = y[I], z = y[I + 1], C = N.from, b = z.from - C;
572
- if (b <= 0) continue;
573
- const _ = Math.max(1, Math.ceil(b / i)), M = b / _;
574
- for (let L = 0; L < _; L += 1) {
575
- F += M;
576
- const v = (F - C) / b, T = N.azimuth + v * (z.azimuth - N.azimuth), S = N.dip + v * (z.dip - N.dip), Y = Ct(M, N.azimuth, N.dip, z.azimuth, z.dip, s);
577
- h += Y.dx, A += Y.dy, O += Y.dz;
578
- const ue = {
579
- hole_id: d,
580
- md: F,
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;
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 = {
708
+ hole_id: f,
709
+ md: E,
581
710
  x: h,
582
- y: A,
583
- z: O,
584
- azimuth: s === "minimum_curvature" ? T : Y.azimuth,
585
- dip: s === "minimum_curvature" ? S : Y.dip
711
+ y: z,
712
+ z: C,
713
+ azimuth: s === "minimum_curvature" ? I : x.azimuth,
714
+ dip: s === "minimum_curvature" ? S : x.dip
586
715
  };
587
- a.aliasCol !== "hole_id" && p[a.aliasCol] !== void 0 && (ue[a.aliasCol] = p[a.aliasCol]), m.push(ue);
716
+ a.aliasCol !== "hole_id" && p[a.aliasCol] !== void 0 && (O[a.aliasCol] = p[a.aliasCol]), d.push(O);
588
717
  }
589
718
  }
590
- }), m;
719
+ }), d;
591
720
  }
592
- function _t(e, t, n = {}) {
593
- return ve(e, t, { ...n, method: "minimum_curvature" });
721
+ function Bt(e, t, n = {}) {
722
+ return Re(e, t, { ...n, method: "minimum_curvature" });
594
723
  }
595
- function zn(e, t, n = {}) {
596
- return ve(e, t, { ...n, method: "tangential" });
724
+ function sr(e, t, n = {}) {
725
+ return Re(e, t, { ...n, method: "tangential" });
597
726
  }
598
- function xn(e, t, n = {}) {
599
- return ve(e, t, { ...n, method: "balanced_tangential" });
727
+ function ar(e, t, n = {}) {
728
+ return Re(e, t, { ...n, method: "balanced_tangential" });
600
729
  }
601
- function Nn(e, t, n = {}) {
602
- return _t(e, t, n);
730
+ function lr(e, t, n = {}) {
731
+ return Bt(e, t, n);
603
732
  }
604
- function zt(e, t) {
733
+ function Gt(e, t) {
605
734
  if (!e.length || !Number.isFinite(t)) return null;
606
735
  let n = null, r = 1 / 0;
607
736
  for (let o = 0; o < e.length; o += 1) {
608
- const s = e[o], i = G(s.md);
737
+ const s = e[o], i = J(s.md);
609
738
  if (!Number.isFinite(i)) continue;
610
739
  const a = Math.abs(i - t);
611
740
  a < r && (r = a, n = s);
612
741
  }
613
742
  return n;
614
743
  }
615
- function Mn(e = [], t = [], n = {}) {
616
- const r = n.holeIdCol || "hole_id", o = pe(e, r), s = pe(t, r);
744
+ function cr(e = [], t = [], n = {}) {
745
+ const r = n.holeIdCol || "hole_id", o = Ae(e, r), s = Ae(t, r);
617
746
  if (!o.rows.length || !s.rows.length) return [...o.rows];
618
747
  const i = /* @__PURE__ */ new Map();
619
748
  return s.rows.forEach((a) => {
620
749
  a.hole_id && (i.has(a.hole_id) || i.set(a.hole_id, []), i.get(a.hole_id).push(a));
621
- }), i.forEach((a, c) => {
622
- i.set(c, [...a].sort((l, u) => G(l.md, 0) - G(u.md, 0)));
750
+ }), i.forEach((a, u) => {
751
+ i.set(u, [...a].sort((c, l) => J(c.md, 0) - J(l.md, 0)));
623
752
  }), o.rows.map((a) => {
624
- const c = G(a.from), l = G(a.to), u = Number.isFinite(c) && Number.isFinite(l) ? 0.5 * (c + l) : void 0;
625
- if (!a.hole_id || !Number.isFinite(u)) return { ...a };
626
- const m = zt(i.get(a.hole_id) || [], u);
627
- if (!m) return { ...a };
628
- const f = { ...a };
629
- return ["md", "x", "y", "z", "azimuth", "dip"].forEach((d) => {
630
- m[d] !== void 0 && (Object.prototype.hasOwnProperty.call(f, d) ? f[`${d}_trace`] = m[d] : f[d] = m[d]);
631
- }), f;
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 };
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;
632
761
  });
633
762
  }
634
- function An(e, t = null) {
763
+ function ur(e, t = null) {
635
764
  return new Promise((n, r) => {
636
- ee.parse(e, {
765
+ W.parse(e, {
637
766
  header: !0,
638
767
  dynamicTyping: !0,
639
768
  skipEmptyLines: !0,
640
769
  complete: (o) => {
641
770
  const s = /* @__PURE__ */ new Map();
642
- o.data.forEach((a, c) => {
643
- const l = ce(a, null, t), u = l[x], m = u !== void 0 ? `${u}`.trim() : "", f = l[K] ?? l.x, d = l[J] ?? l.y, p = l[oe] ?? l.z, y = l.order ?? c;
644
- !m || f === null || f === void 0 || d === null || d === void 0 || p === null || p === void 0 || (s.has(m) || s.set(m, []), s.get(m).push({
645
- ...l,
646
- holeId: m,
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,
647
776
  order: y,
648
- x: Number(f) ?? 0,
649
- y: Number(d) ?? 0,
777
+ x: Number(m) ?? 0,
778
+ y: Number(f) ?? 0,
650
779
  z: Number(p) ?? 0
651
780
  }));
652
781
  });
653
- const i = Array.from(s.entries()).map(([a, c]) => ({
782
+ const i = Array.from(s.entries()).map(([a, u]) => ({
654
783
  id: a,
655
- points: c.sort((l, u) => l.order - u.order).map((l) => ({
656
- ...l,
657
- x: Number(l.x) || 0,
658
- y: Number(l.y) || 0,
659
- z: Number(l.z) || 0
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
660
789
  }))
661
790
  }));
662
791
  n({ holes: i });
663
792
  },
664
- error: (o) => r(P("parseDrillholesCSV", o))
793
+ error: (o) => r(w("parseDrillholesCSV", o))
665
794
  });
666
795
  });
667
796
  }
668
- function le(e) {
797
+ function be(e) {
669
798
  return e ? Array.isArray(e) ? [...e] : [] : [];
670
799
  }
671
- function U(e) {
800
+ function K(e) {
672
801
  const t = Number(e);
673
802
  return Number.isFinite(t) ? t : void 0;
674
803
  }
675
- function We(e = [], t = []) {
804
+ function ft(e = [], t = []) {
676
805
  const n = [...e];
677
806
  return n.sort((r, o) => {
678
807
  for (let s = 0; s < t.length; s += 1) {
679
- const i = t[s], a = r == null ? void 0 : r[i], c = o == null ? void 0 : o[i];
680
- if (a !== c)
681
- return a == null ? 1 : c == null ? -1 : typeof a == "number" && typeof c == "number" ? a - c : `${a}`.localeCompare(`${c}`);
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}`);
682
811
  }
683
812
  return 0;
684
813
  }), n;
685
814
  }
686
- function xt(e, t = {}) {
815
+ function Xt(e, t = {}) {
687
816
  return new Promise((n, r) => {
688
- ee.parse(e, {
817
+ W.parse(e, {
689
818
  header: !0,
690
819
  dynamicTyping: !0,
691
820
  skipEmptyLines: !0,
692
821
  ...t,
693
822
  complete: (o) => n(Array.isArray(o == null ? void 0 : o.data) ? o.data : []),
694
- error: (o) => r(P("loadTable(csv)", o))
823
+ error: (o) => r(w("loadTable(csv)", o))
695
824
  });
696
825
  });
697
826
  }
698
- function Nt(e = [], t = null, n = null) {
699
- return e.map((r) => ce(r, t, n));
827
+ function qt(e = [], t = null, n = null) {
828
+ return e.map((r) => ue(r, t, n));
700
829
  }
701
- async function De(e, t = {}) {
830
+ async function $e(e, t = {}) {
702
831
  const {
703
832
  kind: n = "csv",
704
833
  columnMap: r = null,
@@ -707,80 +836,80 @@ async function De(e, t = {}) {
707
836
  } = t;
708
837
  let i;
709
838
  if (Array.isArray(e))
710
- i = le(e);
839
+ i = be(e);
711
840
  else if (n === "csv")
712
- i = await xt(e, s);
713
- else throw n === "parquet" || n === "sql" ? P("loadTable", new Error(`Unsupported kind in JS runtime: ${n}`)) : P("loadTable", new Error(`Unsupported kind: ${n}`));
714
- return Nt(i, r, o);
841
+ i = await Xt(e, s);
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);
715
844
  }
716
- async function In(e, t = {}) {
845
+ async function dr(e, t = {}) {
717
846
  const {
718
847
  crs: n = null,
719
848
  sourceColumnMap: r = null,
720
849
  keepAll: o = !0,
721
850
  ...s
722
- } = t, i = await De(e, { ...s, sourceColumnMap: r });
723
- if (!i.some((f) => x in f))
724
- throw P("loadCollars", new Error(`Collar table missing column: ${x}`));
725
- const c = i.some((f) => K in f && J in f), l = i.some((f) => q in f && X in f);
726
- if (!c && !l)
727
- throw P("loadCollars", new Error("Collar table missing coordinate columns (need easting/northing or latitude/longitude)"));
728
- const u = i.map((f) => {
729
- const d = { ...f };
730
- if (x in d) {
731
- const p = d[x];
732
- d[x] = p == null ? "" : `${p}`.trim();
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)
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();
733
862
  }
734
- return q in d && (d[q] = U(d[q])), X in d && (d[X] = U(d[X])), oe in d && (d[oe] = U(d[oe])), K in d && (d[K] = U(d[K])), J in d && (d[J] = U(d[J])), !("datasource_hole_id" in d) && x in d && (d.datasource_hole_id = d[x]), d;
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;
735
864
  });
736
- if (!u.every((f) => !(!f[x] || l && (!Number.isFinite(f[q]) || !Number.isFinite(f[X])) || c && !l && (!Number.isFinite(f[K]) || !Number.isFinite(f[J])))))
737
- throw P("loadCollars", new Error("Collar table has missing required values"));
738
- return u;
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])))))
866
+ throw w("loadCollars", new Error("Collar table has missing required values"));
867
+ return l;
739
868
  }
740
- async function En(e, t = {}) {
869
+ async function mr(e, t = {}) {
741
870
  const {
742
871
  sourceColumnMap: n = null,
743
872
  keepAll: r = !0,
744
873
  ...o
745
- } = t, s = await De(e, { ...o, sourceColumnMap: n }), i = [x, V, j, B];
746
- for (const l of i)
747
- if (!s.some((m) => l in m))
748
- throw P("loadSurveys", new Error(`Survey table missing column: ${l}`));
749
- const a = s.map((l) => {
750
- const u = { ...l };
751
- if (x in u) {
752
- const m = u[x];
753
- u[x] = m == null ? "" : `${m}`.trim();
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();
754
883
  }
755
- return V in u && (u[V] = U(u[V])), H in u && (u[H] = U(u[H])), j in u && (u[j] = U(u[j])), B in u && (u[B] = U(u[B])), u;
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;
756
885
  });
757
- if (!a.every((l) => !(!l[x] || !Number.isFinite(l[V]) || !Number.isFinite(l[j]) || !Number.isFinite(l[B]))))
758
- throw P("loadSurveys", new Error("Survey table has missing required values"));
759
- return We(a, [x, V]);
886
+ if (!a.every((c) => !(!c[b] || !Number.isFinite(c[R]) || !Number.isFinite(c[D]) || !Number.isFinite(c[L]))))
887
+ throw w("loadSurveys", new Error("Survey table has missing required values"));
888
+ return ft(a, [b, R]);
760
889
  }
761
- async function vn(e, t = {}) {
890
+ async function fr(e, t = {}) {
762
891
  const {
763
892
  sourceColumnMap: n = null,
764
893
  keepAll: r = !0,
765
894
  ...o
766
- } = t, s = await De(e, { ...o, sourceColumnMap: n }), i = [x, $, H];
767
- for (const l of i)
768
- if (!s.some((m) => l in m))
769
- throw P("loadAssays", new Error(`Assay table missing column: ${l}`));
770
- const a = s.map((l) => {
771
- const u = { ...l };
772
- if (x in u) {
773
- const m = u[x];
774
- u[x] = m == null ? "" : `${m}`.trim();
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();
775
904
  }
776
- return $ in u && (u[$] = U(u[$])), H in u && (u[H] = U(u[H])), $ in u && H in u && Number.isFinite(u[$]) && Number.isFinite(u[H]) && (u[we] = 0.5 * (u[$] + u[H])), u;
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;
777
906
  });
778
- if (!a.every((l) => !(!l[x] || !Number.isFinite(l[$]) || !Number.isFinite(l[H]))))
779
- throw P("loadAssays", new Error("Assay table has missing required values"));
780
- return We(a, [x, $, H]);
907
+ if (!a.every((c) => !(!c[b] || !Number.isFinite(c[$]) || !Number.isFinite(c[F]))))
908
+ throw w("loadAssays", new Error("Assay table has missing required values"));
909
+ return ft(a, [b, $, F]);
781
910
  }
782
- function Dn(e = [], t = [], n = {}) {
783
- const r = Array.isArray(n.onCols) && n.onCols.length ? n.onCols : [x];
911
+ function hr(e = [], t = [], n = {}) {
912
+ const r = Array.isArray(n.onCols) && n.onCols.length ? n.onCols : [b];
784
913
  if (!t.length) return [...e];
785
914
  const o = (i) => r.map((a) => `${(i == null ? void 0 : i[a]) ?? ""}`).join("|"), s = /* @__PURE__ */ new Map();
786
915
  return t.forEach((i) => {
@@ -788,26 +917,26 @@ function Dn(e = [], t = [], n = {}) {
788
917
  }), e.map((i) => {
789
918
  const a = s.get(o(i));
790
919
  if (!a) return { ...i };
791
- const c = { ...i };
792
- return Object.entries(a).forEach(([l, u]) => {
793
- r.includes(l) || (Object.prototype.hasOwnProperty.call(c, l) ? c[`${l}_trace`] = u : c[l] = u);
794
- }), c;
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);
923
+ }), u;
795
924
  });
796
925
  }
797
- function Ln(e = [], t = null) {
798
- return t == null ? [...e] : e.length ? e.some((r) => Z in r) ? e.filter((r) => (r == null ? void 0 : r[Z]) === t) : [...e] : [];
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] : [];
799
928
  }
800
- function Tn(e = [], t = []) {
929
+ function yr(e = [], t = []) {
801
930
  return e.map((n) => {
802
931
  const r = { ...n };
803
932
  return t.forEach((o) => {
804
933
  if (!(o in r)) return;
805
- const s = U(r[o]);
934
+ const s = K(r[o]);
806
935
  r[o] = s;
807
936
  }), r;
808
937
  });
809
938
  }
810
- function Pn({
939
+ function gr({
811
940
  collars: e = [],
812
941
  surveys: t = [],
813
942
  assays: n = [],
@@ -815,16 +944,16 @@ function Pn({
815
944
  metadata: o = {}
816
945
  } = {}) {
817
946
  return {
818
- collars: le(e),
819
- surveys: le(t),
820
- assays: le(n),
821
- structures: le(r),
947
+ collars: be(e),
948
+ surveys: be(t),
949
+ assays: be(n),
950
+ structures: be(r),
822
951
  metadata: o || {}
823
952
  };
824
953
  }
825
- function On(e) {
954
+ function br(e) {
826
955
  return new Promise((t, n) => {
827
- ee.parse(e, {
956
+ W.parse(e, {
828
957
  header: !0,
829
958
  dynamicTyping: !0,
830
959
  complete: (r) => {
@@ -836,12 +965,12 @@ function On(e) {
836
965
  t({ data: o, properties: i });
837
966
  },
838
967
  error: (r) => {
839
- n(P("parseBlockModelCSV", r));
968
+ n(w("parseBlockModelCSV", r));
840
969
  }
841
970
  });
842
971
  });
843
972
  }
844
- function Fn(e, t) {
973
+ function _r(e, t) {
845
974
  const n = e.map((s) => s[t]).filter((s) => s != null);
846
975
  if (n.every((s) => typeof s == "number")) {
847
976
  const s = Math.min(...n), i = Math.max(...n);
@@ -849,7 +978,7 @@ function Fn(e, t) {
849
978
  }
850
979
  return { type: "categorical", categories: [...new Set(n)], values: n };
851
980
  }
852
- function Mt(e, t, n) {
981
+ function Wt(e, t, n) {
853
982
  if (!t) return new n.Color("#888888");
854
983
  if (t.type === "numeric") {
855
984
  const s = t.max - t.min, a = (1 - (s === 0 ? 0.5 : (e - t.min) / s)) * 240;
@@ -858,8 +987,215 @@ function Mt(e, t, n) {
858
987
  const o = t.categories.indexOf(e) / Math.max(t.categories.length, 1) * 360;
859
988
  return new n.Color().setHSL(o / 360, 0.7, 0.5);
860
989
  }
861
- const He = "#8b1e3f", At = "#a8324f", It = "#6b7280";
862
- function Ve(e, t) {
990
+ const He = (e, t = null) => ue(e, null, t);
991
+ function Zt(e) {
992
+ if (!e.length) return null;
993
+ const t = e[0], n = $ in t && F in t, r = R in t && !n;
994
+ return n ? "interval" : r ? "point" : null;
995
+ }
996
+ function te(e) {
997
+ const t = Number(e);
998
+ return Number.isFinite(t) ? t : null;
999
+ }
1000
+ function ht(e) {
1001
+ const t = e[b] !== void 0 ? `${e[b]}`.trim() : "";
1002
+ if (!t) return null;
1003
+ const n = te(e[R]);
1004
+ return n === null ? null : {
1005
+ [b]: t,
1006
+ [R]: n,
1007
+ [L]: te(e[L]),
1008
+ [D]: te(e[D]),
1009
+ comments: e.comments != null ? `${e.comments}` : null,
1010
+ ...e
1011
+ };
1012
+ }
1013
+ function pt(e) {
1014
+ const t = e[b] !== void 0 ? `${e[b]}`.trim() : "";
1015
+ if (!t) return null;
1016
+ const n = te(e[$]), r = te(e[F]);
1017
+ if (n === null || r === null || r <= n) return null;
1018
+ const o = 0.5 * (n + r);
1019
+ return {
1020
+ [b]: t,
1021
+ [$]: n,
1022
+ [F]: r,
1023
+ mid: o,
1024
+ [L]: te(e[L]),
1025
+ [D]: te(e[D]),
1026
+ classification: e.classification != null ? `${e.classification}` : null,
1027
+ comments: e.comments != null ? `${e.comments}` : null,
1028
+ ...e
1029
+ };
1030
+ }
1031
+ function xr(e) {
1032
+ const t = [], n = [];
1033
+ for (const r of e) {
1034
+ const o = [], s = te(r[L]), i = te(r[D]);
1035
+ 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
+ }
1037
+ return { valid: t, errors: n };
1038
+ }
1039
+ function Cr(e, t = null) {
1040
+ return new Promise((n, r) => {
1041
+ const o = {
1042
+ header: !0,
1043
+ dynamicTyping: !0,
1044
+ skipEmptyLines: !0,
1045
+ complete: (s) => {
1046
+ const i = [];
1047
+ for (const a of s.data) {
1048
+ const u = He(a, t), c = ht(u);
1049
+ c && i.push(c);
1050
+ }
1051
+ n(i);
1052
+ },
1053
+ error: (s) => r(w("parseStructuralPointsCSV", s))
1054
+ };
1055
+ typeof e == "string" && !e.startsWith("data:") && e.includes(`
1056
+ `) ? W.parse(e, o) : W.parse(e, o);
1057
+ });
1058
+ }
1059
+ function zr(e, t = null) {
1060
+ return new Promise((n, r) => {
1061
+ W.parse(e, {
1062
+ header: !0,
1063
+ dynamicTyping: !0,
1064
+ skipEmptyLines: !0,
1065
+ complete: (o) => {
1066
+ const s = [];
1067
+ for (const i of o.data) {
1068
+ const a = He(i, t), u = pt(a);
1069
+ u && s.push(u);
1070
+ }
1071
+ n(s);
1072
+ },
1073
+ error: (o) => r(w("parseStructuralIntervalsCSV", o))
1074
+ });
1075
+ });
1076
+ }
1077
+ function Kt(e, t = b) {
1078
+ const n = /* @__PURE__ */ new Map();
1079
+ for (const r of e) {
1080
+ const o = r[t] != null ? String(r[t]).trim() : "";
1081
+ o && (n.has(o) || n.set(o, { holeId: o, points: [] }), n.get(o).points.push(r));
1082
+ }
1083
+ return Array.from(n.values());
1084
+ }
1085
+ function Jt(e, t = null) {
1086
+ return new Promise((n, r) => {
1087
+ W.parse(e, {
1088
+ header: !0,
1089
+ dynamicTyping: !0,
1090
+ skipEmptyLines: !0,
1091
+ complete: (o) => {
1092
+ const s = o.data.map((u) => He(u, t)), i = Zt(s);
1093
+ if (!i) {
1094
+ r(w(
1095
+ "parseStructuralCSV",
1096
+ new Error("Structural CSV requires either 'depth' (point) or 'from'/'to' (interval) columns")
1097
+ ));
1098
+ return;
1099
+ }
1100
+ const a = [];
1101
+ for (const u of s) {
1102
+ const c = i === "interval" ? pt(u) : ht(u);
1103
+ c && a.push(c);
1104
+ }
1105
+ n({ schema: i, rows: a });
1106
+ },
1107
+ error: (o) => r(w("parseStructuralCSV", o))
1108
+ });
1109
+ });
1110
+ }
1111
+ function Qt(e) {
1112
+ return new Promise((t) => {
1113
+ W.parse(e, {
1114
+ header: !0,
1115
+ dynamicTyping: !0,
1116
+ skipEmptyLines: !0,
1117
+ complete: (n) => {
1118
+ const r = /* @__PURE__ */ new Map();
1119
+ 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 = {
1125
+ ...f,
1126
+ [b]: a,
1127
+ [$]: u,
1128
+ [F]: c,
1129
+ [we]: l,
1130
+ [R]: l,
1131
+ // unified depth field for y-axis rendering
1132
+ _source: "assay"
1133
+ };
1134
+ r.has(a) || r.set(a, []), r.get(a).push(p);
1135
+ }
1136
+ const o = Array.from(r.entries()).map(([s, i]) => ({
1137
+ holeId: s,
1138
+ points: i.sort((a, u) => a[$] - u[$])
1139
+ }));
1140
+ t(o);
1141
+ }
1142
+ });
1143
+ });
1144
+ }
1145
+ async function Nr({ assayCsv: e, structuralCsv: t } = {}) {
1146
+ 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" })))
1150
+ ) : Promise.resolve([])
1151
+ ]), o = new Map(n.map((s) => [s.holeId, { ...s, points: [...s.points] }]));
1152
+ for (const s of r) {
1153
+ const i = s.holeId;
1154
+ if (i)
1155
+ if (o.has(i)) {
1156
+ const a = o.get(i);
1157
+ o.set(i, { ...a, points: [...a.points, ...s.points || []] });
1158
+ } else
1159
+ o.set(i, s);
1160
+ }
1161
+ return { holes: Array.from(o.values()) };
1162
+ }
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) {
1165
+ return e ? typeof e == "string" ? { text: e } : e : {};
1166
+ }
1167
+ function yt(e = {}) {
1168
+ const t = Qe(e.xaxis && e.xaxis.title), n = Qe(e.yaxis && e.yaxis.title);
1169
+ return {
1170
+ ...e,
1171
+ margin: nn,
1172
+ autosize: !0,
1173
+ width: void 0,
1174
+ xaxis: {
1175
+ ...e.xaxis || {},
1176
+ tickfont: {
1177
+ ...e.xaxis && e.xaxis.tickfont || {},
1178
+ size: Ke
1179
+ },
1180
+ title: {
1181
+ ...t,
1182
+ font: { ...t.font || {}, size: Je }
1183
+ }
1184
+ },
1185
+ yaxis: {
1186
+ ...e.yaxis || {},
1187
+ tickfont: {
1188
+ ...e.yaxis && e.yaxis.tickfont || {},
1189
+ size: Ke
1190
+ },
1191
+ title: {
1192
+ ...n,
1193
+ font: { ...n.font || {}, size: Je }
1194
+ }
1195
+ }
1196
+ };
1197
+ }
1198
+ function rn(e, t) {
863
1199
  var r;
864
1200
  if (!e || !t) return !1;
865
1201
  const n = e.points || [];
@@ -870,308 +1206,608 @@ function Ve(e, t) {
870
1206
  }
871
1207
  return !1;
872
1208
  }
873
- function Et(e, t, n) {
1209
+ function on(e, t, n) {
874
1210
  if (!e || !t) return [];
875
1211
  const r = (e == null ? void 0 : e.points) || [], o = [], s = /* @__PURE__ */ new Set();
876
1212
  return r.forEach((i) => {
877
- const a = Number(
1213
+ let a = Number(
878
1214
  i.from ?? i.samp_from ?? i.sample_from ?? i.fromdepth ?? i.from_depth ?? i.depth_from
879
- ), c = Number(
1215
+ ), u = Number(
880
1216
  i.to ?? i.samp_to ?? i.sample_to ?? i.todepth ?? i.to_depth ?? i.depth_to
881
- ), l = i == null ? void 0 : i[t];
882
- if (!Number.isFinite(a) || !Number.isFinite(c) || c <= a || l == null || l === "") return;
883
- const u = `${t}:${a}-${c}`;
884
- if (s.has(u)) return;
885
- s.add(u);
886
- const m = (a + c) / 2, f = n ? l : Number(l);
887
- !n && !Number.isFinite(f) || o.push({
888
- z: m,
889
- val: f,
1217
+ );
1218
+ if (!Number.isFinite(a) || !Number.isFinite(u)) {
1219
+ const f = Number(i.depth ?? i.md);
1220
+ Number.isFinite(f) && (a = f, u = f);
1221
+ }
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,
890
1231
  from: a,
891
- to: c,
892
- errorPlus: c - m,
893
- errorMinus: m - a
1232
+ to: u,
1233
+ errorPlus: u - d,
1234
+ errorMinus: d - a
894
1235
  });
895
1236
  }), o.sort((i, a) => a.z - i.z);
896
1237
  }
897
- function vt(e, t) {
1238
+ function sn(e, t) {
898
1239
  if (!e.length) return { data: [], layout: {} };
899
- const n = [...e].sort((c, l) => l.z - c.z), r = [];
900
- for (let c = 0; c < n.length; c += 1) {
901
- const l = n[c], u = n[c + 1], m = l.z, f = u ? u.z : l.z - 20;
902
- f !== m && r.push({ y0: m, y1: f, category: l.val || "unknown" });
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 });
903
1246
  }
904
- const o = ["#8b1e3f", "#a8324f", "#b84c68", "#d16587", "#e07ba0", "#f091b6", "#f7a7c8", "#fbcfe8"], s = r.map((c, l) => ({
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) => ({
905
1250
  type: "rect",
906
1251
  xref: "x",
907
1252
  yref: "y",
908
1253
  x0: 0,
909
1254
  x1: 1,
910
- y0: c.y0,
911
- y1: c.y1,
912
- fillcolor: o[l % o.length],
1255
+ y0: l.y0,
1256
+ y1: l.y1,
1257
+ fillcolor: i[l.category],
913
1258
  line: { width: 0 }
914
1259
  }));
915
1260
  return { data: [{
916
1261
  x: r.map(() => 0.5),
917
- y: r.map((c) => (c.y0 + c.y1) / 2),
1262
+ y: r.map((l) => (l.y0 + l.y1) / 2),
918
1263
  mode: "text",
919
- text: r.map((c) => c.category),
1264
+ text: r.map((l) => l.category),
920
1265
  textposition: "middle center",
921
1266
  showlegend: !1,
922
1267
  hoverinfo: "text",
923
- customdata: r.map((c) => [c.y0, c.y1]),
924
- hovertemplate: "Category: %{text}<br>from: %{customdata[0]} to %{customdata[1]}<extra></extra>"
925
- }], layout: {
926
- height: 260,
927
- margin: { l: 50, r: 10, t: 10, b: 30 },
1268
+ customdata: r.map((l) => [Math.min(l.fromVal, l.toVal), Math.max(l.fromVal, l.toVal)]),
1269
+ hovertemplate: "Category: %{text}<br>from: %{customdata[0]} to: %{customdata[1]}<extra></extra>"
1270
+ }], layout: yt({
928
1271
  xaxis: { range: [0, 1], visible: !1, fixedrange: !0 },
929
1272
  yaxis: { title: "Depth (m)", autorange: "reversed", zeroline: !1 },
930
- shapes: s,
1273
+ shapes: a,
931
1274
  showlegend: !1,
932
1275
  title: t || void 0
933
- } };
1276
+ }) };
934
1277
  }
935
- function Dt(e, t, n) {
1278
+ function an(e, t, n) {
936
1279
  if (!e.length) return { data: [], layout: {} };
937
1280
  const r = n === "bar", o = n === "markers", s = n === "line", i = {
938
- x: e.map((u) => u.val),
939
- y: e.map((u) => u.z),
940
- hovertemplate: `${t}: %{x}<br>from: %{customdata[0]} to %{customdata[1]}<extra></extra>`,
941
- customdata: e.map((u) => [u.from, u.to])
1281
+ x: e.map((l) => l.val),
1282
+ y: e.map((l) => l.z),
1283
+ 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)])
942
1285
  }, a = {
943
1286
  type: "data",
944
1287
  symmetric: !1,
945
- array: e.map((u) => u.errorPlus),
946
- arrayminus: e.map((u) => u.errorMinus),
1288
+ array: e.map((l) => l.errorPlus),
1289
+ arrayminus: e.map((l) => l.errorMinus),
947
1290
  thickness: 1.5,
948
1291
  width: 2,
949
- color: It
1292
+ color: tn
950
1293
  };
951
1294
  return { data: [r ? {
952
1295
  ...i,
953
1296
  type: "bar",
954
1297
  orientation: "h",
955
- marker: { color: He },
1298
+ marker: { color: Ze },
956
1299
  error_y: a
957
1300
  } : {
958
1301
  ...i,
959
1302
  type: "scatter",
960
1303
  mode: o ? "markers" : s ? "lines" : "lines+markers",
961
- line: { color: He, width: 2 },
962
- marker: { size: 7, color: At },
1304
+ line: { color: Ze, width: 2 },
1305
+ marker: { size: 7, color: en },
963
1306
  error_y: s ? void 0 : a
964
- }], layout: {
965
- height: 260,
966
- margin: { l: 50, r: 10, t: 10, b: 30 },
1307
+ }], layout: yt({
967
1308
  xaxis: { title: t, zeroline: !1 },
968
1309
  yaxis: { title: "Depth (m)", autorange: "reversed", zeroline: !1 },
969
1310
  barmode: "overlay",
970
1311
  showlegend: !1
1312
+ }) };
1313
+ }
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);
1316
+ }
1317
+ const gt = [
1318
+ "#0f172a",
1319
+ "#1e3a5f",
1320
+ "#7c3aed",
1321
+ "#dc2626",
1322
+ "#16a34a",
1323
+ "#d97706",
1324
+ "#0ea5e9",
1325
+ "#db2777",
1326
+ "#65a30d",
1327
+ "#9333ea"
1328
+ ], cn = { l: 4, r: 4, t: 4, b: 4 }, et = 10, tt = 12;
1329
+ function bt(e = {}) {
1330
+ return {
1331
+ ...e,
1332
+ margin: cn,
1333
+ autosize: !0,
1334
+ width: void 0,
1335
+ xaxis: {
1336
+ ...e.xaxis || {},
1337
+ tickfont: {
1338
+ ...e.xaxis && e.xaxis.tickfont || {},
1339
+ size: et
1340
+ },
1341
+ title: {
1342
+ ...e.xaxis && e.xaxis.title || {},
1343
+ font: {
1344
+ ...e.xaxis && e.xaxis.title && e.xaxis.title.font || {},
1345
+ size: tt
1346
+ }
1347
+ }
1348
+ },
1349
+ yaxis: {
1350
+ ...e.yaxis || {},
1351
+ tickfont: {
1352
+ ...e.yaxis && e.yaxis.tickfont || {},
1353
+ size: et
1354
+ },
1355
+ title: {
1356
+ ...e.yaxis && e.yaxis.title || {},
1357
+ font: {
1358
+ ...e.yaxis && e.yaxis.title && e.yaxis.title.font || {},
1359
+ size: tt
1360
+ }
1361
+ }
1362
+ }
1363
+ };
1364
+ }
1365
+ function un(e, {
1366
+ tailScale: t = 5,
1367
+ colorBy: n = null,
1368
+ palette: r = gt,
1369
+ depthCol: o = R,
1370
+ dipCol: s = L,
1371
+ azCol: i = D
1372
+ } = {}) {
1373
+ const a = e.filter(
1374
+ (p) => p[o] != null && p[s] != null && p[i] != null
1375
+ );
1376
+ if (!a.length)
1377
+ return { data: [], layout: {} };
1378
+ 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];
1381
+ });
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({
1390
+ type: "line",
1391
+ x0: h,
1392
+ y0: y,
1393
+ x1: h + P,
1394
+ y1: y + N,
1395
+ line: { color: E, width: 2 }
1396
+ });
1397
+ }
1398
+ const d = [], m = n && c.size > 1;
1399
+ for (const [p, y] of c.entries())
1400
+ d.push({
1401
+ type: "scatter",
1402
+ x: y.xs,
1403
+ y: y.ys,
1404
+ 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]]),
1409
+ hovertemplate: "Depth: %{y}<br>Dip: %{customdata[0]}<br>Az: %{customdata[1]}<extra></extra>"
1410
+ });
1411
+ return { data: d, layout: {
1412
+ shapes: l,
1413
+ height: 400,
1414
+ margin: { l: 40, r: 10, t: 10, b: 40 },
1415
+ xaxis: {
1416
+ title: "Dip (°)",
1417
+ autorange: !0,
1418
+ fixedrange: !0,
1419
+ zeroline: !0,
1420
+ tickvals: [-90, -60, -30, 0, 30, 60, 90]
1421
+ },
1422
+ yaxis: { title: "Depth (m)", autorange: "reversed" },
1423
+ showlegend: !!m
971
1424
  } };
972
1425
  }
973
- function Lt({ points: e, isCategorical: t, property: n, chartType: r }) {
974
- return !e || !e.length || !n ? { data: [], layout: {} } : t || r === "categorical" ? vt(e, n) : Dt(e, n, r);
1426
+ function Mr(e, {
1427
+ labelCol: t = "structure_type",
1428
+ palette: n = gt,
1429
+ fromCol: r = $,
1430
+ toCol: o = F
1431
+ } = {}) {
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();
1436
+ 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);
1438
+ if (!s.length)
1439
+ return { data: [], layout: {} };
1440
+ const i = [], a = [], u = [];
1441
+ return s.forEach((d, m) => {
1442
+ i.push({
1443
+ type: "rect",
1444
+ xref: "x",
1445
+ yref: "y",
1446
+ x0: 0,
1447
+ x1: 1,
1448
+ y0: d.from,
1449
+ y1: d.to,
1450
+ fillcolor: n[m % n.length],
1451
+ line: { width: 0 }
1452
+ }), a.push(0.5 * (d.from + d.to)), u.push(d.label);
1453
+ }), { data: [{
1454
+ type: "scatter",
1455
+ x: Array(u.length).fill(0.5),
1456
+ y: a,
1457
+ mode: "text",
1458
+ text: u,
1459
+ textposition: "middle center",
1460
+ showlegend: !1,
1461
+ hoverinfo: "text"
1462
+ }], layout: bt({
1463
+ shapes: i,
1464
+ height: 400,
1465
+ xaxis: { range: [0, 1], visible: !1, fixedrange: !0 },
1466
+ yaxis: { title: "Depth (m)", autorange: "reversed" },
1467
+ showlegend: !1
1468
+ }) };
975
1469
  }
976
- const Le = "markers+line", Tt = [{ value: "categorical", label: "Categorical bands" }], Pt = [
977
- { value: "bar", label: "Bars" },
978
- { value: "markers", label: "Markers" },
979
- { value: Le, label: "Markers + Line" },
980
- { value: "line", label: "Line only" }
981
- ];
982
- function Ot(e, t) {
983
- var n;
984
- return e.some((r) => r.value === t) ? t : ((n = e[0]) == null ? void 0 : n.value) || Le;
985
- }
986
- function Sn({ config: e, graph: t, holeOptions: n = [], propertyOptions: r = [], onConfigChange: o }) {
987
- const s = rt(null), i = t == null ? void 0 : t.hole, a = (t == null ? void 0 : t.points) || [], c = (e == null ? void 0 : e.property) || "", l = (e == null ? void 0 : e.chartType) || Le, u = (e == null ? void 0 : e.holeId) || "", m = (t == null ? void 0 : t.isCategorical) || !1, f = m ? Tt : Pt, d = Ot(f, l), [p, y] = W("");
988
- return re(() => {
989
- if (!i || !c || a.length === 0) return;
990
- const h = s.current;
991
- if (!h) return;
992
- const { data: A, layout: O } = Lt({ points: a, isCategorical: m, property: c, chartType: d });
993
- if (!A || A.length === 0) return;
994
- const F = {
1470
+ function dn(e, t) {
1471
+ if (!e) return "";
1472
+ const n = String(e).trim().split(/\s+/), r = [];
1473
+ let o = "";
1474
+ for (const s of n)
1475
+ o && o.length + 1 + s.length > t ? (r.push(o), o = s) : o = o ? `${o} ${s}` : s;
1476
+ return o && r.push(o), r.join("<br>");
1477
+ }
1478
+ function mn(e, {
1479
+ commentCol: t = "comments",
1480
+ fromCol: n = $,
1481
+ toCol: r = F,
1482
+ bgColor: o = "#f1f5f9",
1483
+ borderColor: s = "#cbd5e1",
1484
+ textColor: i = "#1e293b",
1485
+ charsPerLine: a = 18
1486
+ } = {}) {
1487
+ 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);
1491
+ if (!u.length)
1492
+ return { data: [], layout: {} };
1493
+ const c = [], l = [], d = [], m = [], f = [];
1494
+ for (const h of u) {
1495
+ const z = 0.5 * (h.from + h.to), C = !!h.comment;
1496
+ c.push({
1497
+ type: "rect",
1498
+ xref: "x",
1499
+ yref: "y",
1500
+ x0: 0,
1501
+ x1: 1,
1502
+ y0: h.from,
1503
+ y1: h.to,
1504
+ fillcolor: C ? o : "rgba(0,0,0,0)",
1505
+ 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}`));
1507
+ }
1508
+ return { data: l.length ? [{
1509
+ type: "scatter",
1510
+ x: l,
1511
+ y: d,
1512
+ mode: "text",
1513
+ text: m,
1514
+ textposition: "middle center",
1515
+ textfont: { color: i, size: 10 },
1516
+ hovertext: f,
1517
+ hoverinfo: "text",
1518
+ showlegend: !1
1519
+ }] : [], layout: bt({
1520
+ shapes: c,
1521
+ height: 400,
1522
+ xaxis: { range: [0, 1], visible: !1, fixedrange: !0 },
1523
+ yaxis: { title: "Depth (m)", autorange: "reversed" },
1524
+ showlegend: !1
1525
+ }) };
1526
+ }
1527
+ function Ir(e, {
1528
+ symbolSize: t = 10,
1529
+ xCol: n = "easting",
1530
+ yCol: r = "northing"
1531
+ } = {}) {
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);
1535
+ return {
1536
+ strike: u,
1537
+ dipValue: i,
1538
+ x: o,
1539
+ 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
1546
+ };
1547
+ }
1548
+ const _t = "markers+line";
1549
+ function fn(e, t) {
1550
+ 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;
1562
+ 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,
1566
+ property: u,
1567
+ chartType: f
1568
+ });
1569
+ } catch (A) {
1570
+ console.error("Plot build error", A), y((A == null ? void 0 : A.message) || "Plot build error");
1571
+ return;
1572
+ }
1573
+ if ((!(E != null && E.data) || E.data.length === 0) && !h)
1574
+ return;
1575
+ const H = {
995
1576
  displayModeBar: !0,
996
1577
  responsive: !0,
997
1578
  useResizeHandler: !0,
998
1579
  modeBarButtonsToRemove: ["select2d", "lasso2d", "zoom2d", "zoomIn2d", "zoomOut2d", "autoScale2d"]
999
1580
  };
1000
1581
  try {
1001
- y(""), me.react(h, A, O, F), requestAnimationFrame(() => {
1002
- h && h.parentElement && me.Plots.resize(h);
1582
+ y(""), xe.react(C, E.data, E.layout, H), requestAnimationFrame(() => {
1583
+ C && C.parentElement && xe.Plots.resize(C);
1003
1584
  });
1004
- } catch (D) {
1005
- console.error("Plot render error", D), y((D == null ? void 0 : D.message) || "Plot render error");
1585
+ } catch (A) {
1586
+ console.error("Plot render error", A), y((A == null ? void 0 : A.message) || "Plot render error");
1006
1587
  }
1007
1588
  return () => {
1008
- if (h)
1589
+ if (C)
1009
1590
  try {
1010
- me.purge(h);
1011
- } catch (D) {
1012
- console.warn("Plot purge error", D);
1591
+ xe.purge(C);
1592
+ } catch (A) {
1593
+ console.warn("Plot purge error", A);
1013
1594
  }
1014
1595
  };
1015
- }, [i, c, d, m, a]), re(() => {
1596
+ }, [i, u, f, d, a]), oe(() => {
1016
1597
  const h = s.current;
1017
1598
  if (!h || typeof ResizeObserver > "u") return;
1018
- const A = new ResizeObserver(() => {
1599
+ const z = new ResizeObserver(() => {
1019
1600
  try {
1020
- h && h.data && me.Plots.resize(h);
1021
- } catch (O) {
1022
- console.warn("Plot resize error", O);
1601
+ h && h.data && xe.Plots.resize(h);
1602
+ } catch (C) {
1603
+ console.warn("Plot resize error", C);
1023
1604
  }
1024
1605
  });
1025
- return A.observe(h), () => A.disconnect();
1026
- }, []), !i || !c ? /* @__PURE__ */ k("div", { className: "plot-card empty", children: /* @__PURE__ */ k("div", { className: "placeholder", children: e != null && e.holeId ? t != null && t.loading ? `Loading ${e.holeId}...` : "Select a property" : "Loading demo data..." }) }) : a.length === 0 ? /* @__PURE__ */ k("div", { className: "plot-card empty", children: /* @__PURE__ */ ae("div", { className: "placeholder", children: [
1027
- "No numeric data for ",
1028
- c
1029
- ] }) }) : p ? /* @__PURE__ */ k("div", { className: "plot-card empty", children: /* @__PURE__ */ ae("div", { className: "placeholder", children: [
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: [
1030
1608
  "Plot error: ",
1031
1609
  p
1032
- ] }) }) : /* @__PURE__ */ ae("div", { className: "plot-card", children: [
1033
- /* @__PURE__ */ k("div", { className: "plot-title", children: /* @__PURE__ */ k(
1610
+ ] }) }) : /* @__PURE__ */ Ce("div", { className: "plot-card", children: [
1611
+ /* @__PURE__ */ G("div", { className: "plot-title", children: /* @__PURE__ */ G(
1034
1612
  "select",
1035
1613
  {
1036
1614
  className: "plot-select",
1037
- value: u,
1615
+ value: l,
1038
1616
  onChange: (h) => o && o({ holeId: h.target.value }),
1039
1617
  children: n.map((h) => {
1040
- const A = typeof h == "string" ? h : h.holeId, O = typeof h == "string" ? h : h.label || h.holeId;
1041
- return /* @__PURE__ */ k("option", { value: A, children: O }, A);
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);
1042
1620
  })
1043
1621
  }
1044
1622
  ) }),
1045
- /* @__PURE__ */ ae("div", { className: "plot-controls column", children: [
1046
- r.length > 0 && /* @__PURE__ */ k(
1623
+ /* @__PURE__ */ Ce("div", { className: "plot-controls column", children: [
1624
+ r.length > 0 && /* @__PURE__ */ G(
1047
1625
  "select",
1048
1626
  {
1049
1627
  className: "plot-select",
1050
- value: c,
1628
+ value: u,
1051
1629
  onChange: (h) => o && o({ property: h.target.value }),
1052
- children: r.map((h) => /* @__PURE__ */ k("option", { value: h, children: h }, h))
1630
+ children: r.map((h) => /* @__PURE__ */ G("option", { value: h, children: h }, h))
1053
1631
  }
1054
1632
  ),
1055
- /* @__PURE__ */ k(
1633
+ m.length > 1 && /* @__PURE__ */ G(
1056
1634
  "select",
1057
1635
  {
1058
1636
  className: "plot-select",
1059
- value: d,
1637
+ value: f,
1060
1638
  onChange: (h) => o && o({ chartType: h.target.value }),
1061
- children: f.map((h) => /* @__PURE__ */ k("option", { value: h.value, children: h.label }, h.value))
1639
+ children: m.map((h) => /* @__PURE__ */ G("option", { value: h.value, children: h.label }, h.value))
1062
1640
  }
1063
1641
  )
1064
1642
  ] }),
1065
- /* @__PURE__ */ k("div", { className: "plotly-chart", ref: s })
1643
+ /* @__PURE__ */ G("div", { className: "plotly-chart", ref: s })
1066
1644
  ] });
1067
1645
  }
1068
- function kn({
1646
+ function nt(e, t) {
1647
+ if (!(t != null && t.length)) return e;
1648
+ const n = new Map(e.map((r) => [r.id || r.holeId, { ...r }]));
1649
+ for (const r of t) {
1650
+ const o = r.id || r.holeId;
1651
+ if (o)
1652
+ if (n.has(o)) {
1653
+ const s = n.get(o);
1654
+ n.set(o, { ...s, points: [...s.points || [], ...r.points || []] });
1655
+ } else
1656
+ n.set(o, r);
1657
+ }
1658
+ return Array.from(n.values());
1659
+ }
1660
+ function hn(e, t) {
1661
+ if (!e || !t) return [];
1662
+ const n = /* @__PURE__ */ new Set(), r = [];
1663
+ for (const o of e.points || []) {
1664
+ 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
+ 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] ?? "" }));
1668
+ }
1669
+ return r;
1670
+ }
1671
+ function Er({
1069
1672
  initialFocusedHoleId: e = "",
1070
1673
  sourceFile: t = null,
1071
- plotCount: n = 4
1674
+ extraHoles: n = [],
1675
+ plotCount: r = 4
1072
1676
  } = {}) {
1073
- const [r, o] = W([]), [s, i] = W([]), [a, c] = W([]), [l, u] = W([]), [m, f] = W(""), [d, p] = W([]), [y, h] = W(""), [A, O] = W(e || ""), [F, D] = W([]);
1074
- re(() => {
1075
- !t || s.length > 0 || pt(t).then((z) => {
1076
- if (!z) return;
1077
- const C = Array.from(new Map(z.map((E) => [E.holeId, E])).values());
1078
- i(C), p(qe({
1079
- holeIds: C.map((E) => E.holeId),
1080
- focusedHoleId: A,
1081
- plotCount: n,
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,
1685
+ plotCount: r,
1082
1686
  defaultProp: "",
1083
1687
  categoricalProps: l,
1688
+ commentProps: m,
1084
1689
  numericDefaultChartType: "markers+line"
1085
1690
  }));
1086
- }).catch((z) => {
1087
- console.info("Assay metadata load skipped:", z.message);
1691
+ }).catch((M) => {
1692
+ console.info("Assay metadata load skipped:", M.message);
1693
+ }));
1694
+ }, [t, j, r, l, m]), oe(() => {
1695
+ 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] : _;
1088
1700
  });
1089
- }, [t, s.length, A, n, l]), re(() => {
1090
- h((z) => z && z.startsWith("Loading assays for hole") ? z : "");
1091
- }, [d]), re(() => {
1092
- if (!s.length) {
1093
- p([]);
1701
+ }, [n]), oe(() => {
1702
+ A((M) => M && M.startsWith("Loading data for hole") ? M : "");
1703
+ }, [C]), oe(() => {
1704
+ if (!i.length) {
1705
+ E([]);
1094
1706
  return;
1095
1707
  }
1096
- const z = Ge(s.map((C) => C.holeId), A);
1097
- p((C) => Array.from({ length: n }).map((b, _) => {
1098
- var S;
1099
- const M = C[_] || {}, L = s.some((Y) => Y.holeId === M.holeId) ? M.holeId : z[_] || ((S = s[_]) == null ? void 0 : S.holeId) || "", v = M.property || m, T = he({
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({
1100
1712
  property: v,
1101
- chartType: M.chartType,
1713
+ chartType: O.chartType,
1102
1714
  categoricalProps: l,
1715
+ commentProps: m,
1103
1716
  numericDefaultChartType: "markers+line"
1104
1717
  });
1105
- return { holeId: L, property: v, chartType: T };
1718
+ return { holeId: k, property: v, chartType: U };
1106
1719
  }));
1107
- }, [s, A, m, l, n]), re(() => {
1720
+ }, [i, j, h, l, m, r]), oe(() => {
1108
1721
  if (!t) return;
1109
- d.map((C) => C.holeId).filter(Boolean).forEach((C) => {
1110
- const E = r.some((_) => (_.id || _.holeId) === C), b = F.includes(C);
1111
- E || b || (D((_) => [..._, C]), yt(t, C).then((_) => {
1112
- D((M) => M.filter((L) => L !== C)), _ && o((M) => {
1113
- const L = [...M.filter((T) => (T.id || T.holeId) !== C), _], v = Xe(L);
1114
- return c(v.numericProps), u(v.categoricalProps), !m && v.defaultProp && (f(v.defaultProp), p((T) => T.map((S) => ({
1115
- ...S,
1116
- property: S.property || v.defaultProp,
1117
- chartType: he({
1118
- property: S.property || v.defaultProp,
1119
- chartType: S.chartType,
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],
1728
+ 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,
1120
1736
  categoricalProps: v.categoricalProps,
1737
+ commentProps: v.commentProps,
1121
1738
  numericDefaultChartType: "markers+line"
1122
1739
  })
1123
- })))), L;
1740
+ })))), k;
1124
1741
  });
1125
- }).catch((_) => {
1126
- console.error(_), D((M) => M.filter((L) => L !== C)), h(_.message || `Error loading hole ${C}`);
1742
+ }).catch((x) => {
1743
+ console.error(x), V((O) => O.filter((k) => k !== _)), A(x.message || `Error loading hole ${_}`);
1127
1744
  }));
1128
1745
  });
1129
- }, [d, t, r, F, m]);
1130
- const R = ze(() => [...a, ...l], [a, l]), w = ze(
1131
- () => s.map((z) => ({ holeId: z.holeId, label: z.holeId })).sort((z, C) => z.label.localeCompare(C.label)),
1132
- [s]
1133
- ), I = ze(() => Array.from({ length: n }).map((z, C) => {
1134
- const E = d[C] || {}, b = r.find((S) => (S.id || S.holeId) === E.holeId) || null;
1135
- let _ = E.property || m;
1136
- if (b && (!_ || !Ve(b, _))) {
1137
- const S = [...a, ...l].find((Y) => Ve(b, Y));
1138
- S && (_ = S);
1139
- }
1140
- const M = E.chartType || (_ && l.includes(_) ? "categorical" : "markers+line"), L = E.holeId || (b == null ? void 0 : b.id) || (b == null ? void 0 : b.holeId) || "", v = l.includes(_), T = Et(b, _, v);
1141
- return {
1142
- config: { holeId: L, property: _, chartType: M },
1143
- hole: b,
1144
- loading: F.includes(E.holeId),
1145
- isCategorical: v,
1146
- points: T,
1147
- label: L
1148
- };
1149
- }), [d, r, m, l, F, n, a]), N = (z, C) => {
1150
- p((E) => {
1151
- const b = [...E], M = { ...b[z] || {}, ...C };
1152
- return C.property && (M.chartType = he({
1153
- property: C.property,
1154
- chartType: M.chartType,
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;
1751
+ }
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), _;
1754
+ });
1755
+ }, [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)),
1761
+ [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);
1769
+ 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
1780
+ };
1781
+ });
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,
1155
1788
  categoricalProps: l,
1789
+ commentProps: m,
1156
1790
  numericDefaultChartType: "markers+line"
1157
- })), b[z] = M, b;
1791
+ })), S[M] = O, S;
1158
1792
  });
1159
1793
  };
1160
1794
  return {
1161
- error: y,
1162
- focusedHoleId: A,
1163
- setFocusedHoleId: O,
1164
- setError: h,
1165
- holeCount: s.length,
1166
- numericProps: a,
1795
+ error: H,
1796
+ focusedHoleId: j,
1797
+ setFocusedHoleId: P,
1798
+ setError: A,
1799
+ holeCount: i.length,
1800
+ numericProps: u,
1167
1801
  categoricalProps: l,
1168
- propertyOptions: R,
1169
- labeledHoleOptions: w,
1170
- traceGraphs: I,
1171
- handleConfigChange: N
1802
+ commentProps: m,
1803
+ columnMeta: p,
1804
+ propertyOptions: re,
1805
+ labeledHoleOptions: T,
1806
+ traceGraphs: B,
1807
+ handleConfigChange: q
1172
1808
  };
1173
1809
  }
1174
- const Ft = [
1810
+ const pn = [
1175
1811
  "#313695",
1176
1812
  "#4575b4",
1177
1813
  "#74add1",
@@ -1183,8 +1819,8 @@ const Ft = [
1183
1819
  "#d73027",
1184
1820
  "#a50026"
1185
1821
  ];
1186
- function St(e = [], t = Ft) {
1187
- const n = e.filter((l) => Number.isFinite(l));
1822
+ function yn(e = [], t = pn) {
1823
+ const n = e.filter((c) => Number.isFinite(c));
1188
1824
  if (!n.length)
1189
1825
  return {
1190
1826
  min: null,
@@ -1193,10 +1829,10 @@ function St(e = [], t = Ft) {
1193
1829
  bins: [],
1194
1830
  colors: t
1195
1831
  };
1196
- const r = n.slice().sort((l, u) => l - u), o = r[0], s = r[r.length - 1], i = t.length;
1832
+ const r = n.slice().sort((c, l) => c - l), o = r[0], s = r[r.length - 1], i = t.length;
1197
1833
  if (s === o) {
1198
- const l = t.map((u, m) => ({
1199
- index: m,
1834
+ const c = t.map((l, d) => ({
1835
+ index: d,
1200
1836
  min: o,
1201
1837
  max: s,
1202
1838
  label: `${o}`
@@ -1205,32 +1841,32 @@ function St(e = [], t = Ft) {
1205
1841
  min: o,
1206
1842
  max: s,
1207
1843
  step: 0,
1208
- bins: l,
1844
+ bins: c,
1209
1845
  colors: t
1210
1846
  };
1211
1847
  }
1212
- const a = t.map((l, u) => {
1213
- const m = u / i, f = (u + 1) / i, d = Math.floor(m * r.length), p = Math.min(r.length - 1, Math.floor(f * r.length)), y = r[d], h = u === i - 1 ? s : r[p];
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];
1214
1850
  return {
1215
- index: u,
1851
+ index: l,
1216
1852
  min: y,
1217
1853
  max: h,
1218
- label: kt(y, h)
1854
+ label: gn(y, h)
1219
1855
  };
1220
- }), c = (s - o) / i;
1856
+ }), u = (s - o) / i;
1221
1857
  return {
1222
1858
  min: o,
1223
1859
  max: s,
1224
- step: c,
1860
+ step: u,
1225
1861
  bins: a,
1226
1862
  colors: t
1227
1863
  };
1228
1864
  }
1229
- function kt(e, t) {
1865
+ function gn(e, t) {
1230
1866
  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";
1231
1867
  return `${n(e)} – ${n(t)}`;
1232
1868
  }
1233
- function Ze(e, t) {
1869
+ function xt(e, t) {
1234
1870
  if (!Number.isFinite(e) || !t || !Array.isArray(t.bins) || !t.bins.length)
1235
1871
  return -1;
1236
1872
  if (t.max === t.min)
@@ -1242,43 +1878,43 @@ function Ze(e, t) {
1242
1878
  }
1243
1879
  return -1;
1244
1880
  }
1245
- function Ht(e, t, n = "#8b1e3f") {
1246
- const r = Ze(e, t);
1881
+ function bn(e, t, n = "#8b1e3f") {
1882
+ const r = xt(e, t);
1247
1883
  return r < 0 ? n : t.colors[r] || n;
1248
1884
  }
1249
- function Ke(e) {
1885
+ function Ct(e) {
1250
1886
  return Array.isArray(e) ? e : [];
1251
1887
  }
1252
- function Ne(e) {
1888
+ function Te(e) {
1253
1889
  const t = Number(e);
1254
1890
  return Number.isFinite(t) ? t : void 0;
1255
1891
  }
1256
- function Je(e = {}) {
1892
+ function zt(e = {}) {
1257
1893
  return {
1258
1894
  ...e,
1259
- x: Ne(e.x),
1260
- y: Ne(e.y),
1261
- z: Ne(e.z)
1895
+ x: Te(e.x),
1896
+ y: Te(e.y),
1897
+ z: Te(e.z)
1262
1898
  };
1263
1899
  }
1264
- function Vt(e = [], t = [0, 0], n = 0) {
1900
+ function _n(e = [], t = [0, 0], n = 0) {
1265
1901
  const [r, o] = t, s = Number(n) * Math.PI / 180, i = Math.cos(s), a = Math.sin(s);
1266
- return Ke(e).map(Je).map((c) => {
1267
- if (!Number.isFinite(c.x) || !Number.isFinite(c.y)) return { ...c };
1268
- const l = c.x - r, u = c.y - o;
1902
+ return Ct(e).map(zt).map((u) => {
1903
+ if (!Number.isFinite(u.x) || !Number.isFinite(u.y)) return { ...u };
1904
+ const c = u.x - r, l = u.y - o;
1269
1905
  return {
1270
- ...c,
1271
- along: l * a + u * i,
1272
- across: l * i - u * a
1906
+ ...u,
1907
+ along: c * a + l * i,
1908
+ across: c * i - l * a
1273
1909
  };
1274
1910
  });
1275
1911
  }
1276
- function Rt(e = [], t = [0, 0], n = 0, r = 50) {
1277
- const o = Vt(e, t, n), s = 0.5 * Number(r || 0);
1912
+ function xn(e = [], t = [0, 0], n = 0, r = 50) {
1913
+ const o = _n(e, t, n), s = 0.5 * Number(r || 0);
1278
1914
  return !Number.isFinite(s) || s <= 0 ? o : o.filter((i) => Number.isFinite(i.across) && Math.abs(i.across) <= s);
1279
1915
  }
1280
- function Hn(e = [], t = null, n = null) {
1281
- let r = Ke(e).map(Je);
1916
+ function Sr(e = [], t = null, n = null) {
1917
+ let r = Ct(e).map(zt);
1282
1918
  if (Array.isArray(t) && t.length === 2) {
1283
1919
  const [o, s] = t;
1284
1920
  r = r.filter((i) => Number.isFinite(i.z) && i.z <= Number(o) && i.z >= Number(s));
@@ -1288,46 +1924,46 @@ function Hn(e = [], t = null, n = null) {
1288
1924
  color_value: o == null ? void 0 : o[n]
1289
1925
  }))), r;
1290
1926
  }
1291
- function Vn(e = [], t = [0, 0], n = 0, r = 50, o = null) {
1292
- let s = Rt(e, t, n, r);
1927
+ function vr(e = [], t = [0, 0], n = 0, r = 50, o = null) {
1928
+ let s = xn(e, t, n, r);
1293
1929
  return o && (s = s.map((i) => ({
1294
1930
  ...i,
1295
1931
  color_value: i == null ? void 0 : i[o]
1296
1932
  }))), s;
1297
1933
  }
1298
- function Te(e) {
1934
+ function je(e) {
1299
1935
  return Array.isArray(e) ? e : [];
1300
1936
  }
1301
- function Pe(e = {}) {
1937
+ function Ue(e = {}) {
1302
1938
  return e.hole_id ?? e.holeId ?? e.id;
1303
1939
  }
1304
- function te(e, t = void 0) {
1940
+ function ce(e, t = void 0) {
1305
1941
  const n = Number(e);
1306
1942
  return Number.isFinite(n) ? n : t;
1307
1943
  }
1308
- function Rn(e = [], t = null) {
1944
+ function Pr(e = [], t = null) {
1309
1945
  const n = /* @__PURE__ */ new Map();
1310
- Te(e).forEach((o) => {
1311
- const s = Pe(o);
1946
+ je(e).forEach((o) => {
1947
+ const s = Ue(o);
1312
1948
  if (s == null || `${s}`.trim() === "") return;
1313
1949
  const i = `${s}`;
1314
1950
  n.has(i) || n.set(i, []), n.get(i).push(o);
1315
1951
  });
1316
1952
  const r = [];
1317
1953
  return n.forEach((o, s) => {
1318
- const i = [...o].sort((c, l) => te(c.md, 0) - te(l.md, 0)), a = {
1954
+ const i = [...o].sort((u, c) => ce(u.md, 0) - ce(c.md, 0)), a = {
1319
1955
  hole_id: s,
1320
- x: i.map((c) => te(c.x, 0)),
1321
- y: i.map((c) => te(c.y, 0)),
1322
- z: i.map((c) => te(c.z, 0)),
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)),
1323
1959
  color: null
1324
1960
  };
1325
- t && (a.color = i.map((c) => c == null ? void 0 : c[t])), r.push(a);
1961
+ t && (a.color = i.map((u) => u == null ? void 0 : u[t])), r.push(a);
1326
1962
  }), r;
1327
1963
  }
1328
- function wn(e = [], t = 1, n = null) {
1329
- return Te(e).map((r) => ({
1330
- hole_id: Pe(r),
1964
+ function Tr(e = [], t = 1, n = null) {
1965
+ return je(e).map((r) => ({
1966
+ hole_id: Ue(r),
1331
1967
  from: r == null ? void 0 : r.from,
1332
1968
  to: r == null ? void 0 : r.to,
1333
1969
  radius: t,
@@ -1335,17 +1971,70 @@ function wn(e = [], t = 1, n = null) {
1335
1971
  value: n ? r == null ? void 0 : r[n] : null
1336
1972
  }));
1337
1973
  }
1338
- function $n(e = [], t = null) {
1339
- return t ? Te(e).filter((n) => Object.prototype.hasOwnProperty.call(n || {}, t)).map((n) => ({
1340
- hole_id: Pe(n),
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),
1341
1977
  label: n == null ? void 0 : n[t],
1342
- depth: 0.5 * (te(n == null ? void 0 : n.from, 0) + te(n == null ? void 0 : n.to, 0))
1978
+ depth: 0.5 * (ce(n == null ? void 0 : n.from, 0) + ce(n == null ? void 0 : n.to, 0))
1343
1979
  })) : [];
1344
1980
  }
1345
- function Oe(e) {
1346
- var n, r, o, s, i, a, c, l, u;
1981
+ const Cn = {
1982
+ bedding: "#2563eb",
1983
+ foliation: "#16a34a",
1984
+ joint: "#9333ea",
1985
+ fault: "#dc2626",
1986
+ vein: "#f59e0b",
1987
+ "shear zone": "#0ea5e9",
1988
+ "fault zone": "#ef4444"
1989
+ };
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();
1993
+ }
1994
+ function Nn(e, t) {
1995
+ const n = e * Math.PI / 180, r = t * Math.PI / 180;
1996
+ return new g.Vector3(
1997
+ Math.sin(r) * Math.sin(n),
1998
+ // East component
1999
+ Math.cos(r) * Math.sin(n),
2000
+ // North component
2001
+ Math.cos(n)
2002
+ // Up component
2003
+ ).normalize();
2004
+ }
2005
+ function Lr(e, t = {}) {
2006
+ const {
2007
+ radius: n = 5,
2008
+ discThickness: r = 0.2,
2009
+ opacity: o = 0.7,
2010
+ segments: s = 32,
2011
+ 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),
2018
+ transparent: !0,
2019
+ 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 = {
2023
+ type: "structure",
2024
+ hole_id: c.hole_id,
2025
+ depth: c.depth ?? c.mid,
2026
+ structure_type: c.structure_type,
2027
+ dip: f,
2028
+ azimuth: p,
2029
+ comments: c.comments
2030
+ }, a.add(C);
2031
+ }
2032
+ return a;
2033
+ }
2034
+ function Ye(e) {
2035
+ var n, r, o, s, i, a, u, c, l;
1347
2036
  if (!e) return "";
1348
- const t = (m) => Number.isFinite(m) ? m.toFixed(3) : "nan";
2037
+ const t = (d) => Number.isFinite(d) ? d.toFixed(3) : "nan";
1349
2038
  return [
1350
2039
  t((n = e.camera) == null ? void 0 : n.x),
1351
2040
  t((r = e.camera) == null ? void 0 : r.y),
@@ -1353,12 +2042,12 @@ function Oe(e) {
1353
2042
  t((s = e.target) == null ? void 0 : s.x),
1354
2043
  t((i = e.target) == null ? void 0 : i.y),
1355
2044
  t((a = e.target) == null ? void 0 : a.z),
1356
- t((c = e.up) == null ? void 0 : c.x),
1357
- t((l = e.up) == null ? void 0 : l.y),
1358
- t((u = e.up) == null ? void 0 : u.z)
2045
+ 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)
1359
2048
  ].join("|");
1360
2049
  }
1361
- function Qe(e) {
2050
+ function Nt(e) {
1362
2051
  return !e.camera || !e.controls ? null : {
1363
2052
  camera: {
1364
2053
  x: e.camera.position.x,
@@ -1377,37 +2066,37 @@ function Qe(e) {
1377
2066
  }
1378
2067
  };
1379
2068
  }
1380
- function wt(e, t) {
2069
+ function Mn(e, t) {
1381
2070
  if (!e.camera || !e.controls || !t) return !1;
1382
2071
  const n = t.camera || {}, r = t.target || {}, o = t.up || {};
1383
- 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 = Oe(t), !0) : !1;
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;
1384
2073
  }
1385
- function $t(e) {
2074
+ function In(e) {
1386
2075
  if (!e.viewChangeHandler) return;
1387
2076
  const t = Date.now();
1388
2077
  if (t - e._lastViewEmitMs < 250) return;
1389
- const n = Qe(e);
2078
+ const n = Nt(e);
1390
2079
  if (!n) return;
1391
- const r = Oe(n);
2080
+ const r = Ye(n);
1392
2081
  r !== e._lastViewSignature && (e._lastViewSignature = r, e._lastViewEmitMs = t, e.viewChangeHandler(n));
1393
2082
  }
1394
- function Me(e, { minX: t, maxX: n, minY: r, maxY: o, minZ: s, maxZ: i }) {
1395
- const a = (t + n) / 2, c = (r + o) / 2, l = (s + i) / 2, u = n - t, m = o - r, f = i - s, p = Math.max(u, m, f, 1) * 2;
1396
- e.controls.target.set(a, c, l), e.camera.position.set(a + p, c + p, l + p), e.camera.lookAt(a, c, l), e.controls.update();
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();
1397
2086
  }
1398
- function jt(e, t = 1e3) {
2087
+ function An(e, t = 1e3) {
1399
2088
  !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());
1400
2089
  }
1401
- function Bt(e, t = 2e3) {
2090
+ function En(e, t = 2e3) {
1402
2091
  !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());
1403
2092
  }
1404
- function Ut(e, t = 0, n = 0) {
2093
+ function Sn(e, t = 0, n = 0) {
1405
2094
  e.controls && typeof e.controls.pan == "function" && (e.controls.pan(t, n), e.controls.update());
1406
2095
  }
1407
- function Yt(e, t = 1.1) {
2096
+ function vn(e, t = 1.1) {
1408
2097
  !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());
1409
2098
  }
1410
- function Gt(e, t = 1.2) {
2099
+ function Pn(e, t = 1.2) {
1411
2100
  if (!e.lastBounds) return;
1412
2101
  const {
1413
2102
  minX: n,
@@ -1416,10 +2105,10 @@ function Gt(e, t = 1.2) {
1416
2105
  maxY: s,
1417
2106
  minZ: i,
1418
2107
  maxZ: a
1419
- } = e.lastBounds, c = (r - n) * t, l = (s - o) * t, u = (a - i) * t, m = (n + r) / 2, f = (o + s) / 2, d = (i + a) / 2, y = Math.max(c, l, u, 1) * 2;
1420
- e.controls.target.set(m, f, d), e.camera.position.set(m + y, f + y, d + y), e.camera.lookAt(m, f, d), e.controls.update();
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();
1421
2110
  }
1422
- function qt(e, t = "orbit") {
2111
+ function Tn(e, t = "orbit") {
1423
2112
  if (e.controlMode = t === "fly" ? "fly" : "orbit", e.controlMode === "fly")
1424
2113
  e.controls && (e.controls.enabled = !1), e.flyControls && (e.flyControls.enabled = !0);
1425
2114
  else if (e.flyControls && (e.flyControls.enabled = !1), e.controls) {
@@ -1428,39 +2117,39 @@ function qt(e, t = "orbit") {
1428
2117
  e.controls.target.copy(n), e.controls.update();
1429
2118
  }
1430
2119
  }
1431
- const Q = "#9ca3af";
1432
- function Re(e, t) {
2120
+ const ae = "#9ca3af";
2121
+ function rt(e, t) {
1433
2122
  const n = Number(e == null ? void 0 : e.md), r = Number(t == null ? void 0 : t.md);
1434
2123
  if (!Number.isFinite(n) || !Number.isFinite(r)) return null;
1435
2124
  const o = Math.min(n, r), s = Math.max(n, r);
1436
2125
  return s <= o ? null : { segStart: o, segEnd: s };
1437
2126
  }
1438
- function Xt(e, t, n) {
2127
+ function Dn(e, t, n) {
1439
2128
  let r = 0, o = 0;
1440
2129
  for (let i = 0; i < e.length; i += 1) {
1441
- const a = e[i], c = Number(a == null ? void 0 : a.from), l = Number(a == null ? void 0 : a.to), u = Number(a == null ? void 0 : a.value);
1442
- if (!Number.isFinite(c) || !Number.isFinite(l) || !Number.isFinite(u) || l <= c) continue;
1443
- const m = Math.max(t, c), d = Math.min(n, l) - m;
1444
- d <= 0 || (r += u * d, o += d);
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);
1445
2134
  }
1446
2135
  if (o <= 0) return null;
1447
2136
  const s = r / o;
1448
2137
  return Number.isFinite(s) ? s : null;
1449
2138
  }
1450
- function Wt(e, t) {
1451
- if (!Number.isFinite(e)) return new g.Color(Q);
1452
- if (Ze(e, t) < 0) return new g.Color(Q);
1453
- const r = Ht(e, t, Q);
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);
1454
2143
  return new g.Color(r);
1455
2144
  }
1456
- function Zt(e = {}) {
2145
+ function On(e = {}) {
1457
2146
  return {
1458
2147
  preserveView: !!e.preserveView,
1459
2148
  assayIntervalsByHole: e.assayIntervalsByHole || null,
1460
2149
  selectedAssayVariable: e.selectedAssayVariable || ""
1461
2150
  };
1462
2151
  }
1463
- function Kt(e, t) {
2152
+ function kn(e, t) {
1464
2153
  if (!e || !t) return [];
1465
2154
  const n = [];
1466
2155
  return Object.values(e).forEach((r) => {
@@ -1470,13 +2159,13 @@ function Kt(e, t) {
1470
2159
  });
1471
2160
  }), n;
1472
2161
  }
1473
- function Ae(e) {
2162
+ function Le(e) {
1474
2163
  return {
1475
2164
  holeId: e.id,
1476
2165
  project: e.project
1477
2166
  };
1478
2167
  }
1479
- class jn {
2168
+ class Or {
1480
2169
  constructor() {
1481
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;
1482
2171
  }
@@ -1490,14 +2179,14 @@ class jn {
1490
2179
  const s = new g.DirectionalLight(16777215, 0.6);
1491
2180
  s.position.set(10, 10, 5), this.scene.add(s);
1492
2181
  const i = new g.AxesHelper(20);
1493
- 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 = {
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 = {
1494
2183
  LEFT: g.MOUSE.PAN,
1495
2184
  MIDDLE: g.MOUSE.DOLLY,
1496
2185
  RIGHT: g.MOUSE.ROTATE
1497
2186
  }, this.controls.touches = {
1498
2187
  ONE: g.TOUCH.ROTATE,
1499
2188
  TWO: g.TOUCH.PAN
1500
- }, this.controls.maxPolarAngle = Math.PI, this.flyControls = new it(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 st(this.camera, this.renderer, {
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, {
1501
2190
  container: this.container,
1502
2191
  placement: "top-right",
1503
2192
  size: 110,
@@ -1506,10 +2195,10 @@ class jn {
1506
2195
  speed: 1.5
1507
2196
  }), this.gizmo.attachControls(this.controls), this._attachCanvasClickHandler();
1508
2197
  const a = () => {
1509
- var l;
2198
+ var c;
1510
2199
  this.frameId = requestAnimationFrame(a);
1511
- const c = this.clock.getDelta();
1512
- this.renderer.clear(), this.controlMode === "fly" && ((l = this.flyControls) != null && l.enabled) ? this.flyControls.update(c) : this.controls && this.controls.update(), this._emitViewChangeIfNeeded(), this.renderer.render(this.scene, this.camera), this.gizmo && this.gizmo.render();
2200
+ 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();
1513
2202
  };
1514
2203
  a();
1515
2204
  }
@@ -1517,23 +2206,23 @@ class jn {
1517
2206
  this.viewChangeHandler = typeof t == "function" ? t : null;
1518
2207
  }
1519
2208
  getViewState() {
1520
- return Qe(this);
2209
+ return Nt(this);
1521
2210
  }
1522
2211
  setViewState(t) {
1523
- return wt(this, t);
2212
+ return Mn(this, t);
1524
2213
  }
1525
2214
  _buildViewSignature(t) {
1526
- return Oe(t);
2215
+ return Ye(t);
1527
2216
  }
1528
2217
  _emitViewChangeIfNeeded() {
1529
- $t(this);
2218
+ In(this);
1530
2219
  }
1531
2220
  _attachCanvasClickHandler() {
1532
2221
  const t = this.renderer;
1533
2222
  t && (this.handleCanvasClick = (n) => {
1534
- var u, m, f, d;
2223
+ var l, d, m, f;
1535
2224
  if (n.button !== 0) return;
1536
- if ((u = this.gizmo) != null && u.domElement) {
2225
+ if ((l = this.gizmo) != null && l.domElement) {
1537
2226
  const p = this.gizmo.domElement.getBoundingClientRect();
1538
2227
  if (n.clientX >= p.left && n.clientX <= p.right && n.clientY >= p.top && n.clientY <= p.bottom)
1539
2228
  return;
@@ -1543,10 +2232,10 @@ class jn {
1543
2232
  const i = this.raycaster.intersectObjects(this.drillMeshes, !0);
1544
2233
  if (i.length === 0) return;
1545
2234
  let a = i[0].object;
1546
- for (; a && a.parent && !((m = a.userData) != null && m.holeId); )
2235
+ for (; a && a.parent && !((d = a.userData) != null && d.holeId); )
1547
2236
  a = a.parent;
1548
- const c = (f = a == null ? void 0 : a.userData) == null ? void 0 : f.holeId, l = (d = a == null ? void 0 : a.userData) == null ? void 0 : d.project;
1549
- c && this.drillholeClickHandler && this.drillholeClickHandler({ holeId: c, project: l });
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 });
1550
2239
  }, t.domElement.addEventListener("click", this.handleCanvasClick));
1551
2240
  }
1552
2241
  resize() {
@@ -1556,91 +2245,91 @@ class jn {
1556
2245
  }
1557
2246
  setBlocks(t, n, r) {
1558
2247
  if (!this.scene || (this._clearBlocks(), !t || !n || !r)) return;
1559
- let o = 1 / 0, s = -1 / 0, i = 1 / 0, a = -1 / 0, c = 1 / 0, l = -1 / 0;
1560
- t.forEach((u) => {
2248
+ let o = 1 / 0, s = -1 / 0, i = 1 / 0, a = -1 / 0, u = 1 / 0, c = -1 / 0;
2249
+ t.forEach((l) => {
1561
2250
  const {
1562
- center_x: m = 0,
1563
- center_y: f = 0,
1564
- center_z: d = 0,
2251
+ center_x: d = 0,
2252
+ center_y: m = 0,
2253
+ center_z: f = 0,
1565
2254
  size_x: p = 1,
1566
2255
  size_y: y = 1,
1567
2256
  size_z: h = 1
1568
- } = u;
1569
- o = Math.min(o, m - p / 2), s = Math.max(s, m + p / 2), i = Math.min(i, f - y / 2), a = Math.max(a, f + y / 2), c = Math.min(c, d - h / 2), l = Math.max(l, d + h / 2);
1570
- const A = new g.BoxGeometry(p, y, h), O = Mt(u[n], r, g), F = new g.MeshStandardMaterial({
1571
- color: O,
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,
1572
2261
  transparent: !0,
1573
2262
  opacity: 0.7,
1574
2263
  side: g.DoubleSide
1575
- }), D = new g.Mesh(A, F);
1576
- D.position.set(m, f, d), this.scene.add(D), this.blocks.push(D);
1577
- }), this.camera && this.controls && (this.lastBounds = { minX: o, maxX: s, minY: i, maxY: a, minZ: c, maxZ: l }, Me(this, { minX: o, maxX: s, minY: i, maxY: a, minZ: c, maxZ: l }));
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 }));
1578
2267
  }
1579
2268
  setDrillholes(t, n = {}) {
1580
2269
  if (!this.scene || (this._clearDrillholes(), !t || t.length === 0)) return;
1581
- const { preserveView: r, assayIntervalsByHole: o, selectedAssayVariable: s } = Zt(n), i = Kt(o, s), a = St(i);
1582
- let c = 1 / 0, l = -1 / 0, u = 1 / 0, m = -1 / 0, f = 1 / 0, d = -1 / 0;
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;
1583
2272
  const p = new g.Vector3(), y = new g.Vector3(0, 1, 0);
1584
- t.forEach((h, A) => {
1585
- const F = A * 137.5 % 360 / 360, D = new g.Color().setHSL(F, 0.75, 0.55), R = (h.points || []).map((N) => {
1586
- c = Math.min(c, N.x), l = Math.max(l, N.x), u = Math.min(u, N.y), m = Math.max(m, N.y), f = Math.min(f, N.z), d = Math.max(d, N.z);
1587
- const z = new g.Vector3(N.x, N.y, N.z);
1588
- return z.md = N.md, z;
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;
1589
2278
  });
1590
- if (R.length < 2) {
1591
- if (R.length === 1) {
1592
- const N = new g.SphereGeometry(5, 12, 12), z = new g.MeshLambertMaterial({
1593
- color: D,
1594
- emissive: D,
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,
1595
2284
  emissiveIntensity: 0.2
1596
- }), C = new g.Mesh(N, z);
1597
- C.position.copy(R[0]), C.userData = Ae(h), this.scene.add(C), this.drillLines.push(C), this.drillMeshes.push(C);
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);
1598
2287
  }
1599
2288
  return;
1600
2289
  }
1601
- const w = new g.Group();
1602
- w.userData = Ae(h);
1603
- const I = s ? this._resolveAssayIntervalsForHole(h, o) : [];
1604
- for (let N = 0; N < R.length - 1; N += 1) {
1605
- const z = R[N], C = R[N + 1], E = p.subVectors(C, z), b = E.length();
1606
- if (b <= 1e-3) continue;
1607
- const _ = 2.2, M = new g.CylinderGeometry(_, _, b, 6, 1, !1), L = this._getSegmentColor({
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();
2295
+ if (T <= 1e-3) continue;
2296
+ const B = 2.2, q = new g.CylinderGeometry(B, B, T, 6, 1, !0), M = this._getSegmentColor({
1608
2297
  selectedAssayVariable: s,
1609
- assayIntervals: I,
2298
+ assayIntervals: P,
1610
2299
  assayScale: a,
1611
2300
  holeId: h.id,
1612
2301
  segmentIndex: N,
1613
- p1: z,
1614
- p2: C
1615
- }), v = new g.MeshLambertMaterial({
1616
- color: L,
2302
+ p1: V,
2303
+ p2: Y
2304
+ }), _ = new g.MeshLambertMaterial({
2305
+ color: M,
1617
2306
  flatShading: !0,
1618
- emissive: L,
2307
+ emissive: M,
1619
2308
  emissiveIntensity: 0.15
1620
- }), T = new g.Mesh(M, v);
1621
- T.position.copy(z.clone().addScaledVector(E, 0.5)), T.quaternion.setFromUnitVectors(y, E.clone().normalize()), T.userData = Ae(h), w.add(T), this.drillMeshes.push(T);
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);
1622
2311
  }
1623
- this.scene.add(w), this.drillLines.push(w);
1624
- }), this.camera && this.controls && (this.lastBounds = { minX: c, maxX: l, minY: u, maxY: m, minZ: f, maxZ: d }, r || Me(this, { minX: c, maxX: l, minY: u, maxY: m, minZ: f, maxZ: d }));
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 }));
1625
2314
  }
1626
2315
  _getSegmentColor({ selectedAssayVariable: t, assayIntervals: n, assayScale: r, holeId: o, segmentIndex: s, p1: i, p2: a }) {
1627
2316
  if (!t)
1628
- return Qt(o, s);
2317
+ return wn(o, s);
1629
2318
  if (t === "__HAS_ASSAY__") {
1630
- if (!(n != null && n.length)) return new g.Color(Q);
1631
- const u = Re(i, a);
1632
- return u ? n.some((f) => {
1633
- const d = Number(f == null ? void 0 : f.from), p = Number(f == null ? void 0 : f.to);
1634
- if (!Number.isFinite(d) || !Number.isFinite(p)) return !1;
1635
- const y = Math.max(u.segStart, d);
1636
- return Math.min(u.segEnd, p) > y;
1637
- }) ? new g.Color("#ff8c42") : new g.Color(Q) : new g.Color(Q);
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);
1638
2327
  }
1639
- if (!(n != null && n.length)) return new g.Color(Q);
1640
- const c = Re(i, a);
1641
- if (!c) return new g.Color(Q);
1642
- const l = Xt(n, c.segStart, c.segEnd);
1643
- return Wt(l, r);
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);
1644
2333
  }
1645
2334
  _resolveAssayIntervalsForHole(t, n) {
1646
2335
  if (!n || !t) return [];
@@ -1648,7 +2337,7 @@ class jn {
1648
2337
  if (!r) return [];
1649
2338
  const o = n[r];
1650
2339
  if (Array.isArray(o) && o.length) return o;
1651
- const s = Jt(r);
2340
+ const s = Fn(r);
1652
2341
  if (s) {
1653
2342
  const i = n[s];
1654
2343
  if (Array.isArray(i) && i.length) return i;
@@ -1656,22 +2345,22 @@ class jn {
1656
2345
  return [];
1657
2346
  }
1658
2347
  _fitCameraToBounds({ minX: t, maxX: n, minY: r, maxY: o, minZ: s, maxZ: i }) {
1659
- Me(this, { 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 });
1660
2349
  }
1661
2350
  recenterCameraToOrigin(t = 1e3) {
1662
- jt(this, t);
2351
+ An(this, t);
1663
2352
  }
1664
2353
  lookDown(t = 2e3) {
1665
- Bt(this, t);
2354
+ En(this, t);
1666
2355
  }
1667
2356
  pan(t = 0, n = 0) {
1668
- Ut(this, t, n);
2357
+ Sn(this, t, n);
1669
2358
  }
1670
2359
  dolly(t = 1.1) {
1671
- Yt(this, t);
2360
+ vn(this, t);
1672
2361
  }
1673
2362
  focusOnLastBounds(t = 1.2) {
1674
- Gt(this, t);
2363
+ Pn(this, t);
1675
2364
  }
1676
2365
  _clearBlocks() {
1677
2366
  this.blocks.forEach((t) => {
@@ -1692,24 +2381,24 @@ class jn {
1692
2381
  this.drillholeClickHandler = t;
1693
2382
  }
1694
2383
  setControlMode(t = "orbit") {
1695
- qt(this, t);
2384
+ Tn(this, t);
1696
2385
  }
1697
2386
  }
1698
- function Jt(e) {
2387
+ function Fn(e) {
1699
2388
  return `${e ?? ""}`.trim().toLowerCase();
1700
2389
  }
1701
- function Qt(e, t) {
1702
- const n = `${e ?? ""}:${t ?? 0}`, r = en(n), o = (t ?? 0) % 14 / 14, s = (r * 0.15 + o * 0.85) % 1, i = new g.Color();
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();
1703
2392
  return i.setHSL(s, 1, 0.5), i;
1704
2393
  }
1705
- function en(e) {
2394
+ function Vn(e) {
1706
2395
  const t = `${e ?? ""}`;
1707
2396
  let n = 2166136261;
1708
2397
  for (let r = 0; r < t.length; r += 1)
1709
2398
  n ^= t.charCodeAt(r), n = Math.imul(n, 16777619);
1710
2399
  return (n >>> 0) / 4294967295;
1711
2400
  }
1712
- function Bn({
2401
+ function kr({
1713
2402
  controlMode: e = "orbit",
1714
2403
  onToggleFly: t = () => {
1715
2404
  },
@@ -1720,102 +2409,128 @@ function Bn({
1720
2409
  onFit: o = () => {
1721
2410
  }
1722
2411
  }) {
1723
- return /* @__PURE__ */ ae("div", { className: "baselode-3d-controls", children: [
1724
- /* @__PURE__ */ k("button", { type: "button", className: "ghost-button", onClick: n, children: "Recenter to (0,0,0)" }),
1725
- /* @__PURE__ */ k("button", { type: "button", className: "ghost-button", onClick: r, children: "Look down" }),
1726
- /* @__PURE__ */ k("button", { type: "button", className: "ghost-button", onClick: o, children: "Fit to scene" }),
1727
- /* @__PURE__ */ k("button", { type: "button", className: "ghost-button", onClick: t, children: e === "orbit" ? "Enable fly controls" : "Disable fly controls" })
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" })
1728
2417
  ] });
1729
2418
  }
1730
2419
  export {
1731
- Ft as ASSAY_COLOR_PALETTE_10,
1732
- Be as ASSAY_NON_VALUE_FIELDS,
1733
- j as AZIMUTH,
1734
- dn as BASELODE_DATA_MODEL_DRILL_ASSAY,
1735
- cn as BASELODE_DATA_MODEL_DRILL_COLLAR,
1736
- un as BASELODE_DATA_MODEL_DRILL_SURVEY,
1737
- Bn as Baselode3DControls,
1738
- jn as Baselode3DScene,
1739
- $e as CRS,
1740
- at as DEFAULT_COLUMN_MAP,
1741
- V as DEPTH,
1742
- B as DIP,
1743
- K as EASTING,
1744
- oe as ELEVATION,
1745
- It as ERROR_COLOR,
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,
1746
2443
  $ as FROM,
1747
- x as HOLE_ID,
1748
- q as LATITUDE,
1749
- X as LONGITUDE,
2444
+ Ge as HIDDEN_COLUMNS,
2445
+ b as HOLE_ID,
2446
+ Q as LATITUDE,
2447
+ ee as LONGITUDE,
1750
2448
  we as MID,
1751
- J as NORTHING,
1752
- He as NUMERIC_LINE_COLOR,
1753
- At as NUMERIC_MARKER_COLOR,
1754
- Z as PROJECT_ID,
1755
- H as TO,
1756
- Sn as TracePlot,
1757
- $n as annotationsFromIntervals,
1758
- Pn as assembleDataset,
1759
- Mn as attachAssayPositions,
1760
- xn as balancedTangentialDesurvey,
1761
- gt as buildAssayState,
1762
- St as buildEqualRangeColorScale,
1763
- Et as buildIntervalPoints,
1764
- Lt as buildPlotConfig,
1765
- Nn as buildTraces,
1766
- Oe as buildViewSignature,
1767
- Fn as calculatePropertyStats,
1768
- Tn as coerceNumeric,
1769
- Xe as deriveAssayProps,
1770
- _n as desurveyTraces,
1771
- Yt as dolly,
1772
- $t as emitViewChangeIfNeeded,
1773
- Ln as filterByProject,
1774
- Me as fitCameraToBounds,
1775
- Gt as focusOnLastBounds,
1776
- Mt as getColorForValue,
1777
- Ze as getEqualRangeBinIndex,
1778
- Ht as getEqualRangeColor,
1779
- Qe as getViewState,
1780
- Ve as holeHasData,
1781
- wn as intervalsAsTubes,
1782
- Dn as joinAssaysToTraces,
1783
- bn as loadAssayFile,
1784
- yt as loadAssayHole,
1785
- pt as loadAssayMetadata,
1786
- vn as loadAssays,
1787
- In as loadCollars,
1788
- En as loadSurveys,
1789
- De as loadTable,
1790
- hn as logDataInfo,
1791
- fn as logDataWarning,
1792
- Bt as lookDown,
1793
- _t as minimumCurvatureDesurvey,
1794
- yn as normalizeCsvRow,
1795
- fe as normalizeFieldName,
1796
- Ut as pan,
1797
- mt as parseAssayHole,
1798
- pn as parseAssayHoleIds,
1799
- dt as parseAssayHoleIdsWithAssays,
1800
- ft as parseAssaysCSV,
1801
- On as parseBlockModelCSV,
1802
- An as parseDrillholesCSV,
1803
- Cn as parseSurveyCSV,
1804
- gn as pickFirstPresent,
1805
- Hn as planView,
1806
- Vt as projectTraceToSection,
1807
- jt as recenterCameraToOrigin,
1808
- Ge as reorderHoleIds,
1809
- Vn as sectionView,
1810
- Rt as sectionWindow,
1811
- qt as setControlMode,
1812
- wt as setViewState,
1813
- ce as standardizeColumns,
1814
- mn as standardizeRowArray,
1815
- zn as tangentialDesurvey,
1816
- lt as toError,
1817
- Rn as tracesAsSegments,
1818
- kn as useDrillholeTraceGrid,
1819
- P as withDataErrorContext
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,
2534
+ w as withDataErrorContext
1820
2535
  };
1821
2536
  //# sourceMappingURL=baselode.js.map