@nika-js/onlymap 0.6.0 → 0.6.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/README.md +39 -14
  3. package/THIRD-PARTY-LICENSES.md +27 -0
  4. package/dist/{LercDecode.es-fbo6h5rt.js → LercDecode.es-BOJJr6Gx.js} +1 -1
  5. package/dist/{basemap-CprSan9q.js → basemap-BofXgXxy.js} +13 -3
  6. package/dist/basemap.d.ts +10 -1
  7. package/dist/cityjson-D_V5GY8b.js +332 -0
  8. package/dist/clip-box-controller.d.ts +94 -0
  9. package/dist/clip-box.d.ts +109 -0
  10. package/dist/crs-Ciu7Xs7a.js +108 -0
  11. package/dist/crs.d.ts +50 -0
  12. package/dist/ctx.d.ts +8 -1
  13. package/dist/data-layer.d.ts +11 -3
  14. package/dist/draw-controller.d.ts +75 -1
  15. package/dist/draw.d.ts +22 -4
  16. package/dist/elements/om-map.d.ts +45 -2
  17. package/dist/elements/om-overlay.d.ts +13 -1
  18. package/dist/elements/om-widget.d.ts +4 -0
  19. package/dist/feature-colors.d.ts +41 -0
  20. package/dist/geodesy.d.ts +29 -3
  21. package/dist/{geoparquet-Bm8pfxyo.js → geoparquet-DapHATA0.js} +1 -1
  22. package/dist/html-data.d.ts +2 -2
  23. package/dist/ifc-Dc-TdSJr.js +877 -0
  24. package/dist/ifc.d.ts +406 -0
  25. package/dist/{index-Bz-rbmhj.js → index-7B-6Cbzu.js} +31619 -26565
  26. package/dist/{index-DSRIZR81.js → index-BF9iO8Tq.js} +1 -1
  27. package/dist/{index-GOwMjqm6.js → index-BmX6IId3.js} +1 -1
  28. package/dist/{index-UzmNhuS0.js → index-SPJVn_n_.js} +1 -1
  29. package/dist/{index-CCQttJzO.js → index-xmJjZxQJ.js} +2 -2
  30. package/dist/index.d.ts +13 -2
  31. package/dist/ir-snapshot.d.ts +3 -1
  32. package/dist/layer-registry.d.ts +14 -0
  33. package/dist/layers/bim-layer.d.ts +127 -0
  34. package/dist/layers/feature-mesh-layer.d.ts +288 -0
  35. package/dist/layers/gltf-scene-walk.d.ts +55 -0
  36. package/dist/layers/popup-layer.d.ts +13 -0
  37. package/dist/legend-spec.d.ts +1 -1
  38. package/dist/{lerc-CuifOkoA.js → lerc-C6k7EzSN.js} +2 -2
  39. package/dist/license.d.ts +12 -5
  40. package/dist/measure-controller.d.ts +458 -4
  41. package/dist/meshopt_simplifier-Co6uRDDA.js +370 -0
  42. package/dist/onlymap.standalone.js +57077 -50729
  43. package/dist/onlymapjs.js +72 -69
  44. package/dist/parse-manifest.d.ts +3 -0
  45. package/dist/programmatic.d.ts +39 -5
  46. package/dist/{raster-dysYIQ_k.js → raster-Cuzhibe2.js} +2 -2
  47. package/dist/{raster-pipeline-ZdCOGfqV.js → raster-pipeline-DLrnJK8y.js} +1 -1
  48. package/dist/react/om-layer.d.ts +6 -1
  49. package/dist/react/om-overlay.d.ts +9 -0
  50. package/dist/react.js +176 -169
  51. package/dist/region-export-controller.d.ts +37 -0
  52. package/dist/region-export.d.ts +56 -0
  53. package/dist/runtime-core.d.ts +260 -3
  54. package/dist/selection.d.ts +44 -1
  55. package/dist/site-placement.d.ts +107 -0
  56. package/dist/snapping.d.ts +88 -0
  57. package/dist/terrain-heightfield.d.ts +53 -0
  58. package/dist/terrain-sample.d.ts +30 -0
  59. package/dist/terrain.d.ts +6 -1
  60. package/dist/testing.d.ts +6 -2
  61. package/dist/tile3d-metadata.d.ts +185 -0
  62. package/dist/units.d.ts +27 -0
  63. package/dist/version.d.ts +1 -1
  64. package/dist/volumetrics-run.d.ts +13 -0
  65. package/dist/volumetrics-worker.d.ts +1 -0
  66. package/dist/volumetrics.d.ts +201 -0
  67. package/dist/widget-registry.d.ts +11 -0
  68. package/dist/widgets/ifc-clash.d.ts +18 -0
  69. package/dist/widgets/ifc.d.ts +41 -0
  70. package/dist/{zarr-OewK7k2K.js → zarr-CUzEX8fB.js} +79 -66
  71. package/docs/3d-assets.md +48 -0
  72. package/docs/live-data.md +9 -1
  73. package/docs/testing.md +4 -2
  74. package/llms.txt +10 -5
  75. package/onlymapjs.html-data.json +313 -2
  76. package/package.json +6 -2
  77. package/skills/onlymapjs/SKILL.md +14 -2
  78. package/skills/onlymapjs/references/react.md +2 -2
  79. package/skills/onlymapjs/references/syntax.md +314 -15
  80. package/dist/cityjson-urQeujQv.js +0 -407
@@ -36,6 +36,17 @@ export interface WidgetImpl {
36
36
  */
37
37
  neverHides?: boolean;
38
38
  render(ctx: RuntimeContext, host: WidgetHost): void | Promise<void>;
39
+ /**
40
+ * Optional teardown, called by <om-widget> when the element is REMOVED for
41
+ * real — an author delete, or an SPA unmounting the whole <om-map> — never
42
+ * on the transient disconnect of a slot/fold/cluster reparent (om-widget
43
+ * distinguishes the two; see its disconnectedCallback). For releasing
44
+ * resources the document would otherwise pin past the widget's life: blob
45
+ * URLs, external listeners, large cached tables held in `host.state`.
46
+ * May fire again after a re-connect if the widget is removed a second
47
+ * time, so implementations must tolerate repeat calls.
48
+ */
49
+ destroy?(host: WidgetHost): void;
39
50
  }
