@harpern/edu-modelhub-viewer-core 0.1.0-beta.3 → 0.1.0-beta.5

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { SpriteMaterial as V, CanvasTexture as E, Sprite as W, Vector3 as b, Raycaster as q, AmbientLight as Y, SpotLight as H, Color as T, DirectionalLight as X, Box3 as v } from "three";
2
- const C = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
3
- function _(e, t) {
1
+ import { SpriteMaterial as H, CanvasTexture as U, Sprite as Y, Vector3 as b, Raycaster as K, AmbientLight as X, SpotLight as Z, Color as R, DirectionalLight as Q, Box3 as A } from "three";
2
+ const F = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
3
+ function z(e, t) {
4
4
  const n = /* @__PURE__ */ new WeakSet(), o = [
5
5
  { value: e, path: "" }
6
6
  ], r = (i, s) => {
@@ -16,36 +16,36 @@ function _(e, t) {
16
16
  t(i, s, r);
17
17
  }
18
18
  }
19
- function K(e) {
19
+ function J(e) {
20
20
  const t = [];
21
- return _(e, (n, o, r) => {
21
+ return z(e, (n, o, r) => {
22
22
  for (const i of Object.keys(n)) {
23
23
  const s = o === "" ? i : `${o}.${i}`;
24
- C.has(i) ? t.push({ path: s, key: i }) : r(n[i], s);
24
+ F.has(i) ? t.push({ path: s, key: i }) : r(n[i], s);
25
25
  }
26
26
  }), t;
27
27
  }
28
- function Z(e) {
29
- return _(e, (t, n, o) => {
28
+ function ee(e) {
29
+ return z(e, (t, n, o) => {
30
30
  for (const r of Object.keys(t))
31
- C.has(r) ? delete t[r] : o(t[r], n);
31
+ F.has(r) ? delete t[r] : o(t[r], n);
32
32
  }), e;
33
33
  }
34
- const N = 1179937895, k = 2, Q = 1313821514, J = 21;
34
+ const E = 1179937895, k = 2, te = 1313821514, ne = 21;
35
35
  class g extends Error {
36
36
  constructor(t) {
37
37
  super(t), this.name = "GlbParseError";
38
38
  }
39
39
  }
40
- function ee(e) {
40
+ function oe(e) {
41
41
  return e instanceof ArrayBuffer ? new DataView(e) : new DataView(e.buffer, e.byteOffset, e.byteLength);
42
42
  }
43
- function te(e) {
43
+ function re(e) {
44
44
  return e === null ? "null" : Array.isArray(e) ? "an array" : typeof e;
45
45
  }
46
- function ne(e) {
47
- const t = ee(e);
48
- if (t.byteLength < J)
46
+ function ie(e) {
47
+ const t = oe(e);
48
+ if (t.byteLength < ne)
49
49
  throw new g(
50
50
  `Input too short to be a GLB file (${t.byteLength} bytes).`
51
51
  );
@@ -54,9 +54,9 @@ function ne(e) {
54
54
  !0
55
55
  /* littleEndian */
56
56
  );
57
- if (n !== N)
57
+ if (n !== E)
58
58
  throw new g(
59
- `Invalid GLB magic: expected 0x${N.toString(16)}, got 0x${n.toString(16)}.`
59
+ `Invalid GLB magic: expected 0x${E.toString(16)}, got 0x${n.toString(16)}.`
60
60
  );
61
61
  const o = t.getUint32(4, !0);
62
62
  if (o !== k)
@@ -71,7 +71,7 @@ function ne(e) {
71
71
  if (t.byteLength < 20)
72
72
  throw new g("GLB file truncated before first chunk header.");
73
73
  const i = t.getUint32(12, !0), s = t.getUint32(16, !0);
74
- if (s !== Q)
74
+ if (s !== te)
75
75
  throw new g(
76
76
  `First GLB chunk is not JSON (type 0x${s.toString(16)}).`
77
77
  );
@@ -98,34 +98,34 @@ function ne(e) {
98
98
  }
99
99
  if (a === null || typeof a != "object" || Array.isArray(a))
100
100
  throw new g(
101
- `GLB JSON chunk root must be an object, got ${te(a)}.`
101
+ `GLB JSON chunk root must be an object, got ${re(a)}.`
102
102
  );
103
103
  return a;
104
104
  }
105
- function oe(e) {
106
- const t = ne(e).extensions;
105
+ function se(e) {
106
+ const t = ie(e).extensions;
107
107
  if (t === null || typeof t != "object" || Array.isArray(t))
108
108
  return null;
109
109
  const n = t.EDU_modelhub;
110
- return n === void 0 ? null : Z(n);
110
+ return n === void 0 ? null : ee(n);
111
111
  }
112
- const re = /^[a-z][a-z0-9_]*$/, ie = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/, se = /^[a-z]{2}$/, ae = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
112
+ const ae = /^[a-z][a-z0-9_]*$/, ce = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/, ue = /^[a-z]{2}$/, le = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
113
113
  function d(e, t) {
114
114
  return { field: e, message: t, severity: "error" };
115
115
  }
116
116
  function $(e, t) {
117
117
  return { field: e, message: t, severity: "warning" };
118
118
  }
119
- function x(e) {
119
+ function w(e) {
120
120
  return typeof e == "object" && e !== null && !Array.isArray(e);
121
121
  }
122
- function w(e) {
122
+ function x(e) {
123
123
  return typeof e == "string" && e.trim() !== "";
124
124
  }
125
- function U(e) {
125
+ function G(e) {
126
126
  return typeof e == "number" && Number.isInteger(e) && e >= 0;
127
127
  }
128
- function h(e) {
128
+ function p(e) {
129
129
  if (e === void 0) return "undefined";
130
130
  let t;
131
131
  if (typeof e == "string")
@@ -140,16 +140,16 @@ function h(e) {
140
140
  }
141
141
  return t.length > 60 ? `${t.slice(0, 57)}...` : t;
142
142
  }
143
- function F(e) {
143
+ function P(e) {
144
144
  const t = [], n = e;
145
- if (!x(n))
146
- return [d("", `Payload must be a JSON object, got ${h(n)}.`)];
147
- ce(n, t), ue(n.specVersion, t), le(n.coordinateSpace, t), de(n.model, t);
148
- const o = pe(n.regions, t);
149
- return ye(n.annotations, o, t), t;
150
- }
151
- function ce(e, t) {
152
- for (const n of K(e))
145
+ if (!w(n))
146
+ return [d("", `Payload must be a JSON object, got ${p(n)}.`)];
147
+ de(n, t), fe(n.specVersion, t), me(n.coordinateSpace, t), pe(n.model, t);
148
+ const o = be(n.regions, t);
149
+ return xe(n.annotations, o, t), t;
150
+ }
151
+ function de(e, t) {
152
+ for (const n of J(e))
153
153
  t.push(
154
154
  d(
155
155
  n.path,
@@ -157,41 +157,41 @@ function ce(e, t) {
157
157
  )
158
158
  );
159
159
  }
160
- function ue(e, t) {
161
- (typeof e != "string" || !ae.test(e)) && t.push(
160
+ function fe(e, t) {
161
+ (typeof e != "string" || !le.test(e)) && t.push(
162
162
  d(
163
163
  "specVersion",
164
- `specVersion must be a semver string (e.g. "0.1.0"), got ${h(e)}.`
164
+ `specVersion must be a semver string (e.g. "0.1.0"), got ${p(e)}.`
165
165
  )
166
166
  );
167
167
  }
168
- function le(e, t) {
168
+ function me(e, t) {
169
169
  e !== void 0 && e !== "gltf" && e !== "blender" && t.push(
170
170
  d(
171
171
  "coordinateSpace",
172
- `coordinateSpace must be "gltf" or "blender" when present, got ${h(e)}.`
172
+ `coordinateSpace must be "gltf" or "blender" when present, got ${p(e)}.`
173
173
  )
174
174
  );
175
175
  }
176
- function de(e, t) {
177
- if (!x(e)) {
176
+ function pe(e, t) {
177
+ if (!w(e)) {
178
178
  t.push(
179
179
  d(
180
180
  "model",
181
- `model is required and must be an object, got ${h(e)}.`
181
+ `model is required and must be an object, got ${p(e)}.`
182
182
  )
183
183
  );
184
184
  return;
185
185
  }
186
186
  const n = e, o = n.title;
187
- w(o) || t.push(
187
+ x(o) || t.push(
188
188
  d(
189
189
  "model.title",
190
- `model.title is required and must be a non-empty string, got ${h(o)}.`
190
+ `model.title is required and must be a non-empty string, got ${p(o)}.`
191
191
  )
192
192
  );
193
193
  const r = n.altText;
194
- w(r) ? r.length > 300 && t.push(
194
+ x(r) ? r.length > 300 && t.push(
195
195
  d(
196
196
  "model.altText",
197
197
  `model.altText exceeds 300 characters (${r.length} chars).`
@@ -199,34 +199,34 @@ function de(e, t) {
199
199
  ) : t.push(
200
200
  d(
201
201
  "model.altText",
202
- `model.altText is required and must be a non-empty string, got ${h(r)}.`
202
+ `model.altText is required and must be a non-empty string, got ${p(r)}.`
203
203
  )
204
204
  );
205
205
  const i = n.language;
206
- i !== void 0 && (typeof i != "string" || !se.test(i)) && t.push(
206
+ i !== void 0 && (typeof i != "string" || !ue.test(i)) && t.push(
207
207
  $(
208
208
  "model.language",
209
- `model.language should be an ISO 639-1 two-letter code (e.g. "en"), got ${h(i)}.`
209
+ `model.language should be an ISO 639-1 two-letter code (e.g. "en"), got ${p(i)}.`
210
210
  )
211
- ), fe(n, t), me(n.source, t), he(n, t), w(n.longDescription) || t.push(
211
+ ), he(n, t), ge(n.source, t), ye(n, t), x(n.longDescription) || t.push(
212
212
  $("model.longDescription", "model.longDescription is recommended.")
213
213
  );
214
214
  }
215
- function fe(e, t) {
215
+ function he(e, t) {
216
216
  const n = ["CC0", "CC BY", "CC BY-SA", "All Rights Reserved"], o = e.license;
217
217
  o !== void 0 && (typeof o != "string" || !n.includes(o)) && t.push(
218
218
  d(
219
219
  "model.license",
220
- `model.license must be one of ${n.map((r) => `"${r}"`).join(", ")}, got ${h(o)}.`
220
+ `model.license must be one of ${n.map((r) => `"${r}"`).join(", ")}, got ${p(o)}.`
221
221
  )
222
- ), (o === "CC BY" || o === "CC BY-SA") && !w(e.attribution) && t.push(
222
+ ), (o === "CC BY" || o === "CC BY-SA") && !x(e.attribution) && t.push(
223
223
  $(
224
224
  "model.attribution",
225
225
  'model.attribution is recommended when license is "CC BY" or "CC BY-SA".'
226
226
  )
227
227
  );
228
228
  }
229
- function me(e, t) {
229
+ function ge(e, t) {
230
230
  if (e === void 0) return;
231
231
  const n = ["scan", "photogrammetry", "manual", "other"];
232
232
  if (typeof e != "string" || !n.includes(e)) {
@@ -234,44 +234,44 @@ function me(e, t) {
234
234
  t.push(
235
235
  d(
236
236
  "model.source",
237
- `model.source must be one of ${o}, got ${h(e)}.`
237
+ `model.source must be one of ${o}, got ${p(e)}.`
238
238
  )
239
239
  );
240
240
  }
241
241
  }
242
- function he(e, t) {
242
+ function ye(e, t) {
243
243
  for (const n of ["created", "modified"]) {
244
244
  const o = e[n];
245
- o !== void 0 && (typeof o != "string" || !ie.test(o)) && t.push(
245
+ o !== void 0 && (typeof o != "string" || !ce.test(o)) && t.push(
246
246
  $(
247
247
  `model.${n}`,
248
- `model.${n} should be ISO 8601 UTC (YYYY-MM-DDTHH:MM:SSZ), got ${h(o)}.`
248
+ `model.${n} should be ISO 8601 UTC (YYYY-MM-DDTHH:MM:SSZ), got ${p(o)}.`
249
249
  )
250
250
  );
251
251
  }
252
252
  }
253
- function pe(e, t) {
253
+ function be(e, t) {
254
254
  const n = /* @__PURE__ */ new Set();
255
255
  if (!Array.isArray(e) || e.length === 0)
256
256
  return t.push(d("regions", "At least one region is required.")), n;
257
257
  for (let o = 0; o < e.length; o++) {
258
258
  const r = e[o], i = `regions[${o}]`;
259
- if (!x(r)) {
259
+ if (!w(r)) {
260
260
  t.push(
261
- d(i, `${i} must be an object, got ${h(r)}.`)
261
+ d(i, `${i} must be an object, got ${p(r)}.`)
262
262
  );
263
263
  continue;
264
264
  }
265
- ge(r, i, n, t);
265
+ $e(r, i, n, t);
266
266
  }
267
267
  return n;
268
268
  }
269
- function ge(e, t, n, o) {
269
+ function $e(e, t, n, o) {
270
270
  const r = e.id;
271
- typeof r != "string" || !re.test(r) ? o.push(
271
+ typeof r != "string" || !ae.test(r) ? o.push(
272
272
  d(
273
273
  `${t}.id`,
274
- `${t}.id must be a non-empty snake_case string (lowercase letters, digits, underscores; must start with a letter), got ${h(r)}.`
274
+ `${t}.id must be a non-empty snake_case string (lowercase letters, digits, underscores; must start with a letter), got ${p(r)}.`
275
275
  )
276
276
  ) : n.has(r) ? o.push(
277
277
  d(`${t}.id`, `Duplicate region id "${r}" at ${t}.`)
@@ -280,18 +280,18 @@ function ge(e, t, n, o) {
280
280
  i !== void 0 && i !== "shown" && i !== "hidden" && o.push(
281
281
  d(
282
282
  `${t}.visibilityDefault`,
283
- `${t}.visibilityDefault must be "shown" or "hidden", got ${h(i)}.`
283
+ `${t}.visibilityDefault must be "shown" or "hidden", got ${p(i)}.`
284
284
  )
285
285
  );
286
286
  const s = e.order;
287
- s !== void 0 && !U(s) && o.push(
287
+ s !== void 0 && !G(s) && o.push(
288
288
  $(
289
289
  `${t}.order`,
290
- `${t}.order should be a non-negative integer, got ${h(s)}.`
290
+ `${t}.order should be a non-negative integer, got ${p(s)}.`
291
291
  )
292
292
  );
293
293
  }
294
- function ye(e, t, n) {
294
+ function xe(e, t, n) {
295
295
  if (!Array.isArray(e)) {
296
296
  n.push(d("annotations", "annotations must be an array."));
297
297
  return;
@@ -314,36 +314,36 @@ function ye(e, t, n) {
314
314
  };
315
315
  for (let r = 0; r < e.length; r++) {
316
316
  const i = e[r], s = `annotations[${r}]`;
317
- if (!x(i)) {
317
+ if (!w(i)) {
318
318
  n.push(
319
- d(s, `${s} must be an object, got ${h(i)}.`)
319
+ d(s, `${s} must be an object, got ${p(i)}.`)
320
320
  );
321
321
  continue;
322
322
  }
323
- be(i, s, o, n);
323
+ we(i, s, o, n);
324
324
  }
325
- ve(o.seenReadingOrders, n);
325
+ Me(o.seenReadingOrders, n);
326
326
  }
327
- function be(e, t, n, o) {
327
+ function we(e, t, n, o) {
328
328
  const r = e.id;
329
- w(r) ? n.seenAnnotationIds.has(r) ? o.push(
329
+ x(r) ? n.seenAnnotationIds.has(r) ? o.push(
330
330
  d(`${t}.id`, `Duplicate annotation id "${r}" at ${t}.`)
331
331
  ) : n.seenAnnotationIds.add(r) : o.push(
332
332
  d(
333
333
  `${t}.id`,
334
- `${t}.id is required and must be a non-empty string, got ${h(r)}.`
334
+ `${t}.id is required and must be a non-empty string, got ${p(r)}.`
335
335
  )
336
336
  );
337
337
  const i = e.regionId;
338
338
  i !== void 0 && i !== "" && (typeof i != "string" || !n.seenRegionIds.has(i)) && o.push(
339
339
  d(
340
340
  `${t}.regionId`,
341
- `${t}.regionId ${h(i)} does not match any region id.`
341
+ `${t}.regionId ${p(i)} does not match any region id.`
342
342
  )
343
- ), $e(e.readingOrder, t, n, o), we(e.anchor, t, o), xe(e.camera, t, o);
343
+ ), Ae(e.readingOrder, t, n, o), Se(e.anchor, t, o), ve(e.camera, t, o);
344
344
  }
345
- function $e(e, t, n, o) {
346
- e !== void 0 && (U(e) ? n.seenReadingOrders.has(e) ? o.push(
345
+ function Ae(e, t, n, o) {
346
+ e !== void 0 && (G(e) ? n.seenReadingOrders.has(e) ? o.push(
347
347
  d(
348
348
  `${t}.readingOrder`,
349
349
  `Duplicate readingOrder value ${e} at ${t}.`
@@ -351,16 +351,16 @@ function $e(e, t, n, o) {
351
351
  ) : n.seenReadingOrders.add(e) : o.push(
352
352
  d(
353
353
  `${t}.readingOrder`,
354
- `${t}.readingOrder must be a non-negative integer, got ${h(e)}.`
354
+ `${t}.readingOrder must be a non-negative integer, got ${p(e)}.`
355
355
  )
356
356
  ));
357
357
  }
358
- function we(e, t, n) {
359
- if (!x(e)) {
358
+ function Se(e, t, n) {
359
+ if (!w(e)) {
360
360
  n.push(
361
361
  d(
362
362
  `${t}.anchor`,
363
- `${t}.anchor is required and must be an object, got ${h(e)}.`
363
+ `${t}.anchor is required and must be an object, got ${p(e)}.`
364
364
  )
365
365
  );
366
366
  return;
@@ -374,7 +374,7 @@ function we(e, t, n) {
374
374
  `${t}.anchor.position must be an array of exactly 3 numbers for type "marker".`
375
375
  )
376
376
  );
377
- } else r === "node" || r === "primitive" || r === "aabb" ? w(o.ref) || n.push(
377
+ } else r === "node" || r === "primitive" || r === "aabb" ? x(o.ref) || n.push(
378
378
  d(
379
379
  `${t}.anchor.ref`,
380
380
  `${t}.anchor.ref is required for anchor type "${r}".`
@@ -382,17 +382,17 @@ function we(e, t, n) {
382
382
  ) : n.push(
383
383
  d(
384
384
  `${t}.anchor.type`,
385
- `${t}.anchor.type must be "marker", "node", "primitive", or "aabb", got ${h(r)}.`
385
+ `${t}.anchor.type must be "marker", "node", "primitive", or "aabb", got ${p(r)}.`
386
386
  )
387
387
  );
388
388
  }
389
- function xe(e, t, n) {
389
+ function ve(e, t, n) {
390
390
  if (e === void 0) return;
391
- if (!x(e)) {
391
+ if (!w(e)) {
392
392
  n.push(
393
393
  d(
394
394
  `${t}.camera`,
395
- `${t}.camera must be an object when present, got ${h(e)}.`
395
+ `${t}.camera must be an object when present, got ${p(e)}.`
396
396
  )
397
397
  );
398
398
  return;
@@ -410,11 +410,11 @@ function xe(e, t, n) {
410
410
  o !== void 0 && (typeof o != "number" || !(o > 0)) && n.push(
411
411
  d(
412
412
  `${t}.camera.fov`,
413
- `${t}.camera.fov must be a number greater than 0 when present, got ${h(o)}.`
413
+ `${t}.camera.fov must be a number greater than 0 when present, got ${p(o)}.`
414
414
  )
415
415
  );
416
416
  }
417
- function ve(e, t) {
417
+ function Me(e, t) {
418
418
  if (e.size === 0) return;
419
419
  const n = [...e].sort((o, r) => o - r);
420
420
  for (let o = 0; o < n.length; o++)
@@ -428,49 +428,49 @@ function ve(e, t) {
428
428
  break;
429
429
  }
430
430
  }
431
- class B extends Error {
431
+ class _ extends Error {
432
432
  constructor(t) {
433
433
  super(t), this.name = "AdaptError";
434
434
  }
435
435
  }
436
- class Ae {
436
+ class Ie {
437
437
  adapt(t) {
438
438
  var n, o;
439
439
  const r = t.model, i = ((n = r == null ? void 0 : r.title) == null ? void 0 : n.trim()) ?? "", s = ((o = r == null ? void 0 : r.altText) == null ? void 0 : o.trim()) ?? "";
440
440
  if (!i)
441
- throw new B("Sidecar is missing required field: model.title");
441
+ throw new _("Sidecar is missing required field: model.title");
442
442
  if (!s)
443
- throw new B("Sidecar is missing required field: model.altText");
443
+ throw new _("Sidecar is missing required field: model.altText");
444
444
  return t;
445
445
  }
446
446
  }
447
- const Se = new Ae();
448
- function Ie(e) {
449
- return Se.adapt(e);
447
+ const Te = new Ie();
448
+ function Oe(e) {
449
+ return Te.adapt(e);
450
450
  }
451
- function Me(e) {
451
+ function Ne(e) {
452
452
  return e.filter((t) => t.severity === "error");
453
453
  }
454
- function Oe(e) {
454
+ function Re(e) {
455
455
  const [t, n = ""] = e.split("?", 2);
456
456
  if (!/\.glb$/i.test(t)) return null;
457
457
  const o = t.replace(/\.glb$/i, ".modelhub.json");
458
458
  return n ? `${o}?${n}` : o;
459
459
  }
460
- function Ke(e, t) {
460
+ function nt(e, t) {
461
461
  var i;
462
462
  if (!e || e.startsWith("blob:") || e.startsWith("data:")) return "";
463
463
  const n = t ?? ((i = globalThis.location) == null ? void 0 : i.href), o = n ? new URL(e, n).href : e, r = o.lastIndexOf("/");
464
464
  return r === -1 ? "" : o.slice(0, r + 1);
465
465
  }
466
- async function Te(e, t = fetch) {
466
+ async function Ee(e, t = fetch) {
467
467
  const n = await t(e);
468
468
  if (!n.ok)
469
469
  throw new Error(`Failed to fetch ${e} (HTTP ${n.status}).`);
470
470
  return n.arrayBuffer();
471
471
  }
472
- function Ne(e) {
473
- const t = oe(e);
472
+ function ke(e) {
473
+ const t = se(e);
474
474
  if (!t)
475
475
  return {
476
476
  payload: null,
@@ -478,23 +478,23 @@ function Ne(e) {
478
478
  findings: [],
479
479
  problem: "This model carries no EDU_modelhub metadata."
480
480
  };
481
- const n = F(t);
481
+ const n = P(t);
482
482
  return { payload: t, source: "embedded", findings: n, problem: null };
483
483
  }
484
- async function Ze(e, t = {}) {
485
- const n = t.fetchImpl ?? fetch, o = await Te(e, n), r = Ne(o);
484
+ async function ot(e, t = {}) {
485
+ const n = t.fetchImpl ?? fetch, o = await Ee(e, n), r = ke(o);
486
486
  if (r.payload) return { ...r, bytes: o };
487
487
  if (t.sidecar === !1) return { ...r, bytes: o };
488
- const s = (t.sidecarUrl ?? Oe)(e);
488
+ const s = (t.sidecarUrl ?? Re)(e);
489
489
  if (!s) return { ...r, bytes: o };
490
490
  try {
491
491
  const c = await n(s);
492
492
  if (c.ok) {
493
- const l = Ie(await c.json());
493
+ const l = Oe(await c.json());
494
494
  return {
495
495
  payload: l,
496
496
  source: "sidecar",
497
- findings: F(l),
497
+ findings: P(l),
498
498
  problem: null,
499
499
  bytes: o
500
500
  };
@@ -509,34 +509,34 @@ async function Ze(e, t = {}) {
509
509
  bytes: o
510
510
  };
511
511
  }
512
- function Qe(e, t = "EDU_modelhub", n = console) {
512
+ function rt(e, t = "EDU_modelhub", n = console) {
513
513
  if (!(e != null && e.length)) return;
514
- const o = Me(e), r = e.filter((i) => i.severity !== "error");
514
+ const o = Ne(e), r = e.filter((i) => i.severity !== "error");
515
515
  o.length && n.warn(`${t}: ${o.length} validation error(s)`, o), r.length && n.info(
516
516
  `${t}: ${r.length} validation warning(s)`,
517
517
  r
518
518
  );
519
519
  }
520
- function Je(e) {
520
+ function it(e) {
521
521
  return (e == null ? void 0 : e.name) === "GlbParseError";
522
522
  }
523
- function G(e) {
523
+ function j(e) {
524
524
  return Array.isArray(e) && e.length === 3 && e.every((t) => typeof t == "number" && Number.isFinite(t));
525
525
  }
526
- function P(e) {
526
+ function V(e) {
527
527
  return e === "blender";
528
528
  }
529
- function A(e, t) {
530
- if (!G(e)) return null;
529
+ function S(e, t) {
530
+ if (!j(e)) return null;
531
531
  const [n, o, r] = e;
532
- return P(t) ? [n, r, -o] : [n, o, r];
532
+ return V(t) ? [n, r, -o] : [n, o, r];
533
533
  }
534
- function et(e, t) {
535
- if (!G(e)) return null;
534
+ function st(e, t) {
535
+ if (!j(e)) return null;
536
536
  const [n, o, r] = e;
537
- return P(t) ? [n, -r, o] : [n, o, r];
537
+ return V(t) ? [n, -r, o] : [n, o, r];
538
538
  }
539
- function ke(e) {
539
+ function _e(e) {
540
540
  if (!Array.isArray(e)) return [];
541
541
  const t = /* @__PURE__ */ new Set();
542
542
  return e.map((n, o) => {
@@ -546,13 +546,13 @@ function ke(e) {
546
546
  return t.add(s), { ...n ?? {}, id: s };
547
547
  });
548
548
  }
549
- function M(e) {
550
- const t = ke(e == null ? void 0 : e.annotations), n = (o) => Number.isFinite(o.readingOrder) ? o.readingOrder : Number.MAX_SAFE_INTEGER;
549
+ function I(e) {
550
+ const t = _e(e == null ? void 0 : e.annotations), n = (o) => Number.isFinite(o.readingOrder) ? o.readingOrder : Number.MAX_SAFE_INTEGER;
551
551
  return t.map((o, r) => ({ annotation: o, index: r })).sort(
552
552
  (o, r) => n(o.annotation) - n(r.annotation) || o.index - r.index
553
553
  ).map((o) => o.annotation);
554
554
  }
555
- function z(e) {
555
+ function W(e) {
556
556
  return (Array.isArray(e == null ? void 0 : e.regions) ? e.regions : []).map((n, o) => ({ region: n, index: o })).sort(
557
557
  (n, o) => (n.region.order ?? Number.MAX_SAFE_INTEGER) - (o.region.order ?? Number.MAX_SAFE_INTEGER) || n.index - o.index
558
558
  ).map((n) => n.region);
@@ -563,7 +563,7 @@ function Le(e) {
563
563
  const t = (n = e == null ? void 0 : e.description) == null ? void 0 : n.trim();
564
564
  return t ? !t.startsWith(Be) : !1;
565
565
  }
566
- function tt(e) {
566
+ function at(e) {
567
567
  return Array.isArray(e) ? e.filter(
568
568
  (t) => {
569
569
  var n;
@@ -571,11 +571,11 @@ function tt(e) {
571
571
  }
572
572
  ) : [];
573
573
  }
574
- function L(e) {
574
+ function B(e) {
575
575
  var t;
576
576
  return e ? ((t = e.label) == null ? void 0 : t.trim()) || e.id || "Unnamed region" : "Unknown region";
577
577
  }
578
- function nt(e) {
578
+ function ct(e) {
579
579
  if (!e) return [];
580
580
  const t = [], n = /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g;
581
581
  let o = 0, r;
@@ -583,8 +583,8 @@ function nt(e) {
583
583
  r.index > o && t.push({ text: e.slice(o, r.index) }), t.push({ text: r[1], url: r[2] }), o = r.index + r[0].length;
584
584
  return o < e.length && t.push({ text: e.slice(o) }), t.filter((i) => i.text.trim() || i.url);
585
585
  }
586
- function ot(e) {
587
- const t = e == null ? void 0 : e.coordinateSpace, n = z(e), o = M(e), r = new Map(n.map((a) => [a.id, a])), i = new Map(
586
+ function ut(e) {
587
+ const t = e == null ? void 0 : e.coordinateSpace, n = W(e), o = I(e), r = new Map(n.map((a) => [a.id, a])), i = new Map(
588
588
  o.map((a) => [a.id, a])
589
589
  ), s = /* @__PURE__ */ new Map();
590
590
  for (const a of o) {
@@ -597,15 +597,15 @@ function ot(e) {
597
597
  for (const a of o) {
598
598
  const u = a.anchor;
599
599
  if (!u || u.type !== "marker") continue;
600
- const f = A(u.position, t);
600
+ const f = S(u.position, t);
601
601
  if (!f) continue;
602
- const m = a.camera, p = m ? A(m.eye, t) : null, y = m ? A(m.target, t) : null;
602
+ const m = a.camera, h = m ? S(m.eye, t) : null, y = m ? S(m.target, t) : null;
603
603
  c.push({
604
604
  annotation: a,
605
605
  position: f,
606
- ...p && y ? {
606
+ ...h && y ? {
607
607
  camera: {
608
- eye: p,
608
+ eye: h,
609
609
  target: y,
610
610
  ...m != null && m.fov ? { fov: m.fov } : {}
611
611
  }
@@ -629,7 +629,7 @@ function ot(e) {
629
629
  function De(e) {
630
630
  return e.isMesh === !0;
631
631
  }
632
- function rt(e, t, n = []) {
632
+ function lt(e, t, n = []) {
633
633
  var l;
634
634
  const o = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
635
635
  for (const [a, u] of ((t == null ? void 0 : t.meshes) ?? []).entries())
@@ -644,39 +644,39 @@ function rt(e, t, n = []) {
644
644
  }
645
645
  const c = new Set(n.map((a) => a.id));
646
646
  return e.traverse((a) => {
647
- var p, y;
647
+ var h, y;
648
648
  if (!De(a)) return;
649
- const u = (y = (p = a.geometry) == null ? void 0 : p.userData) == null ? void 0 : y.modelhubRegionId, f = typeof u == "string" && u || i.get(a.name) || r.get(a.name) || (c.has(a.name) ? a.name : void 0);
649
+ const u = (y = (h = a.geometry) == null ? void 0 : h.userData) == null ? void 0 : y.modelhubRegionId, f = typeof u == "string" && u || i.get(a.name) || r.get(a.name) || (c.has(a.name) ? a.name : void 0);
650
650
  if (!f) return;
651
651
  const m = o.get(f);
652
652
  m ? m.push(a) : o.set(f, [a]), a.userData.modelhubOriginalMaterial === void 0 && (a.userData.modelhubOriginalMaterial = a.material);
653
653
  }), o;
654
654
  }
655
- function it(e) {
655
+ function dt(e) {
656
656
  const t = {};
657
657
  for (const [n, o] of e) t[n] = o.length;
658
658
  return t;
659
659
  }
660
- function Re(e, t, n) {
660
+ function Ce(e, t, n) {
661
661
  for (const o of e.get(t) ?? []) o.visible = n;
662
662
  }
663
- function st(e, t) {
663
+ function ft(e, t) {
664
664
  for (const n of e.keys())
665
- Re(e, n, !t.has(n));
665
+ Ce(e, n, !t.has(n));
666
666
  }
667
- function at(e, t, n) {
667
+ function mt(e, t, n) {
668
668
  for (const o of e.get(t) ?? []) o.material = n;
669
669
  }
670
- function ct(e, t) {
670
+ function pt(e, t) {
671
671
  for (const n of e.get(t) ?? []) {
672
672
  const o = n.userData.modelhubOriginalMaterial;
673
673
  o && (n.material = o);
674
674
  }
675
675
  }
676
- const Ee = "#2196f3", ut = "#ff5722";
677
- function j(e, t = {}) {
676
+ const Ue = "#2196f3", ht = "#ff5722";
677
+ function q(e, t = {}) {
678
678
  const {
679
- fill: n = Ee,
679
+ fill: n = Ue,
680
680
  text: o = "#ffffff",
681
681
  textStroke: r = "rgba(0, 0, 0, 0.45)"
682
682
  } = t, i = 256, s = document.createElement("canvas");
@@ -684,68 +684,102 @@ function j(e, t = {}) {
684
684
  const c = s.getContext("2d");
685
685
  return c && (c.beginPath(), c.arc(i / 2, i / 2, i / 2 - 4, 0, Math.PI * 2), c.fillStyle = n, c.fill(), c.strokeStyle = "#ffffff", c.lineWidth = 8, c.stroke(), c.fillStyle = o, c.strokeStyle = r, c.lineWidth = 10, c.font = "bold 132px Arial, sans-serif", c.textAlign = "center", c.textBaseline = "middle", c.strokeText(String(e), i / 2, i / 2), c.fillText(String(e), i / 2, i / 2)), s;
686
686
  }
687
- function Ce(e, t = 0.2, n) {
688
- const o = new V({
689
- map: new E(j(e, n)),
687
+ function Fe(e, t = T, n) {
688
+ const o = new H({
689
+ map: new U(q(e, n)),
690
690
  transparent: !0,
691
691
  depthTest: !1
692
- }), r = new W(o);
692
+ }), r = new Y(o);
693
693
  return r.scale.set(t, t, 1), r.renderOrder = 999, r;
694
694
  }
695
- function lt(e, t, n) {
695
+ function gt(e, t, n) {
696
696
  var r;
697
697
  const o = e.material;
698
- (r = o.map) == null || r.dispose(), o.map = new E(j(t, { fill: n })), o.needsUpdate = !0;
698
+ (r = o.map) == null || r.dispose(), o.map = new U(q(t, { fill: n })), o.needsUpdate = !0;
699
699
  }
700
- function dt(e, t, n = 0.2, o) {
700
+ function yt(e, t, n = T, o) {
701
701
  return t.map((r, i) => {
702
- const s = Ce(i + 1, n, o);
702
+ const s = Fe(i + 1, n, o);
703
703
  return s.position.set(...r.position), s.name = `modelhub_marker_${r.annotation.id}`, s.userData.annotationId = r.annotation.id, s.userData.displayNumber = i + 1, e.add(s), s;
704
704
  });
705
705
  }
706
- function ft(e) {
706
+ const L = Object.freeze({
707
+ min: 0.5,
708
+ max: 2,
709
+ step: 0.1,
710
+ default: 1
711
+ }), T = 0.2, ze = 0.3;
712
+ function O(e) {
713
+ let t = Number.NaN;
714
+ if (typeof e == "number" ? t = e : typeof e == "string" && e.trim() !== "" && (t = Number(e)), !Number.isFinite(t)) return L.default;
715
+ const { min: n, max: o, step: r } = L, i = Number((Math.round(t / r) * r).toFixed(6));
716
+ return Math.min(o, Math.max(n, i));
717
+ }
718
+ function bt(e) {
719
+ return `${O(e).toFixed(1)} times`;
720
+ }
721
+ function $t(e, t, n = {}) {
722
+ const o = O(t), {
723
+ base: r = T,
724
+ activeBase: i = ze,
725
+ activeId: s = null
726
+ } = n;
727
+ for (const c of e) {
728
+ const a = (s !== null && c.userData.annotationId === s ? i : r) * o;
729
+ c.scale.set(a, a, 1);
730
+ }
731
+ }
732
+ function xt(e) {
707
733
  const { camera: t, model: n, anchors: o, width: r, height: i, isOccluded: s } = e, c = e.referenceDistance ?? 1, l = new b(), a = {};
708
734
  n.updateMatrixWorld();
709
735
  for (const u of o) {
710
736
  l.set(...u.position).applyMatrix4(n.matrixWorld);
711
- const f = l.distanceTo(t.position), m = s ? s(l, f) : !1, p = l.clone().project(t);
737
+ const f = l.distanceTo(t.position), m = s ? s(l, f) : !1, h = l.clone().project(t);
712
738
  a[u.annotation.id] = {
713
- x: (p.x * 0.5 + 0.5) * r,
714
- y: (-p.y * 0.5 + 0.5) * i,
739
+ x: (h.x * 0.5 + 0.5) * r,
740
+ y: (-h.y * 0.5 + 0.5) * i,
715
741
  scale: Math.min(
716
742
  1.6,
717
743
  Math.max(0.55, c / Math.max(f, 1e-3))
718
744
  ),
719
- zIndex: Math.max(1, Math.round((1 - p.z) * 1e5)) + (m ? 0 : 2e5),
720
- inView: p.z < 1 && p.x > -1.05 && p.x < 1.05 && p.y > -1.05 && p.y < 1.05,
745
+ zIndex: Math.max(1, Math.round((1 - h.z) * 1e5)) + (m ? 0 : 2e5),
746
+ inView: h.z < 1 && h.x > -1.05 && h.x < 1.05 && h.y > -1.05 && h.y < 1.05,
721
747
  occluded: m
722
748
  };
723
749
  }
724
750
  return a;
725
751
  }
726
- const _e = 0.03, Ue = {
752
+ const Ge = 1.65, Pe = 0.8;
753
+ function wt(e, t, n = {}) {
754
+ const o = O(t) * e;
755
+ return {
756
+ diameter: (n.diameter ?? Ge) * o,
757
+ fontSize: (n.fontSize ?? Pe) * o
758
+ };
759
+ }
760
+ const je = 0.03, Ve = {
727
761
  enabled: !1,
728
762
  isOccluded: () => !1,
729
763
  dispose: () => {
730
764
  }
731
765
  };
732
- async function mt(e) {
766
+ async function At(e) {
733
767
  var i;
734
768
  let t = [], n = [];
735
769
  if (e.traverse((s) => {
736
770
  if (!s.isMesh) return;
737
771
  const c = s.geometry;
738
772
  c != null && c.computeBoundsTree && (t.push(c), n.push(s));
739
- }), !t.length) return Ue;
773
+ }), !t.length) return Ve;
740
774
  for (const s of t)
741
- s.boundsTree || (i = s.computeBoundsTree) == null || i.call(s, { maxLeafTris: 8 });
742
- const o = new q();
775
+ s.boundsTree || (i = s.computeBoundsTree) == null || i.call(s);
776
+ const o = new K();
743
777
  o.firstHitOnly = !0;
744
778
  const r = new b();
745
779
  return {
746
780
  enabled: !0,
747
781
  isOccluded(s, c, l) {
748
- return r.subVectors(c, s.position).normalize(), o.set(s.position, r), o.near = 0, o.far = Math.max(0, l - _e), o.camera = s, o.intersectObjects(n, !1).length > 0;
782
+ return r.subVectors(c, s.position).normalize(), o.set(s.position, r), o.near = 0, o.far = Math.max(0, l - je), o.camera = s, o.intersectObjects(n, !1).length > 0;
749
783
  },
750
784
  dispose() {
751
785
  var s;
@@ -754,7 +788,7 @@ async function mt(e) {
754
788
  }
755
789
  };
756
790
  }
757
- const I = {
791
+ const M = {
758
792
  headlight: {
759
793
  ambient: 0.7,
760
794
  lights: [
@@ -811,27 +845,27 @@ const I = {
811
845
  { color: [0.42, 0.74, 1], intensity: 0.25, position: [7.23, 6.78, 1.29] }
812
846
  ]
813
847
  }
814
- }, Fe = "headlight";
815
- function ht() {
816
- return Object.keys(I);
848
+ }, We = "headlight";
849
+ function St() {
850
+ return Object.keys(M);
817
851
  }
818
- function Ge(e) {
852
+ function qe(e) {
819
853
  var t;
820
854
  (t = e.parent) == null || t.remove(e);
821
855
  }
822
- function pt(e) {
856
+ function vt(e) {
823
857
  var c;
824
858
  const { scene: t, camera: n, exposure: o = 1 } = e;
825
859
  (c = e.previous) == null || c.remove();
826
- const r = I[e.preset ?? ""] ?? I[Fe], i = [], s = new Y(16777215, r.ambient * o);
860
+ const r = M[e.preset ?? ""] ?? M[We], i = [], s = new X(16777215, r.ambient * o);
827
861
  t.add(s), i.push(s);
828
862
  for (const l of r.lights) {
829
863
  let a;
830
864
  if (l.spot) {
831
- const f = new H(new T(...l.color));
865
+ const f = new Z(new R(...l.color));
832
866
  f.angle = 0.5, f.penumbra = 0.9, f.decay = 0, a = f;
833
867
  } else
834
- a = new X(new T(...l.color));
868
+ a = new Q(new R(...l.color));
835
869
  a.intensity = l.intensity, a.position.set(...l.position);
836
870
  const u = a.target;
837
871
  l.attach ? (u == null || u.position.set(0, 0, l.spot ? -1 : 0), n.add(a), u && n.add(u)) : (t.add(a), u && t.add(u)), i.push(a), u && i.push(u);
@@ -839,56 +873,56 @@ function pt(e) {
839
873
  return {
840
874
  lights: i,
841
875
  remove() {
842
- for (const l of i) Ge(l);
876
+ for (const l of i) qe(l);
843
877
  i.length = 0;
844
878
  }
845
879
  };
846
880
  }
847
- const S = [
881
+ const v = [
848
882
  { id: "white", label: "White", hex: "#ffffff", light: !0 },
849
883
  { id: "light-grey", label: "Light gray", hex: "#d4d4d4", light: !0 },
850
884
  { id: "medium-grey", label: "Medium gray", hex: "#808080", light: !1 },
851
885
  { id: "dark-grey", label: "Dark gray", hex: "#252525", light: !1 },
852
886
  { id: "black", label: "Black", hex: "#000000", light: !1 }
853
- ], Pe = "dark-grey";
854
- function ze(e) {
887
+ ], He = "dark-grey";
888
+ function Ye(e) {
855
889
  if (typeof e != "string") return "";
856
890
  const t = e.trim().replace(/^#/, "");
857
891
  return /^[0-9a-f]{6}$/i.test(t) ? `#${t.toLowerCase()}` : /^[0-9a-f]{3}$/i.test(t) ? `#${[...t].map((n) => n + n).join("").toLowerCase()}` : "";
858
892
  }
859
- function je(e) {
893
+ function Ke(e) {
860
894
  const t = Number.parseInt(e.replace("#", ""), 16);
861
895
  return Number.isFinite(t) ? (0.299 * (t >> 16 & 255) + 0.587 * (t >> 8 & 255) + 0.114 * (t & 255)) / 255 : 0;
862
896
  }
863
- function gt(e, t) {
864
- const n = ze(t);
897
+ function Mt(e, t) {
898
+ const n = Ye(t);
865
899
  return n ? {
866
900
  id: "custom",
867
901
  label: "Custom",
868
902
  hex: n,
869
- light: je(n) > 0.5
870
- } : S.find((o) => o.id === e) ?? S.find((o) => o.id === Pe) ?? S[0];
903
+ light: Ke(n) > 0.5
904
+ } : v.find((o) => o.id === e) ?? v.find((o) => o.id === He) ?? v[0];
871
905
  }
872
- const Ve = 2;
906
+ const Xe = 2;
873
907
  function D(e) {
874
908
  e.updateMatrixWorld(!0);
875
- const t = new v(), n = new v();
909
+ const t = new A(), n = new A();
876
910
  return e.traverse((o) => {
877
911
  const r = o, i = o;
878
912
  r.isSkinnedMesh ? (r.computeBoundingBox(), r.boundingBox && (n.copy(r.boundingBox).applyMatrix4(r.matrixWorld), t.union(n))) : i.isMesh && i.geometry && (i.geometry.boundingBox || i.geometry.computeBoundingBox(), i.geometry.boundingBox && (n.copy(i.geometry.boundingBox).applyMatrix4(i.matrixWorld), t.union(n)));
879
- }), t.isEmpty() ? new v().setFromObject(e) : t;
913
+ }), t.isEmpty() ? new A().setFromObject(e) : t;
880
914
  }
881
- function yt(e, t = Ve) {
915
+ function It(e, t = Xe) {
882
916
  const o = D(e).getSize(new b()), r = Math.max(o.x, o.y, o.z) || 1, i = t / r;
883
917
  e.scale.multiplyScalar(i);
884
918
  const s = D(e);
885
919
  return e.position.sub(s.getCenter(new b())), i;
886
920
  }
887
- function bt(e, t = 1.3) {
921
+ function Tt(e, t = 1.3) {
888
922
  return t / Math.tan(e * Math.PI / 360);
889
923
  }
890
- const We = 0.5, qe = 1.5;
891
- function $t(e, t, n = {}) {
924
+ const Ze = 0.5, Qe = 1.5;
925
+ function Ot(e, t, n = {}) {
892
926
  t.updateMatrixWorld();
893
927
  const o = new b(...e.position).applyMatrix4(
894
928
  t.matrixWorld
@@ -909,22 +943,22 @@ function $t(e, t, n = {}) {
909
943
  }
910
944
  const r = n.outward ?? !0, i = new b(o.x, 0, o.z);
911
945
  i.lengthSq() < 1e-8 && i.set(0, 0, 1), i.normalize();
912
- const s = r ? -(n.outwardDistance ?? We) : n.inwardDistance ?? qe, c = o.clone().addScaledVector(i, s);
946
+ const s = r ? -(n.outwardDistance ?? Ze) : n.inwardDistance ?? Qe, c = o.clone().addScaledVector(i, s);
913
947
  return c.y = o.y, { position: c, target: o };
914
948
  }
915
- const Ye = { cancel: () => {
949
+ const Je = { cancel: () => {
916
950
  } };
917
- function wt(e) {
951
+ function Nt(e) {
918
952
  const { camera: t, controls: n, to: o, onFrame: r, onDone: i } = e, s = () => {
919
953
  r == null || r(), i == null || i();
920
954
  };
921
955
  if (e.reducedMotion)
922
- return t.position.copy(o.position), n.target.copy(o.target), n.update(), s(), Ye;
956
+ return t.position.copy(o.position), n.target.copy(o.target), n.update(), s(), Je;
923
957
  const c = e.durationMs ?? 900, l = t.position.clone(), a = n.target.clone(), u = performance.now();
924
958
  let f = null;
925
- const m = (p) => {
926
- const y = Math.min((p - u) / c, 1), O = y * (2 - y);
927
- t.position.lerpVectors(l, o.position, O), n.target.lerpVectors(a, o.target, O), n.update(), r == null || r(), y < 1 ? f = requestAnimationFrame(m) : (f = null, i == null || i());
959
+ const m = (h) => {
960
+ const y = Math.min((h - u) / c, 1), N = y * (2 - y);
961
+ t.position.lerpVectors(l, o.position, N), n.target.lerpVectors(a, o.target, N), n.update(), r == null || r(), y < 1 ? f = requestAnimationFrame(m) : (f = null, i == null || i());
928
962
  };
929
963
  return f = requestAnimationFrame(m), {
930
964
  cancel() {
@@ -932,26 +966,26 @@ function wt(e) {
932
966
  }
933
967
  };
934
968
  }
935
- function xt(e, t, n) {
969
+ function Rt(e, t, n) {
936
970
  const o = t || n;
937
971
  e.fov !== o && (e.fov = o, e.updateProjectionMatrix());
938
972
  }
939
- const He = 500;
940
- function vt(e) {
973
+ const et = 500;
974
+ function Et(e) {
941
975
  var r, i, s;
942
976
  if (!e)
943
977
  return "Model loaded, but it carries no educational metadata.";
944
978
  const t = [];
945
979
  (r = e.model) != null && r.title && t.push(`${e.model.title} loaded`), (i = e.model) != null && i.altText && t.push(e.model.altText);
946
- const n = ((s = e.regions) == null ? void 0 : s.length) ?? 0, o = M(e).length;
980
+ const n = ((s = e.regions) == null ? void 0 : s.length) ?? 0, o = I(e).length;
947
981
  return n && t.push(`${n} labeled ${n === 1 ? "region" : "regions"}`), o && t.push(
948
982
  `${o} ${o === 1 ? "annotation" : "annotations"}`
949
983
  ), t.map((c) => c.replace(/\.$/, "")).join(". ") + ".";
950
984
  }
951
- function At(e, t, n) {
985
+ function kt(e, t, n) {
952
986
  return `Annotation ${t + 1} of ${n}: ${e || "Untitled"}.`;
953
987
  }
954
- function St(e, t = He, n = () => Date.now()) {
988
+ function _t(e, t = et, n = () => Date.now()) {
955
989
  let o = -1 / 0, r = null, i = null;
956
990
  const s = (a) => {
957
991
  o = n(), r = null, e(a);
@@ -969,23 +1003,23 @@ function St(e, t = He, n = () => Date.now()) {
969
1003
  i && (clearTimeout(i), i = null), r !== null && s(r);
970
1004
  } };
971
1005
  }
972
- function R(e, t) {
1006
+ function C(e, t) {
973
1007
  return `## ${e}
974
1008
  ${t}
975
1009
 
976
1010
  `;
977
1011
  }
978
- function It(e, t = {}) {
979
- const n = e.model ?? {}, o = z(e), r = M(e);
1012
+ function Bt(e, t = {}) {
1013
+ const n = e.model ?? {}, o = W(e), r = I(e);
980
1014
  let i = `# ${n.title || "Untitled model"}
981
1015
 
982
1016
  `;
983
- if (n.altText && (i += R(t.summaryHeading ?? "Summary", n.altText)), n.longDescription && (i += R("Full description", n.longDescription)), o.length) {
1017
+ if (n.altText && (i += C(t.summaryHeading ?? "Summary", n.altText)), n.longDescription && (i += C("Full description", n.longDescription)), o.length) {
984
1018
  i += `## Regions (${o.length})
985
1019
 
986
1020
  `;
987
1021
  for (const s of o)
988
- i += `### ${L(s)}
1022
+ i += `### ${B(s)}
989
1023
  ${s.description || "No description."}
990
1024
 
991
1025
  `;
@@ -993,7 +1027,7 @@ ${s.description || "No description."}
993
1027
  return r.length && (i += `## Annotations (${r.length})
994
1028
 
995
1029
  `, r.forEach((s, c) => {
996
- const l = s.regionId ? ` (${L(o.find((u) => u.id === s.regionId))})` : "", a = `${c + 1}. ${s.title || "Untitled"}${l}`;
1030
+ const l = s.regionId ? ` (${B(o.find((u) => u.id === s.regionId))})` : "", a = `${c + 1}. ${s.title || "Untitled"}${l}`;
997
1031
  i += `### ${a}
998
1032
  ${s.body || "No description."}
999
1033
 
@@ -1005,11 +1039,11 @@ ${s.body || "No description."}
1005
1039
  `, i += `- **Source:** ${n.source || "Not specified"}
1006
1040
  `, i;
1007
1041
  }
1008
- function Mt(e) {
1042
+ function Lt(e) {
1009
1043
  var n;
1010
1044
  return `${(((n = e.model) == null ? void 0 : n.title) || "model").trim().replace(/[^\w\-. ]+/g, "").replace(/\s+/g, "_") || "model"}_transcript.md`;
1011
1045
  }
1012
- function Ot(e) {
1046
+ function Dt(e) {
1013
1047
  e && e.traverse((t) => {
1014
1048
  var i, s;
1015
1049
  const n = t, o = n.geometry;
@@ -1028,64 +1062,73 @@ function Ot(e) {
1028
1062
  });
1029
1063
  }
1030
1064
  export {
1031
- S as BACKGROUND_OPTIONS,
1032
- He as CAMERA_ANNOUNCE_INTERVAL,
1033
- Pe as DEFAULT_BACKGROUND,
1034
- Fe as DEFAULT_LIGHTING,
1035
- I as LIGHTING_PRESETS,
1036
- Ee as MARKER_FILL,
1037
- ut as MARKER_FILL_ACTIVE,
1038
- Ve as NORMALIZED_SIZE,
1039
- _e as OCCLUSION_BIAS,
1040
- qe as TOUR_DISTANCE_INWARD,
1041
- We as TOUR_DISTANCE_OUTWARD,
1042
- At as annotationSummary,
1043
- M as annotationsInReadingOrder,
1044
- xt as applyFov,
1045
- pt as applyLighting,
1046
- st as applyVisibilityDefaults,
1047
- rt as buildRegionMeshMap,
1048
- It as buildTranscript,
1049
- ct as clearRegionHighlight,
1065
+ v as BACKGROUND_OPTIONS,
1066
+ et as CAMERA_ANNOUNCE_INTERVAL,
1067
+ He as DEFAULT_BACKGROUND,
1068
+ We as DEFAULT_LIGHTING,
1069
+ M as LIGHTING_PRESETS,
1070
+ Ue as MARKER_FILL,
1071
+ ht as MARKER_FILL_ACTIVE,
1072
+ Ge as MARKER_HTML_DIAMETER_REM,
1073
+ Pe as MARKER_HTML_FONT_REM,
1074
+ L as MARKER_SIZE,
1075
+ T as MARKER_SPRITE_SCALE,
1076
+ ze as MARKER_SPRITE_SCALE_ACTIVE,
1077
+ Xe as NORMALIZED_SIZE,
1078
+ je as OCCLUSION_BIAS,
1079
+ Qe as TOUR_DISTANCE_INWARD,
1080
+ Ze as TOUR_DISTANCE_OUTWARD,
1081
+ kt as annotationSummary,
1082
+ I as annotationsInReadingOrder,
1083
+ Rt as applyFov,
1084
+ vt as applyLighting,
1085
+ $t as applyMarkerSpriteSize,
1086
+ ft as applyVisibilityDefaults,
1087
+ lt as buildRegionMeshMap,
1088
+ Bt as buildTranscript,
1089
+ O as clampMarkerSize,
1090
+ pt as clearRegionHighlight,
1050
1091
  D as computeDisplayBox,
1051
- $t as computeTourPlacement,
1052
- St as createAnnouncer,
1053
- Ce as createMarkerSprite,
1054
- dt as createMarkerSprites,
1055
- mt as createOcclusionIndex,
1056
- Ot as disposeSceneGraph,
1057
- bt as distanceForFov,
1058
- j as drawMarkerCanvas,
1059
- Me as errorsOf,
1060
- Te as fetchBytes,
1061
- wt as flyCamera,
1062
- yt as frameModel,
1063
- et as fromViewerPosition,
1064
- at as highlightRegion,
1092
+ Ot as computeTourPlacement,
1093
+ _t as createAnnouncer,
1094
+ Fe as createMarkerSprite,
1095
+ yt as createMarkerSprites,
1096
+ At as createOcclusionIndex,
1097
+ Dt as disposeSceneGraph,
1098
+ Tt as distanceForFov,
1099
+ q as drawMarkerCanvas,
1100
+ Ne as errorsOf,
1101
+ Ee as fetchBytes,
1102
+ Nt as flyCamera,
1103
+ It as frameModel,
1104
+ st as fromViewerPosition,
1105
+ mt as highlightRegion,
1065
1106
  Le as isAuthoredRegion,
1066
- Je as isGlbParseError,
1067
- G as isVec3,
1068
- ht as lightingPresetNames,
1069
- Ze as loadModel,
1070
- Qe as logFindings,
1071
- je as luminance,
1072
- vt as modelSummary,
1073
- P as needsConversion,
1074
- ke as normalizeAnnotationIds,
1075
- ze as normalizeHexColor,
1076
- ot as normalizeModel,
1077
- nt as parseBodySegments,
1078
- ft as projectMarkers,
1079
- Ne as readEmbedded,
1080
- tt as readableRegions,
1081
- it as regionBindingCounts,
1082
- L as regionLabel,
1083
- z as regionsInOrder,
1084
- gt as resolveBackground,
1085
- Ke as resourcePathFor,
1086
- lt as setMarkerSpriteColor,
1087
- Re as setRegionVisible,
1088
- Oe as sidecarUrlFor,
1089
- A as toViewerPosition,
1090
- Mt as transcriptFileName
1107
+ it as isGlbParseError,
1108
+ j as isVec3,
1109
+ St as lightingPresetNames,
1110
+ ot as loadModel,
1111
+ rt as logFindings,
1112
+ Ke as luminance,
1113
+ bt as markerSizeText,
1114
+ Et as modelSummary,
1115
+ V as needsConversion,
1116
+ _e as normalizeAnnotationIds,
1117
+ Ye as normalizeHexColor,
1118
+ ut as normalizeModel,
1119
+ ct as parseBodySegments,
1120
+ xt as projectMarkers,
1121
+ wt as projectedMarkerSize,
1122
+ ke as readEmbedded,
1123
+ at as readableRegions,
1124
+ dt as regionBindingCounts,
1125
+ B as regionLabel,
1126
+ W as regionsInOrder,
1127
+ Mt as resolveBackground,
1128
+ nt as resourcePathFor,
1129
+ gt as setMarkerSpriteColor,
1130
+ Ce as setRegionVisible,
1131
+ Re as sidecarUrlFor,
1132
+ S as toViewerPosition,
1133
+ Lt as transcriptFileName
1091
1134
  };