@mapvx/web-js 3.3.0 → 3.3.2-dev.1

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/umd/index.js CHANGED
@@ -11240,7 +11240,7 @@ const extractSafariExtensionDetails = (func, filename) => {
11240
11240
  // exists only for the type-checker, so in the ES/CJS builds the identifier is
11241
11241
  // genuinely absent and a direct comparison throws ReferenceError at module load.
11242
11242
  // `typeof` is the only safe way to probe a possibly-undeclared global.
11243
- var sentry_SDK_VERSION = false ? 0 : "3.3.0";
11243
+ var sentry_SDK_VERSION = false ? 0 : "3.3.2-dev.1";
11244
11244
  var DSN = false ? 0 : "https://872f598f020e3cd73a0933b562d24c81@sentry.mapvx.app/5";
11245
11245
 
11246
11246
  /**
@@ -19116,9 +19116,16 @@ function getGltfLoader() {
19116
19116
  * `DRACOLoader` into an undefined state: sometimes a decode error, sometimes no callback at all.
19117
19117
  * Without a timeout, one such asset never settles and blocks every other load queued behind it.
19118
19118
  *
19119
+ * Declarative GLB scenes can legitimately include very large assets — a client's ground-mesh
19120
+ * "Suelo" model measured at ~400 MB took ~26s to download alone on a solid connection, before any
19121
+ * Draco decode time, and totem hardware/networks in the field are often slower than that. The
19122
+ * timeout only needs to be long enough that no realistically-sized valid asset ever hits it; a
19123
+ * truly hung load (the actual failure this guards against) would still hang forever whether this
19124
+ * is 30 seconds or 500 seconds, so there is no tradeoff in keeping it generous.
19125
+ *
19119
19126
  * @group Configuration
19120
19127
  */
19121
- var DEFAULT_GLB_LOAD_TIMEOUT_MS = 30000;
19128
+ var DEFAULT_GLB_LOAD_TIMEOUT_MS = 500000;
19122
19129
 
19123
19130
  /**
19124
19131
  * Magic number ("glTF" read little-endian) at byte offset 0 of every binary glTF (`.glb`)
@@ -19320,6 +19327,89 @@ function addScene3DLights(three, scene, lights) {
19320
19327
  }
19321
19328
  return count;
19322
19329
  }
19330
+
19331
+ /** Every material texture-slot property name across three.js's built-in material types. */
19332
+ var MATERIAL_TEXTURE_KEYS = ["map", "alphaMap", "aoMap", "bumpMap", "displacementMap", "emissiveMap", "envMap", "lightMap", "metalnessMap", "normalMap", "roughnessMap", "specularMap", "gradientMap", "clearcoatMap", "clearcoatNormalMap", "clearcoatRoughnessMap", "sheenColorMap", "sheenRoughnessMap", "transmissionMap", "thicknessMap", "iridescenceMap", "iridescenceThicknessMap", "anisotropyMap"];
19333
+ function disposeMaterial(three, material, disposeTextures) {
19334
+ if (disposeTextures) {
19335
+ var record = material;
19336
+ var _iterator2 = threeScene_createForOfIteratorHelper(MATERIAL_TEXTURE_KEYS),
19337
+ _step2;
19338
+ try {
19339
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
19340
+ var key = _step2.value;
19341
+ var value = record[key];
19342
+ if (value instanceof three.Texture) {
19343
+ value.dispose();
19344
+ }
19345
+ }
19346
+ } catch (err) {
19347
+ _iterator2.e(err);
19348
+ } finally {
19349
+ _iterator2.f();
19350
+ }
19351
+ }
19352
+ material.dispose();
19353
+ }
19354
+
19355
+ /**
19356
+ * Disposes every mesh's material(s) under `root`, releasing each one's GPU-side program reference,
19357
+ * without touching geometries or textures. Use this for a group whose geometries/textures are
19358
+ * shared with a still-live cache (e.g. a GLB template reused by future placements via `.clone(true)`)
19359
+ * and only its per-placement material clones (made so each placement's opacity is independent) are
19360
+ * exclusively owned by the group.
19361
+ *
19362
+ * @param three - The resolved Three.js module (from `loadThree()`).
19363
+ */
19364
+ function disposeMaterialsOnly(three, root) {
19365
+ root.traverse(function (obj) {
19366
+ var mesh = obj;
19367
+ if (!mesh.isMesh) return;
19368
+ var materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
19369
+ var _iterator3 = threeScene_createForOfIteratorHelper(materials),
19370
+ _step3;
19371
+ try {
19372
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
19373
+ var material = _step3.value;
19374
+ disposeMaterial(three, material, false);
19375
+ }
19376
+ } catch (err) {
19377
+ _iterator3.e(err);
19378
+ } finally {
19379
+ _iterator3.f();
19380
+ }
19381
+ });
19382
+ }
19383
+
19384
+ /**
19385
+ * Fully disposes every mesh's geometry, material(s), and textures under `root`. Use this only for
19386
+ * an object that exclusively owns its GPU resources — e.g. a loaded GLB template root being evicted
19387
+ * from cache — never for a placement group whose geometries/textures came from a shared template
19388
+ * (use {@link disposeMaterialsOnly} for that instead).
19389
+ *
19390
+ * @param three - The resolved Three.js module (from `loadThree()`).
19391
+ */
19392
+ function disposeObject3D(three, root) {
19393
+ root.traverse(function (obj) {
19394
+ var _mesh$geometry;
19395
+ var mesh = obj;
19396
+ if (!mesh.isMesh) return;
19397
+ (_mesh$geometry = mesh.geometry) === null || _mesh$geometry === void 0 || _mesh$geometry.dispose();
19398
+ var materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
19399
+ var _iterator4 = threeScene_createForOfIteratorHelper(materials),
19400
+ _step4;
19401
+ try {
19402
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
19403
+ var material = _step4.value;
19404
+ disposeMaterial(three, material, true);
19405
+ }
19406
+ } catch (err) {
19407
+ _iterator4.e(err);
19408
+ } finally {
19409
+ _iterator4.f();
19410
+ }
19411
+ });
19412
+ }
19323
19413
  ;// ./src/map/scene3DController.ts