40
51
  /** Clusterable (spec: "Widget Layout Manager") — the type is compact AND the author didn't opt out. One predicate for the cluster pass AND the validation lint. */
41
52
  export declare function isClusterableWidget(el: Element): boolean;
@@ -0,0 +1,18 @@
1
+ interface ClashItem {
2
+ id: number;
3
+ ifcClass: string;
4
+ name: string;
5
+ box: number[];
6
+ }
7
+ /** Rows to clash candidates, dropping ignored classes and anything with no real box. */
8
+ export declare function clashCandidates(rows: Record<string, unknown>[]): ClashItem[];
9
+ /**
10
+ * Axis-aligned overlap, with a tolerance that SHRINKS both boxes.
11
+ *
12
+ * The strict comparison matters: two slabs meeting exactly face to face share a
13
+ * plane, and reporting that would mean every floor clashes with every wall
14
+ * standing on it. `tolerance` then demands a real interpenetration of that
15
+ * depth before a pair counts, which is how modelling noise gets tuned out.
16
+ */
17
+ export declare function boxesOverlap(a: number[], b: number[], tolerance: number): boolean;
18
+ export {};
@@ -0,0 +1,41 @@
1
+ export declare function ensureStyles(root: ShadowRoot): void;
2
+ /** Every `<om-layer pick-features>` on a map — the BIM widgets' shared universe of pickable models. */
3
+ export declare function pickFeatureLayers(map: Element | null | undefined): Element[];
4
+ interface TreeNode {
5
+ /** Full prefix identifying this node — also its key in the visibility state. */
6
+ key: string;
7
+ label: string;
8
+ count: number;
9
+ /** Every concrete `spatialPath` value at or below this node. */
10
+ values: string[];
11
+ children: Map<string, TreeNode>;
12
+ }
13
+ /**
14
+ * Distinct spatial paths -> a nested tree, with counts aggregated upward.
15
+ *
16
+ * Depth is NOT uniform in real models: the bridge sample mixes 1-level and
17
+ * 5-level paths in one file, and a model can leave elements with no spatial
18
+ * container at all (700 of the clinic's 2,626). Both are represented rather
19
+ * than dropped — an element that vanishes from the tree is an element nobody
20
+ * can find again.
21
+ */
22
+ export declare function buildSpatialTree(counts: Map<string, number>): TreeNode;
23
+ /**
24
+ * Writes an attribute only when it would actually change.
25
+ *
26
+ * These widgets re-render on the `layers`/`features` tokens and their writes
27
+ * mutate layers, so an unconditional write schedules the MutationObserver →
28
+ * reconcile → full parseManifest pass that produced it — on EVERY render,
29
+ * even when nothing changed. `setAttribute` notifies observers even when the
30
+ * value is identical, so equality has to be checked here rather than relied
31
+ * on.
32
+ *
33
+ * It also matters for size: an isolate list or a serialized feature-styles
34
+ * table spans every element and runs to tens of kilobytes, and re-parsing
35
+ * that on a loop would be felt.
36
+ *
37
+ * Shared with ifc-clash (imported from here — the dependency already flows
38
+ * that way for ensureStyles/pickFeatureLayers).
39
+ */
40
+ export declare function setIfChanged(element: Element | null, name: string, value: string | null): void;
41
+ export {};
@@ -1,5 +1,5 @@
1
- import { A as ur, d as lr, R as zt, e as fr, m as dr, p as St, f as hr, g as pr, h as mr } from "./raster-pipeline-ZdCOGfqV.js";
2
- import { ap as gr } from "./index-Bz-rbmhj.js";
1
+ import { A as ur, d as lr, R as zt, e as fr, m as dr, p as St, f as hr, g as pr, h as mr } from "./raster-pipeline-DLrnJK8y.js";
2
+ import { ap as gr } from "./index-7B-6Cbzu.js";
3
3
  import $t from "./index-CW1n5LdO.js";
4
4
  var Et;
