minerender 2.1.0-alpha.76 → 2.1.0-alpha.78

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.
@@ -814,8 +814,8 @@ var init_Textures = __esm({
814
814
  for (let y = 0; y < size; y++) {
815
815
  for (let x = 0; x < size; x++) {
816
816
  const offset = (y * size + x) * 4;
817
- const color = (x + y) % 2 === 0 ? 255 : 0;
818
- data[offset] = data[offset + 2] = color;
817
+ const color2 = (x + y) % 2 === 0 ? 255 : 0;
818
+ data[offset] = data[offset + 2] = color2;
819
819
  data[offset + 3] = 255;
820
820
  }
821
821
  }
@@ -1400,17 +1400,17 @@ var init_AssetKey = __esm({
1400
1400
  var DisplayPosition, DISPLAY_POSITIONS;
1401
1401
  var init_DisplayPosition = __esm({
1402
1402
  "src/model/DisplayPosition.ts"() {
1403
- DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
1404
- DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1405
- DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1406
- DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1407
- DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1408
- DisplayPosition2["GUI"] = "gui";
1409
- DisplayPosition2["HEAD"] = "head";
1410
- DisplayPosition2["GROUND"] = "ground";
1411
- DisplayPosition2["FIXED"] = "fixed";
1412
- DisplayPosition2["ON_SHELF"] = "on_shelf";
1413
- return DisplayPosition2;
1403
+ DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1404
+ DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1405
+ DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1406
+ DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1407
+ DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1408
+ DisplayPosition3["GUI"] = "gui";
1409
+ DisplayPosition3["HEAD"] = "head";
1410
+ DisplayPosition3["GROUND"] = "ground";
1411
+ DisplayPosition3["FIXED"] = "fixed";
1412
+ DisplayPosition3["ON_SHELF"] = "on_shelf";
1413
+ return DisplayPosition3;
1414
1414
  })(DisplayPosition || {});
1415
1415
  DISPLAY_POSITIONS = Object.values(DisplayPosition);
1416
1416
  }
@@ -1628,11 +1628,11 @@ var init_Models = __esm({
1628
1628
  return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
1629
1629
  return AssetLoader.get(key, "model" /* MODEL */);
1630
1630
  });
1631
- }).then((asset) => {
1632
- if (asset) {
1633
- asset.key = key;
1631
+ }).then((asset2) => {
1632
+ if (asset2) {
1633
+ asset2.key = key;
1634
1634
  }
1635
- return asset;
1635
+ return asset2;
1636
1636
  });
1637
1637
  }
1638
1638
  /**
@@ -1722,11 +1722,11 @@ var init_BlockStates = __esm({
1722
1722
  return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
1723
1723
  return AssetLoader.get(key, "blockstate" /* BLOCKSTATE */);
1724
1724
  });
1725
- }).then((asset) => {
1726
- if (asset) {
1727
- asset.key = key;
1725
+ }).then((asset2) => {
1726
+ if (asset2) {
1727
+ asset2.key = key;
1728
1728
  }
1729
- return asset;
1729
+ return asset2;
1730
1730
  });
1731
1731
  }
1732
1732
  static getAll(keys) {
@@ -1875,29 +1875,29 @@ function applyGenericRotation(axis, rotation, obj) {
1875
1875
  break;
1876
1876
  }
1877
1877
  }
1878
- function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1878
+ function addBox3WireframeToObject(box, obj, color2 = 16777215, w = 2) {
1879
1879
  let size = new import_three8.Vector3();
1880
1880
  box.getSize(size);
1881
1881
  let boxGeo = new import_three8.BoxGeometry(size.x, size.y, size.z, 1, 1, 1);
1882
1882
  let wireGeo = new import_three8.EdgesGeometry(boxGeo);
1883
- let wireMat = new import_three8.LineBasicMaterial({ color, linewidth: w });
1883
+ let wireMat = new import_three8.LineBasicMaterial({ color: color2, linewidth: w });
1884
1884
  let wireframe = new import_three8.LineSegments(wireGeo, wireMat);
1885
1885
  obj.add(wireframe);
1886
1886
  let axes = new import_three8.AxesHelper(1);
1887
1887
  obj.add(axes);
1888
1888
  }