19324
19414
  function scene3DController_typeof(o) { "@babel/helpers - typeof"; return scene3DController_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, scene3DController_typeof(o); }
19325
19415
  function scene3DController_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -19328,12 +19418,12 @@ function scene3DController_slicedToArray(r, e) { return scene3DController_arrayW
19328
19418
  function scene3DController_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
19329
19419
  function scene3DController_iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
19330
19420
  function scene3DController_arrayWithHoles(r) { if (Array.isArray(r)) return r; }
19331
- function scene3DController_createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = scene3DController_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
19332
19421
  function scene3DController_toConsumableArray(r) { return scene3DController_arrayWithoutHoles(r) || scene3DController_iterableToArray(r) || scene3DController_unsupportedIterableToArray(r) || scene3DController_nonIterableSpread(); }
19333
19422
  function scene3DController_nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
19334
- function scene3DController_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return scene3DController_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? scene3DController_arrayLikeToArray(r, a) : void 0; } }
19335
19423
  function scene3DController_iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
19336
19424
  function scene3DController_arrayWithoutHoles(r) { if (Array.isArray(r)) return scene3DController_arrayLikeToArray(r); }
19425
+ function scene3DController_createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = scene3DController_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
19426
+ function scene3DController_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return scene3DController_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? scene3DController_arrayLikeToArray(r, a) : void 0; } }
19337
19427
  function scene3DController_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
19338
19428
  function scene3DController_regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return scene3DController_regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (scene3DController_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, scene3DController_regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, scene3DController_regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), scene3DController_regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", scene3DController_regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), scene3DController_regeneratorDefine2(u), scene3DController_regeneratorDefine2(u, o, "Generator"), scene3DController_regeneratorDefine2(u, n, function () { return this; }), scene3DController_regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (scene3DController_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
19339
19429
  function scene3DController_regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } scene3DController_regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { scene3DController_regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, scene3DController_regeneratorDefine2(e, r, n, t); }