5
5
  function h(e, t, n) {
@@ -48,7 +48,7 @@ class zn extends Error {
48
48
  }
49
49
  (Et = globalThis).__zod_globalConfig ?? (Et.__zod_globalConfig = {});
50
50
  const et = globalThis.__zod_globalConfig;
51
- function L(e) {
51
+ function M(e) {
52
52
  return et;
53
53
  }
54
54
  function Sn(e) {
@@ -396,7 +396,7 @@ const st = (e) => (t, n, r, o) => {
396
396
  if (i instanceof Promise)
397
397
  throw new ee();
398
398
  if (i.issues.length) {
399
- const a = new (o?.Err ?? e)(i.issues.map((c) => D(c, s, L())));
399
+ const a = new (o?.Err ?? e)(i.issues.map((c) => D(c, s, M())));
400
400
  throw $n(a, o?.callee), a;
401
401
  }
402
402
  return i.value;
@@ -404,7 +404,7 @@ const st = (e) => (t, n, r, o) => {
404
404
  const s = r ? { ...r, async: !0 } : { async: !0 };
405
405
  let i = t._zod.run({ value: n, issues: [] }, s);
406
406
  if (i instanceof Promise && (i = await i), i.issues.length) {
407
- const a = new (o?.Err ?? e)(i.issues.map((c) => D(c, s, L())));
407
+ const a = new (o?.Err ?? e)(i.issues.map((c) => D(c, s, M())));
408
408
  throw $n(a, o?.callee), a;
409
409
  }
410
410
  return i.value;
@@ -414,14 +414,14 @@ const st = (e) => (t, n, r, o) => {
414
414
  throw new ee();
415
415
  return s.issues.length ? {
416
416
  success: !1,
417
- error: new (e ?? In)(s.issues.map((i) => D(i, o, L())))
417
+ error: new (e ?? In)(s.issues.map((i) => D(i, o, M())))
418
418
  } : { success: !0, data: s.value };
419
419
  }, Cr = /* @__PURE__ */ Pe(Zn), je = (e) => async (t, n, r) => {
420
420
  const o = r ? { ...r, async: !0 } : { async: !0 };
421
421
  let s = t._zod.run({ value: n, issues: [] }, o);
422
422
  return s instanceof Promise && (s = await s), s.issues.length ? {
423
423
  success: !1,
424
- error: new e(s.issues.map((i) => D(i, o, L())))
424
+ error: new e(s.issues.map((i) => D(i, o, M())))
425
425
  } : { success: !0, data: s.value };
426
426
  }, Pr = /* @__PURE__ */ je(Zn), jr = (e) => (t, n, r) => {
427
427
  const o = r ? { ...r, direction: "backward" } : { direction: "backward" };
@@ -429,7 +429,7 @@ const st = (e) => (t, n, r, o) => {
429
429
  }, xr = (e) => (t, n, r) => st(e)(t, n, r), Rr = (e) => async (t, n, r) => {
430
430
  const o = r ? { ...r, direction: "backward" } : { direction: "backward" };
431
431
  return it(e)(t, n, o);
432
- }, Mr = (e) => async (t, n, r) => it(e)(t, n, r), Lr = (e) => (t, n, r) => {
432
+ }, Lr = (e) => async (t, n, r) => it(e)(t, n, r), Mr = (e) => (t, n, r) => {
433
433
  const o = r ? { ...r, direction: "backward" } : { direction: "backward" };
434
434
  return Pe(e)(t, n, o);
435
435
  }, Dr = (e) => (t, n, r) => Pe(e)(t, n, r), Ur = (e) => async (t, n, r) => {
@@ -925,9 +925,9 @@ const Io = {
925
925
  t.pattern ?? (t.pattern = Jr), z.init(e, t);
926
926
  }), Ro = /* @__PURE__ */ h("$ZodULID", (e, t) => {
927
927
  t.pattern ?? (t.pattern = Vr), z.init(e, t);
928
- }), Mo = /* @__PURE__ */ h("$ZodXID", (e, t) => {
928
+ }), Lo = /* @__PURE__ */ h("$ZodXID", (e, t) => {
929
929
  t.pattern ?? (t.pattern = Wr), z.init(e, t);
930
- }), Lo = /* @__PURE__ */ h("$ZodKSUID", (e, t) => {
930
+ }), Mo = /* @__PURE__ */ h("$ZodKSUID", (e, t) => {
931
931
  t.pattern ?? (t.pattern = Gr), z.init(e, t);
932
932
  }), Do = /* @__PURE__ */ h("$ZodISODateTime", (e, t) => {
933
933
  t.pattern ?? (t.pattern = uo(t)), z.init(e, t);
@@ -1046,7 +1046,7 @@ const Qo = /* @__PURE__ */ h("$ZodJWT", (e, t) => {
1046
1046
  continue: !t.abort
1047
1047
  });
1048
1048
  };
1049
- }), Mn = /* @__PURE__ */ h("$ZodNumber", (e, t) => {
1049
+ }), Ln = /* @__PURE__ */ h("$ZodNumber", (e, t) => {
1050
1050
  $.init(e, t), e._zod.pattern = e._zod.bag.pattern ?? Cn, e._zod.parse = (n, r) => {
1051
1051
  if (t.coerce)
1052
1052
  try {
@@ -1066,7 +1066,7 @@ const Qo = /* @__PURE__ */ h("$ZodJWT", (e, t) => {
1066
1066
  }), n;
1067
1067
  };
1068
1068
  }), es = /* @__PURE__ */ h("$ZodNumberFormat", (e, t) => {
1069
- go.init(e, t), Mn.init(e, t);
1069
+ go.init(e, t), Ln.init(e, t);
1070
1070
  }), ts = /* @__PURE__ */ h("$ZodUnknown", (e, t) => {
1071
1071
  $.init(e, t), e._zod.parse = (n) => n;
1072
1072
  }), ns = /* @__PURE__ */ h("$ZodNever", (e, t) => {
@@ -1120,7 +1120,7 @@ function ve(e, t, n, r, o, s) {
1120
1120
  }
1121
1121
  e.value === void 0 ? i && (t.value[n] = void 0) : t.value[n] = e.value;
1122
1122
  }
1123
- function Ln(e) {
1123
+ function Mn(e) {
1124
1124
  const t = Object.keys(e.shape);
1125
1125
  for (const r of t)
1126
1126
  if (!e.shape?.[r]?._zod?.traits?.has("$ZodType"))
@@ -1165,7 +1165,7 @@ const os = /* @__PURE__ */ h("$ZodObject", (e, t) => {
1165
1165
  }
1166
1166
  });
1167
1167
  }
1168
- const r = tt(() => Ln(t));
1168
+ const r = tt(() => Mn(t));
1169
1169
  v(e._zod, "propValues", () => {
1170
1170
  const a = t.shape, c = {};
1171
1171
  for (const u in a) {
@@ -1200,7 +1200,7 @@ const os = /* @__PURE__ */ h("$ZodObject", (e, t) => {
1200
1200
  };
1201
1201
  }), ss = /* @__PURE__ */ h("$ZodObjectJIT", (e, t) => {
1202
1202
  os.init(e, t);
1203
- const n = e._zod.parse, r = tt(() => Ln(t)), o = (d) => {
1203
+ const n = e._zod.parse, r = tt(() => Mn(t)), o = (d) => {
1204
1204
  const p = new To(["shape", "payload", "ctx"]), g = r.value, k = (O) => {
1205
1205
  const y = It(O);
1206
1206
  return `shape[${y}]._zod.run({ value: input[${y}], issues: [] }, ctx)`;
@@ -1301,7 +1301,7 @@ function At(e, t, n, r) {
1301
1301
  code: "invalid_union",
1302
1302
  input: t.value,
1303
1303
  inst: n,
1304
- errors: e.map((s) => s.issues.map((i) => D(i, r, L())))
1304
+ errors: e.map((s) => s.issues.map((i) => D(i, r, M())))
1305
1305
  }), t);
1306
1306
  }
1307
1307
  const is = /* @__PURE__ */ h("$ZodUnion", (e, t) => {
@@ -1501,7 +1501,7 @@ const us = /* @__PURE__ */ h("$ZodRecord", (e, t) => {
1501
1501
  n.issues.push({
1502
1502
  code: "invalid_key",
1503
1503
  origin: "record",
1504
- issues: l.issues.map((p) => D(p, r, L())),
1504
+ issues: l.issues.map((p) => D(p, r, M())),
1505
1505
  input: u,
1506
1506
  path: [u],
1507
1507
  inst: e
@@ -1540,7 +1540,7 @@ const us = /* @__PURE__ */ h("$ZodRecord", (e, t) => {
1540
1540
  t.mode === "loose" ? n.value[a] = o[a] : n.issues.push({
1541
1541
  code: "invalid_key",
1542
1542
  origin: "record",
1543
- issues: c.issues.map((f) => D(f, r, L())),
1543
+ issues: c.issues.map((f) => D(f, r, M())),
1544
1544
  input: a,
1545
1545
  path: [a],
1546
1546
  inst: e
@@ -1621,10 +1621,10 @@ const ms = /* @__PURE__ */ h("$ZodPrefault", (e, t) => {
1621
1621
  return n ? new Set([...n].filter((r) => r !== void 0)) : void 0;
1622
1622
  }), e._zod.parse = (n, r) => {
1623
1623
  const o = t.innerType._zod.run(n, r);
1624
- return o instanceof Promise ? o.then((s) => Mt(s, e)) : Mt(o, e);
1624
+ return o instanceof Promise ? o.then((s) => Lt(s, e)) : Lt(o, e);
1625
1625
  };
1626
1626
  });
1627
- function Mt(e, t) {
1627
+ function Lt(e, t) {
1628
1628
  return !e.issues.length && e.value === void 0 && e.issues.push({
1629
1629
  code: "invalid_type",
1630
1630
  expected: "nonoptional",
@@ -1640,13 +1640,13 @@ const ys = /* @__PURE__ */ h("$ZodCatch", (e, t) => {
1640
1640
  return o instanceof Promise ? o.then((s) => (n.value = s.value, s.issues.length && (n.value = t.catchValue({
1641
1641
  ...n,
1642
1642
  error: {
1643
- issues: s.issues.map((i) => D(i, r, L()))
1643
+ issues: s.issues.map((i) => D(i, r, M()))
1644
1644
  },
1645
1645
  input: n.value
1646
1646
  }), n.issues = [], n.fallback = !0), n)) : (n.value = o.value, o.issues.length && (n.value = t.catchValue({
1647
1647
  ...n,
1648
1648
  error: {
1649
- issues: o.issues.map((s) => D(s, r, L()))
1649
+ issues: o.issues.map((s) => D(s, r, M()))
1650
1650
  },
1651
1651
  input: n.value
1652
1652
  }), n.issues = [], n.fallback = !0), n);
@@ -1669,10 +1669,10 @@ const ws = /* @__PURE__ */ h("$ZodReadonly", (e, t) => {
1669
1669
  if (r.direction === "backward")
1670
1670
  return t.innerType._zod.run(n, r);
1671
1671
  const o = t.innerType._zod.run(n, r);
1672
- return o instanceof Promise ? o.then(Lt) : Lt(o);
1672
+ return o instanceof Promise ? o.then(Mt) : Mt(o);
1673
1673
  };
1674
1674
  });
1675
- function Lt(e) {
1675
+ function Mt(e) {
1676
1676
  return e.value = Object.freeze(e.value), e;
1677
1677
  }
1678
1678
  const bs = /* @__PURE__ */ h("$ZodCustom", (e, t) => {
@@ -1894,7 +1894,7 @@ function Rs(e, t) {
1894
1894
  });
1895
1895
  }
1896
1896
  // @__NO_SIDE_EFFECTS__
1897
- function Ms(e, t) {
1897
+ function Ls(e, t) {
1898
1898
  return new e({
1899
1899
  type: "string",
1900
1900
  format: "ipv6",
@@ -1904,7 +1904,7 @@ function Ms(e, t) {
1904
1904
  });
1905
1905
  }
1906
1906
  // @__NO_SIDE_EFFECTS__
1907
- function Ls(e, t) {
1907
+ function Ms(e, t) {
1908
1908
  return new e({
1909
1909
  type: "string",
1910
1910
  format: "cidrv4",
@@ -2044,7 +2044,7 @@ function Bt(e, t) {
2044
2044
  });
2045
2045
  }
2046
2046
  // @__NO_SIDE_EFFECTS__
2047
- function Me(e, t) {
2047
+ function Le(e, t) {
2048
2048
  return new jn({
2049
2049
  check: "less_than",
2050
2050
  ...m(t),
@@ -2062,7 +2062,7 @@ function Jt(e, t) {
2062
2062
  });
2063
2063
  }
2064
2064
  // @__NO_SIDE_EFFECTS__
2065
- function Le(e, t) {
2065
+ function Me(e, t) {
2066
2066
  return new xn({
2067
2067
  check: "greater_than",
2068
2068
  ...m(t),
@@ -2625,11 +2625,11 @@ const pi = (e, t = {}) => (n) => {
2625
2625
  function Ri(e) {
2626
2626
  return /* @__PURE__ */ Vs(xi, e);
2627
2627
  }
2628
- const Mi = /* @__PURE__ */ h("ZodISODate", (e, t) => {
2628
+ const Li = /* @__PURE__ */ h("ZodISODate", (e, t) => {
2629
2629
  Uo.init(e, t), E.init(e, t);
2630
2630
  });
2631
- function Li(e) {
2632
- return /* @__PURE__ */ Ws(Mi, e);
2631
+ function Mi(e) {
2632
+ return /* @__PURE__ */ Ws(Li, e);
2633
2633
  }
2634
2634
  const Di = /* @__PURE__ */ h("ZodISOTime", (e, t) => {
2635
2635
  Fo.init(e, t), E.init(e, t);
@@ -2674,7 +2674,7 @@ const Ji = (e, t) => {
2674
2674
  });
2675
2675
  }, x = /* @__PURE__ */ h("ZodError", Ji, {
2676
2676
  Parent: Error
2677
- }), Vi = /* @__PURE__ */ st(x), Wi = /* @__PURE__ */ it(x), Gi = /* @__PURE__ */ Pe(x), Ki = /* @__PURE__ */ je(x), Yi = /* @__PURE__ */ jr(x), qi = /* @__PURE__ */ xr(x), Xi = /* @__PURE__ */ Rr(x), Hi = /* @__PURE__ */ Mr(x), Qi = /* @__PURE__ */ Lr(x), ea = /* @__PURE__ */ Dr(x), ta = /* @__PURE__ */ Ur(x), na = /* @__PURE__ */ Fr(x), Wt = /* @__PURE__ */ new WeakMap();
2677
+ }), Vi = /* @__PURE__ */ st(x), Wi = /* @__PURE__ */ it(x), Gi = /* @__PURE__ */ Pe(x), Ki = /* @__PURE__ */ je(x), Yi = /* @__PURE__ */ jr(x), qi = /* @__PURE__ */ xr(x), Xi = /* @__PURE__ */ Rr(x), Hi = /* @__PURE__ */ Lr(x), Qi = /* @__PURE__ */ Mr(x), ea = /* @__PURE__ */ Dr(x), ta = /* @__PURE__ */ Ur(x), na = /* @__PURE__ */ Fr(x), Wt = /* @__PURE__ */ new WeakMap();
2678
2678
  function fe(e, t, n) {
2679
2679
  const r = Object.getPrototypeOf(e);
2680
2680
  let o = Wt.get(r);
@@ -2770,7 +2770,7 @@ const I = /* @__PURE__ */ h("ZodType", (e, t) => ($.init(e, t), Object.assign(e[
2770
2770
  return Xt(this, Ca(n));
2771
2771
  },
2772
2772
  default(n) {
2773
- return Ma(this, n);
2773
+ return La(this, n);
2774
2774
  },
2775
2775
  prefault(n) {
2776
2776
  return Da(this, n);
@@ -2859,9 +2859,9 @@ const I = /* @__PURE__ */ h("ZodType", (e, t) => ($.init(e, t), Object.assign(e[
2859
2859
  }
2860
2860
  });
2861
2861
  }), ra = /* @__PURE__ */ h("ZodString", (e, t) => {
2862
- at.init(e, t), Kn.init(e, t), e.email = (n) => e.check(/* @__PURE__ */ Ss(oa, n)), e.url = (n) => e.check(/* @__PURE__ */ Zs(sa, n)), e.jwt = (n) => e.check(/* @__PURE__ */ Js(ba, n)), e.emoji = (n) => e.check(/* @__PURE__ */ Os(ia, n)), e.guid = (n) => e.check(/* @__PURE__ */ Ft(Gt, n)), e.uuid = (n) => e.check(/* @__PURE__ */ $s(ye, n)), e.uuidv4 = (n) => e.check(/* @__PURE__ */ Es(ye, n)), e.uuidv6 = (n) => e.check(/* @__PURE__ */ Ts(ye, n)), e.uuidv7 = (n) => e.check(/* @__PURE__ */ Is(ye, n)), e.nanoid = (n) => e.check(/* @__PURE__ */ As(aa, n)), e.guid = (n) => e.check(/* @__PURE__ */ Ft(Gt, n)), e.cuid = (n) => e.check(/* @__PURE__ */ Ns(ca, n)), e.cuid2 = (n) => e.check(/* @__PURE__ */ Cs(ua, n)), e.ulid = (n) => e.check(/* @__PURE__ */ Ps(la, n)), e.base64 = (n) => e.check(/* @__PURE__ */ Us(ya, n)), e.base64url = (n) => e.check(/* @__PURE__ */ Fs(_a, n)), e.xid = (n) => e.check(/* @__PURE__ */ js(fa, n)), e.ksuid = (n) => e.check(/* @__PURE__ */ xs(da, n)), e.ipv4 = (n) => e.check(/* @__PURE__ */ Rs(ha, n)), e.ipv6 = (n) => e.check(/* @__PURE__ */ Ms(pa, n)), e.cidrv4 = (n) => e.check(/* @__PURE__ */ Ls(ma, n)), e.cidrv6 = (n) => e.check(/* @__PURE__ */ Ds(ga, n)), e.e164 = (n) => e.check(/* @__PURE__ */ Bs(wa, n)), e.datetime = (n) => e.check(Ri(n)), e.date = (n) => e.check(Li(n)), e.time = (n) => e.check(Ui(n)), e.duration = (n) => e.check(Bi(n));
2862
+ at.init(e, t), Kn.init(e, t), e.email = (n) => e.check(/* @__PURE__ */ Ss(oa, n)), e.url = (n) => e.check(/* @__PURE__ */ Zs(sa, n)), e.jwt = (n) => e.check(/* @__PURE__ */ Js(ba, n)), e.emoji = (n) => e.check(/* @__PURE__ */ Os(ia, n)), e.guid = (n) => e.check(/* @__PURE__ */ Ft(Gt, n)), e.uuid = (n) => e.check(/* @__PURE__ */ $s(ye, n)), e.uuidv4 = (n) => e.check(/* @__PURE__ */ Es(ye, n)), e.uuidv6 = (n) => e.check(/* @__PURE__ */ Ts(ye, n)), e.uuidv7 = (n) => e.check(/* @__PURE__ */ Is(ye, n)), e.nanoid = (n) => e.check(/* @__PURE__ */ As(aa, n)), e.guid = (n) => e.check(/* @__PURE__ */ Ft(Gt, n)), e.cuid = (n) => e.check(/* @__PURE__ */ Ns(ca, n)), e.cuid2 = (n) => e.check(/* @__PURE__ */ Cs(ua, n)), e.ulid = (n) => e.check(/* @__PURE__ */ Ps(la, n)), e.base64 = (n) => e.check(/* @__PURE__ */ Us(ya, n)), e.base64url = (n) => e.check(/* @__PURE__ */ Fs(_a, n)), e.xid = (n) => e.check(/* @__PURE__ */ js(fa, n)), e.ksuid = (n) => e.check(/* @__PURE__ */ xs(da, n)), e.ipv4 = (n) => e.check(/* @__PURE__ */ Rs(ha, n)), e.ipv6 = (n) => e.check(/* @__PURE__ */ Ls(pa, n)), e.cidrv4 = (n) => e.check(/* @__PURE__ */ Ms(ma, n)), e.cidrv6 = (n) => e.check(/* @__PURE__ */ Ds(ga, n)), e.e164 = (n) => e.check(/* @__PURE__ */ Bs(wa, n)), e.datetime = (n) => e.check(Ri(n)), e.date = (n) => e.check(Mi(n)), e.time = (n) => e.check(Ui(n)), e.duration = (n) => e.check(Bi(n));
2863
2863
  });
2864
- function M(e) {
2864
+ function L(e) {
2865
2865
  return /* @__PURE__ */ zs(ra, e);
2866
2866
  }
2867
2867
  const E = /* @__PURE__ */ h("ZodStringFormat", (e, t) => {
@@ -2885,9 +2885,9 @@ const E = /* @__PURE__ */ h("ZodStringFormat", (e, t) => {
2885
2885
  }), la = /* @__PURE__ */ h("ZodULID", (e, t) => {
2886
2886
  Ro.init(e, t), E.init(e, t);
2887
2887
  }), fa = /* @__PURE__ */ h("ZodXID", (e, t) => {
2888
- Mo.init(e, t), E.init(e, t);
2889
- }), da = /* @__PURE__ */ h("ZodKSUID", (e, t) => {
2890
2888
  Lo.init(e, t), E.init(e, t);
2889
+ }), da = /* @__PURE__ */ h("ZodKSUID", (e, t) => {
2890
+ Mo.init(e, t), E.init(e, t);
2891
2891
  }), ha = /* @__PURE__ */ h("ZodIPv4", (e, t) => {
2892
2892
  Jo.init(e, t), E.init(e, t);
2893
2893
  }), pa = /* @__PURE__ */ h("ZodIPv6", (e, t) => {
@@ -2905,24 +2905,24 @@ const E = /* @__PURE__ */ h("ZodStringFormat", (e, t) => {
2905
2905
  }), ba = /* @__PURE__ */ h("ZodJWT", (e, t) => {
2906
2906
  Qo.init(e, t), E.init(e, t);
2907
2907
  }), Yn = /* @__PURE__ */ h("ZodNumber", (e, t) => {
2908
- Mn.init(e, t), I.init(e, t), e._zod.processJSONSchema = (r, o, s) => yi(e, r, o), fe(e, "ZodNumber", {
2908
+ Ln.init(e, t), I.init(e, t), e._zod.processJSONSchema = (r, o, s) => yi(e, r, o), fe(e, "ZodNumber", {
2909
2909
  gt(r, o) {
2910
2910
  return this.check(/* @__PURE__ */ Jt(r, o));
2911
2911
  },
2912
2912
  gte(r, o) {
2913
- return this.check(/* @__PURE__ */ Le(r, o));
2913
+ return this.check(/* @__PURE__ */ Me(r, o));
2914
2914
  },
2915
2915
  min(r, o) {
2916
- return this.check(/* @__PURE__ */ Le(r, o));
2916
+ return this.check(/* @__PURE__ */ Me(r, o));
2917
2917
  },
2918
2918
  lt(r, o) {
2919
2919
  return this.check(/* @__PURE__ */ Bt(r, o));
2920
2920
  },
2921
2921
  lte(r, o) {
2922
- return this.check(/* @__PURE__ */ Me(r, o));
2922
+ return this.check(/* @__PURE__ */ Le(r, o));
2923
2923
  },
2924
2924
  max(r, o) {
2925
- return this.check(/* @__PURE__ */ Me(r, o));
2925
+ return this.check(/* @__PURE__ */ Le(r, o));
2926
2926
  },
2927
2927
  int(r) {
2928
2928
  return this.check(Se(r));
@@ -2934,13 +2934,13 @@ const E = /* @__PURE__ */ h("ZodStringFormat", (e, t) => {
2934
2934
  return this.check(/* @__PURE__ */ Jt(0, r));
2935
2935
  },
2936
2936
  nonnegative(r) {
2937
- return this.check(/* @__PURE__ */ Le(0, r));
2937
+ return this.check(/* @__PURE__ */ Me(0, r));
2938
2938
  },
2939
2939
  negative(r) {
2940
2940
  return this.check(/* @__PURE__ */ Bt(0, r));
2941
2941
  },
2942
2942
  nonpositive(r) {
2943
- return this.check(/* @__PURE__ */ Me(0, r));
2943
+ return this.check(/* @__PURE__ */ Le(0, r));
2944
2944
  },
2945
2945
  multipleOf(r, o) {
2946
2946
  return this.check(/* @__PURE__ */ Vt(r, o));
@@ -3090,7 +3090,7 @@ const Kt = /* @__PURE__ */ h("ZodRecord", (e, t) => {
3090
3090
  function Aa(e, t, n) {
3091
3091
  return !t || !t._zod ? new Kt({
3092
3092
  type: "record",
3093
- keyType: M(),
3093
+ keyType: L(),
3094
3094
  valueType: e,
3095
3095
  ...m(t)
3096
3096
  }) : new Kt({
@@ -3191,7 +3191,7 @@ function qt(e) {
3191
3191
  const Ra = /* @__PURE__ */ h("ZodDefault", (e, t) => {
3192
3192
  ps.init(e, t), I.init(e, t), e._zod.processJSONSchema = (n, r, o) => Ai(e, n, r, o), e.unwrap = () => e._zod.def.innerType, e.removeDefault = e.unwrap;
3193
3193
  });
3194
- function Ma(e, t) {
3194
+ function La(e, t) {
3195
3195
  return new Ra({
3196
3196
  type: "default",
3197
3197
  innerType: e,
@@ -3200,11 +3200,11 @@ function Ma(e, t) {
3200
3200
  }
3201
3201
  });
3202
3202
  }
3203
- const La = /* @__PURE__ */ h("ZodPrefault", (e, t) => {
3203
+ const Ma = /* @__PURE__ */ h("ZodPrefault", (e, t) => {
3204
3204
  ms.init(e, t), I.init(e, t), e._zod.processJSONSchema = (n, r, o) => Ni(e, n, r, o), e.unwrap = () => e._zod.def.innerType;
3205
3205
  });
3206
3206
  function Da(e, t) {
3207
- return new La({
3207
+ return new Ma({
3208
3208
  type: "prefault",
3209
3209
  innerType: e,
3210
3210
  get defaultValue() {
@@ -3264,9 +3264,9 @@ function Ya(e, t) {
3264
3264
  const qa = {
3265
3265
  custom: "custom"
3266
3266
  }, Xa = ct([
3267
- J({ "proj:code": M().regex(/^[A-Z]+:[0-9]+$/) }),
3268
- J({ "proj:wkt2": M() }),
3269
- J({ "proj:projjson": Aa(M(), Ke()) })
3267
+ J({ "proj:code": L().regex(/^[A-Z]+:[0-9]+$/) }),
3268
+ J({ "proj:wkt2": L() }),
3269
+ J({ "proj:projjson": Aa(L(), Ke()) })
3270
3270
  ]), Qn = $e([
3271
3271
  A(),
3272
3272
  A(),
@@ -3275,23 +3275,23 @@ const qa = {
3275
3275
  A(),
3276
3276
  A()
3277
3277
  ]), er = $e([Se().min(1), Se().min(1)]), Ha = J({
3278
- asset: M(),
3279
- derived_from: M().optional(),
3278
+ asset: L(),
3279
+ derived_from: L().optional(),
3280
3280
  transform: J({
3281
3281
  scale: le(A()).optional(),
3282
3282
  translation: le(A()).optional()
3283
3283
  }).optional(),
3284
- resampling_method: M().optional(),
3284
+ resampling_method: L().optional(),
3285
3285
  // spatial: overrides per level — required here when not at group level
3286
3286
  "spatial:transform": Qn.optional(),
3287
3287
  "spatial:shape": er.optional()
3288
3288
  }).passthrough(), Qa = J({
3289
3289
  multiscales: J({
3290
3290
  layout: le(Ha).min(1),
3291
- resampling_method: M().optional()
3291
+ resampling_method: L().optional()
3292
3292
  })
3293
3293
  }), ec = J({
3294
- "spatial:dimensions": le(M()).min(2).max(3),
3294
+ "spatial:dimensions": le(L()).min(2).max(3),
3295
3295
  "spatial:transform": Qn.optional(),
3296
3296
  "spatial:shape": er.optional(),
3297
3297
  "spatial:bbox": ct([
@@ -3305,7 +3305,7 @@ const qa = {
3305
3305
  A()
3306
3306
  ])
3307
3307
  ]).optional(),
3308
- "spatial:transform_type": M().optional(),
3308
+ "spatial:transform_type": L().optional(),
3309
3309
  "spatial:registration": qn(["node", "pixel"]).optional(),
3310
3310
  multiscales: Qa.shape.multiscales.optional()
3311
3311
  }), tc = ec.superRefine((e, t) => {
@@ -4778,15 +4778,15 @@ function Rc(e, t) {
4778
4778
  n instanceof Promise ? n = n.then((o) => r(o)) : n = r(n);
4779
4779
  return n;
4780
4780
  }
4781
- function Mc(e, ...t) {
4781
+ function Lc(e, ...t) {
4782
4782
  return Rc(e, t);
4783
4783
  }
4784
4784
  async function ar(e) {
4785
4785
  let t = e.store.arrayExtensions;
4786
- return t?.length ? await Mc(e, ...t) : e;
4786
+ return t?.length ? await Lc(e, ...t) : e;
4787
4787
  }
4788
- let pe = Lc();
4789
- function Lc() {
4788
+ let pe = Mc();
4789
+ function Mc() {
4790
4790
  let e = /* @__PURE__ */ new WeakMap();
4791
4791
  function t(n) {
4792
4792
  let r = e.get(n) ?? { v2: 0, v3: 0 };
@@ -5428,8 +5428,20 @@ const ku = async (e, t) => {
5428
5428
  function _e(e) {
5429
5429
  return JSON.stringify([e.src ?? "", e.variable ?? "", e.select ?? "", e.bounds ?? null, e.crs ?? "", e.spatialDims ?? ""]);
5430
5430
  }
5431
+ class zu extends _u {
5432
+ static layerName = "OmZarrTileLayer";
5433
+ renderLayers() {
5434
+ const t = super.renderLayers();
5435
+ if (!t) return t;
5436
+ const r = {
5437
+ updateTriggers: { ...t.props.updateTriggers, getTileData: this.props.selectTrigger },
5438
+ onViewportLoad: () => requestAnimationFrame(() => this.setNeedsRedraw())
5439
+ };
5440
+ return t.clone(r);
5441
+ }
5442
+ }
5431
5443
  const kn = /* @__PURE__ */ new Map();
5432
- async function zu(e) {
5444
+ async function Su(e) {
5433
5445
  const t = new URL(e.src ?? "", typeof document < "u" ? document.baseURI : void 0).href, n = new oc(t);
5434
5446
  let r = n;
5435
5447
  try {
@@ -5446,7 +5458,7 @@ async function zu(e) {
5446
5458
  }
5447
5459
  return { node: o, variable: e.variable };
5448
5460
  }
5449
- class Iu extends gr {
5461
+ class Zu extends gr {
5450
5462
  static layerName = "OmZarrLayer";
5451
5463
  static defaultProps = {
5452
5464
  src: "",
@@ -5470,7 +5482,7 @@ class Iu extends gr {
5470
5482
  if (!t.src) throw new Error('ZarrLayer requires a src (the ".zarr" store URL).');
5471
5483
  const r = bu(t.select), o = JSON.stringify([t.src, t.variable ?? "", t.bounds ?? null, t.crs ?? "", t.spatialDims ?? ""]);
5472
5484
  let s = kn.get(o);
5473
- if (s || (s = await zu(t), kn.set(o, s)), n !== _e(this.props)) return;
5485
+ if (s || (s = await Su(t), kn.set(o, s)), n !== _e(this.props)) return;
5474
5486
  this.setState({ status: "ready", node: s.node, variable: s.variable, metadata: s.metadata, selection: r, loadKey: n });
5475
5487
  } catch (r) {
5476
5488
  console.error(`[onlymapjs] ZarrLayer src="${t.src}" failed to load:`, r), n === _e(this.props) && this.setState({ status: "error", loadKey: n });
@@ -5485,13 +5497,14 @@ class Iu extends gr {
5485
5497
  colormap: this.props.colormap,
5486
5498
  nodataOverride: this.props.nodataOverride
5487
5499
  };
5488
- return new _u(
5500
+ return new zu(
5489
5501
  this.getSubLayerProps({
5490
5502
  id: "zarr",
5491
5503
  node: n,
5492
5504
  ...r !== void 0 ? { variable: r } : {},
5493
5505
  ...o !== void 0 ? { metadata: o } : {},
5494
5506
  selection: s,
5507
+ selectTrigger: this.props.select,
5495
5508
  getTileData: ku,
5496
5509
  renderTile: (a) => pr(a, i),
5497
5510
  opacity: this.props.opacity
@@ -5500,7 +5513,7 @@ class Iu extends gr {
5500
5513
  }
5501
5514
  }
5502
5515
  export {
5503
- Iu as OmZarrLayer,
5516
+ Zu as OmZarrLayer,
5504
5517
  vu as buildManualGeoZarrAttrs,
5505
5518
  bu as parseZarrSelection
5506
5519
  };
package/docs/3d-assets.md CHANGED
@@ -69,6 +69,54 @@ For LOD experiments, common loaders.gl tileset options have first-class attribut
69
69
 
70
70
  Upstream converters exist for IFC/CityGML → 3D Tiles (e.g. Cesium ion, `py3dtiles`, FME). Same rule: convert upstream, ingest the standard.
71
71
 
72
+ ## Working inside a 3D scene: cutting, exporting, picking
73
+
74
+ Three tools operate on whatever 3D content is already loaded — `Tile3DLayer` tilesets, `BIMLayer` models, extruded vector geometry alike. They compose: cut a box open, outline what's inside, export it.
75
+
76
+ ### Clip box — cut the scene open
77
+
78
+ ```html
79
+ <om-map terrain="mapterhorn"
80
+ clip-box-min="[6.145, 46.201, 380]"
81
+ clip-box-max="[6.149, 46.204, 440]">
82
+ <om-widget type="clip-box"></om-widget>
83
+ </om-map>
84
+ ```
85
+
86
+ Geometry outside the box is discarded. Every layer is clipped **by default** — `clip="off"` on an `<om-layer>` opts one out (a basemap, usually). Two modifiers change what "outside" means rather than how much is cut:
87
+
88
+ - `clip-box-invert` — show what's *outside* the box instead of inside.
89
+ - `clip-box-highlight` — dim clipped-out geometry instead of discarding it, so nothing disappears (a non-destructive preview).
90
+
91
+ The `clip-box` widget renders the box as a draggable cuboid; its "Show face gizmos" toggle adds a double-headed arrow on each of the 6 faces so you can resize by dragging, and keeps those handles off ordinary map panning when you're not using them. The box is attribute-backed like `terrain`/`lighting`, so changes are undoable and story-steppable, and the `set-clip-box` action (`{min, max, invert?, highlight?}`, or `{clear: true}`) drives it programmatically.
92
+
93
+ v1 is **axis-aligned only** — rotated/oriented boxes are a documented follow-up.
94
+
95
+ ### Region export — download the 3D content inside a footprint
96
+
97
+ ```html
98
+ <om-widget type="draw" export-3d></om-widget> <!-- GLB (default) -->
99
+ <om-widget type="draw" export-3d="b3dm"></om-widget> <!-- b3dm, for Cesium/3D-Tiles pipelines -->
100
+ ```
101
+
102
+ Outline a footprint with the draw widget, then hit **Export 3D**: every triangle of every loaded, *visible* 3D Tiles/BIM layer inside that ring is clipped exactly and downloaded. Positions are re-framed to a local coordinate frame at the footprint's own centroid, so the file opens correctly in Blender/three.js without ECEF-scale support. Each triangle carries its own source color as per-vertex `COLOR_0`; there are no textures (BIM/IFC materials are flat colors). `b3dm` adds a `_BATCHID` attribute and a feature table, namespaced per source tileset.
103
+
104
+ A layer hidden via `visible="false"` (or the `toggle-layer` action) is skipped, with distinct console warnings for "nothing loaded yet" vs. "everything loaded but hidden."
105
+
106
+ The clip and pack run **synchronously on the main thread** — fine at single-model/BIM scale, but a city-scale tileset under a large footprint will visibly block the tab. Keep footprints to the region you actually want.
107
+
108
+ ### `pickable="3d"` — a real elevation on hover and click
109
+
110
+ An ordinary `pickable` layer resolves a click against the z=0 ground plane, so clicking a building face reports the point on the ground *behind* it. `pickable="3d"` opts the layer into deck's depth-pick pass instead:
111
+
112
+ ```html
113
+ <om-layer id="city" type="Tile3DLayer" tileset="…/tileset.json" pickable="3d"></om-layer>
114
+ ```
115
+
116
+ The resolved coordinate then carries a real third (elevation) component, which flows through `ctx.selection.coordinate` and `{{z}}` in `<om-overlay>` / `show-tooltip` templates. `terrain` sets this on itself automatically. `{{z}}` is **absent, not `0`**, when no layer in the scene ran the depth pass for that pick — so a missing elevation is distinguishable from sea level.
117
+
118
+ Snapping (`<om-map snap="vertex edge midpoint">`, see the README) also reads a `BIMLayer`'s edge/crease overlay, converting real wall corners back to `[lng, lat]` — so a drawn footprint can land on an actual building corner rather than near it. `snap="off"` opts a layer out.
119
+
72
120
  ## Semantic city models: CityJSON
73
121
 
74
122
  3D Tiles is the right target for *visual* city models. It is the wrong one for **CityJSON**, because converting flattens the per-building semantics — and semantics are the whole reason municipal programmes publish it: the Netherlands' [3DBAG](https://3dbag.nl) (~10M buildings), Japan's [PLATEAU](https://www.mlit.go.jp/plateau/) (250+ cities), swisstopo, several German states. Rooftop-solar, shadow, zoning and noise studies all read those attributes.
package/docs/live-data.md CHANGED
@@ -76,7 +76,15 @@ This applies to **every** Data Layer request: initial loads, polling refreshes,
76
76
 
77
77
  Every flush/poll takes the same path a resolved fetch takes: a **new data reference** enters the layer IR → the reconciler hands it to deck.gl, which re-uploads geometry without recompiling any accessor → `data:<layerId>` watch tokens fire, so widgets (stats panels, charts) re-render once per update. `om-map-ready` resolves after the *first* load for polling; for streams it resolves immediately (a stream never "finishes" — don't wait for a first message to consider the map ready).
78
78
 
79
- Known limitation: sockets and poll loops are keyed by URL and live for the page — removing the layer stops the data being *read*, not the connection.
79
+ Live transports follow the active descriptor document. Removing a layer,
80
+ changing its URL or stream options, destroying its `MapController`, or
81
+ disconnecting its `<om-map>` releases that owner's handle. Identical
82
+ URL/options across maps share one transport, and the final release aborts the
83
+ fetch/poller or closes the socket. `MapController.suspend()` releases its live
84
+ handles while preserving descriptors and rendered state;
85
+ `MapController.resume()` reacquires them from the current descriptor document.
86
+ This is the intended app-background/app-foreground integration for native
87
+ hosts.
80
88
 
81
89
  ## Testing live layers
82
90