1889
- function addWireframeToObject(obj, color = 16777215, w = 2) {
1889
+ function addWireframeToObject(obj, color2 = 16777215, w = 2) {
1890
1890
  let boxGeo = new import_three8.BoxGeometry(16, 16, 16, 1, 1, 1);
1891
1891
  let wireGeo = new import_three8.EdgesGeometry(boxGeo);
1892
- let wireMat = new import_three8.LineBasicMaterial({ color, linewidth: w });
1892
+ let wireMat = new import_three8.LineBasicMaterial({ color: color2, linewidth: w });
1893
1893
  let wireframe = new import_three8.LineSegments(wireGeo, wireMat);
1894
1894
  obj.add(wireframe);
1895
1895
  let axes = new import_three8.AxesHelper(1);
1896
1896
  obj.add(axes);
1897
1897
  }
1898
- function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
1898
+ function addWireframeToMesh(geo, mesh, color2 = 16777215, w = 2) {
1899
1899
  let wireGeo = new import_three8.EdgesGeometry(geo);
1900
- let wireMat = new import_three8.LineBasicMaterial({ color, linewidth: w });
1900
+ let wireMat = new import_three8.LineBasicMaterial({ color: color2, linewidth: w });
1901
1901
  let wireframe = new import_three8.LineSegments(wireGeo, wireMat);
1902
1902
  mesh.add(wireframe);
1903
1903
  let axes = new import_three8.AxesHelper(1);
@@ -2328,27 +2328,27 @@ var init_PackFormats = __esm({
2328
2328
  init_Requests();
2329
2329
  PackFormats = class {
2330
2330
  /** Resolves pack formats from Mojang's client metadata hosted on assets.mcasset.cloud. */
2331
- static async get(version, type) {
2332
- let pending = this.versions.get(version);
2331
+ static async get(version2, type) {
2332
+ let pending = this.versions.get(version2);
2333
2333
  if (!pending || pending.expires <= Date.now()) {
2334
2334
  pending = {
2335
- formats: this.load(version),
2336
- expires: ["latest", "release", "snapshot"].includes(version) ? Date.now() + 3e5 : Infinity
2335
+ formats: this.load(version2),
2336
+ expires: ["latest", "release", "snapshot"].includes(version2) ? Date.now() + 3e5 : Infinity
2337
2337
  };
2338
- this.versions.set(version, pending);
2338
+ this.versions.set(version2, pending);
2339
2339
  }
2340
2340
  try {
2341
2341
  return (await pending.formats)[type];
2342
2342
  } catch (cause) {
2343
- if (this.versions.get(version) === pending) this.versions.delete(version);
2343
+ if (this.versions.get(version2) === pending) this.versions.delete(version2);
2344
2344
  const option = type === "assets" ? "resourcePackFormat" : "dataPackFormat";
2345
2345
  const reason = cause instanceof Error ? cause.message : String(cause);
2346
- throw new Error(`Could not resolve the pack format for Minecraft ${version}. Set ArchiveAssetSource ${option} explicitly. ${reason}`);
2346
+ throw new Error(`Could not resolve the pack format for Minecraft ${version2}. Set ArchiveAssetSource ${option} explicitly. ${reason}`);
2347
2347
  }
2348
2348
  }
2349
- static async load(version) {
2349
+ static async load(version2) {
2350
2350
  const response = await Requests.genericRequest({
2351
- url: `https://assets.mcasset.cloud/${encodeURIComponent(version)}/game-version.json`,
2351
+ url: `https://assets.mcasset.cloud/${encodeURIComponent(version2)}/game-version.json`,
2352
2352
  responseType: "json"
2353
2353
  });
2354
2354
  const data = response.data;
@@ -2437,7 +2437,7 @@ var init_ArchiveAssetSource = __esm({
2437
2437
  }
2438
2438
  async load(key, parser) {
2439
2439
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
2440
- const version = AssetLoader.version;
2440
+ const version2 = AssetLoader.version;
2441
2441
  let selectedPath = path;
2442
2442
  let url;
2443
2443
  try {
@@ -2445,7 +2445,7 @@ var init_ArchiveAssetSource = __esm({
2445
2445
  if (key.rootType === "assets" || key.rootType === "data") {
2446
2446
  const metadata = await this.getMetadata(key);
2447
2447
  if (metadata.hasOverlays) {
2448
- const format2 = (key.rootType === "assets" ? this.options.resourcePackFormat : this.options.dataPackFormat) ?? await PackFormats.get(version, key.rootType);
2448
+ const format2 = (key.rootType === "assets" ? this.options.resourcePackFormat : this.options.dataPackFormat) ?? await PackFormats.get(version2, key.rootType);
2449
2449
  directories = metadata.overlayDirectories(format2);
2450
2450
  }
2451
2451
  }
@@ -2532,8 +2532,8 @@ var init_AssetLoader = __esm({
2532
2532
  return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
2533
2533
  }
2534
2534
  /** Selects an mcasset.cloud version, updates the vanilla source, and clears in-memory caches. */
2535
- static setVersion(version) {
2536
- this.ROOT = `https://assets.mcasset.cloud/${version}`;
2535
+ static setVersion(version2) {
2536
+ this.ROOT = `https://assets.mcasset.cloud/${version2}`;
2537
2537
  const source = new HostedAssetSource(this.ROOT, { retryDefaults: false });
2538
2538
  const index = this._SOURCES.findIndex((s) => s.key === "mcassets");
2539
2539
  if (index !== -1) {
@@ -2598,8 +2598,8 @@ ${key}` : key;
2598
2598
  const sources = [...this._SOURCES];
2599
2599
  const results = [];
2600
2600
  for (const { source } of sources) {
2601
- const asset = await source.get(key, parser);
2602
- if (asset != void 0) results.push(asset);
2601
+ const asset2 = await source.get(key, parser);
2602
+ if (asset2 != void 0) results.push(asset2);
2603
2603
  if (await source.blocks(key)) break;
2604
2604
  }
2605
2605
  return results;
@@ -2669,9 +2669,9 @@ var init_ModelTextures = __esm({
2669
2669
  const pending = this.preload(key);
2670
2670
  const cached2 = Caching.textureAssetCache.getIfPresent(keyStr);
2671
2671
  try {
2672
- const asset = await pending;
2673
- if (asset) {
2674
- return await ImageLoader.infoToCanvasData(asset);
2672
+ const asset2 = await pending;
2673
+ if (asset2) {
2674
+ return await ImageLoader.infoToCanvasData(asset2);
2675
2675
  }
2676
2676
  return void 0;
2677
2677
  } catch (err) {
@@ -2685,10 +2685,10 @@ var init_ModelTextures = __esm({
2685
2685
  static async preload(key) {
2686
2686
  const keyStr = key.serialize();
2687
2687
  return Caching.textureAssetCache.get(keyStr, (k) => {
2688
- return AssetLoader.get(key, "image" /* IMAGE */).then((asset) => {
2689
- if (asset)
2690
- asset.key = key;
2691
- return asset;
2688
+ return AssetLoader.get(key, "image" /* IMAGE */).then((asset2) => {
2689
+ if (asset2)
2690
+ asset2.key = key;
2691
+ return asset2;
2692
2692
  });
2693
2693
  });
2694
2694
  }
@@ -2701,10 +2701,10 @@ var init_ModelTextures = __esm({
2701
2701
  const keyStr = key.serialize();
2702
2702
  return Caching.textureMetaCache.get(keyStr, (k) => {
2703
2703
  return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
2704
- return AssetLoader.get(key, "meta" /* META */).then((asset) => {
2705
- if (asset)
2706
- asset.key = key;
2707
- return asset;
2704
+ return AssetLoader.get(key, "meta" /* META */).then((asset2) => {
2705
+ if (asset2)
2706
+ asset2.key = key;
2707
+ return asset2;
2708
2708
  });
2709
2709
  });
2710
2710
  });
@@ -3258,12 +3258,12 @@ var init_UVMapper = __esm({
3258
3258
  } else {
3259
3259
  uniqueTextureNames.push(textureKey);
3260
3260
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
3261
- promises.push(ModelTextures.get(assetKey).then((asset) => {
3262
- if (!asset) {
3261
+ promises.push(ModelTextures.get(assetKey).then((asset2) => {
3262
+ if (!asset2) {
3263
3263
  console.warn(p5, "Missing texture", assetKey);
3264
3264
  return;
3265
3265
  }
3266
- textureMap[textureKey] = new WrappedImage(asset);
3266
+ textureMap[textureKey] = new WrappedImage(asset2);
3267
3267
  }));
3268
3268
  promises.push(ModelTextures.getMeta(assetKey).then((meta) => {
3269
3269
  metaMap[textureKey] = meta;
@@ -3607,10 +3607,10 @@ var init_Entities = __esm({
3607
3607
  const collect = async (path) => {
3608
3608
  const prefix2 = path ? `${path}/` : "";
3609
3609
  const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
3610
- const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
3611
- if (!list) return [];
3612
- const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
3613
- const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
3610
+ const list2 = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
3611
+ if (!list2) return [];
3612
+ const files = list2.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
3613
+ const children = await Promise.all(list2.directories.map((directory) => collect(`${prefix2}${directory}`)));
3614
3614
  return [...files, ...children.flat()];
3615
3615
  };
3616
3616
  return collect("");
@@ -3694,8 +3694,8 @@ var init_Entities = __esm({
3694
3694
  if (await ModelTextures.get(texture2)) return texture2;
3695
3695
  }
3696
3696
  const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json", root);
3697
- const list = await AssetLoader.get(listKey, "list" /* LIST */);
3698
- const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
3697
+ const list2 = await AssetLoader.get(listKey, "list" /* LIST */);
3698
+ const files = list2?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
3699
3699
  const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
3700
3700
  if (!file) return void 0;
3701
3701
  const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json", root);
@@ -3800,27 +3800,27 @@ var init_EntityAnimationPlayer = __esm({
3800
3800
  for (const layer of layers) {
3801
3801
  const objects = [];
3802
3802
  if (poses) {
3803
- layer.traverse((object2) => {
3804
- if (poses.has(object2)) objects.push(object2);
3803
+ layer.traverse((object3) => {
3804
+ if (poses.has(object3)) objects.push(object3);
3805
3805
  });
3806
3806
  } else {
3807
3807
  for (const bone of Object.keys(animation.bones)) {
3808
- const object2 = layer.getObjectByName(`group:${bone}`);
3809
- if (object2) objects.push(object2);
3808
+ const object3 = layer.getObjectByName(`group:${bone}`);
3809
+ if (object3) objects.push(object3);
3810
3810
  }
3811
3811
  }
3812
- for (const object2 of objects) {
3813
- const bone = object2.name.slice("group:".length);
3814
- const pose = poses?.get(object2);
3812
+ for (const object3 of objects) {
3813
+ const bone = object3.name.slice("group:".length);
3814
+ const pose = poses?.get(object3);
3815
3815
  this.parts.push({
3816
3816
  bone,
3817
- object: object2,
3818
- position: object2.position.clone(),
3819
- rotation: object2.rotation.clone(),
3820
- scale: object2.scale.clone(),
3821
- basePosition: pose ? new import_three11.Vector3(...pose.offset) : object2.position.clone(),
3822
- baseRotation: pose ? new import_three11.Euler(...pose.rotation, "ZYX") : object2.rotation.clone(),
3823
- baseScale: pose ? new import_three11.Vector3(...pose.scale ?? [1, 1, 1]) : object2.scale.clone()
3817
+ object: object3,
3818
+ position: object3.position.clone(),
3819
+ rotation: object3.rotation.clone(),
3820
+ scale: object3.scale.clone(),
3821
+ basePosition: pose ? new import_three11.Vector3(...pose.offset) : object3.position.clone(),
3822
+ baseRotation: pose ? new import_three11.Euler(...pose.rotation, "ZYX") : object3.rotation.clone(),
3823
+ baseScale: pose ? new import_three11.Vector3(...pose.scale ?? [1, 1, 1]) : object3.scale.clone()
3824
3824
  });
3825
3825
  }
3826
3826
  }
@@ -4178,10 +4178,10 @@ var init_SceneObject = __esm({
4178
4178
  return new import_three12.InstancedBufferAttribute(array, attribute.itemSize, attribute.normalized, attribute.meshPerAttribute).setUsage(attribute.usage);
4179
4179
  };
4180
4180
  const matrix = grow(mesh.instanceMatrix, 0);
4181
- const color = mesh.instanceColor ? grow(mesh.instanceColor, 1) : null;
4181
+ const color2 = mesh.instanceColor ? grow(mesh.instanceColor, 1) : null;
4182
4182
  mesh.dispose();
4183
4183
  mesh.instanceMatrix = matrix;
4184
- mesh.instanceColor = color;
4184
+ mesh.instanceColor = color2;
4185
4185
  }
4186
4186
  *activeInstanceIndices() {
4187
4187
  if (this.instanceMesh) {
@@ -4354,15 +4354,15 @@ var init_SceneObject = __esm({
4354
4354
  }
4355
4355
  }
4356
4356
  //</editor-fold>
4357
- toggleObjectVisibility(object2, visible) {
4358
- if (object2) {
4357
+ toggleObjectVisibility(object3, visible) {
4358
+ if (object3) {
4359
4359
  if (typeof visible !== "undefined") {
4360
- object2.visible = visible;
4360
+ object3.visible = visible;
4361
4361
  } else {
4362
- object2.visible = !object2.visible;
4362
+ object3.visible = !object3.visible;
4363
4363
  }
4364
4364
  this.notifyDirty();
4365
- return object2.visible;
4365
+ return object3.visible;
4366
4366
  }
4367
4367
  this.notifyDirty();
4368
4368
  return false;
@@ -4662,8 +4662,8 @@ var init_EntityObject = __esm({
4662
4662
  this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
4663
4663
  }
4664
4664
  }
4665
- this.getLayerGroup(name)?.traverse((object2) => {
4666
- if (isMesh(object2)) object2.material = mat;
4665
+ this.getLayerGroup(name)?.traverse((object3) => {
4666
+ if (isMesh(object3)) object3.material = mat;
4667
4667
  });
4668
4668
  }));
4669
4669
  if (!this.children.length) {
@@ -4993,8 +4993,8 @@ function toTrianglesDrawMode(geometry, drawMode) {
4993
4993
  return geometry;
4994
4994
  }
4995
4995
  }
4996
- function computeMorphedAttributes(object2) {
4997
- if (object2.geometry.isBufferGeometry !== true) {
4996
+ function computeMorphedAttributes(object3) {
4997
+ if (object3.geometry.isBufferGeometry !== true) {
4998
4998
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
4999
4999
  return null;
5000
5000
  }
@@ -5007,11 +5007,11 @@ function computeMorphedAttributes(object2) {
5007
5007
  const _morphA = new import_three22.Vector3();
5008
5008
  const _morphB = new import_three22.Vector3();
5009
5009
  const _morphC = new import_three22.Vector3();
5010
- function _calculateMorphedAttributeData(object3, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
5010
+ function _calculateMorphedAttributeData(object4, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
5011
5011
  _vA.fromBufferAttribute(attribute, a2);
5012
5012
  _vB.fromBufferAttribute(attribute, b2);
5013
5013
  _vC.fromBufferAttribute(attribute, c2);
5014
- const morphInfluences = object3.morphTargetInfluences;
5014
+ const morphInfluences = object4.morphTargetInfluences;
5015
5015
  if (material2.morphTargets && morphAttribute && morphInfluences) {
5016
5016
  _morphA.set(0, 0, 0);
5017
5017
  _morphB.set(0, 0, 0);
@@ -5037,10 +5037,10 @@ function computeMorphedAttributes(object2) {
5037
5037
  _vB.add(_morphB);
5038
5038
  _vC.add(_morphC);
5039
5039
  }
5040
- if (object3.isSkinnedMesh) {
5041
- object3.boneTransform(a2, _vA);
5042
- object3.boneTransform(b2, _vB);
5043
- object3.boneTransform(c2, _vC);
5040
+ if (object4.isSkinnedMesh) {
5041
+ object4.boneTransform(a2, _vA);
5042
+ object4.boneTransform(b2, _vB);
5043
+ object4.boneTransform(c2, _vC);
5044
5044
  }
5045
5045
  modifiedAttributeArray[a2 * 3 + 0] = _vA.x;
5046
5046
  modifiedAttributeArray[a2 * 3 + 1] = _vA.y;
@@ -5052,8 +5052,8 @@ function computeMorphedAttributes(object2) {
5052
5052
  modifiedAttributeArray[c2 * 3 + 1] = _vC.y;
5053
5053
  modifiedAttributeArray[c2 * 3 + 2] = _vC.z;
5054
5054
  }
5055
- const geometry = object2.geometry;
5056
- const material = object2.material;
5055
+ const geometry = object3.geometry;
5056
+ const material = object3.material;
5057
5057
  let a, b, c;
5058
5058
  const index = geometry.index;
5059
5059
  const positionAttribute = geometry.attributes.position;
@@ -5080,7 +5080,7 @@ function computeMorphedAttributes(object2) {
5080
5080
  b = index.getX(j + 1);
5081
5081
  c = index.getX(j + 2);
5082
5082
  _calculateMorphedAttributeData(
5083
- object2,
5083
+ object3,
5084
5084
  groupMaterial,
5085
5085
  positionAttribute,
5086
5086
  morphPosition,
@@ -5091,7 +5091,7 @@ function computeMorphedAttributes(object2) {
5091
5091
  modifiedPosition
5092
5092
  );
5093
5093
  _calculateMorphedAttributeData(
5094
- object2,
5094
+ object3,
5095
5095
  groupMaterial,
5096
5096
  normalAttribute,
5097
5097
  morphNormal,
@@ -5111,7 +5111,7 @@ function computeMorphedAttributes(object2) {
5111
5111
  b = index.getX(i + 1);
5112
5112
  c = index.getX(i + 2);
5113
5113
  _calculateMorphedAttributeData(
5114
- object2,
5114
+ object3,
5115
5115
  material,
5116
5116
  positionAttribute,
5117
5117
  morphPosition,
@@ -5122,7 +5122,7 @@ function computeMorphedAttributes(object2) {
5122
5122
  modifiedPosition
5123
5123
  );
5124
5124
  _calculateMorphedAttributeData(
5125
- object2,
5125
+ object3,
5126
5126
  material,
5127
5127
  normalAttribute,
5128
5128
  morphNormal,
@@ -5146,7 +5146,7 @@ function computeMorphedAttributes(object2) {
5146
5146
  b = j + 1;
5147
5147
  c = j + 2;
5148
5148
  _calculateMorphedAttributeData(
5149
- object2,
5149
+ object3,
5150
5150
  groupMaterial,
5151
5151
  positionAttribute,
5152
5152
  morphPosition,
@@ -5157,7 +5157,7 @@ function computeMorphedAttributes(object2) {
5157
5157
  modifiedPosition
5158
5158
  );
5159
5159
  _calculateMorphedAttributeData(
5160
- object2,
5160
+ object3,
5161
5161
  groupMaterial,
5162
5162
  normalAttribute,
5163
5163
  morphNormal,
@@ -5177,7 +5177,7 @@ function computeMorphedAttributes(object2) {
5177
5177
  b = i + 1;
5178
5178
  c = i + 2;
5179
5179
  _calculateMorphedAttributeData(
5180
- object2,
5180
+ object3,
5181
5181
  material,
5182
5182
  positionAttribute,
5183
5183
  morphPosition,
@@ -5188,7 +5188,7 @@ function computeMorphedAttributes(object2) {
5188
5188
  modifiedPosition
5189
5189
  );
5190
5190
  _calculateMorphedAttributeData(
5191
- object2,
5191
+ object3,
5192
5192
  material,
5193
5193
  normalAttribute,
5194
5194
  morphNormal,
@@ -5446,9 +5446,9 @@ var init_ItemTints = __esm({
5446
5446
  }));
5447
5447
  return colors;
5448
5448
  }
5449
- static rgb(color) {
5450
- if (!Array.isArray(color)) return color & 16777215;
5451
- const [red, green, blue] = color.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)));
5449
+ static rgb(color2) {
5450
+ if (!Array.isArray(color2)) return color2 & 16777215;
5451
+ const [red, green, blue] = color2.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)));
5452
5452
  return red << 16 | green << 8 | blue;
5453
5453
  }
5454
5454
  };
@@ -5501,13 +5501,13 @@ var init_ModelObject = __esm({
5501
5501
  transform.multiply(new import_three25.Matrix4().makeTranslation(-8, -8, -8));
5502
5502
  try {
5503
5503
  for (const part of parts) {
5504
- const object2 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5505
- object2.matrix.copy(transform).multiply(part.transform);
5506
- object2.matrixWorldNeedsUpdate = true;
5507
- object2.matrixAutoUpdate = false;
5508
- this.add(object2);
5509
- await object2.init();
5510
- object2.iterateAllMeshes((mesh) => {
5504
+ const object3 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5505
+ object3.matrix.copy(transform).multiply(part.transform);
5506
+ object3.matrixWorldNeedsUpdate = true;
5507
+ object3.matrixAutoUpdate = false;
5508
+ this.add(object3);
5509
+ await object3.init();
5510
+ object3.iterateAllMeshes((mesh) => {
5511
5511
  const source = mesh.material;
5512
5512
  let material = this.specialMaterials.get(source);
5513
5513
  if (!material) {
@@ -5518,7 +5518,7 @@ var init_ModelObject = __esm({
5518
5518
  mesh.material = material;
5519
5519
  });
5520
5520
  for (const [name, rotation] of Object.entries(part.rotations)) {
5521
- object2.getGroupByName(name)?.rotation.set(...rotation, "ZYX");
5521
+ object3.getGroupByName(name)?.rotation.set(...rotation, "ZYX");
5522
5522
  }
5523
5523
  }
5524
5524
  } catch (error) {
@@ -5571,9 +5571,9 @@ var init_ModelObject = __esm({
5571
5571
  if (tintIndex === void 0 || tintIndex < 0) continue;
5572
5572
  const tint = this.options.tints[tintIndex];
5573
5573
  if (tint === void 0) continue;
5574
- const color = new import_three25.Color(tint);
5574
+ const color2 = new import_three25.Color(tint);
5575
5575
  for (let vertex = 0; vertex < 4; vertex++) {
5576
- color.toArray(colors, (faceIndex * 4 + vertex) * 3);
5576
+ color2.toArray(colors, (faceIndex * 4 + vertex) * 3);
5577
5577
  }
5578
5578
  }
5579
5579
  elGeo.setAttribute("color", new import_three25.BufferAttribute(colors, 3));
@@ -5890,9 +5890,9 @@ var init_FluidModelObject = __esm({
5890
5890
  }
5891
5891
  }
5892
5892
  geometry.clearGroups();
5893
- const color = new import_three31.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
5893
+ const color2 = new import_three31.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
5894
5894
  const colors = new Float32Array(geometry.getAttribute("position").count * 3);
5895
- for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
5895
+ for (let i = 0; i < colors.length; i += 3) color2.toArray(colors, i);
5896
5896
  geometry.setAttribute("color", new import_three31.BufferAttribute(colors, 3));
5897
5897
  geometry.computeBoundingBox();
5898
5898
  geometry.computeBoundingSphere();
@@ -5970,6 +5970,7 @@ __export(index_browser_exports, {
5970
5970
  Env: () => Env,
5971
5971
  FluidModelObject: () => FluidModelObject,
5972
5972
  Fonts: () => Fonts,
5973
+ GUI_CONTAINER_LAYOUTS: () => GUI_CONTAINER_LAYOUTS,
5973
5974
  Geometries: () => Geometries,
5974
5975
  GuiHelper: () => GuiHelper,
5975
5976
  GuiLight: () => GuiLight,
@@ -6003,6 +6004,7 @@ __export(index_browser_exports, {
6003
6004
  RequestError: () => RequestError,
6004
6005
  Requests: () => Requests,
6005
6006
  SKIN_PARTS: () => SKIN_PARTS,
6007
+ SceneDocumentLoader: () => SceneDocumentLoader,
6006
6008
  SceneExporter: () => SceneExporter,
6007
6009
  SceneInspector: () => SceneInspector,
6008
6010
  SceneObject: () => SceneObject,
@@ -6078,6 +6080,7 @@ __export(index_browser_exports, {
6078
6080
  mergeBufferAttributes: () => mergeBufferAttributes,
6079
6081
  mergeBufferGeometries: () => mergeBufferGeometries,
6080
6082
  mergeVertices: () => mergeVertices,
6083
+ parseSceneDocument: () => parseSceneDocument,
6081
6084
  prefix: () => prefix,
6082
6085
  probeImageSize: () => probeImageSize,
6083
6086
  registerBrowserEnv: () => registerBrowserEnv,
@@ -6206,11 +6209,11 @@ var BrowserEnv = class {
6206
6209
  imageSize(data) {
6207
6210
  return probeImageSize(data);
6208
6211
  }
6209
- openCache(name, version) {
6212
+ openCache(name, version2) {
6210
6213
  return new BrowserCache(import_localforage.default.createInstance({
6211
6214
  // IndexedDB schema upgrades retain records; each cache generation needs its own database.
6212
- name: name + version,
6213
- version
6215
+ name: name + version2,
6216
+ version: version2
6214
6217
  }));
6215
6218
  }
6216
6219
  };
@@ -6370,8 +6373,8 @@ var Fonts = class {
6370
6373
  const stack = await AssetLoader.getAll(key, "json" /* JSON */);
6371
6374
  if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
6372
6375
  const glyphs = /* @__PURE__ */ new Map();
6373
- for (const asset of stack) {
6374
- for (const provider of asset.providers) {
6376
+ for (const asset2 of stack) {
6377
+ for (const provider of asset2.providers) {
6375
6378
  if (provider.filter?.uniform || provider.filter?.jp) continue;
6376
6379
  let provided;
6377
6380
  switch (provider.type) {
@@ -6510,13 +6513,13 @@ var OBJExporter = class {
6510
6513
  * @param {Object3D} object - The 3D object to export.
6511
6514
  * @return {string} The exported OBJ.
6512
6515
  */
6513
- parse(object2) {
6516
+ parse(object3) {
6514
6517
  let output = "";
6515
6518
  let indexVertex = 0;
6516
6519
  let indexVertexUvs = 0;
6517
6520
  let indexNormals = 0;
6518
6521
  const vertex = new import_three16.Vector3();
6519
- const color = new import_three16.Color();
6522
+ const color2 = new import_three16.Color();
6520
6523
  const normal = new import_three16.Vector3();
6521
6524
  const uv = new import_three16.Vector2();
6522
6525
  const face = [];
@@ -6615,9 +6618,9 @@ var OBJExporter = class {
6615
6618
  vertex.applyMatrix4(points.matrixWorld);
6616
6619
  output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
6617
6620
  if (colors !== void 0) {
6618
- color.fromBufferAttribute(colors, i);
6619
- import_three16.ColorManagement.workingToColorSpace(color, import_three16.SRGBColorSpace);
6620
- output += " " + color.r + " " + color.g + " " + color.b;
6621
+ color2.fromBufferAttribute(colors, i);
6622
+ import_three16.ColorManagement.workingToColorSpace(color2, import_three16.SRGBColorSpace);
6623
+ output += " " + color2.r + " " + color2.g + " " + color2.b;
6621
6624
  }
6622
6625
  output += "\n";
6623
6626
  }
@@ -6629,7 +6632,7 @@ var OBJExporter = class {
6629
6632
  }
6630
6633
  indexVertex += nbVertex;
6631
6634
  }
6632
- object2.traverse(function(child) {
6635
+ object3.traverse(function(child) {
6633
6636
  if (child.isMesh === true) {
6634
6637
  parseMesh(child);
6635
6638
  }
@@ -6657,9 +6660,9 @@ var PLYExporter = class {
6657
6660
  * @param {PLYExporter~Options} options - The export options.
6658
6661
  * @return {?(string|ArrayBuffer)} The exported PLY.
6659
6662
  */
6660
- parse(object2, onDone, options = {}) {
6663
+ parse(object3, onDone, options = {}) {
6661
6664
  function traverseMeshes(cb) {
6662
- object2.traverse(function(child) {
6665
+ object3.traverse(function(child) {
6663
6666
  if (child.isMesh === true || child.isPoints) {
6664
6667
  const mesh = child;
6665
6668
  const geometry = mesh.geometry;
@@ -6692,7 +6695,7 @@ var PLYExporter = class {
6692
6695
  for (const name of customAttributeNames) customTypes[name] = "float";
6693
6696
  let vertexCount = 0;
6694
6697
  let faceCount = 0;
6695
- object2.traverse(function(child) {
6698
+ object3.traverse(function(child) {
6696
6699
  if (child.isMesh === true) {
6697
6700
  const mesh = child;
6698
6701
  const geometry = mesh.geometry;
@@ -7286,8 +7289,8 @@ function equalArray(array1, array2) {
7286
7289
  return element === array2[index];
7287
7290
  });
7288
7291
  }
7289
- function stringToArrayBuffer(text) {
7290
- return new TextEncoder().encode(text).buffer;
7292
+ function stringToArrayBuffer(text2) {
7293
+ return new TextEncoder().encode(text2).buffer;
7291
7294
  }
7292
7295
  function isIdentityMatrix(matrix) {
7293
7296
  return equalArray(matrix.elements, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
@@ -7480,12 +7483,12 @@ var GLTFWriter = class {
7480
7483
  * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry|THREE.AnimationClip} object
7481
7484
  * @param {Object} objectDef
7482
7485
  */
7483
- serializeUserData(object2, objectDef) {
7484
- if (Object.keys(object2.userData).length === 0) return;
7486
+ serializeUserData(object3, objectDef) {
7487
+ if (Object.keys(object3.userData).length === 0) return;
7485
7488
  const options = this.options;
7486
7489
  const extensionsUsed = this.extensionsUsed;
7487
7490
  try {
7488
- const json = JSON.parse(JSON.stringify(object2.userData));
7491
+ const json = JSON.parse(JSON.stringify(object3.userData));
7489
7492
  if (options.includeCustomExtensions && json.gltfExtensions) {
7490
7493
  if (objectDef.extensions === void 0) objectDef.extensions = {};
7491
7494
  for (const extensionName in json.gltfExtensions) {
@@ -7496,7 +7499,7 @@ var GLTFWriter = class {
7496
7499
  }
7497
7500
  if (Object.keys(json).length > 0) objectDef.extras = json;
7498
7501
  } catch (error) {
7499
- console.warn("THREE.GLTFExporter: userData of '" + object2.name + "' won't be serialized because of JSON.stringify error - " + error.message);
7502
+ console.warn("THREE.GLTFExporter: userData of '" + object3.name + "' won't be serialized because of JSON.stringify error - " + error.message);
7500
7503
  }
7501
7504
  }
7502
7505
  /**
@@ -8005,9 +8008,9 @@ var GLTFWriter = class {
8005
8008
  if (material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true) {
8006
8009
  console.warn("GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.");
8007
8010
  }
8008
- const color = material.color.toArray().concat([material.opacity]);
8009
- if (!equalArray(color, [1, 1, 1, 1])) {
8010
- materialDef.pbrMetallicRoughness.baseColorFactor = color;
8011
+ const color2 = material.color.toArray().concat([material.opacity]);
8012
+ if (!equalArray(color2, [1, 1, 1, 1])) {
8013
+ materialDef.pbrMetallicRoughness.baseColorFactor = color2;
8011
8014
  }
8012
8015
  if (material.isMeshStandardMaterial) {
8013
8016
  materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
@@ -8422,13 +8425,13 @@ var GLTFWriter = class {
8422
8425
  * @param {THREE.Object3D} object
8423
8426
  * @return {?number}
8424
8427
  */
8425
- processSkin(object2) {
8428
+ processSkin(object3) {
8426
8429
  const json = this.json;
8427
8430
  const nodeMap = this.nodeMap;
8428
- const node = json.nodes[nodeMap.get(object2)];
8429
- const skeleton = object2.skeleton;
8431
+ const node = json.nodes[nodeMap.get(object3)];
8432
+ const skeleton = object3.skeleton;
8430
8433
  if (skeleton === void 0) return null;
8431
- const rootJoint = object2.skeleton.bones[0];
8434
+ const rootJoint = object3.skeleton.bones[0];
8432
8435
  if (rootJoint === void 0) return null;
8433
8436
  const joints = [];
8434
8437
  const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
@@ -8436,7 +8439,7 @@ var GLTFWriter = class {
8436
8439
  for (let i = 0; i < skeleton.bones.length; ++i) {
8437
8440
  joints.push(nodeMap.get(skeleton.bones[i]));
8438
8441
  temporaryBoneInverse.copy(skeleton.boneInverses[i]);
8439
- temporaryBoneInverse.multiply(object2.bindMatrix).toArray(inverseBindMatrices, i * 16);
8442
+ temporaryBoneInverse.multiply(object3.bindMatrix).toArray(inverseBindMatrices, i * 16);
8440
8443
  }
8441
8444
  if (json.skins === void 0) json.skins = [];
8442
8445
  json.skins.push({
@@ -8452,19 +8455,19 @@ var GLTFWriter = class {
8452
8455
  * @param {THREE.Object3D} object Object3D to processNodeAsync
8453
8456
  * @return {Promise<number>} Index of the node in the nodes list
8454
8457
  */
8455
- async processNodeAsync(object2) {
8458
+ async processNodeAsync(object3) {
8456
8459
  const json = this.json;
8457
8460
  const options = this.options;
8458
8461
  const nodeMap = this.nodeMap;
8459
8462
  if (!json.nodes) json.nodes = [];
8460
- if (object2.pivot !== null) {
8461
- return await this._processNodeWithPivotAsync(object2);
8463
+ if (object3.pivot !== null) {
8464
+ return await this._processNodeWithPivotAsync(object3);
8462
8465
  }
8463
8466
  const nodeDef = {};
8464
8467
  if (options.trs) {
8465
- const rotation = object2.quaternion.toArray();
8466
- const position = object2.position.toArray();
8467
- const scale = object2.scale.toArray();
8468
+ const rotation = object3.quaternion.toArray();
8469
+ const position = object3.position.toArray();
8470
+ const scale = object3.scale.toArray();
8468
8471
  if (!equalArray(rotation, [0, 0, 0, 1])) {
8469
8472
  nodeDef.rotation = rotation;
8470
8473
  }
@@ -8475,28 +8478,28 @@ var GLTFWriter = class {
8475
8478
  nodeDef.scale = scale;
8476
8479
  }
8477
8480
  } else {
8478
- if (object2.matrixAutoUpdate) {
8479
- object2.updateMatrix();
8481
+ if (object3.matrixAutoUpdate) {
8482
+ object3.updateMatrix();
8480
8483
  }
8481
- if (isIdentityMatrix(object2.matrix) === false) {
8482
- nodeDef.matrix = object2.matrix.elements;
8484
+ if (isIdentityMatrix(object3.matrix) === false) {
8485
+ nodeDef.matrix = object3.matrix.elements;
8483
8486
  }
8484
8487
  }
8485
- if (object2.name !== "") nodeDef.name = String(object2.name);
8486
- this.serializeUserData(object2, nodeDef);
8487
- if (object2.isMesh || object2.isLine || object2.isPoints) {
8488
- const meshIndex = await this.processMeshAsync(object2);
8488
+ if (object3.name !== "") nodeDef.name = String(object3.name);
8489
+ this.serializeUserData(object3, nodeDef);
8490
+ if (object3.isMesh || object3.isLine || object3.isPoints) {
8491
+ const meshIndex = await this.processMeshAsync(object3);
8489
8492
  if (meshIndex !== null) nodeDef.mesh = meshIndex;
8490
- } else if (object2.isCamera) {
8491
- nodeDef.camera = this.processCamera(object2);
8493
+ } else if (object3.isCamera) {
8494
+ nodeDef.camera = this.processCamera(object3);
8492
8495
  }
8493
- if (object2.isSkinnedMesh) this.skins.push(object2);
8496
+ if (object3.isSkinnedMesh) this.skins.push(object3);
8494
8497
  const nodeIndex = json.nodes.push(nodeDef) - 1;
8495
- nodeMap.set(object2, nodeIndex);
8496
- if (object2.children.length > 0) {
8498
+ nodeMap.set(object3, nodeIndex);
8499
+ if (object3.children.length > 0) {
8497
8500
  const children = [];
8498
- for (let i = 0, l = object2.children.length; i < l; i++) {
8499
- const child = object2.children[i];
8501
+ for (let i = 0, l = object3.children.length; i < l; i++) {
8502
+ const child = object3.children[i];
8500
8503
  if (child.visible || options.onlyVisible === false) {
8501
8504
  const childNodeIndex = await this.processNodeAsync(child);
8502
8505
  if (childNodeIndex !== null) children.push(childNodeIndex);
@@ -8505,7 +8508,7 @@ var GLTFWriter = class {
8505
8508
  if (children.length > 0) nodeDef.children = children;
8506
8509
  }
8507
8510
  await this._invokeAllAsync(function(ext) {
8508
- ext.writeNode && ext.writeNode(object2, nodeDef);
8511
+ ext.writeNode && ext.writeNode(object3, nodeDef);
8509
8512
  });
8510
8513
  return nodeIndex;
8511
8514
  }
@@ -8514,19 +8517,19 @@ var GLTFWriter = class {
8514
8517
  * @param {THREE.Object3D} object Object3D with pivot
8515
8518
  * @return {Promise<number>} Index of the container node
8516
8519
  */
8517
- async _processNodeWithPivotAsync(object2) {
8520
+ async _processNodeWithPivotAsync(object3) {
8518
8521
  const json = this.json;
8519
8522
  const options = this.options;
8520
8523
  const nodeMap = this.nodeMap;
8521
- const pivot = object2.pivot;
8524
+ const pivot = object3.pivot;
8522
8525
  const containerDef = {};
8523
- const rotation = object2.quaternion.toArray();
8526
+ const rotation = object3.quaternion.toArray();
8524
8527
  const position = [
8525
- object2.position.x + pivot.x,
8526
- object2.position.y + pivot.y,
8527
- object2.position.z + pivot.z
8528
+ object3.position.x + pivot.x,
8529
+ object3.position.y + pivot.y,
8530
+ object3.position.z + pivot.z
8528
8531
  ];
8529
- const scale = object2.scale.toArray();
8532
+ const scale = object3.scale.toArray();
8530
8533
  if (!equalArray(rotation, [0, 0, 0, 1])) {
8531
8534
  containerDef.rotation = rotation;
8532
8535
  }
@@ -8537,28 +8540,28 @@ var GLTFWriter = class {
8537
8540
  containerDef.scale = scale;
8538
8541
  }
8539
8542
  containerDef.extras = { pivot: pivot.toArray() };
8540
- if (object2.name !== "") containerDef.name = String(object2.name);
8541
- this.serializeUserData(object2, containerDef);
8543
+ if (object3.name !== "") containerDef.name = String(object3.name);
8544
+ this.serializeUserData(object3, containerDef);
8542
8545
  const containerIndex = json.nodes.push(containerDef) - 1;
8543
- nodeMap.set(object2, containerIndex);
8546
+ nodeMap.set(object3, containerIndex);
8544
8547
  const childDef = {};
8545
8548
  const childPosition = [-pivot.x, -pivot.y, -pivot.z];
8546
8549
  if (!equalArray(childPosition, [0, 0, 0])) {
8547
8550
  childDef.translation = childPosition;
8548
8551
  }
8549
- if (object2.isMesh || object2.isLine || object2.isPoints) {
8550
- const meshIndex = await this.processMeshAsync(object2);
8552
+ if (object3.isMesh || object3.isLine || object3.isPoints) {
8553
+ const meshIndex = await this.processMeshAsync(object3);
8551
8554
  if (meshIndex !== null) childDef.mesh = meshIndex;
8552
- } else if (object2.isCamera) {
8553
- childDef.camera = this.processCamera(object2);
8555
+ } else if (object3.isCamera) {
8556
+ childDef.camera = this.processCamera(object3);
8554
8557
  }
8555
- if (object2.isSkinnedMesh) this.skins.push(object2);
8558
+ if (object3.isSkinnedMesh) this.skins.push(object3);
8556
8559
  const childIndex = json.nodes.push(childDef) - 1;
8557
8560
  const containerChildren = [childIndex];
8558
- if (object2.children.length > 0) {
8561
+ if (object3.children.length > 0) {
8559
8562
  const grandchildren = [];
8560
- for (let i = 0, l = object2.children.length; i < l; i++) {
8561
- const child = object2.children[i];
8563
+ for (let i = 0, l = object3.children.length; i < l; i++) {
8564
+ const child = object3.children[i];
8562
8565
  if (child.visible || options.onlyVisible === false) {
8563
8566
  const childNodeIndex = await this.processNodeAsync(child);
8564
8567
  if (childNodeIndex !== null) grandchildren.push(childNodeIndex);
@@ -8568,7 +8571,7 @@ var GLTFWriter = class {
8568
8571
  }
8569
8572
  containerDef.children = containerChildren;
8570
8573
  await this._invokeAllAsync(function(ext) {
8571
- ext.writeNode && ext.writeNode(object2, containerDef);
8574
+ ext.writeNode && ext.writeNode(object3, containerDef);
8572
8575
  });
8573
8576
  return containerIndex;
8574
8577
  }
@@ -9011,10 +9014,10 @@ var GLTFMeshGpuInstancing = class {
9011
9014
  this.writer = writer;
9012
9015
  this.name = "EXT_mesh_gpu_instancing";
9013
9016
  }
9014
- writeNode(object2, nodeDef) {
9015
- if (!object2.isInstancedMesh) return;
9017
+ writeNode(object3, nodeDef) {
9018
+ if (!object3.isInstancedMesh) return;
9016
9019
  const writer = this.writer;
9017
- const mesh = object2;
9020
+ const mesh = object3;
9018
9021
  const translationAttr = new Float32Array(mesh.count * 3);
9019
9022
  const rotationAttr = new Float32Array(mesh.count * 4);
9020
9023
  const scaleAttr = new Float32Array(mesh.count * 3);
@@ -9204,8 +9207,8 @@ var SceneExporter = class {
9204
9207
  }
9205
9208
  }
9206
9209
  };
9207
- function localMatrix(object2) {
9208
- return object2.matrixAutoUpdate ? new import_three19.Matrix4().compose(object2.position, object2.quaternion, object2.scale) : object2.matrix.clone();
9210
+ function localMatrix(object3) {
9211
+ return object3.matrixAutoUpdate ? new import_three19.Matrix4().compose(object3.position, object3.quaternion, object3.scale) : object3.matrix.clone();
9209
9212
  }
9210
9213
  function createSnapshot(root, gltf, bakeColors = false) {
9211
9214
  const scene = new import_three19.Scene();
@@ -9309,24 +9312,24 @@ function createSnapshot(root, gltf, bakeColors = false) {
9309
9312
  scene.add(copy);
9310
9313
  }
9311
9314
  };
9312
- const visit = (object2, parentWorld) => {
9313
- if (!object2.visible) return;
9314
- const world = parentWorld.clone().multiply(localMatrix(object2));
9315
- const mesh = object2;
9315
+ const visit = (object3, parentWorld) => {
9316
+ if (!object3.visible) return;
9317
+ const world = parentWorld.clone().multiply(localMatrix(object3));
9318
+ const mesh = object3;
9316
9319
  if (mesh.isMesh) {
9317
9320
  const instanced = mesh;
9318
9321
  if (instanced.isInstancedMesh) {
9319
9322
  for (let i = 0; i < instanced.count; i++) {
9320
9323
  const matrix = new import_three19.Matrix4();
9321
9324
  instanced.getMatrixAt(i, matrix);
9322
- const color = instanced.instanceColor ? new import_three19.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
9323
- addMesh(mesh, world.clone().multiply(matrix), color);
9325
+ const color2 = instanced.instanceColor ? new import_three19.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
9326
+ addMesh(mesh, world.clone().multiply(matrix), color2);
9324
9327
  }
9325
9328
  } else {
9326
9329
  addMesh(mesh, world);
9327
9330
  }
9328
9331
  }
9329
- for (const child of object2.children) visit(child, world);
9332
+ for (const child of object3.children) visit(child, world);
9330
9333
  };
9331
9334
  try {
9332
9335
  const ancestors = [];
@@ -9399,16 +9402,17 @@ function copyDataTexture(source) {
9399
9402
 
9400
9403
  // src/gui/GuiHelper.ts
9401
9404
  init_AssetKey();
9405
+ init_ModelTextures();
9402
9406
 
9403
9407
  // src/gui/GuiText.ts
9404
9408
  var import_three20 = require("three");
9405
- async function layoutGuiText(text, options = {}) {
9409
+ async function layoutGuiText(text2, options = {}) {
9406
9410
  const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;
9407
9411
  if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {
9408
9412
  throw new Error("Text wrap width and line height must be positive");
9409
9413
  }
9410
9414
  const font = await Fonts.get(options.font);
9411
- const runs = typeof text === "string" ? [{ text }] : text;
9415
+ const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
9412
9416
  const glyphs = [], lineWidths = [];
9413
9417
  let line = [], width = 0;
9414
9418
  let trailingNewline = false;
@@ -9462,7 +9466,7 @@ function createGuiTextGeometry(layout, shadow = true) {
9462
9466
  batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };
9463
9467
  batches.push(batch);
9464
9468
  }
9465
- const color = new import_three20.Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
9469
+ const color2 = new import_three20.Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
9466
9470
  const offset = isShadow ? 1 : 0;
9467
9471
  const top = glyph ? 7 - glyph.ascent : 0;
9468
9472
  const height = glyph ? glyph.height * glyph.scale : 8;
@@ -9490,7 +9494,7 @@ function createGuiTextGeometry(layout, shadow = true) {
9490
9494
  const v0 = glyph ? 1 - glyph.y / glyph.image.height : 1;
9491
9495
  const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image.height : 0;
9492
9496
  batch.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);
9493
- for (let i = 0; i < 4; i++) batch.colors.push(color.r, color.g, color.b);
9497
+ for (let i = 0; i < 4; i++) batch.colors.push(color2.r, color2.g, color2.b);
9494
9498
  batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
9495
9499
  };
9496
9500
  for (const boldOffset of style.bold ? [0, 1] : [0]) {
@@ -9508,7 +9512,128 @@ function createGuiTextGeometry(layout, shadow = true) {
9508
9512
  }
9509
9513
 
9510
9514
  // src/gui/GuiHelper.ts
9515
+ var GUI_CONTAINER_LAYOUTS = {
9516
+ generic_54: {
9517
+ texture: "minecraft:gui/container/generic_54",
9518
+ crop: [0, 0, 176, 222],
9519
+ slotOrigin: [8, 18],
9520
+ slotOffset: [18, 18],
9521
+ rowSize: 9,
9522
+ slotCount: 54
9523
+ },
9524
+ crafting_table: {
9525
+ texture: "minecraft:gui/container/crafting_table",
9526
+ crop: [0, 0, 176, 166],
9527
+ slotOrigin: [30, 17],
9528
+ slotOffset: [18, 18],
9529
+ rowSize: 3,
9530
+ slotCount: 9,
9531
+ resultPosition: [124, 35]
9532
+ }
9533
+ };
9511
9534
  var GuiHelper = class {
9535
+ /**
9536
+ * Creates a 182×5 boss bar using the active resource pack. Finite progress is clamped to 0–1.
9537
+ * The fill crops the source image; explicit crops do not apply `.mcmeta` sprite scaling.
9538
+ */
9539
+ static async bossBar(options = {}) {
9540
+ const { color: color2 = "pink", progress = 1, position = [0, 0] } = options;
9541
+ this.validatePosition(position);
9542
+ if (!["pink", "blue", "red", "green", "yellow", "purple", "white"].includes(color2)) {
9543
+ throw new Error(`Unsupported boss bar color: ${color2}`);
9544
+ }
9545
+ if (!Number.isFinite(progress)) throw new Error("Boss bar progress must be finite");
9546
+ const value = Math.max(0, Math.min(1, progress));
9547
+ const width = value > 0 ? Math.floor(value * 181) + 1 : 0;
9548
+ const texture = `minecraft:gui/sprites/boss_bar/${color2}`;
9549
+ const layers = [{
9550
+ name: "boss-bar-background",
9551
+ texture: `${texture}_background`,
9552
+ position: [...position],
9553
+ size: [182, 5]
9554
+ }];
9555
+ if (width > 0) {
9556
+ layers.push({
9557
+ ...await this.cropTexture(`${texture}_progress`, [0, 0, width, 5], [182, 5], position),
9558
+ name: "boss-bar-progress"
9559
+ });
9560
+ }
9561
+ return layers;
9562
+ }
9563
+ /**
9564
+ * Creates a 192×192 book page with optional arrows and supplied text. Buttons are hidden by default.
9565
+ * Callers choose the page content and button states; this helper does not paginate or handle clicks.
9566
+ */
9567
+ static async book(options = {}) {
9568
+ const {
9569
+ position = [0, 0],
9570
+ previous = "hidden",
9571
+ next = "hidden",
9572
+ text: text2,
9573
+ color: color2 = 0,
9574
+ shadow = false,
9575
+ maxWidth = 114,
9576
+ lineHeight = 9,
9577
+ ...style
9578
+ } = options;
9579
+ this.validatePosition(position);
9580
+ for (const state of [previous, next]) {
9581
+ if (!["hidden", "normal", "hover"].includes(state)) throw new Error(`Unsupported book button state: ${state}`);
9582
+ }
9583
+ const layers = [{
9584
+ ...await this.cropTexture("minecraft:gui/book", [0, 0, 192, 192], [256, 256], position),
9585
+ name: "book-background"
9586
+ }];
9587
+ for (const [name, direction, state, x] of [
9588
+ ["previous", "backward", previous, 43],
9589
+ ["next", "forward", next, 116]
9590
+ ]) {
9591
+ if (state === "hidden") continue;
9592
+ layers.push({
9593
+ name: `book-${name}`,
9594
+ texture: `minecraft:gui/sprites/widget/page_${direction}${state === "hover" ? "_highlighted" : ""}`,
9595
+ position: [position[0] + x, position[1] + 157],
9596
+ size: [23, 13]
9597
+ });
9598
+ }
9599
+ if (text2 !== void 0) {
9600
+ layers.push({
9601
+ name: "book-text",
9602
+ text: text2,
9603
+ position: [position[0] + 36, position[1] + 30],
9604
+ color: color2,
9605
+ shadow,
9606
+ maxWidth,
9607
+ lineHeight,
9608
+ ...style
9609
+ });
9610
+ }
9611
+ return layers;
9612
+ }
9613
+ /** Creates a container background. Use {@link GUI_CONTAINER_LAYOUTS} with {@link inventorySlot} to place its items. */
9614
+ static async container(type, position = [0, 0]) {
9615
+ this.validatePosition(position);
9616
+ if (type !== "generic_54" && type !== "crafting_table") throw new Error(`Unsupported GUI container: ${type}`);
9617
+ const layout = GUI_CONTAINER_LAYOUTS[type];
9618
+ return [{ ...await this.cropTexture(layout.texture, layout.crop, [256, 256], position), name: "background" }];
9619
+ }
9620
+ static validatePosition(position) {
9621
+ if (!Array.isArray(position) || position.length !== 2 || !position.every(Number.isFinite)) {
9622
+ throw new Error("GUI position must contain two finite coordinates");
9623
+ }
9624
+ }
9625
+ static async cropTexture(texture, crop, referenceSize, position) {
9626
+ const image = await ModelTextures.preload(AssetKey.parse("textures", texture));
9627
+ if (!image) throw new Error(`Could not load GUI texture ${texture}`);
9628
+ const [x, y, width, height] = crop;
9629
+ const scaleX = image.width / referenceSize[0], scaleY = image.height / referenceSize[1];
9630
+ return {
9631
+ texture,
9632
+ crop: [x * scaleX, y * scaleY, width * scaleX, height * scaleY],
9633
+ position: [...position],
9634
+ size: [width, height]
9635
+ };
9636
+ }
9512
9637
  /** Sizes a tooltip around supplied text; the first entry is its title. */
9513
9638
  static async tooltip(lines, options = {}) {
9514
9639
  if (!lines.length) return [];
@@ -9524,8 +9649,8 @@ var GuiHelper = class {
9524
9649
  size: [width + 24, height + 24]
9525
9650
  }));
9526
9651
  let y = position[1];
9527
- lines.forEach((text, index) => {
9528
- layers.push({ ...textOptions, name: `tooltip-line-${index}`, text, position: [position[0], y] });
9652
+ lines.forEach((text2, index) => {
9653
+ layers.push({ ...textOptions, name: `tooltip-line-${index}`, text: text2, position: [position[0], y] });
9529
9654
  y += layouts[index].height + (index === 0 ? titleGap : 0);
9530
9655
  });
9531
9656
  return layers;
@@ -9543,8 +9668,9 @@ var GuiHelper = class {
9543
9668
  }
9544
9669
  /** Creates crafting-table layers for ingredients and the result; stack counts are not drawn. */
9545
9670
  static recipe(recipe, options = {}) {
9671
+ const layout = GUI_CONTAINER_LAYOUTS.crafting_table;
9546
9672
  const layers = [
9547
- { name: "background", texture: "minecraft:gui/container/crafting_table", crop: [0, 0, 176, 166] }
9673
+ { name: "background", texture: layout.texture, crop: [...layout.crop] }
9548
9674
  ];
9549
9675
  const itemKey = (ingredient) => {
9550
9676
  const item = typeof ingredient === "string" && !ingredient.startsWith("#") ? ingredient : typeof ingredient === "object" && "item" in ingredient ? ingredient.item : options.resolveIngredient?.(ingredient);
@@ -9559,7 +9685,7 @@ var GuiHelper = class {
9559
9685
  layers.push({
9560
9686
  name: `ingredient-${slot}`,
9561
9687
  item: itemKey(ingredient),
9562
- position: this.inventorySlot(slot, [30, 17], [18, 18], 3)
9688
+ position: this.inventorySlot(slot, layout.slotOrigin, layout.slotOffset, layout.rowSize)
9563
9689
  });
9564
9690
  };
9565
9691
  switch (recipe.type) {
@@ -9594,7 +9720,7 @@ var GuiHelper = class {
9594
9720
  layers.push({
9595
9721
  name: "result",
9596
9722
  item: itemKey("id" in recipe.result ? recipe.result.id : recipe.result.item),
9597
- position: [124, 35]
9723
+ position: [...layout.resultPosition]
9598
9724
  });
9599
9725
  return layers;
9600
9726
  }
@@ -9981,29 +10107,29 @@ var SceneInspector = class {
9981
10107
  this.objectControlsContainer.innerHTML = "";
9982
10108
  this.addControls(targetObject, targetIntersection, instance);
9983
10109
  }
9984
- addControls(object2, intersection, instance) {
10110
+ addControls(object3, intersection, instance) {
9985
10111
  const container = document.createElement("div");
9986
10112
  container.append(this.separator("Select Parent/Child"));
9987
- if (object2.parent) {
9988
- container.append(this.buttonControl("Select Parent " + object2.parent.constructor.name + " " + object2.parent.name, "P", () => {
9989
- this.selectObject(object2.parent, intersection, instance);
10113
+ if (object3.parent) {
10114
+ container.append(this.buttonControl("Select Parent " + object3.parent.constructor.name + " " + object3.parent.name, "P", () => {
10115
+ this.selectObject(object3.parent, intersection, instance);
9990
10116
  }));
9991
10117
  }
9992
- if (object2.children.length > 0) {
10118
+ if (object3.children.length > 0) {
9993
10119
  let i = 1;
9994
- for (let child of object2.children) {
10120
+ for (let child of object3.children) {
9995
10121
  container.append(this.buttonControl("Select Child " + child.constructor.name + " " + child.name, "C" + i++, () => {
9996
10122
  this.selectObject(child, intersection, instance);
9997
10123
  }));
9998
10124
  }
9999
10125
  }
10000
10126
  container.append(this.separator());
10001
- const selectedInstance = instance && (object2 === instance.instanceable || object2 === intersection?.object) ? instance : void 0;
10127
+ const selectedInstance = instance && (object3 === instance.instanceable || object3 === intersection?.object) ? instance : void 0;
10002
10128
  if (!selectedInstance) {
10003
- container.append(this.toggleControl("Visibility", "V", object2.visible, (v) => object2.visible = v));
10129
+ container.append(this.toggleControl("Visibility", "V", object3.visible, (v) => object3.visible = v));
10004
10130
  }
10005
10131
  container.append(this.separator("Mesh"));
10006
- this.addObjectControls(object2, intersection, container, selectedInstance);
10132
+ this.addObjectControls(object3, intersection, container, selectedInstance);
10007
10133
  container.append(this.separator());
10008
10134
  this.objectControlsContainer.append(container);
10009
10135
  }
@@ -10419,29 +10545,29 @@ var BlockTints = class {
10419
10545
  }
10420
10546
  }
10421
10547
  if (!indices.size) return tints;
10422
- let color;
10548
+ let color2;
10423
10549
  switch (rule.source) {
10424
10550
  case "constant":
10425
- color = rule.color;
10551
+ color2 = rule.color;
10426
10552
  break;
10427
10553
  case "grass":
10428
- color = await Colormaps.grassColor(key);
10554
+ color2 = await Colormaps.grassColor(key);
10429
10555
  break;
10430
10556
  case "redstone": {
10431
10557
  const power = Number(state.power ?? 0) / 15;
10432
10558
  const red = power * 0.6 + (power > 0 ? 0.4 : 0.3);
10433
10559
  const green = Math.max(0, power * power * 0.7 - 0.5);
10434
10560
  const blue = Math.max(0, power * power * 0.6 - 0.7);
10435
- color = Math.floor(red * 255) << 16 | Math.floor(green * 255) << 8 | Math.floor(blue * 255);
10561
+ color2 = Math.floor(red * 255) << 16 | Math.floor(green * 255) << 8 | Math.floor(blue * 255);
10436
10562
  break;
10437
10563
  }
10438
10564
  case "stem": {
10439
10565
  const age = Number(state.age ?? 0);
10440
- color = age * 32 << 16 | 255 - age * 8 << 8 | age * 4;
10566
+ color2 = age * 32 << 16 | 255 - age * 8 << 8 | age * 4;
10441
10567
  break;
10442
10568
  }
10443
10569
  }
10444
- return { ...Object.fromEntries([...indices].map((index) => [index, color])), ...tints };
10570
+ return { ...Object.fromEntries([...indices].map((index) => [index, color2])), ...tints };
10445
10571
  }
10446
10572
  };
10447
10573
 
@@ -10578,8 +10704,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
10578
10704
  return false;
10579
10705
  }
10580
10706
  return this._models.some((model) => {
10581
- const object2 = isInstanceReference(model) ? model.instanceable : model;
10582
- return object2.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
10707
+ const object3 = isInstanceReference(model) ? model.instanceable : model;
10708
+ return object3.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
10583
10709
  });
10584
10710
  }
10585
10711
  getModelMatrix(model) {
@@ -10588,8 +10714,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
10588
10714
  return model.matrix.clone();
10589
10715
  }
10590
10716
  getModelCullMask(model, worldMask) {
10591
- const object2 = isInstanceReference(model) ? model.instanceable : model;
10592
- if (object2.options.displayPosition) return 0;
10717
+ const object3 = isInstanceReference(model) ? model.instanceable : model;
10718
+ if (object3.options.displayPosition) return 0;
10593
10719
  const position = new import_three32.Vector3();
10594
10720
  const rotation = new import_three32.Quaternion();
10595
10721
  const scale = new import_three32.Vector3();
@@ -10606,14 +10732,14 @@ var _BlockObject = class _BlockObject extends SceneObject {
10606
10732
  replacements.push(model);
10607
10733
  continue;
10608
10734
  }
10609
- const object2 = isInstanceReference(model) ? model.instanceable : model;
10735
+ const object3 = isInstanceReference(model) ? model.instanceable : model;
10610
10736
  const cullMask = this.getModelCullMask(model, worldMask);
10611
- if (cullMask === (object2.options.cullMask ?? 0)) {
10737
+ if (cullMask === (object3.options.cullMask ?? 0)) {
10612
10738
  replacements.push(model);
10613
10739
  continue;
10614
10740
  }
10615
10741
  const matrix = this.getModelMatrix(model);
10616
- const replacement = await this.scene.addModel(object2.originalModel, { ...object2.options, cullMask });
10742
+ const replacement = await this.scene.addModel(object3.originalModel, { ...object3.options, cullMask });
10617
10743
  replacements.push(replacement);
10618
10744
  if (isInstanceReference(replacement)) {
10619
10745
  replacement.setMatrix(matrix);
@@ -10621,8 +10747,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
10621
10747
  replacement.matrix.copy(matrix);
10622
10748
  replacement.matrixWorldNeedsUpdate = true;
10623
10749
  matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
10624
- replacement.matrixAutoUpdate = object2.matrixAutoUpdate;
10625
- replacement.visible = object2.visible;
10750
+ replacement.matrixAutoUpdate = object3.matrixAutoUpdate;
10751
+ replacement.visible = object3.visible;
10626
10752
  }
10627
10753
  }
10628
10754
  } catch (error) {
@@ -13770,60 +13896,60 @@ var _MineRenderScene = class _MineRenderScene extends import_three34.Scene {
13770
13896
  this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
13771
13897
  }
13772
13898
  add(...objects) {
13773
- for (const object2 of objects) {
13899
+ for (const object3 of objects) {
13774
13900
  this.dirty = true;
13775
13901
  try {
13776
- super.add(object2);
13902
+ super.add(object3);
13777
13903
  } finally {
13778
- if (object2?.isObject3D && object2 !== this) {
13779
- this.updateObjectRegistration(object2, object2.parent === this);
13904
+ if (object3?.isObject3D && object3 !== this) {
13905
+ this.updateObjectRegistration(object3, object3.parent === this);
13780
13906
  }
13781
13907
  }
13782
13908
  }
13783
13909
  return this;
13784
13910
  }
13785
13911
  remove(...objects) {
13786
- for (const object2 of objects) {
13787
- if (!this.children.includes(object2)) continue;
13912
+ for (const object3 of objects) {
13913
+ if (!this.children.includes(object3)) continue;
13788
13914
  this.dirty = true;
13789
- this.updateObjectRegistration(object2, false);
13915
+ this.updateObjectRegistration(object3, false);
13790
13916
  try {
13791
- super.remove(object2);
13917
+ super.remove(object3);
13792
13918
  } finally {
13793
- this.updateObjectRegistration(object2, object2.parent === this);
13919
+ this.updateObjectRegistration(object3, object3.parent === this);
13794
13920
  }
13795
13921
  }
13796
13922
  return this;
13797
13923
  }
13798
- updateObjectRegistration(object2, attached) {
13799
- if (this.observedObjects.has(object2) === attached) return;
13800
- const observable = object2;
13924
+ updateObjectRegistration(object3, attached) {
13925
+ if (this.observedObjects.has(object3) === attached) return;
13926
+ const observable = object3;
13801
13927
  if (attached) {
13802
- this.observedObjects.add(object2);
13928
+ this.observedObjects.add(object3);
13803
13929
  observable.addEventListener("change", this.onObjectChange);
13804
13930
  } else {
13805
- this.observedObjects.delete(object2);
13931
+ this.observedObjects.delete(object3);
13806
13932
  observable.removeEventListener("change", this.onObjectChange);
13807
13933
  }
13808
13934
  const change = attached ? 1 : -1;
13809
13935
  this.stats.objectCount += change;
13810
- if (isSceneObject(object2)) {
13936
+ if (isSceneObject(object3)) {
13811
13937
  this.stats.sceneObjectCount += change;
13812
13938
  }
13813
13939
  }
13814
13940
  /** Initializes each object before attaching it to the scene. */
13815
- async initAndAdd(...object2) {
13941
+ async initAndAdd(...object3) {
13816
13942
  this.dirty = true;
13817
- for (let obj of object2) {
13943
+ for (let obj of object3) {
13818
13944
  await obj.init();
13819
13945
  }
13820
- return this.add(...object2);
13946
+ return this.add(...object3);
13821
13947
  }
13822
- async addSceneObject(asset, objectSupplier, _options, parent = this) {
13948
+ async addSceneObject(asset2, objectSupplier, _options, parent = this) {
13823
13949
  this.dirty = true;
13824
13950
  const obj = await objectSupplier();
13825
- if (obj?.options?.instanceMeshes && asset.key && asset.key?.assetType === "models") {
13826
- let key = asset.key.serialize();
13951
+ if (obj?.options?.instanceMeshes && asset2.key && asset2.key?.assetType === "models") {
13952
+ let key = asset2.key.serialize();
13827
13953
  if (isModelObject(obj)) {
13828
13954
  const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
13829
13955
  if (displayPosition) key += `|display:${displayPosition}`;
@@ -13923,11 +14049,11 @@ var _changeEvent = { type: "change" };
13923
14049
  var _startEvent = { type: "start" };
13924
14050
  var _endEvent = { type: "end" };
13925
14051
  var OrbitControls = class extends import_three35.EventDispatcher {
13926
- constructor(object2, domElement) {
14052
+ constructor(object3, domElement) {
13927
14053
  super();
13928
14054
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
13929
14055
  if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
13930
- this.object = object2;
14056
+ this.object = object3;
13931
14057
  this.domElement = domElement;
13932
14058
  this.domElement.style.touchAction = "none";
13933
14059
  this.enabled = true;
@@ -13984,7 +14110,7 @@ var OrbitControls = class extends import_three35.EventDispatcher {
13984
14110
  };
13985
14111
  this.update = function() {
13986
14112
  const offset = new import_three35.Vector3();
13987
- const quat = new import_three35.Quaternion().setFromUnitVectors(object2.up, new import_three35.Vector3(0, 1, 0));
14113
+ const quat = new import_three35.Quaternion().setFromUnitVectors(object3.up, new import_three35.Vector3(0, 1, 0));
13988
14114
  const quatInverse = quat.clone().invert();
13989
14115
  const lastPosition = new import_three35.Vector3();
13990
14116
  const lastQuaternion = new import_three35.Quaternion();
@@ -14549,8 +14675,8 @@ var OrbitControls = class extends import_three35.EventDispatcher {
14549
14675
  }
14550
14676
  };
14551
14677
  var MapControls = class extends OrbitControls {
14552
- constructor(object2, domElement) {
14553
- super(object2, domElement);
14678
+ constructor(object3, domElement) {
14679
+ super(object3, domElement);
14554
14680
  this.screenSpacePanning = false;
14555
14681
  this.mouseButtons.LEFT = import_three35.MOUSE.PAN;
14556
14682
  this.mouseButtons.RIGHT = import_three35.MOUSE.ROTATE;
@@ -14978,6 +15104,232 @@ init_SceneObject();
14978
15104
  // src/index.ts
14979
15105
  init_request();
14980
15106
 
15107
+ // src/scene/SceneDocument.ts
15108
+ init_DisplayPosition();
15109
+ function fail(path, message) {
15110
+ throw new Error(`${path}: ${message}`);
15111
+ }
15112
+ function object2(value, path) {
15113
+ if (!value || typeof value !== "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) fail(path, "expected a JSON object");
15114
+ for (const key of Object.keys(value)) {
15115
+ if (["__proto__", "prototype", "constructor"].includes(key)) fail(`${path}.${key}`, "unsupported property");
15116
+ }
15117
+ return value;
15118
+ }
15119
+ function fields(value, path, allowed, required = []) {
15120
+ const input = object2(value, path);
15121
+ for (const key of required) if (input[key] === void 0) fail(`${path}.${key}`, "required");
15122
+ for (const [key, entry] of Object.entries(input)) {
15123
+ if (!Object.prototype.hasOwnProperty.call(allowed, key)) fail(`${path}.${key}`, "unsupported property");
15124
+ if (entry !== void 0) allowed[key](entry, `${path}.${key}`);
15125
+ }
15126
+ return input;
15127
+ }
15128
+ var text = (value, path) => {
15129
+ if (typeof value !== "string" || !value.trim()) fail(path, "expected a nonempty string");
15130
+ };
15131
+ var literalText = (value, path) => {
15132
+ if (typeof value !== "string") fail(path, "expected a string");
15133
+ };
15134
+ var boolean = (value, path) => {
15135
+ if (typeof value !== "boolean") fail(path, "expected a boolean");
15136
+ };
15137
+ var number = (value, path) => {
15138
+ if (typeof value !== "number" || !Number.isFinite(value)) fail(path, "expected a finite number");
15139
+ };
15140
+ var positive = (value, path) => {
15141
+ number(value, path);
15142
+ if (value <= 0) fail(path, "expected a positive number");
15143
+ };
15144
+ var nonnegative = (value, path) => {
15145
+ number(value, path);
15146
+ if (value < 0) fail(path, "expected a nonnegative number");
15147
+ };
15148
+ var color = (value, path) => {
15149
+ number(value, path);
15150
+ if (!Number.isInteger(value) || value < 0 || value > 16777215) {
15151
+ fail(path, "expected an RGB integer from 0 to 16777215");
15152
+ }
15153
+ };
15154
+ var asset = (value, path) => {
15155
+ text(value, path);
15156
+ if (!/^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(value) || value.split(/[:/]/).some((part) => !part || part === "." || part === "..")) {
15157
+ fail(path, "expected a resource ID such as minecraft:stone");
15158
+ }
15159
+ };
15160
+ var version = (value, path) => {
15161
+ text(value, path);
15162
+ if (!/^[a-zA-Z0-9._-]+$/.test(value)) fail(path, "expected a Minecraft version without slashes");
15163
+ };
15164
+ var tuple = (size, item = number) => (value, path) => {
15165
+ if (!Array.isArray(value) || value.length !== size) fail(path, `expected ${size} numbers`);
15166
+ for (let index = 0; index < size; index++) item(value[index], `${path}[${index}]`);
15167
+ };
15168
+ var list = (item) => (value, path) => {
15169
+ if (!Array.isArray(value)) fail(path, "expected an array");
15170
+ for (let index = 0; index < value.length; index++) item(value[index], `${path}[${index}]`);
15171
+ };
15172
+ var dictionary = (item, numericKeys = false) => (value, path) => {
15173
+ for (const [key, entry] of Object.entries(object2(value, path))) {
15174
+ if (numericKeys && !/^\d+$/.test(key)) fail(`${path}.${key}`, "expected a nonnegative tint index");
15175
+ item(entry, `${path}.${key}`);
15176
+ }
15177
+ };
15178
+ var enumeration = (values) => (value, path) => {
15179
+ if (!values.includes(value)) fail(path, `expected one of: ${values.join(", ")}`);
15180
+ };
15181
+ var textStyle = { color, bold: boolean, italic: boolean };
15182
+ function guiLayer(value, path) {
15183
+ const layer = object2(value, path);
15184
+ if (["texture", "item", "text"].filter((key) => layer[key] !== void 0).length !== 1) {
15185
+ fail(path, "expected exactly one of texture, item, or text");
15186
+ }
15187
+ const layout = { name: text, position: tuple(2), size: tuple(2, positive) };
15188
+ if (layer.texture !== void 0) {
15189
+ fields(value, path, { ...layout, texture: asset, crop: (value2, path2) => {
15190
+ tuple(4)(value2, path2);
15191
+ const [x, y, width, height] = value2;
15192
+ nonnegative(x, `${path2}[0]`);
15193
+ nonnegative(y, `${path2}[1]`);
15194
+ positive(width, `${path2}[2]`);
15195
+ positive(height, `${path2}[3]`);
15196
+ } });
15197
+ } else if (layer.item !== void 0) {
15198
+ fields(value, path, { ...layout, item: asset, tints: dictionary(color, true) });
15199
+ } else {
15200
+ fields(value, path, {
15201
+ ...layout,
15202
+ ...textStyle,
15203
+ font: asset,
15204
+ shadow: boolean,
15205
+ maxWidth: positive,
15206
+ lineHeight: positive,
15207
+ text: (value2, path2) => {
15208
+ if (typeof value2 === "string") return;
15209
+ list((run, path3) => {
15210
+ fields(run, path3, { text: literalText, ...textStyle }, ["text"]);
15211
+ })(value2, path2);
15212
+ }
15213
+ });
15214
+ }
15215
+ }
15216
+ function validateObject(value, path) {
15217
+ const input = object2(value, path);
15218
+ const common = { id: text, name: text, type: text, position: tuple(3), rotation: tuple(3), scale: tuple(3), visible: boolean };
15219
+ const required = ["id", "type"];
15220
+ const renderOptions = { wireframe: boolean };
15221
+ switch (input.type) {
15222
+ case "skin":
15223
+ fields(value, path, {
15224
+ ...common,
15225
+ skin: text,
15226
+ cape: (value2, path2) => {
15227
+ fields(value2, path2, { texture: text, layout: enumeration(["minecraft", "optifine", "labymod"]) }, ["texture"]);
15228
+ },
15229
+ hiddenParts: list(enumeration(SKIN_PARTS)),
15230
+ pose: (value2, path2) => {
15231
+ fields(value2, path2, {
15232
+ head: tuple(3),
15233
+ body: tuple(3),
15234
+ rightArm: tuple(3),
15235
+ leftArm: tuple(3),
15236
+ rightLeg: tuple(3),
15237
+ leftLeg: tuple(3),
15238
+ cape: tuple(3)
15239
+ });
15240
+ },
15241
+ options: (value2, path2) => {
15242
+ fields(value2, path2, { slim: boolean, legacy: boolean });
15243
+ }
15244
+ }, required);
15245
+ break;
15246
+ case "block":
15247
+ fields(value, path, {
15248
+ ...common,
15249
+ asset,
15250
+ state: dictionary(text),
15251
+ options: (value2, path2) => {
15252
+ fields(value2, path2, { ...renderOptions, tints: dictionary(color, true) });
15253
+ }
15254
+ }, [...required, "asset"]);
15255
+ break;
15256
+ case "item":
15257
+ case "model":
15258
+ fields(value, path, {
15259
+ ...common,
15260
+ asset,
15261
+ options: (value2, path2) => {
15262
+ fields(value2, path2, { ...renderOptions, displayPosition: enumeration(DISPLAY_POSITIONS), tints: dictionary(color, true) });
15263
+ }
15264
+ }, [...required, "asset"]);
15265
+ break;
15266
+ case "entity":
15267
+ fields(value, path, {
15268
+ ...common,
15269
+ asset,
15270
+ texture: asset,
15271
+ layers: list(text),
15272
+ when: list(text),
15273
+ textures: dictionary(asset),
15274
+ options: (value2, path2) => {
15275
+ fields(value2, path2, {
15276
+ ...renderOptions,
15277
+ flip: boolean,
15278
+ tints: dictionary((value3, path3) => {
15279
+ typeof value3 === "string" ? text(value3, path3) : color(value3, path3);
15280
+ })
15281
+ });
15282
+ },
15283
+ animation: (value2, path2) => {
15284
+ fields(value2, path2, { name: text, loop: boolean, speed: nonnegative, time: nonnegative, paused: boolean }, ["name"]);
15285
+ }
15286
+ }, [...required, "asset"]);
15287
+ if (Array.isArray(input.layers) && !input.layers.length) fail(`${path}.layers`, "expected at least one layer");
15288
+ break;
15289
+ case "gui":
15290
+ fields(value, path, { ...common, layers: list(guiLayer) }, [...required, "layers"]);
15291
+ break;
15292
+ default:
15293
+ fail(`${path}.type`, "expected skin, block, item, entity, model, or gui");
15294
+ }
15295
+ }
15296
+ function parseSceneDocument(value) {
15297
+ if (typeof value === "string") {
15298
+ try {
15299
+ value = JSON.parse(value);
15300
+ } catch {
15301
+ fail("scene", "invalid JSON");
15302
+ }
15303
+ }
15304
+ const input = fields(value, "scene", {
15305
+ format: enumeration(["minerender-scene"]),
15306
+ version: (value2, path) => {
15307
+ if (value2 !== 1) fail(path, "only scene document version 1 is supported");
15308
+ },
15309
+ minecraftVersion: version,
15310
+ camera: (value2, path) => {
15311
+ fields(value2, path, { position: tuple(3), target: tuple(3) }, ["position", "target"]);
15312
+ },
15313
+ objects: list(validateObject)
15314
+ }, ["format", "version", "objects"]);
15315
+ const ids = /* @__PURE__ */ new Set();
15316
+ for (const [index, entry] of input.objects.entries()) {
15317
+ if (ids.has(entry.id)) fail(`scene.objects[${index}].id`, `duplicate object ID "${entry.id}"`);
15318
+ ids.add(entry.id);
15319
+ }
15320
+ return JSON.parse(JSON.stringify(input));
15321
+ }
15322
+
15323
+ // src/scene/SceneDocumentLoader.ts
15324
+ var import_three38 = require("three");
15325
+ init_AssetKey();
15326
+ init_AssetLoader();
15327
+ init_BlockStates();
15328
+ init_Entities();
15329
+ init_Models();
15330
+ init_DisplayPosition();
15331
+ init_SceneObject();
15332
+
14981
15333
  // src/skin/Skins.ts
14982
15334
  init_Requests();
14983
15335
  var Skins = class {
@@ -15148,6 +15500,195 @@ var Skins = class {
15148
15500
  //</editor-fold>
15149
15501
  };
15150
15502
 
15503
+ // src/scene/SceneDocumentLoader.ts
15504
+ var DocumentObjectScene = class extends MineRenderScene {
15505
+ async addSceneObject(_asset, supplier, _options, parent = this) {
15506
+ const object3 = await supplier();
15507
+ return this.initialize(object3, parent);
15508
+ }
15509
+ async initialize(object3, parent = this) {
15510
+ object3.scene = this;
15511
+ try {
15512
+ await object3.init();
15513
+ parent.add(object3);
15514
+ return object3;
15515
+ } catch (error) {
15516
+ object3.dispose();
15517
+ object3.removeFromParent();
15518
+ throw error;
15519
+ }
15520
+ }
15521
+ dispose() {
15522
+ for (const child of [...this.children]) {
15523
+ if (child.parent !== this) continue;
15524
+ if (isSceneObject(child)) child.dispose();
15525
+ child.removeFromParent();
15526
+ }
15527
+ }
15528
+ };
15529
+ async function skinTexture(value, cape = false) {
15530
+ if (!/^[a-zA-Z0-9_-]{1,36}$/.test(value)) return value;
15531
+ const texture = await (cape ? Skins.capeFromUuidOrUsername(value) : Skins.fromUuidOrUsername(value));
15532
+ if (!texture) throw new Error(`Could not find ${cape ? "cape" : "skin"} for "${value}"`);
15533
+ return texture;
15534
+ }
15535
+ var SceneDocumentLoader = class {
15536
+ static parse(value) {
15537
+ return parseSceneDocument(value);
15538
+ }
15539
+ /**
15540
+ * Loads objects concurrently and attaches them in document order after every load succeeds.
15541
+ * A failure waits for all loads, disposes staged objects, and reports the first error in document order.
15542
+ */
15543
+ static async load(scene, value, parent = scene) {
15544
+ const definition = this.parse(value);
15545
+ if (definition.minecraftVersion !== void 0 && definition.minecraftVersion !== AssetLoader.version) {
15546
+ throw new Error(`Scene requires Minecraft ${definition.minecraftVersion}; call AssetLoader.setVersion("${definition.minecraftVersion}") before loading it`);
15547
+ }
15548
+ const root = new import_three38.Group();
15549
+ root.name = "MineRender scene document";
15550
+ const objects = [];
15551
+ let disposed = false;
15552
+ const loaded = {
15553
+ root,
15554
+ objects,
15555
+ definition,
15556
+ advanceAnimations: (delta) => {
15557
+ if (!disposed) for (const object3 of objects) object3.advanceAnimation(delta);
15558
+ },
15559
+ dispose: () => {
15560
+ if (disposed) return;
15561
+ disposed = true;
15562
+ root.removeFromParent();
15563
+ for (const object3 of objects) object3.dispose();
15564
+ root.clear();
15565
+ scene.dirty = true;
15566
+ }
15567
+ };
15568
+ try {
15569
+ const results = await Promise.allSettled(definition.objects.map((object3) => this.loadValidatedObject(scene, object3)));
15570
+ for (const result of results) if (result.status === "fulfilled") objects.push(result.value);
15571
+ const failure = results.find((result) => result.status === "rejected");
15572
+ if (failure) throw failure.reason;
15573
+ for (const object3 of objects) root.add(object3.root);
15574
+ parent.add(root);
15575
+ scene.dirty = true;
15576
+ return loaded;
15577
+ } catch (error) {
15578
+ loaded.dispose();
15579
+ throw error;
15580
+ }
15581
+ }
15582
+ /** Loads an independently editable object. Its root owns the document's position, rotation, and scale. */
15583
+ static async loadObject(scene, value, parent = scene) {
15584
+ const definition = this.parse({ format: "minerender-scene", version: 1, objects: [value] }).objects[0];
15585
+ return this.loadValidatedObject(scene, definition, parent);
15586
+ }
15587
+ static async loadValidatedObject(scene, definition, parent) {
15588
+ const root = new import_three38.Group();
15589
+ root.name = definition.name ?? definition.id;
15590
+ root.userData.sceneObjectId = definition.id;
15591
+ root.position.fromArray(definition.position ?? [0, 0, 0]);
15592
+ root.rotation.set(...definition.rotation ?? [0, 0, 0]);
15593
+ root.scale.fromArray(definition.scale ?? [1, 1, 1]);
15594
+ root.visible = definition.visible ?? true;
15595
+ const content = new DocumentObjectScene();
15596
+ root.add(content);
15597
+ let object3;
15598
+ try {
15599
+ switch (definition.type) {
15600
+ case "skin": {
15601
+ const skin = new SkinObject({ ...definition.options, instanceMeshes: false });
15602
+ object3 = skin;
15603
+ const texture = definition.skin ? await skinTexture(definition.skin) : `${AssetLoader.ROOT}/assets/minecraft/textures/entity/player/${definition.options?.slim ? "slim/alex" : "wide/steve"}.png`;
15604
+ await skin.setSkinTexture(texture);
15605
+ await content.initialize(skin);
15606
+ if (definition.cape) await skin.setCapeTexture(await skinTexture(definition.cape.texture, true), definition.cape.layout);
15607
+ for (const [part, rotation] of Object.entries(definition.pose ?? {})) {
15608
+ skin.getGroupByName(part)?.rotation.set(...rotation, "XYZ");
15609
+ }
15610
+ for (const part of definition.hiddenParts ?? []) {
15611
+ const mesh = skin.getMeshByName(part);
15612
+ if (mesh) mesh.visible = false;
15613
+ }
15614
+ break;
15615
+ }
15616
+ case "block": {
15617
+ const state = await BlockStates.get(AssetKey.parse("blockstates", definition.asset));
15618
+ if (!state) throw new Error(`Could not load block ${definition.asset}`);
15619
+ object3 = await content.addBlock(state, { ...definition.options, initialState: definition.state, instanceMeshes: false });
15620
+ break;
15621
+ }
15622
+ case "item":
15623
+ case "model": {
15624
+ let key = AssetKey.parse("models", definition.asset);
15625
+ if (definition.type === "item" && key.type !== "item") {
15626
+ key = new AssetKey(key.namespace, key.getFullPath(), "models", "item");
15627
+ }
15628
+ const model = await Models.getMerged(key);
15629
+ if (!model) throw new Error(`Could not load ${definition.type} ${definition.asset}`);
15630
+ object3 = await content.addModel(model, {
15631
+ ...definition.type === "item" ? { displayPosition: "gui" /* GUI */ } : {},
15632
+ ...definition.options,
15633
+ instanceMeshes: false
15634
+ });
15635
+ break;
15636
+ }
15637
+ case "entity": {
15638
+ const key = AssetKey.parse("entity-models", definition.asset);
15639
+ const model = await Entities.getEntity(key, definition.texture ? AssetKey.parse("textures", definition.texture) : void 0, {
15640
+ layers: definition.layers,
15641
+ when: definition.when,
15642
+ textures: definition.textures && Object.fromEntries(Object.entries(definition.textures).map(([name, texture]) => [name, AssetKey.parse("textures", texture)]))
15643
+ });
15644
+ if (!model) throw new Error(`Could not load entity ${definition.asset}`);
15645
+ const entity = await content.addEntity(model, { ...definition.options, instanceMeshes: false });
15646
+ object3 = entity;
15647
+ if (definition.animation) {
15648
+ const animations = await Entities.getAnimations(key);
15649
+ const clip = animations?.[definition.animation.name];
15650
+ if (!clip) throw new Error(`Entity ${definition.asset} has no animation "${definition.animation.name}"`);
15651
+ entity.playAnimation(clip, definition.animation);
15652
+ }
15653
+ break;
15654
+ }
15655
+ case "gui":
15656
+ object3 = await content.initialize(new GuiObject(definition.layers));
15657
+ break;
15658
+ }
15659
+ let disposed = false;
15660
+ const loaded = {
15661
+ root,
15662
+ object: object3,
15663
+ definition,
15664
+ advanceAnimation: (delta) => {
15665
+ if (!disposed && definition.type === "entity" && !definition.animation?.paused) object3.advanceAnimation(delta);
15666
+ },
15667
+ dispose: () => {
15668
+ if (disposed) return;
15669
+ disposed = true;
15670
+ root.removeFromParent();
15671
+ object3.dispose();
15672
+ object3.removeFromParent();
15673
+ content.dispose();
15674
+ root.clear();
15675
+ scene.dirty = true;
15676
+ }
15677
+ };
15678
+ parent?.add(root);
15679
+ scene.dirty = true;
15680
+ return loaded;
15681
+ } catch (error) {
15682
+ object3?.dispose();
15683
+ object3?.removeFromParent();
15684
+ content.dispose();
15685
+ root.removeFromParent();
15686
+ root.clear();
15687
+ throw new Error(`Scene object "${definition.name ?? definition.id}": ${error instanceof Error ? error.message : String(error)}`);
15688
+ }
15689
+ }
15690
+ };
15691
+
15151
15692
  // src/texture/index.ts
15152
15693
  init_Colormaps();
15153
15694
  init_TextureAtlas();
@@ -15429,12 +15970,12 @@ var AnvilParser = class {
15429
15970
  };
15430
15971
 
15431
15972
  // src/world/Chunk.ts
15432
- var import_three41 = require("three");
15973
+ var import_three42 = require("three");
15433
15974
  init_BlockStates();
15434
15975
  init_AssetKey();
15435
15976
 
15436
15977
  // src/world/MineRenderWorld.ts
15437
- var import_three39 = require("three");
15978
+ var import_three40 = require("three");
15438
15979
  init_Model();
15439
15980
  init_BatchedExecutor();
15440
15981
  init_AssetKey();
@@ -15442,7 +15983,7 @@ init_BlockStates();
15442
15983
  init_CubeFace();
15443
15984
 
15444
15985
  // src/world/SectionModels.ts
15445
- var import_three38 = require("three");
15986
+ var import_three39 = require("three");
15446
15987
  init_AssetKey();
15447
15988
  init_Models();
15448
15989
  init_CubeFace();
@@ -15501,20 +16042,20 @@ var SectionModels = class {
15501
16042
  if (!models) this.models.set(model, models = /* @__PURE__ */ new Map());
15502
16043
  const key = JSON.stringify([rotation.x, rotation.y, rotation.z, variant.uvlock, tints]);
15503
16044
  const template = await cached(models, key, async () => {
15504
- const object2 = new SectionModel(model, {
16045
+ const object3 = new SectionModel(model, {
15505
16046
  instanceMeshes: false,
15506
16047
  mergeMeshes: false,
15507
16048
  tints,
15508
16049
  uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
15509
16050
  });
15510
- await object2.init();
15511
- const geometry = object2.children[0].geometry;
15512
- geometry.applyMatrix4(new import_three38.Matrix4().makeRotationFromEuler(rotation));
15513
- object2.clear();
16051
+ await object3.init();
16052
+ const geometry = object3.children[0].geometry;
16053
+ geometry.applyMatrix4(new import_three39.Matrix4().makeRotationFromEuler(rotation));
16054
+ object3.clear();
15514
16055
  const cullFaces = CUBE_FACES.map((face) => {
15515
16056
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
15516
16057
  if (local < 0) return 0;
15517
- const normal = new import_three38.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
16058
+ const normal = new import_three39.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
15518
16059
  const world = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
15519
16060
  return 1 << world;
15520
16061
  });
@@ -15545,20 +16086,20 @@ var MineRenderWorld = class {
15545
16086
  }
15546
16087
  getBlockAt(posOrX, y, z) {
15547
16088
  if (typeof posOrX == "number") {
15548
- return this.getBlockAt(new import_three39.Vector3(posOrX, y, z));
16089
+ return this.getBlockAt(new import_three40.Vector3(posOrX, y, z));
15549
16090
  }
15550
16091
  if (isTripleArray(posOrX)) {
15551
- return this.getBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]));
16092
+ return this.getBlockAt(new import_three40.Vector3(posOrX[0], posOrX[1], posOrX[2]));
15552
16093
  }
15553
16094
  this.validatePosBounds(posOrX);
15554
16095
  return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
15555
16096
  }
15556
16097
  async setBlockAt(posOrX, yOrBlock, z, block) {
15557
16098
  if (typeof posOrX == "number") {
15558
- return this.setBlockAt(new import_three39.Vector3(posOrX, yOrBlock, z), block);
16099
+ return this.setBlockAt(new import_three40.Vector3(posOrX, yOrBlock, z), block);
15559
16100
  }
15560
16101
  if (isTripleArray(posOrX)) {
15561
- return this.setBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
16102
+ return this.setBlockAt(new import_three40.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
15562
16103
  }
15563
16104
  return this.placeBlock(posOrX, yOrBlock);
15564
16105
  }
@@ -15569,10 +16110,10 @@ var MineRenderWorld = class {
15569
16110
  }
15570
16111
  async setBlockVisibleAt(posOrX, yOrVisible, z, visible) {
15571
16112
  if (typeof posOrX === "number") {
15572
- return this.setBlockVisibleAt(new import_three39.Vector3(posOrX, yOrVisible, z), visible);
16113
+ return this.setBlockVisibleAt(new import_three40.Vector3(posOrX, yOrVisible, z), visible);
15573
16114
  }
15574
16115
  if (isTripleArray(posOrX)) {
15575
- return this.setBlockVisibleAt(new import_three39.Vector3(...posOrX), yOrVisible);
16116
+ return this.setBlockVisibleAt(new import_three40.Vector3(...posOrX), yOrVisible);
15576
16117
  }
15577
16118
  this.validatePosBounds(posOrX);
15578
16119
  await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
@@ -15596,7 +16137,7 @@ var MineRenderWorld = class {
15596
16137
  const collect = async (positions2) => {
15597
16138
  for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
15598
16139
  };
15599
- const place = (block) => this.placeBlock(new import_three39.Vector3(...block.position), block, collect);
16140
+ const place = (block) => this.placeBlock(new import_three40.Vector3(...block.position), block, collect);
15600
16141
  const keys = /* @__PURE__ */ new Map();
15601
16142
  for (const block of multiblock.blocks) {
15602
16143
  if (Chunk.isAir(block)) continue;
@@ -15694,13 +16235,13 @@ var MineRenderWorld = class {
15694
16235
  for (const pos of positions) {
15695
16236
  this.pendingCulling.set(pos.toArray().join(","), pos.clone());
15696
16237
  for (const offset of CUBE_FACE_OFFSETS) {
15697
- const neighbor = pos.clone().add(new import_three39.Vector3(...offset));
16238
+ const neighbor = pos.clone().add(new import_three40.Vector3(...offset));
15698
16239
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
15699
16240
  }
15700
16241
  for (let y = -1; y <= 1; y++) {
15701
16242
  for (let z = -1; z <= 1; z++) {
15702
16243
  for (let x = -1; x <= 1; x++) {
15703
- const neighbor = pos.clone().add(new import_three39.Vector3(x, y, z));
16244
+ const neighbor = pos.clone().add(new import_three40.Vector3(x, y, z));
15704
16245
  if (this.getBlockAt(neighbor)?.object?.fluidKind) {
15705
16246
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
15706
16247
  }
@@ -15724,19 +16265,19 @@ var MineRenderWorld = class {
15724
16265
  }
15725
16266
  if (block.object?.fluidKind) {
15726
16267
  await block.object.updateFluid((x, y, z) => {
15727
- const neighbor = pos.clone().add(new import_three39.Vector3(x, y, z));
16268
+ const neighbor = pos.clone().add(new import_three40.Vector3(x, y, z));
15728
16269
  const section = this.getChunkAt(neighbor);
15729
- const object2 = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
16270
+ const object3 = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
15730
16271
  return {
15731
- fluid: object2?.fluidKind,
15732
- level: object2?.fluidLevel,
16272
+ fluid: object3?.fluidKind,
16273
+ level: object3?.fluidLevel,
15733
16274
  solid: section?.isOccludingAt(neighbor) ?? false
15734
16275
  };
15735
16276
  });
15736
16277
  }
15737
16278
  let mask = 0;
15738
16279
  for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
15739
- const neighbor = pos.clone().add(new import_three39.Vector3(...offset));
16280
+ const neighbor = pos.clone().add(new import_three40.Vector3(...offset));
15740
16281
  if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
15741
16282
  mask |= 1 << face;
15742
16283
  }
@@ -15772,7 +16313,7 @@ var MineRenderWorld = class {
15772
16313
  }
15773
16314
  /** Converts block coordinates to scene units by multiplying each component by 16. */
15774
16315
  static worldToScenePosition(pos) {
15775
- return new import_three39.Vector3(
16316
+ return new import_three40.Vector3(
15776
16317
  pos.x * 16,
15777
16318
  pos.y * 16,
15778
16319
  pos.z * 16
@@ -15780,7 +16321,7 @@ var MineRenderWorld = class {
15780
16321
  }
15781
16322
  /** Converts scene units to block coordinates without rounding to an integer block. */
15782
16323
  static sceneToWorldPosition(pos) {
15783
- return new import_three39.Vector3(
16324
+ return new import_three40.Vector3(
15784
16325
  pos.x / 16,
15785
16326
  pos.y / 16,
15786
16327
  pos.z / 16
@@ -15803,10 +16344,10 @@ var MineRenderWorld = class {
15803
16344
  init_Model();
15804
16345
 
15805
16346
  // src/world/SectionMesh.ts
15806
- var import_three40 = require("three");
16347
+ var import_three41 = require("three");
15807
16348
  init_CanvasCompat();
15808
16349
  init_Materials();
15809
- var SectionMesh = class _SectionMesh extends import_three40.Group {
16350
+ var SectionMesh = class _SectionMesh extends import_three41.Group {
15810
16351
  constructor() {
15811
16352
  super(...arguments);
15812
16353
  this.ownedMeshes = [];
@@ -15859,7 +16400,7 @@ var SectionMesh = class _SectionMesh extends import_three40.Group {
15859
16400
  const normal = template.geometry.getAttribute("normal");
15860
16401
  const uv = template.geometry.getAttribute("uv");
15861
16402
  const bounds = template.geometry.getAttribute("uvBounds");
15862
- const color = template.geometry.getAttribute("color");
16403
+ const color2 = template.geometry.getAttribute("color");
15863
16404
  const sourceIndices = template.geometry.getIndex();
15864
16405
  const placement = locations.get(template.atlas).placement;
15865
16406
  const mapU = (u) => (placement.x + u * template.atlas.image.width) / page.width;
@@ -15881,24 +16422,24 @@ var SectionMesh = class _SectionMesh extends import_three40.Group {
15881
16422
  mapU(bounds?.getZ(vertex) ?? 1),
15882
16423
  mapV(bounds?.getW(vertex) ?? 1)
15883
16424
  );
15884
- colors.push(color?.getX(vertex) ?? 1, color?.getY(vertex) ?? 1, color?.getZ(vertex) ?? 1);
16425
+ colors.push(color2?.getX(vertex) ?? 1, color2?.getY(vertex) ?? 1, color2?.getZ(vertex) ?? 1);
15885
16426
  }
15886
16427
  for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
15887
16428
  }
15888
16429
  }
15889
- const geometry = new import_three40.BufferGeometry();
15890
- geometry.setAttribute("position", new import_three40.Float32BufferAttribute(positions, 3));
15891
- geometry.setAttribute("normal", new import_three40.Float32BufferAttribute(normals, 3));
15892
- geometry.setAttribute("uv", new import_three40.Float32BufferAttribute(uvs, 2));
15893
- geometry.setAttribute("uvBounds", new import_three40.Float32BufferAttribute(uvBounds, 4));
15894
- geometry.setAttribute("color", new import_three40.Float32BufferAttribute(colors, 3));
16430
+ const geometry = new import_three41.BufferGeometry();
16431
+ geometry.setAttribute("position", new import_three41.Float32BufferAttribute(positions, 3));
16432
+ geometry.setAttribute("normal", new import_three41.Float32BufferAttribute(normals, 3));
16433
+ geometry.setAttribute("uv", new import_three41.Float32BufferAttribute(uvs, 2));
16434
+ geometry.setAttribute("uvBounds", new import_three41.Float32BufferAttribute(uvBounds, 4));
16435
+ geometry.setAttribute("color", new import_three41.Float32BufferAttribute(colors, 3));
15895
16436
  geometry.setIndex(indices);
15896
16437
  geometry.computeBoundingBox();
15897
16438
  geometry.computeBoundingSphere();
15898
16439
  const material = Materials.createShadedCanvasMaterial(canvas, false, false, true);
15899
16440
  material.vertexColors = true;
15900
16441
  const texture = material.uniforms?.map?.value ?? material.map;
15901
- const mesh = new import_three40.Mesh(geometry, material);
16442
+ const mesh = new import_three41.Mesh(geometry, material);
15902
16443
  section.add(mesh);
15903
16444
  section.ownedMeshes.push({ mesh, texture });
15904
16445
  }
@@ -15934,10 +16475,10 @@ var Chunk = class _Chunk {
15934
16475
  }
15935
16476
  getBlockAt(posOrX, y, z) {
15936
16477
  if (typeof posOrX == "number") {
15937
- return this.getBlockAt(new import_three41.Vector3(posOrX, y, z));
16478
+ return this.getBlockAt(new import_three42.Vector3(posOrX, y, z));
15938
16479
  }
15939
16480
  if (isTripleArray(posOrX)) {
15940
- return this.getBlockAt(new import_three41.Vector3(posOrX[0], posOrX[1], posOrX[2]));
16481
+ return this.getBlockAt(new import_three42.Vector3(posOrX[0], posOrX[1], posOrX[2]));
15941
16482
  }
15942
16483
  const pos = this.worldPosToChunkPos(posOrX);
15943
16484
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -15945,10 +16486,10 @@ var Chunk = class _Chunk {
15945
16486
  }
15946
16487
  async setBlockAt(posOrX, yOrBlock, z, block) {
15947
16488
  if (typeof posOrX == "number") {
15948
- return this.setBlockAt(new import_three41.Vector3(posOrX, yOrBlock, z), block);
16489
+ return this.setBlockAt(new import_three42.Vector3(posOrX, yOrBlock, z), block);
15949
16490
  }
15950
16491
  if (isTripleArray(posOrX)) {
15951
- return this.setBlockAt(new import_three41.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
16492
+ return this.setBlockAt(new import_three42.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
15952
16493
  }
15953
16494
  const worldPos = posOrX;
15954
16495
  const pos = this.worldPosToChunkPos(worldPos);
@@ -15969,7 +16510,7 @@ var Chunk = class _Chunk {
15969
16510
  this.renderedBlocks.get(index)?.object?.removeFromScene();
15970
16511
  if (this.sectionBlocks.delete(index)) this.meshDirty = true;
15971
16512
  this.renderedBlocks.delete(index);
15972
- let object2;
16513
+ let object3;
15973
16514
  try {
15974
16515
  if (!readBlock) return void 0;
15975
16516
  const stored = readBlock();
@@ -15984,22 +16525,22 @@ var Chunk = class _Chunk {
15984
16525
  this.sectionBlocks.set(index, { index, template, cullMask: 0 });
15985
16526
  this.meshDirty = true;
15986
16527
  } else {
15987
- object2 = await this.scene.addBlock(blockState, {
16528
+ object3 = await this.scene.addBlock(blockState, {
15988
16529
  mergeMeshes: true,
15989
16530
  instanceMeshes: true,
15990
16531
  maxInstanceCount: 2e3,
15991
16532
  initialState: stored.properties
15992
16533
  });
15993
- object2.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
16534
+ object3.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
15994
16535
  }
15995
16536
  const info = { get block() {
15996
16537
  return readBlock();
15997
- }, object: object2 };
16538
+ }, object: object3 };
15998
16539
  this.renderedBlocks.set(index, info);
15999
16540
  return info;
16000
16541
  } catch (error) {
16001
16542
  this.data.set(index, void 0);
16002
- object2?.removeFromScene();
16543
+ object3?.removeFromScene();
16003
16544
  throw error;
16004
16545
  } finally {
16005
16546
  await onBlocksChanged?.([worldPos]);
@@ -16062,7 +16603,7 @@ var Chunk = class _Chunk {
16062
16603
  /** Removes stored blocks and their render objects, then notifies the owning world of changed positions. */
16063
16604
  async clear(onBlocksChanged = this.onBlocksChanged) {
16064
16605
  const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
16065
- new import_three41.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
16606
+ new import_three42.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
16066
16607
  ));
16067
16608
  for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
16068
16609
  this.sectionBlocks.clear();
@@ -16088,14 +16629,14 @@ var Chunk = class _Chunk {
16088
16629
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
16089
16630
  }
16090
16631
  worldPosToChunkPos(pos) {
16091
- return new import_three41.Vector3(
16632
+ return new import_three42.Vector3(
16092
16633
  pos.x - this.x * 16,
16093
16634
  pos.y - this.y * 16,
16094
16635
  pos.z - this.z * 16
16095
16636
  );
16096
16637
  }
16097
16638
  chunkPosToWorldPos(pos) {
16098
- return new import_three41.Vector3(
16639
+ return new import_three42.Vector3(
16099
16640
  this.x * 16 + pos.x,
16100
16641
  this.y * 16 + pos.y,
16101
16642
  this.z * 16 + pos.z