@@ -19386,6 +19476,8 @@ var Scene3DController = /*#__PURE__*/function () {
19386
19476
  scene3DController_defineProperty(this, "scene3DGlbLightCount", 0);
19387
19477
  /** Container group holding all placed GLB pivots; rebuilt on each floor change. */
19388
19478
  scene3DController_defineProperty(this, "scene3DModelsGroup", undefined);
19479
+ /** The GLB custom layer's renderer, stored so {@link dispose} can release it; see `createGlbCustomLayer`. */
19480
+ scene3DController_defineProperty(this, "glbRenderer", undefined);
19389
19481
  /**
19390
19482
  * Route points currently used for GLB route-transparency collision, tagged with the floor on
19391
19483
  * which each point's route segment is visible. Stored as coordinates (not pivot references) so
@@ -19493,11 +19585,20 @@ var Scene3DController = /*#__PURE__*/function () {
19493
19585
  this.applyModelOpacity();
19494
19586
  }
19495
19587
 
19496
- /** Rebuilds the deck overlay and GLB placements for the given floor. */
19588
+ /**
19589
+ * Rebuilds the deck overlay and GLB placements for the given floor. Host apps call this on every
19590
+ * floor/place-changing navigation, including many that leave the floor unchanged (e.g. re-entering
19591
+ * a screen, tapping the already-active floor selector); a no-op floor is skipped so those don't
19592
+ * trigger a full, wasteful GLB rebuild.
19593
+ */
19497
19594
  }, {
19498
19595
  key: "onFloorChange",
19499
19596
  value: function onFloorChange(currentFloor) {
19500
- this.currentFloor = currentFloor !== null && currentFloor !== void 0 ? currentFloor : "";
19597
+ var nextFloor = currentFloor !== null && currentFloor !== void 0 ? currentFloor : "";
19598
+ if (nextFloor === this.currentFloor) {
19599
+ return;
19600
+ }
19601
+ this.currentFloor = nextFloor;
19501
19602
  this.updateDeckOverlay();
19502
19603
  this.placeScene3DModels();
19503
19604
  }
@@ -19510,6 +19611,48 @@ var Scene3DController = /*#__PURE__*/function () {
19510
19611
  this.updateDeckOverlay();
19511
19612
  }
19512
19613
 
19614
+ /**
19615
+ * Releases every GPU resource this controller owns: the placed models group's material clones,
19616
+ * the cached GLB templates' geometries/materials/textures, and the `WebGLRenderer` created for the
19617
+ * declarative GLB layer. Idempotent — safe to call more than once (e.g. once via the custom
19618
+ * layer's own `onRemove` and again explicitly).
19619
+ *
19620
+ * Callers must invoke this themselves before tearing down the map: MapLibre's `map.remove()` does
19621
+ * not call a custom layer's `onRemove`, so without an explicit call here nothing ever frees these
19622
+ * resources, and every context-loss recovery cycle (destroy + recreate the map) leaks a full scene.
19623
+ */
19624
+ }, {
19625
+ key: "dispose",
19626
+ value: function dispose() {
19627
+ var _this$threeMod, _this$glbRenderer;
19628
+ var three = (_this$threeMod = this.threeMod) === null || _this$threeMod === void 0 ? void 0 : _this$threeMod.THREE;
19629
+ if (three) {
19630
+ if (this.scene3DModelsGroup) {
19631
+ disposeMaterialsOnly(three, this.scene3DModelsGroup);
19632
+ this.scene3DModelsGroup = undefined;
19633
+ }
19634
+ // Iterate the deduplicated-by-URL roots (not `scene3DGlbTemplateById`, which may map several
19635
+ // asset ids to the same root) so a shared root is never disposed more than once.
19636
+ var _iterator = scene3DController_createForOfIteratorHelper(this.scene3DGlbRootByUrl.values()),
19637
+ _step;
19638
+ try {
19639
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
19640
+ var root = _step.value;
19641
+ disposeObject3D(three, root);
19642
+ }
19643
+ } catch (err) {
19644
+ _iterator.e(err);
19645
+ } finally {
19646
+ _iterator.f();
19647
+ }
19648
+ }
19649
+ this.scene3DGlbRootByUrl.clear();
19650
+ this.scene3DGlbTemplateById.clear();
19651
+ this.scene3DGlbScene = undefined;
19652
+ (_this$glbRenderer = this.glbRenderer) === null || _this$glbRenderer === void 0 || _this$glbRenderer.dispose();
19653
+ this.glbRenderer = undefined;
19654
+ }
19655
+
19513
19656
  // Internal implementation -----------------------------------------------------------------
19514
19657
 
19515
19658
  /**
@@ -19520,15 +19663,15 @@ var Scene3DController = /*#__PURE__*/function () {
19520
19663
  key: "ensure3DLibs",
19521
19664
  value: function () {
19522
19665
  var _ensure3DLibs = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee2() {
19523
- var _this$threeMod, _this$deckMod;
19666
+ var _this$threeMod2, _this$deckMod;
19524
19667
  return scene3DController_regenerator().w(function (_context2) {
19525
19668
  while (1) switch (_context2.n) {
19526
19669
  case 0:
19527
- if (!((_this$threeMod = this.threeMod) !== null && _this$threeMod !== void 0)) {
19670
+ if (!((_this$threeMod2 = this.threeMod) !== null && _this$threeMod2 !== void 0)) {
19528
19671
  _context2.n = 1;
19529
19672
  break;
19530
19673
  }
19531
- _this$threeMod;
19674
+ _this$threeMod2;
19532
19675
  _context2.n = 3;
19533
19676
  break;
19534
19677
  case 1:
@@ -19599,6 +19742,13 @@ var Scene3DController = /*#__PURE__*/function () {
19599
19742
  renderer.setSize = function (width, height) {
19600
19743
  this.setViewport(0, 0, width, height);
19601
19744
  };
19745
+ // Stored on the controller (not just this closure) so `dispose()` can release it — MapLibre
19746
+ // does not call a custom layer's `onRemove` when the whole map/style is torn down via
19747
+ // `map.remove()`, so callers must dispose this controller explicitly before that happens.
19748
+ _this.glbRenderer = renderer;
19749
+ },
19750
+ onRemove: function onRemove() {
19751
+ _this.dispose();
19602
19752
  },
19603
19753
  render: function render(_gl, args) {
19604
19754
  var _args$defaultProjecti;
@@ -19628,13 +19778,13 @@ var Scene3DController = /*#__PURE__*/function () {
19628
19778
  key: "loadScene3DGlbTemplates",
19629
19779
  value: function () {
19630
19780
  var _loadScene3DGlbTemplates = scene3DController_asyncToGenerator(/*#__PURE__*/scene3DController_regenerator().m(function _callee4() {
19631
- var _this$threeMod2,
19781
+ var _this$threeMod3,
19632
19782
  _this2 = this;
19633
- var three, models, uniqueUrls, errorByUrl, semaphore, loadedBytesByUrl, totalBytesByUrl, settledAssets, totalAssets, reportProgress, _iterator2, _step2, asset, root, center, _t5;
19783
+ var three, models, uniqueUrls, errorByUrl, semaphore, loadedBytesByUrl, totalBytesByUrl, settledAssets, totalAssets, reportProgress, _iterator3, _step3, asset, root, center, _t5;
19634
19784
  return scene3DController_regenerator().w(function (_context4) {
19635
19785
  while (1) switch (_context4.p = _context4.n) {
19636
19786
  case 0:
19637
- three = (_this$threeMod2 = this.threeMod) === null || _this$threeMod2 === void 0 ? void 0 : _this$threeMod2.THREE;
19787
+ three = (_this$threeMod3 = this.threeMod) === null || _this$threeMod3 === void 0 ? void 0 : _this$threeMod3.THREE;
19638
19788
  models = this.scene3DConfig.models;
19639
19789
  if (!(!three || !models || models.enabled === false || models.assets.length === 0)) {
19640
19790
  _context4.n = 1;
@@ -19664,20 +19814,20 @@ var Scene3DController = /*#__PURE__*/function () {
19664
19814
  if (!_this2.onModelsProgress) return;
19665
19815
  var loadedBytes = 0;
19666
19816
  var totalBytes = 0;
19667
- var _iterator = scene3DController_createForOfIteratorHelper(uniqueUrls),
19668
- _step;
19817
+ var _iterator2 = scene3DController_createForOfIteratorHelper(uniqueUrls),
19818
+ _step2;
19669
19819
  try {
19670
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
19820
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
19671
19821
  var _loadedBytesByUrl$get;
19672
- var url = _step.value;
19822
+ var url = _step2.value;
19673
19823
  loadedBytes += (_loadedBytesByUrl$get = loadedBytesByUrl.get(url)) !== null && _loadedBytesByUrl$get !== void 0 ? _loadedBytesByUrl$get : 0;
19674
19824
  var total = totalBytesByUrl.get(url);
19675
19825
  totalBytes = total == null || totalBytes === null ? null : totalBytes + total;
19676
19826
  }
19677
19827
  } catch (err) {
19678
- _iterator.e(err);
19828
+ _iterator2.e(err);
19679
19829
  } finally {
19680
- _iterator.f();
19830
+ _iterator2.f();
19681
19831
  }
19682
19832
  try {
19683
19833
  _this2.onModelsProgress({
@@ -19745,15 +19895,15 @@ var Scene3DController = /*#__PURE__*/function () {
19745
19895
  }()));
19746
19896
  case 2:
19747
19897
  reportProgress(true);
19748
- _iterator2 = scene3DController_createForOfIteratorHelper(models.assets);
19898
+ _iterator3 = scene3DController_createForOfIteratorHelper(models.assets);
19749
19899
  _context4.p = 3;
19750
- _iterator2.s();
19900
+ _iterator3.s();
19751
19901
  case 4:
19752
- if ((_step2 = _iterator2.n()).done) {
19902
+ if ((_step3 = _iterator3.n()).done) {
19753
19903
  _context4.n = 7;
19754
19904
  break;
19755
19905
  }
19756
- asset = _step2.value;
19906
+ asset = _step3.value;
19757
19907
  root = this.scene3DGlbRootByUrl.get(asset.url);
19758
19908
  if (root) {
19759
19909
  _context4.n = 5;
@@ -19776,10 +19926,10 @@ var Scene3DController = /*#__PURE__*/function () {
19776
19926
  case 8:
19777
19927
  _context4.p = 8;
19778
19928
  _t5 = _context4.v;
19779
- _iterator2.e(_t5);
19929
+ _iterator3.e(_t5);
19780
19930
  case 9:
19781
19931
  _context4.p = 9;
19782
- _iterator2.f();
19932
+ _iterator3.f();
19783
19933
  return _context4.f(9);
19784
19934
  case 10:
19785
19935
  return _context4.a(2);
@@ -19794,7 +19944,7 @@ var Scene3DController = /*#__PURE__*/function () {
19794
19944
  }, {
19795
19945
  key: "placeScene3DModels",
19796
19946
  value: function placeScene3DModels() {
19797
- var _this$threeMod3,
19947
+ var _this$threeMod4,
19798
19948
  _models$globalOffset$,
19799
19949
  _models$globalOffset,
19800
19950
  _models$globalOffset$2,
@@ -19802,7 +19952,7 @@ var Scene3DController = /*#__PURE__*/function () {
19802
19952
  _models$globalOffset$3,
19803
19953
  _models$globalOffset3,
19804
19954
  _this3 = this;
19805
- var three = (_this$threeMod3 = this.threeMod) === null || _this$threeMod3 === void 0 ? void 0 : _this$threeMod3.THREE;
19955
+ var three = (_this$threeMod4 = this.threeMod) === null || _this$threeMod4 === void 0 ? void 0 : _this$threeMod4.THREE;
19806
19956
  if (!three || !this.scene3DGlbScene) {
19807
19957
  return;
19808
19958
  }
@@ -19811,6 +19961,10 @@ var Scene3DController = /*#__PURE__*/function () {
19811
19961
  return;
19812
19962
  }
19813
19963
  if (this.scene3DModelsGroup) {
19964
+ // Only the per-placement material clones (made below so each placement's zoom-based opacity
19965
+ // is independent) are exclusively owned by this group — geometries/textures come from the
19966
+ // cached templates and stay alive for the next rebuild, so they must not be disposed here.
19967
+ disposeMaterialsOnly(three, this.scene3DModelsGroup);
19814
19968
  this.scene3DGlbScene.remove(this.scene3DModelsGroup);
19815
19969
  this.scene3DModelsGroup = undefined;
19816
19970
  }
@@ -19822,12 +19976,12 @@ var Scene3DController = /*#__PURE__*/function () {
19822
19976
  var floorKey = this.currentFloor;
19823
19977
  var modelsGroup = new three.Group();
19824
19978
  modelsGroup.position.set((_models$globalOffset$ = (_models$globalOffset = models.globalOffset) === null || _models$globalOffset === void 0 ? void 0 : _models$globalOffset.x) !== null && _models$globalOffset$ !== void 0 ? _models$globalOffset$ : 0, (_models$globalOffset$2 = (_models$globalOffset2 = models.globalOffset) === null || _models$globalOffset2 === void 0 ? void 0 : _models$globalOffset2.y) !== null && _models$globalOffset$2 !== void 0 ? _models$globalOffset$2 : 0, (_models$globalOffset$3 = (_models$globalOffset3 = models.globalOffset) === null || _models$globalOffset3 === void 0 ? void 0 : _models$globalOffset3.z) !== null && _models$globalOffset$3 !== void 0 ? _models$globalOffset$3 : 0);
19825
- var _iterator3 = scene3DController_createForOfIteratorHelper(models.placements),
19826
- _step3;
19979
+ var _iterator4 = scene3DController_createForOfIteratorHelper(models.placements),
19980
+ _step4;
19827
19981
  try {
19828
19982
  var _loop = function _loop() {
19829
19983
  var _placement$position$a;
19830
- var placement = _step3.value;
19984
+ var placement = _step4.value;
19831
19985
  if (!isPlacementVisibleOnFloor(placement, floorKey)) {
19832
19986
  return 0; // continue
19833
19987
  }
@@ -19893,14 +20047,14 @@ var Scene3DController = /*#__PURE__*/function () {
19893
20047
  modelsGroup.add(pivot);
19894
20048
  },
19895
20049
  _ret;
19896
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
20050
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
19897
20051
  _ret = _loop();
19898
20052
  if (_ret === 0) continue;
19899
20053
  }
19900
20054
  } catch (err) {
19901
- _iterator3.e(err);
20055
+ _iterator4.e(err);
19902
20056
  } finally {
19903
- _iterator3.f();
20057
+ _iterator4.f();
19904
20058
  }
19905
20059
  this.scene3DModelsGroup = modelsGroup;
19906
20060
  this.scene3DGlbScene.add(modelsGroup);
@@ -19920,9 +20074,9 @@ var Scene3DController = /*#__PURE__*/function () {
19920
20074
  }, {
19921
20075
  key: "recomputeRouteAffectedModels",
19922
20076
  value: function recomputeRouteAffectedModels() {
19923
- var _this$threeMod4,
20077
+ var _this$threeMod5,
19924
20078
  _this4 = this;
19925
- var three = (_this$threeMod4 = this.threeMod) === null || _this$threeMod4 === void 0 ? void 0 : _this$threeMod4.THREE;
20079
+ var three = (_this$threeMod5 = this.threeMod) === null || _this$threeMod5 === void 0 ? void 0 : _this$threeMod5.THREE;
19926
20080
  var modelsGroup = this.scene3DModelsGroup;
19927
20081
  if (!three || !modelsGroup) {
19928
20082
  return;
@@ -19945,11 +20099,11 @@ var Scene3DController = /*#__PURE__*/function () {
19945
20099
  });
19946
20100
  modelsGroup.updateMatrixWorld(true);
19947
20101
  var local = new three.Vector3();
19948
- var _iterator4 = scene3DController_createForOfIteratorHelper(modelsGroup.children),
19949
- _step4;
20102
+ var _iterator5 = scene3DController_createForOfIteratorHelper(modelsGroup.children),
20103
+ _step5;
19950
20104
  try {
19951
20105
  var _loop2 = function _loop2() {
19952
- var pivot = _step4.value;
20106
+ var pivot = _step5.value;
19953
20107
  var routeCfg = pivot.userData.routeTransparency;
19954
20108
  var footprint = pivot.userData.footprint;
19955
20109
  // Only models with a route-transparency config participate (feature activation gate).
@@ -19966,13 +20120,13 @@ var Scene3DController = /*#__PURE__*/function () {
19966
20120
  return pointInFootprint(footprint, local.x, local.z);
19967
20121
  });
19968
20122
  };
19969
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
20123
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
19970
20124
  if (_loop2()) continue;
19971
20125
  }
19972
20126
  } catch (err) {
19973
- _iterator4.e(err);
20127
+ _iterator5.e(err);
19974
20128
  } finally {
19975
- _iterator4.f();
20129
+ _iterator5.f();
19976
20130
  }
19977
20131
  }
19978
20132
 
@@ -19992,11 +20146,11 @@ var Scene3DController = /*#__PURE__*/function () {
19992
20146
  }
19993
20147
  var zoom = this.map.getZoom();
19994
20148
  var changed = false;
19995
- var _iterator5 = scene3DController_createForOfIteratorHelper(this.scene3DModelsGroup.children),
19996
- _step5;
20149
+ var _iterator6 = scene3DController_createForOfIteratorHelper(this.scene3DModelsGroup.children),
20150
+ _step6;
19997
20151
  try {
19998
20152
  var _loop3 = function _loop3() {
19999
- var pivot = _step5.value;
20153
+ var pivot = _step6.value;
20000
20154
  var zoomCfg = pivot.userData.zoomTransparency;
20001
20155
  var routeCfg = pivot.userData.routeTransparency;
20002
20156
  var routeAffected = pivot.userData.routeAffected === true;
@@ -20007,11 +20161,11 @@ var Scene3DController = /*#__PURE__*/function () {
20007
20161
  return;
20008
20162
  }
20009
20163
  var materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
20010
- var _iterator6 = scene3DController_createForOfIteratorHelper(materials),
20011
- _step6;
20164
+ var _iterator7 = scene3DController_createForOfIteratorHelper(materials),
20165
+ _step7;
20012
20166
  try {
20013
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
20014
- var material = _step6.value;
20167
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
20168
+ var material = _step7.value;
20015
20169
  if (material.opacity !== opacity) {
20016
20170
  material.transparent = opacity < 1;
20017
20171
  material.opacity = opacity;
@@ -20021,19 +20175,19 @@ var Scene3DController = /*#__PURE__*/function () {
20021
20175
  }
20022
20176
  }
20023
20177
  } catch (err) {
20024
- _iterator6.e(err);
20178
+ _iterator7.e(err);
20025
20179
  } finally {
20026
- _iterator6.f();
20180
+ _iterator7.f();
20027
20181
  }
20028
20182
  });
20029
20183
  };
20030
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
20184
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
20031
20185
  _loop3();
20032
20186
  }
20033
20187
  } catch (err) {
20034
- _iterator5.e(err);
20188
+ _iterator6.e(err);
20035
20189
  } finally {
20036
- _iterator5.f();
20190
+ _iterator6.f();
20037
20191
  }
20038
20192
  if (changed) {
20039
20193
  this.map.triggerRepaint();
@@ -20285,19 +20439,19 @@ var Scene3DController = /*#__PURE__*/function () {
20285
20439
  key: "hideLayers",
20286
20440
  value: function hideLayers(layersIds) {
20287
20441
  if (!layersIds) return;
20288
- var _iterator7 = scene3DController_createForOfIteratorHelper(layersIds),
20289
- _step7;
20442
+ var _iterator8 = scene3DController_createForOfIteratorHelper(layersIds),
20443
+ _step8;
20290
20444
  try {
20291
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
20292
- var layerId = _step7.value;
20445
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
20446
+ var layerId = _step8.value;
20293
20447
  var layer = this.map.getLayer(layerId);
20294
20448
  if (!layer) continue;
20295
20449
  this.map.setLayoutProperty(layer.id, "visibility", "none");
20296
20450
  }
20297
20451
  } catch (err) {
20298
- _iterator7.e(err);
20452
+ _iterator8.e(err);
20299
20453
  } finally {
20300
- _iterator7.f();
20454
+ _iterator8.f();
20301
20455
  }
20302
20456
  }
20303
20457
  }]);
@@ -21122,8 +21276,12 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
21122
21276
  }, {
21123
21277
  key: "destroyMap",
21124
21278
  value: function destroyMap() {
21279
+ var _this$scene3D;
21125
21280
  this.circles = [];
21126
21281
  this.markerLayoutController.destroy();
21282
+ // Dispose the 3D scene's GPU resources before the map (and its shared WebGL context) go away —
21283
+ // MapLibre's own teardown never calls the custom GLB layer's `onRemove`.
21284
+ (_this$scene3D = this.scene3D) === null || _this$scene3D === void 0 || _this$scene3D.dispose();
21127
21285
  this.map.remove();
21128
21286
  this.unsubscribeFromFailedTiles();
21129
21287
  }
@@ -21176,11 +21334,11 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
21176
21334
  }, {
21177
21335
  key: "setRouteCollisionPath",
21178
21336
  value: function setRouteCollisionPath(points) {
21179
- var _this$scene3D;
21337
+ var _this$scene3D2;
21180
21338
  if (!this.is3DSceneActive()) {
21181
21339
  return;
21182
21340
  }
21183
- (_this$scene3D = this.scene3D) === null || _this$scene3D === void 0 || _this$scene3D.setRouteCollisionPath(points);
21341
+ (_this$scene3D2 = this.scene3D) === null || _this$scene3D2 === void 0 || _this$scene3D2.setRouteCollisionPath(points);
21184
21342
  }
21185
21343
 
21186
21344
  /**
@@ -21197,7 +21355,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
21197
21355
  _this$innerFloors$fin,
21198
21356
  _this$innerFloors$fin2,
21199
21357
  _this$innerFloors$,
21200
- _this$scene3D2,
21358
+ _this$scene3D3,
21201
21359
  _this9 = this;
21202
21360
  var updateStyle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
21203
21361
  var onStyleReady = arguments.length > 2 ? arguments[2] : undefined;
@@ -21212,7 +21370,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
21212
21370
  if (place) {
21213
21371
  this.subPlacesLoad(place.mapvxId);
21214
21372
  }
21215
- (_this$scene3D2 = this.scene3D) === null || _this$scene3D2 === void 0 || _this$scene3D2.onFloorChange(this.currentFloor);
21373
+ (_this$scene3D3 = this.scene3D) === null || _this$scene3D3 === void 0 || _this$scene3D3.onFloorChange(this.currentFloor);
21216
21374
  if (updateStyle) {
21217
21375
  this.repository.fetchAndParseMapStyle(place === null || place === void 0 ? void 0 : place.mapvxId).then(function (style) {
21218
21376
  var useServiceWorkerCaching = _this9.tileCacheConfig.enabled && _this9.tileCacheConfig.persistToServiceWorker;
@@ -21234,7 +21392,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
21234
21392
  }, {
21235
21393
  key: "updatePlaceAndFloor",
21236
21394
  value: function updatePlaceAndFloor(parentPlaceId, floorId) {
21237
- var _place$innerFloors$so2, _ref2, _ref3, _this$innerFloors$fin3, _this$innerFloors$2, _this$scene3D3;
21395
+ var _place$innerFloors$so2, _ref2, _ref3, _this$innerFloors$fin3, _this$innerFloors$2, _this$scene3D4;
21238
21396
  var place = this.potentialParentPlaces.find(function (place) {
21239
21397
  return place.mapvxId === parentPlaceId;
21240
21398
  });
@@ -21246,7 +21404,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
21246
21404
  this.currentFloor = (_ref2 = (_ref3 = floorId !== null && floorId !== void 0 ? floorId : (_this$innerFloors$fin3 = this.innerFloors.find(function (floor) {
21247
21405
  return floor.defaultFloor;
21248
21406
  })) === null || _this$innerFloors$fin3 === void 0 ? void 0 : _this$innerFloors$fin3.key) !== null && _ref3 !== void 0 ? _ref3 : (_this$innerFloors$2 = this.innerFloors[0]) === null || _this$innerFloors$2 === void 0 ? void 0 : _this$innerFloors$2.key) !== null && _ref2 !== void 0 ? _ref2 : "";
21249
- (_this$scene3D3 = this.scene3D) === null || _this$scene3D3 === void 0 || _this$scene3D3.onFloorChange(this.currentFloor);
21407
+ (_this$scene3D4 = this.scene3D) === null || _this$scene3D4 === void 0 || _this$scene3D4.onFloorChange(this.currentFloor);
21250
21408
  }
21251
21409
  }, {
21252
21410
  key: "updateParentPlaceAndFloor",
@@ -21306,14 +21464,14 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
21306
21464
  }, {
21307
21465
  key: "whenStyleUpdates",
21308
21466
  value: function whenStyleUpdates(newStyle) {
21309
- var _this$scene3D4;
21467
+ var _this$scene3D5;
21310
21468
  if (newStyle) {
21311
21469
  this.setBaseFilters(newStyle);
21312
21470
  }
21313
21471
  this.routeController.addSourcesAndLayers();
21314
21472
  this.refreshCircles();
21315
21473
  this.filterByFloorKey(this.currentFloor);
21316
- (_this$scene3D4 = this.scene3D) === null || _this$scene3D4 === void 0 || _this$scene3D4.refreshOverlay(this.currentFloor);
21474
+ (_this$scene3D5 = this.scene3D) === null || _this$scene3D5 === void 0 || _this$scene3D5.refreshOverlay(this.currentFloor);
21317
21475
  }
21318
21476
 
21319
21477
  /**
@@ -22227,9 +22385,9 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
22227
22385
  key: "updateFloor",
22228
22386
  value: function updateFloor(floorId, options) {
22229
22387
  try {
22230
- var _this$scene3D5, _this$onFloorChange2, _options$onComplete6;
22388
+ var _this$scene3D6, _this$onFloorChange2, _options$onComplete6;
22231
22389
  this.filterByFloorKey(floorId);
22232
- (_this$scene3D5 = this.scene3D) === null || _this$scene3D5 === void 0 || _this$scene3D5.onFloorChange(this.currentFloor);
22390
+ (_this$scene3D6 = this.scene3D) === null || _this$scene3D6 === void 0 || _this$scene3D6.onFloorChange(this.currentFloor);
22233
22391
  (_this$onFloorChange2 = this.onFloorChange) === null || _this$onFloorChange2 === void 0 || _this$onFloorChange2.call(this, floorId);
22234
22392
  this.logEvent("updateFloor", {
22235
22393
  floorId: floorId