"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// dist/index.js
var dist_exports = {};
__export(dist_exports, {
  ArcGISWebSceneLoader: () => ArcGISWebSceneLoader,
  COORDINATE_SYSTEM: () => COORDINATE_SYSTEM,
  I3SAttributeLoader: () => I3SAttributeLoader,
  I3SBuildingSceneLayerLoader: () => I3SBuildingSceneLayerLoader,
  I3SContentLoader: () => I3SContentLoader,
  I3SLoader: () => I3SLoader,
  I3SNodePageLoader: () => I3SNodePageLoader,
  LayerError: () => LayerError,
  SLPKArchive: () => SLPKArchive,
  SLPKLoader: () => SLPKLoader,
  customizeColors: () => customizeColors,
  loadFeatureAttributes: () => loadFeatureAttributes,
  parseSLPKArchive: () => parseSLPKArchive
});
module.exports = __toCommonJS(dist_exports);

// dist/lib/parsers/constants.js
var import_math = require("@loaders.gl/math");
function getConstructorForDataFormat(dataType) {
  switch (dataType) {
    case "UInt8":
      return Uint8Array;
    case "UInt16":
      return Uint16Array;
    case "UInt32":
      return Uint32Array;
    case "Float32":
      return Float32Array;
    case "UInt64":
      return Float64Array;
    default:
      throw new Error(`parse i3s tile content: unknown type of data: ${dataType}`);
  }
}
var GL_TYPE_MAP = {
  UInt8: import_math.GL.UNSIGNED_BYTE,
  UInt16: import_math.GL.UNSIGNED_SHORT,
  Float32: import_math.GL.FLOAT,
  UInt32: import_math.GL.UNSIGNED_INT,
  UInt64: import_math.GL.DOUBLE
};
function sizeOf(dataType) {
  switch (dataType) {
    case "UInt8":
      return 1;
    case "UInt16":
    case "Int16":
      return 2;
    case "UInt32":
    case "Int32":
    case "Float32":
      return 4;
    case "UInt64":
    case "Int64":
    case "Float64":
      return 8;
    default:
      throw new Error(`parse i3s tile content: unknown size of data: ${dataType}`);
  }
}
var STRING_ATTRIBUTE_TYPE = "String";
var OBJECT_ID_ATTRIBUTE_TYPE = "Oid32";
var FLOAT_64_TYPE = "Float64";
var INT_16_ATTRIBUTE_TYPE = "Int16";
var COORDINATE_SYSTEM;
(function(COORDINATE_SYSTEM2) {
  COORDINATE_SYSTEM2[COORDINATE_SYSTEM2["DEFAULT"] = -1] = "DEFAULT";
  COORDINATE_SYSTEM2[COORDINATE_SYSTEM2["LNGLAT"] = 1] = "LNGLAT";
  COORDINATE_SYSTEM2[COORDINATE_SYSTEM2["METER_OFFSETS"] = 2] = "METER_OFFSETS";
  COORDINATE_SYSTEM2[COORDINATE_SYSTEM2["LNGLAT_OFFSETS"] = 3] = "LNGLAT_OFFSETS";
  COORDINATE_SYSTEM2[COORDINATE_SYSTEM2["CARTESIAN"] = 0] = "CARTESIAN";
})(COORDINATE_SYSTEM || (COORDINATE_SYSTEM = {}));

// dist/i3s-loader.js
var import_core5 = require("@loaders.gl/core");

// dist/lib/parsers/parse-i3s-tile-content.js
var import_core = require("@loaders.gl/core");
var import_core2 = require("@math.gl/core");
var import_geospatial = require("@math.gl/geospatial");
var import_loader_utils = require("@loaders.gl/loader-utils");
var import_images = require("@loaders.gl/images");
var import_draco = require("@loaders.gl/draco");
var import_textures = require("@loaders.gl/textures");

// dist/types.js
var HeaderAttributeProperty;
(function(HeaderAttributeProperty2) {
  HeaderAttributeProperty2["vertexCount"] = "vertexCount";
  HeaderAttributeProperty2["featureCount"] = "featureCount";
})(HeaderAttributeProperty || (HeaderAttributeProperty = {}));

// dist/lib/utils/url-utils.js
function getUrlWithoutParams(url) {
  let urlWithoutParams;
  try {
    const urlObj = new URL(url);
    urlWithoutParams = `${urlObj.origin}${urlObj.pathname}`;
    if (urlWithoutParams.startsWith("null")) {
      urlWithoutParams = null;
    }
  } catch (e) {
    urlWithoutParams = null;
  }
  return urlWithoutParams || url;
}
function getUrlWithToken(url, token = null) {
  return token ? `${url}?token=${token}` : url;
}
function generateTileAttributeUrls(url, tile) {
  const { attributeData = [] } = tile;
  const attributeUrls = [];
  for (let index = 0; index < attributeData.length; index++) {
    const attributeUrl = attributeData[index].href.replace("./", "");
    attributeUrls.push(`${url}/${attributeUrl}`);
  }
  return attributeUrls;
}
function generateTilesetAttributeUrls(tileset, url, resource) {
  const attributeUrls = [];
  const { attributeStorageInfo = [] } = tileset;
  for (let index = 0; index < attributeStorageInfo.length; index++) {
    const fileName = attributeStorageInfo[index].key;
    attributeUrls.push(`${url}/nodes/${resource}/attributes/${fileName}/0`);
  }
  return attributeUrls;
}

// dist/lib/parsers/parse-i3s-tile-content.js
var scratchVector = new import_core2.Vector3([0, 0, 0]);
function getLoaderForTextureFormat(textureFormat) {
  switch (textureFormat) {
    case "ktx-etc2":
    case "dds":
      return import_textures.CompressedTextureLoader;
    case "ktx2":
      return import_textures.BasisLoader;
    case "jpg":
    case "png":
    default:
      return import_images.ImageLoader;
  }
}
var I3S_ATTRIBUTE_TYPE = "i3s-attribute-type";
async function parseI3STileContent(arrayBuffer, tileOptions, tilesetOptions, options, context) {
  var _a;
  const content = {
    attributes: {},
    indices: null,
    featureIds: [],
    vertexCount: 0,
    modelMatrix: new import_core2.Matrix4(),
    coordinateSystem: 0,
    byteLength: 0,
    texture: null
  };
  if (tileOptions.textureUrl) {
    const url = getUrlWithToken(tileOptions.textureUrl, (_a = options == null ? void 0 : options.i3s) == null ? void 0 : _a.token);
    const loader = getLoaderForTextureFormat(tileOptions.textureFormat);
    const fetchFunc = (context == null ? void 0 : context.fetch) || fetch;
    const response = await fetchFunc(url);
    const arrayBuffer2 = await response.arrayBuffer();
    if (options == null ? void 0 : options.i3s.decodeTextures) {
      if (loader === import_images.ImageLoader) {
        const options2 = { ...tileOptions.textureLoaderOptions, image: { type: "data" } };
        try {
          const texture = await (0, import_loader_utils.parseFromContext)(arrayBuffer2, [], options2, context);
          content.texture = texture;
        } catch (e) {
          const texture = await (0, import_core.parse)(arrayBuffer2, loader, options2, context);
          content.texture = texture;
        }
      } else if (loader === import_textures.CompressedTextureLoader || loader === import_textures.BasisLoader) {
        let texture = await (0, import_core.load)(arrayBuffer2, loader, tileOptions.textureLoaderOptions);
        if (loader === import_textures.BasisLoader) {
          texture = texture[0];
        }
        content.texture = {
          compressed: true,
          mipmaps: false,
          width: texture[0].width,
          height: texture[0].height,
          data: texture
        };
      }
    } else {
      content.texture = arrayBuffer2;
    }
  }
  content.material = makePbrMaterial(tileOptions.materialDefinition, content.texture);
  if (content.material) {
    content.texture = null;
  }
  return await parseI3SNodeGeometry(arrayBuffer, content, tileOptions, tilesetOptions, options);
}
async function parseI3SNodeGeometry(arrayBuffer, content, tileOptions, tilesetOptions, options) {
  var _a, _b;
  const contentByteLength = arrayBuffer.byteLength;
  let attributes;
  let vertexCount;
  let byteOffset = 0;
  let featureCount = 0;
  let indices;
  if (tileOptions.isDracoGeometry) {
    const decompressedGeometry = await (0, import_core.parse)(arrayBuffer, import_draco.DracoLoader, {
      draco: {
        attributeNameEntry: I3S_ATTRIBUTE_TYPE
      }
    });
    vertexCount = decompressedGeometry.header.vertexCount;
    indices = (_a = decompressedGeometry.indices) == null ? void 0 : _a.value;
    const { POSITION, NORMAL, COLOR_0, TEXCOORD_0, ["feature-index"]: featureIndex, ["uv-region"]: uvRegion } = decompressedGeometry.attributes;
    attributes = {
      position: POSITION,
      normal: NORMAL,
      color: COLOR_0,
      uv0: TEXCOORD_0,
      uvRegion,
      id: featureIndex
    };
    updateAttributesMetadata(attributes, decompressedGeometry);
    const featureIds = getFeatureIdsFromFeatureIndexMetadata(featureIndex);
    if (featureIds) {
      flattenFeatureIdsByFeatureIndices(attributes, featureIds);
    }
  } else {
    const { vertexAttributes, ordering: attributesOrder, featureAttributes, featureAttributeOrder } = tilesetOptions.store.defaultGeometrySchema;
    const headers = parseHeaders(arrayBuffer, tilesetOptions);
    byteOffset = headers.byteOffset;
    vertexCount = headers.vertexCount;
    featureCount = headers.featureCount;
    const { attributes: normalizedVertexAttributes, byteOffset: offset } = normalizeAttributes(arrayBuffer, byteOffset, vertexAttributes, vertexCount, attributesOrder);
    const { attributes: normalizedFeatureAttributes } = normalizeAttributes(arrayBuffer, offset, featureAttributes, featureCount, featureAttributeOrder);
    flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes);
    attributes = concatAttributes(normalizedVertexAttributes, normalizedFeatureAttributes);
  }
  if (!((_b = options == null ? void 0 : options.i3s) == null ? void 0 : _b.coordinateSystem) || // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
  options.i3s.coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS) {
    const enuMatrix = parsePositions(attributes.position, tileOptions);
    content.modelMatrix = enuMatrix.invert();
    content.coordinateSystem = COORDINATE_SYSTEM.METER_OFFSETS;
  } else {
    content.modelMatrix = getModelMatrix(attributes.position);
    content.coordinateSystem = COORDINATE_SYSTEM.LNGLAT_OFFSETS;
  }
  content.attributes = {
    positions: attributes.position,
    normals: attributes.normal,
    colors: normalizeAttribute(attributes.color),
    // Normalize from UInt8
    texCoords: attributes.uv0,
    uvRegions: normalizeAttribute(attributes.uvRegion || attributes.region)
    // Normalize from UInt16
  };
  content.indices = indices || null;
  if (attributes.id && attributes.id.value) {
    content.featureIds = attributes.id.value;
  }
  for (const attributeIndex in content.attributes) {
    if (!content.attributes[attributeIndex]) {
      delete content.attributes[attributeIndex];
    }
  }
  content.vertexCount = vertexCount;
  content.byteLength = contentByteLength;
  return content;
}
function updateAttributesMetadata(attributes, decompressedGeometry) {
  for (const key in decompressedGeometry.loaderData.attributes) {
    const dracoAttribute = decompressedGeometry.loaderData.attributes[key];
    switch (dracoAttribute.name) {
      case "POSITION":
        attributes.position.metadata = dracoAttribute.metadata;
        break;
      case "feature-index":
        attributes.id.metadata = dracoAttribute.metadata;
        break;
      default:
        break;
    }
  }
}
function concatAttributes(normalizedVertexAttributes, normalizedFeatureAttributes) {
  return { ...normalizedVertexAttributes, ...normalizedFeatureAttributes };
}
function normalizeAttribute(attribute) {
  if (!attribute) {
    return attribute;
  }
  attribute.normalized = true;
  return attribute;
}
function parseHeaders(arrayBuffer, options) {
  let byteOffset = 0;
  let vertexCount = 0;
  let featureCount = 0;
  for (const { property, type } of options.store.defaultGeometrySchema.header) {
    const TypedArrayTypeHeader = getConstructorForDataFormat(type);
    switch (property) {
      case HeaderAttributeProperty.vertexCount.toString():
        vertexCount = new TypedArrayTypeHeader(arrayBuffer, 0, 4)[0];
        byteOffset += sizeOf(type);
        break;
      case HeaderAttributeProperty.featureCount.toString():
        featureCount = new TypedArrayTypeHeader(arrayBuffer, 4, 4)[0];
        byteOffset += sizeOf(type);
        break;
      default:
        break;
    }
  }
  return {
    vertexCount,
    featureCount,
    byteOffset
  };
}
function normalizeAttributes(arrayBuffer, byteOffset, vertexAttributes, attributeCount, attributesOrder) {
  const attributes = {};
  for (const attribute of attributesOrder) {
    if (vertexAttributes[attribute]) {
      const { valueType, valuesPerElement } = vertexAttributes[attribute];
      if (byteOffset + attributeCount * valuesPerElement * sizeOf(valueType) <= arrayBuffer.byteLength) {
        const buffer = arrayBuffer.slice(byteOffset);
        let value;
        if (valueType === "UInt64") {
          value = parseUint64Values(buffer, attributeCount * valuesPerElement, sizeOf(valueType));
        } else {
          const TypedArrayType = getConstructorForDataFormat(valueType);
          value = new TypedArrayType(buffer, 0, attributeCount * valuesPerElement);
        }
        attributes[attribute] = {
          value,
          type: GL_TYPE_MAP[valueType],
          size: valuesPerElement
        };
        switch (attribute) {
          case "color":
            attributes.color.normalized = true;
            break;
          case "position":
          case "region":
          case "normal":
          default:
        }
        byteOffset = byteOffset + attributeCount * valuesPerElement * sizeOf(valueType);
      } else if (attribute !== "uv0") {
        break;
      }
    }
  }
  return { attributes, byteOffset };
}
function parseUint64Values(buffer, elementsCount, attributeSize) {
  const values = [];
  const dataView = new DataView(buffer);
  let offset = 0;
  for (let index = 0; index < elementsCount; index++) {
    const left = dataView.getUint32(offset, true);
    const right = dataView.getUint32(offset + 4, true);
    const value = left + 2 ** 32 * right;
    values.push(value);
    offset += attributeSize;
  }
  return new Uint32Array(values);
}
function parsePositions(attribute, options) {
  const mbs = options.mbs;
  const value = attribute.value;
  const metadata = attribute.metadata;
  const enuMatrix = new import_core2.Matrix4();
  const cartographicOrigin = new import_core2.Vector3(mbs[0], mbs[1], mbs[2]);
  const cartesianOrigin = new import_core2.Vector3();
  import_geospatial.Ellipsoid.WGS84.cartographicToCartesian(cartographicOrigin, cartesianOrigin);
  import_geospatial.Ellipsoid.WGS84.eastNorthUpToFixedFrame(cartesianOrigin, enuMatrix);
  attribute.value = offsetsToCartesians(value, metadata, cartographicOrigin);
  return enuMatrix;
}
function offsetsToCartesians(vertices, metadata = {}, cartographicOrigin) {
  const positions = new Float64Array(vertices.length);
  const scaleX = metadata["i3s-scale_x"] && metadata["i3s-scale_x"].double || 1;
  const scaleY = metadata["i3s-scale_y"] && metadata["i3s-scale_y"].double || 1;
  for (let i = 0; i < positions.length; i += 3) {
    positions[i] = vertices[i] * scaleX + cartographicOrigin.x;
    positions[i + 1] = vertices[i + 1] * scaleY + cartographicOrigin.y;
    positions[i + 2] = vertices[i + 2] + cartographicOrigin.z;
  }
  for (let i = 0; i < positions.length; i += 3) {
    import_geospatial.Ellipsoid.WGS84.cartographicToCartesian(positions.subarray(i, i + 3), scratchVector);
    positions[i] = scratchVector.x;
    positions[i + 1] = scratchVector.y;
    positions[i + 2] = scratchVector.z;
  }
  return positions;
}
function getModelMatrix(positions) {
  var _a, _b;
  const metadata = positions.metadata;
  const scaleX = ((_a = metadata == null ? void 0 : metadata["i3s-scale_x"]) == null ? void 0 : _a.double) || 1;
  const scaleY = ((_b = metadata == null ? void 0 : metadata["i3s-scale_y"]) == null ? void 0 : _b.double) || 1;
  const modelMatrix = new import_core2.Matrix4();
  modelMatrix[0] = scaleX;
  modelMatrix[5] = scaleY;
  return modelMatrix;
}
function makePbrMaterial(materialDefinition, texture) {
  let pbrMaterial;
  if (materialDefinition) {
    pbrMaterial = {
      ...materialDefinition,
      pbrMetallicRoughness: materialDefinition.pbrMetallicRoughness ? { ...materialDefinition.pbrMetallicRoughness } : { baseColorFactor: [255, 255, 255, 255] }
    };
  } else {
    pbrMaterial = {
      pbrMetallicRoughness: {}
    };
    if (texture) {
      pbrMaterial.pbrMetallicRoughness.baseColorTexture = { texCoord: 0 };
    } else {
      pbrMaterial.pbrMetallicRoughness.baseColorFactor = [255, 255, 255, 255];
    }
  }
  pbrMaterial.alphaCutoff = pbrMaterial.alphaCutoff || 0.25;
  if (pbrMaterial.alphaMode) {
    pbrMaterial.alphaMode = pbrMaterial.alphaMode.toUpperCase();
  }
  if (pbrMaterial.emissiveFactor) {
    pbrMaterial.emissiveFactor = convertColorFormat(pbrMaterial.emissiveFactor);
  }
  if (pbrMaterial.pbrMetallicRoughness && pbrMaterial.pbrMetallicRoughness.baseColorFactor) {
    pbrMaterial.pbrMetallicRoughness.baseColorFactor = convertColorFormat(pbrMaterial.pbrMetallicRoughness.baseColorFactor);
  }
  if (texture) {
    setMaterialTexture(pbrMaterial, texture);
  }
  return pbrMaterial;
}
function convertColorFormat(colorFactor) {
  const normalizedColor = [...colorFactor];
  for (let index = 0; index < colorFactor.length; index++) {
    normalizedColor[index] = colorFactor[index] / 255;
  }
  return normalizedColor;
}
function setMaterialTexture(material, image) {
  const texture = { source: { image } };
  if (material.pbrMetallicRoughness && material.pbrMetallicRoughness.baseColorTexture) {
    material.pbrMetallicRoughness.baseColorTexture = {
      ...material.pbrMetallicRoughness.baseColorTexture,
      texture
    };
  } else if (material.emissiveTexture) {
    material.emissiveTexture = { ...material.emissiveTexture, texture };
  } else if (material.pbrMetallicRoughness && material.pbrMetallicRoughness.metallicRoughnessTexture) {
    material.pbrMetallicRoughness.metallicRoughnessTexture = {
      ...material.pbrMetallicRoughness.metallicRoughnessTexture,
      texture
    };
  } else if (material.normalTexture) {
    material.normalTexture = { ...material.normalTexture, texture };
  } else if (material.occlusionTexture) {
    material.occlusionTexture = { ...material.occlusionTexture, texture };
  }
}
function flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes) {
  const { id, faceRange } = normalizedFeatureAttributes;
  if (!id || !faceRange) {
    return;
  }
  const featureIds = id.value;
  const range = faceRange.value;
  const featureIdsLength = range[range.length - 1] + 1;
  const orderedFeatureIndices = new Uint32Array(featureIdsLength * 3);
  let featureIndex = 0;
  let startIndex = 0;
  for (let index = 1; index < range.length; index += 2) {
    const fillId = Number(featureIds[featureIndex]);
    const endValue = range[index];
    const prevValue = range[index - 1];
    const trianglesCount = endValue - prevValue + 1;
    const endIndex = startIndex + trianglesCount * 3;
    orderedFeatureIndices.fill(fillId, startIndex, endIndex);
    featureIndex++;
    startIndex = endIndex;
  }
  normalizedFeatureAttributes.id.value = orderedFeatureIndices;
}
function flattenFeatureIdsByFeatureIndices(attributes, featureIds) {
  const featureIndices = attributes.id.value;
  const result = new Float32Array(featureIndices.length);
  for (let index = 0; index < featureIndices.length; index++) {
    result[index] = featureIds[featureIndices[index]];
  }
  attributes.id.value = result;
}
function getFeatureIdsFromFeatureIndexMetadata(featureIndex) {
  var _a, _b;
  return (_b = (_a = featureIndex == null ? void 0 : featureIndex.metadata) == null ? void 0 : _a["i3s-feature-ids"]) == null ? void 0 : _b.intArray;
}

// dist/i3s-content-loader.js
var VERSION = true ? "4.4.2" : "latest";
var I3SContentLoader = {
  dataType: null,
  batchType: null,
  name: "I3S Content (Indexed Scene Layers)",
  id: "i3s-content",
  module: "i3s",
  worker: true,
  version: VERSION,
  mimeTypes: ["application/octet-stream"],
  parse: parse2,
  extensions: ["bin"],
  options: {
    "i3s-content": {}
  }
};
async function parse2(data, options, context) {
  const { tile, _tileOptions, tileset, _tilesetOptions } = (options == null ? void 0 : options.i3s) || {};
  const tileOptions = _tileOptions || tile;
  const tilesetOptions = _tilesetOptions || tileset;
  if (!tileOptions || !tilesetOptions) {
    return null;
  }
  return await parseI3STileContent(data, tileOptions, tilesetOptions, options, context);
}

// dist/lib/parsers/parse-i3s.js
var import_culling = require("@math.gl/culling");
var import_geospatial2 = require("@math.gl/geospatial");
var import_core4 = require("@loaders.gl/core");
var import_tiles = require("@loaders.gl/tiles");

// dist/lib/helpers/i3s-nodepages-tiles.js
var import_core3 = require("@loaders.gl/core");

// dist/i3s-node-page-loader.js
var VERSION2 = true ? "4.4.2" : "latest";
var I3SNodePageLoader = {
  dataType: null,
  batchType: null,
  name: "I3S Node Page",
  id: "i3s-node-page",
  module: "i3s",
  version: VERSION2,
  mimeTypes: ["application/json"],
  parse: parseNodePage,
  extensions: ["json"],
  options: {
    i3s: {}
  }
};
async function parseNodePage(data, options) {
  return JSON.parse(new TextDecoder().decode(data));
}

// dist/lib/helpers/i3s-nodepages-tiles.js
var BROWSER_PREFIXES = ["", "WEBKIT_", "MOZ_"];
var WEBGL_EXTENSIONS = {
  /* eslint-disable camelcase */
  WEBGL_compressed_texture_s3tc: "dxt",
  WEBGL_compressed_texture_s3tc_srgb: "dxt-srgb",
  WEBGL_compressed_texture_etc1: "etc1",
  WEBGL_compressed_texture_etc: "etc2",
  WEBGL_compressed_texture_pvrtc: "pvrtc",
  WEBGL_compressed_texture_atc: "atc",
  WEBGL_compressed_texture_astc: "astc",
  EXT_texture_compression_rgtc: "rgtc"
  /* eslint-enable camelcase */
};
var I3SNodePagesTiles = class {
  tileset;
  nodePages = [];
  pendingNodePages = [];
  nodesPerPage;
  options;
  lodSelectionMetricType;
  textureDefinitionsSelectedFormats = [];
  nodesInNodePages;
  url;
  textureLoaderOptions = {};
  /**
   * @constructs
   * Create a I3SNodePagesTiles instance.
   * @param tileset - i3s tileset header ('layers/0')
   * @param url - tileset url
   * @param options - i3s loader options
   */
  constructor(tileset, url = "", options) {
    var _a, _b;
    this.tileset = { ...tileset };
    this.url = url;
    this.nodesPerPage = ((_a = tileset.nodePages) == null ? void 0 : _a.nodesPerPage) || 64;
    this.lodSelectionMetricType = (_b = tileset.nodePages) == null ? void 0 : _b.lodSelectionMetricType;
    this.options = options;
    this.nodesInNodePages = 0;
    this.initSelectedFormatsForTextureDefinitions(tileset);
  }
  /**
   * Loads some nodePage and return a particular node from it
   * @param id - id of node through all node pages
   */
  async getNodeById(id) {
    var _a;
    const pageIndex = Math.floor(id / this.nodesPerPage);
    if (!this.nodePages[pageIndex] && !this.pendingNodePages[pageIndex]) {
      const nodePageUrl = getUrlWithToken(
        `${this.url}/nodepages/${pageIndex}`,
        // @ts-expect-error this.options is not properly typed
        (_a = this.options.i3s) == null ? void 0 : _a.token
      );
      this.pendingNodePages[pageIndex] = {
        status: "Pending",
        promise: (0, import_core3.load)(nodePageUrl, I3SNodePageLoader, this.options)
      };
      this.nodePages[pageIndex] = await this.pendingNodePages[pageIndex].promise;
      this.nodesInNodePages += this.nodePages[pageIndex].nodes.length;
      this.pendingNodePages[pageIndex].status = "Done";
    }
    if (this.pendingNodePages[pageIndex].status === "Pending") {
      this.nodePages[pageIndex] = await this.pendingNodePages[pageIndex].promise;
    }
    const nodeIndex = id % this.nodesPerPage;
    return this.nodePages[pageIndex].nodes[nodeIndex];
  }
  /**
   * Forms tile header using node and tileset data
   * @param id - id of node through all node pages
   */
  // eslint-disable-next-line complexity, max-statements
  async formTileFromNodePages(id) {
    const node = await this.getNodeById(id);
    const children = [];
    const childNodesPromises = [];
    for (const child of node.children || []) {
      childNodesPromises.push(this.getNodeById(child));
    }
    const childNodes = await Promise.all(childNodesPromises);
    for (const childNode of childNodes) {
      children.push({
        id: childNode.index.toString(),
        obb: childNode.obb
      });
    }
    let contentUrl;
    let textureUrl;
    let materialDefinition;
    let textureFormat = "jpg";
    let attributeUrls = [];
    let isDracoGeometry = false;
    if (node && node.mesh) {
      const { url, isDracoGeometry: isDracoGeometryResult } = node.mesh.geometry && this.getContentUrl(node.mesh.geometry) || { isDracoGeometry: false };
      contentUrl = url;
      isDracoGeometry = isDracoGeometryResult;
      const { textureData, materialDefinition: nodeMaterialDefinition } = this.getInformationFromMaterial(node.mesh.material);
      materialDefinition = nodeMaterialDefinition;
      textureFormat = textureData.format || textureFormat;
      if (textureData.name) {
        textureUrl = `${this.url}/nodes/${node.mesh.material.resource}/textures/${textureData.name}`;
      }
      if (this.tileset.attributeStorageInfo) {
        attributeUrls = generateTilesetAttributeUrls(this.tileset, this.url, node.mesh.attribute.resource);
      }
    }
    const lodSelection = this.getLodSelection(node);
    return normalizeTileNonUrlData({
      id: id.toString(),
      lodSelection,
      obb: node.obb,
      contentUrl,
      textureUrl,
      attributeUrls,
      materialDefinition,
      textureFormat,
      textureLoaderOptions: this.textureLoaderOptions,
      children,
      isDracoGeometry
    });
  }
  /**
   * Forms url and type of geometry resource by nodepage's data and `geometryDefinitions` in the tileset
   * @param - data about the node's mesh from the nodepage
   * @returns -
   *   {string} url - url to the geometry resource
   *   {boolean} isDracoGeometry - whether the geometry resource contain DRACO compressed geometry
   */
  getContentUrl(meshGeometryData) {
    let result = null;
    const geometryDefinition = this.tileset.geometryDefinitions[meshGeometryData.definition];
    let geometryIndex = -1;
    const i3sOptions = this.options.i3s;
    if (i3sOptions && typeof i3sOptions === "object" && i3sOptions.useDracoGeometry) {
      geometryIndex = geometryDefinition.geometryBuffers.findIndex((buffer) => buffer.compressedAttributes && buffer.compressedAttributes.encoding === "draco");
    }
    if (geometryIndex === -1) {
      geometryIndex = geometryDefinition.geometryBuffers.findIndex((buffer) => !buffer.compressedAttributes);
    }
    if (geometryIndex !== -1) {
      const isDracoGeometry = Boolean(geometryDefinition.geometryBuffers[geometryIndex].compressedAttributes);
      result = {
        url: `${this.url}/nodes/${meshGeometryData.resource}/geometries/${geometryIndex}`,
        isDracoGeometry
      };
    }
    return result;
  }
  /**
   * Forms 1.6 compatible LOD selection object from a nodepage's node data
   * @param node - a node from nodepage
   * @returns- Array of LodSelection
   */
  getLodSelection(node) {
    const lodSelection = [];
    if (this.lodSelectionMetricType === "maxScreenThresholdSQ") {
      lodSelection.push({
        metricType: "maxScreenThreshold",
        // @ts-ignore
        maxError: Math.sqrt(node.lodThreshold / (Math.PI * 0.25))
      });
    }
    lodSelection.push({
      metricType: this.lodSelectionMetricType,
      // @ts-ignore
      maxError: node.lodThreshold
    });
    return lodSelection;
  }
  /**
   * Returns information about texture and material from `materialDefinitions`
   * @param material - material data from nodepage
   * @returns - Couple {textureData, materialDefinition}
   * {string} textureData.name - path name of the texture
   * {string} textureData.format - format of the texture
   * materialDefinition - PBR-like material definition from `materialDefinitions`
   */
  getInformationFromMaterial(material) {
    var _a, _b, _c;
    const informationFromMaterial = { textureData: { name: null } };
    if (material) {
      const materialDefinition = (_a = this.tileset.materialDefinitions) == null ? void 0 : _a[material.definition];
      if (materialDefinition) {
        informationFromMaterial.materialDefinition = materialDefinition;
        const textureSetDefinitionIndex = (_c = (_b = materialDefinition == null ? void 0 : materialDefinition.pbrMetallicRoughness) == null ? void 0 : _b.baseColorTexture) == null ? void 0 : _c.textureSetDefinitionId;
        if (typeof textureSetDefinitionIndex === "number") {
          informationFromMaterial.textureData = this.textureDefinitionsSelectedFormats[textureSetDefinitionIndex] || informationFromMaterial.textureData;
        }
      }
    }
    return informationFromMaterial;
  }
  /**
   * Sets preferable and supported format for each textureDefinition of the tileset
   * @param tileset - I3S layer data
   * @returns
   */
  initSelectedFormatsForTextureDefinitions(tileset) {
    this.textureDefinitionsSelectedFormats = [];
    const possibleI3sFormats = this.getSupportedTextureFormats();
    const textureSetDefinitions = tileset.textureSetDefinitions || [];
    for (const textureSetDefinition of textureSetDefinitions) {
      const formats = textureSetDefinition && textureSetDefinition.formats || [];
      let selectedFormat = null;
      for (const i3sFormat of possibleI3sFormats) {
        const format = formats.find((value) => value.format === i3sFormat);
        if (format) {
          selectedFormat = format;
          break;
        }
      }
      if (selectedFormat && selectedFormat.format === "ktx2") {
        this.textureLoaderOptions.basis = {
          containerFormat: "ktx2",
          module: "encoder"
        };
      }
      this.textureDefinitionsSelectedFormats.push(selectedFormat);
    }
  }
  /**
   * Returns the array of supported texture format
   * @returns list of format strings
   */
  getSupportedTextureFormats() {
    const formats = [];
    const i3sOptions = this.options.i3s;
    if (!i3sOptions || i3sOptions.useCompressedTextures) {
      const supportedCompressedFormats = getSupportedGPUTextureFormats();
      if (supportedCompressedFormats.has("etc2")) {
        formats.push("ktx-etc2");
      }
      if (supportedCompressedFormats.has("dxt")) {
        formats.push("dds");
      }
      formats.push("ktx2");
    }
    formats.push("jpg");
    formats.push("png");
    return formats;
  }
};
function getSupportedGPUTextureFormats(gl) {
  const formats = /* @__PURE__ */ new Set();
  gl = gl || getWebGLContext() || void 0;
  for (const prefix of BROWSER_PREFIXES) {
    for (const extension in WEBGL_EXTENSIONS) {
      if (gl && gl.getExtension(`${prefix}${extension}`)) {
        formats.add(WEBGL_EXTENSIONS[extension]);
      }
    }
  }
  return formats;
}
function getWebGLContext() {
  try {
    const canvas = document.createElement("canvas");
    return canvas.getContext("webgl");
  } catch {
    return null;
  }
}

// dist/lib/parsers/parse-i3s.js
function normalizeTileData(tile, context) {
  const url = context.url || "";
  let contentUrl;
  if (tile.geometryData) {
    contentUrl = `${url}/${tile.geometryData[0].href}`;
  }
  let textureUrl;
  if (tile.textureData) {
    textureUrl = `${url}/${tile.textureData[0].href}`;
  }
  let attributeUrls;
  if (tile.attributeData) {
    attributeUrls = generateTileAttributeUrls(url, tile);
  }
  const children = tile.children || [];
  return normalizeTileNonUrlData({
    ...tile,
    children,
    url,
    contentUrl,
    textureUrl,
    textureFormat: "jpg",
    // `jpg` format will cause `ImageLoader` usage that will be able to handle `png` as well
    attributeUrls,
    isDracoGeometry: false
  });
}
function normalizeTileNonUrlData(tile) {
  var _a, _b;
  const boundingVolume = {};
  let mbs = [0, 0, 0, 1];
  if (tile.mbs) {
    mbs = tile.mbs;
    boundingVolume.sphere = [
      ...import_geospatial2.Ellipsoid.WGS84.cartographicToCartesian(tile.mbs.slice(0, 3)),
      // cartesian center of sphere
      tile.mbs[3]
      // radius of sphere
    ];
  } else if (tile.obb) {
    boundingVolume.box = [
      ...import_geospatial2.Ellipsoid.WGS84.cartographicToCartesian(tile.obb.center),
      // cartesian center of box
      ...tile.obb.halfSize,
      // halfSize
      ...tile.obb.quaternion
      // quaternion
    ];
    const obb = new import_culling.OrientedBoundingBox().fromCenterHalfSizeQuaternion(boundingVolume.box.slice(0, 3), tile.obb.halfSize, tile.obb.quaternion);
    const boundingSphere = obb.getBoundingSphere();
    boundingVolume.sphere = [...boundingSphere.center, boundingSphere.radius];
    mbs = [...tile.obb.center, boundingSphere.radius];
  }
  const lodMetricType = (_a = tile.lodSelection) == null ? void 0 : _a[0].metricType;
  const lodMetricValue = (_b = tile.lodSelection) == null ? void 0 : _b[0].maxError;
  const type = import_tiles.TILE_TYPE.MESH;
  const refine = import_tiles.TILE_REFINEMENT.REPLACE;
  return { ...tile, mbs, boundingVolume, lodMetricType, lodMetricValue, type, refine };
}
async function normalizeTilesetData(tileset, options, context) {
  const url = getUrlWithoutParams(context.url || "");
  let nodePagesTile;
  let root;
  if (tileset.nodePages) {
    nodePagesTile = new I3SNodePagesTiles(tileset, url, options);
    root = await nodePagesTile.formTileFromNodePages(0);
  } else {
    const parseOptions = options.i3s && typeof options.i3s === "object" ? options.i3s : {};
    const rootNodeUrl = getUrlWithToken(`${url}/nodes/root`, parseOptions.token);
    root = await (0, import_core4.load)(rootNodeUrl, I3SLoader, {
      ...options,
      i3s: {
        ...parseOptions,
        loadContent: false,
        isTileHeader: true,
        isTileset: false
      }
    });
  }
  return {
    ...tileset,
    loader: I3SLoader,
    url,
    basePath: url,
    type: import_tiles.TILESET_TYPE.I3S,
    nodePagesTile,
    // @ts-expect-error
    root,
    lodMetricType: root.lodMetricType,
    lodMetricValue: root.lodMetricValue
  };
}

// dist/i3s-loader.js
var VERSION3 = true ? "4.4.2" : "latest";
var TILESET_REGEX = /layers\/[0-9]+$/;
var LOCAL_SLPK_REGEX = /\.slpk$/;
var TILE_HEADER_REGEX = /nodes\/([0-9-]+|root)$/;
var SLPK_HEX = "504b0304";
var POINT_CLOUD = "PointCloud";
var I3SLoader = {
  dataType: null,
  batchType: null,
  name: "I3S (Indexed Scene Layers)",
  id: "i3s",
  module: "i3s",
  version: VERSION3,
  mimeTypes: ["application/octet-stream"],
  parse: parseI3S,
  extensions: ["bin"],
  options: {
    i3s: {
      token: void 0,
      isTileset: "auto",
      isTileHeader: "auto",
      tile: void 0,
      tileset: void 0,
      _tileOptions: void 0,
      _tilesetOptions: void 0,
      useDracoGeometry: true,
      useCompressedTextures: true,
      decodeTextures: true,
      coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS
    }
  }
};
async function parseI3S(data, options = {}, context) {
  const url = context.url;
  options.i3s = options.i3s || {};
  const magicNumber = getMagicNumber(data);
  if (magicNumber === SLPK_HEX) {
    throw new Error("Files with .slpk extention currently are not supported by I3SLoader");
  }
  const urlWithoutParams = getUrlWithoutParams(url);
  let isTileset;
  if (options.i3s.isTileset === "auto") {
    isTileset = TILESET_REGEX.test(urlWithoutParams) || LOCAL_SLPK_REGEX.test(urlWithoutParams);
  } else {
    isTileset = options.i3s.isTileset;
  }
  let isTileHeader;
  if (options.i3s.isTileHeader === "auto") {
    isTileHeader = TILE_HEADER_REGEX.test(urlWithoutParams);
  } else {
    isTileHeader = options.i3s.isTileHeader;
  }
  if (isTileset) {
    data = await parseTileset(data, options, context);
  } else if (isTileHeader) {
    data = await parseTile(data, context);
  } else {
    data = await parseTileContent(data, options);
  }
  return data;
}
async function parseTileContent(arrayBuffer, options) {
  return await (0, import_core5.parse)(arrayBuffer, I3SContentLoader, options);
}
async function parseTileset(data, options, context) {
  const tilesetJson = JSON.parse(new TextDecoder().decode(data));
  if ((tilesetJson == null ? void 0 : tilesetJson.layerType) === POINT_CLOUD) {
    throw new Error("Point Cloud layers currently are not supported by I3SLoader");
  }
  const tilesetPostprocessed = await normalizeTilesetData(tilesetJson, options, context);
  return tilesetPostprocessed;
}
async function parseTile(data, context) {
  data = JSON.parse(new TextDecoder().decode(data));
  return normalizeTileData(data, context);
}
function getMagicNumber(data) {
  if (data instanceof ArrayBuffer) {
    return [...new Uint8Array(data, 0, 4)].map((value) => value.toString(16).padStart(2, "0")).join("");
  }
  return null;
}

// dist/i3s-slpk-loader.js
var import_zip3 = require("@loaders.gl/zip");

// dist/lib/parsers/parse-slpk/parse-slpk.js
var import_zip2 = require("@loaders.gl/zip");

// dist/lib/parsers/parse-slpk/slpk-archieve.js
var import_crypto = require("@loaders.gl/crypto");
var import_zip = require("@loaders.gl/zip");
var import_compression = require("@loaders.gl/compression");
var PATH_DESCRIPTIONS = [
  {
    test: /^$/,
    extensions: ["3dSceneLayer.json.gz"]
  },
  {
    test: /nodepages\/\d+$/,
    extensions: [".json.gz"]
  },
  {
    test: /sublayers\/\d+$/,
    extensions: ["/3dSceneLayer.json.gz"]
  },
  {
    test: /nodes\/(\d+|root)$/,
    extensions: ["/3dNodeIndexDocument.json.gz"]
  },
  {
    test: /nodes\/\d+\/textures\/.+$/,
    extensions: [".jpg", ".png", ".bin.dds.gz", ".ktx", ".ktx2"]
  },
  {
    test: /nodes\/\d+\/geometries\/\d+$/,
    extensions: [".bin.gz", ".draco.gz"]
  },
  {
    test: /nodes\/\d+\/attributes\/f_\d+\/\d+$/,
    extensions: [".bin.gz"]
  },
  {
    test: /statistics\/(f_\d+\/\d+|summary)$/,
    extensions: [".json.gz"]
  },
  {
    test: /nodes\/\d+\/shared$/,
    extensions: ["/sharedResource.json.gz"]
  }
];
var SLPKArchive = class extends import_zip.IndexedArchive {
  // Maps hex-encoded md5 filename hashes to bigint offsets into the archive
  hashTable;
  _textEncoder = new TextEncoder();
  _textDecoder = new TextDecoder();
  _md5Hash = new import_crypto.MD5Hash();
  /**
   * Constructor
   * @param fileProvider - readable file handle for random access
   * @param hashTable - pre-loaded hashTable. If presented, getFile will skip reading the hash file
   * @param fileName - name of the archive. It is used to add to an URL of a loader context
   */
  constructor(fileProvider, hashTable, fileName) {
    super(fileProvider, hashTable, fileName);
    this.hashTable = hashTable;
  }
  /**
   * Returns file with the given path from slpk archive
   * @param path - path inside the slpk
   * @param mode - currently only raw mode supported
   * @returns buffer with ready to use file
   */
  async getFile(path, mode = "raw") {
    var _a;
    if (mode === "http") {
      const extensions = (_a = PATH_DESCRIPTIONS.find((val) => val.test.test(path))) == null ? void 0 : _a.extensions;
      if (extensions) {
        let data;
        for (const ext of extensions) {
          data = await this.getDataByPath(`${path}${ext}`);
          if (data) {
            break;
          }
        }
        if (data) {
          return data;
        }
      }
    }
    if (mode === "raw") {
      const decompressedFile = await this.getDataByPath(`${path}.gz`);
      if (decompressedFile) {
        return decompressedFile;
      }
      const fileWithoutCompression = await this.getFileBytes(path);
      if (fileWithoutCompression) {
        return fileWithoutCompression;
      }
    }
    throw new Error(`No such file in the archive: ${path}`);
  }
  /**
   * returning uncompressed data for paths that ends with .gz and raw data for all other paths
   * @param path - path inside the archive
   * @returns buffer with the file data
   */
  async getDataByPath(path) {
    let data = await this.getFileBytes(path.toLocaleLowerCase());
    if (!data) {
      data = await this.getFileBytes(path);
    }
    if (!data) {
      return void 0;
    }
    if (/\.gz$/.test(path)) {
      const compression = new import_compression.GZipCompression();
      const decompressedData = await compression.decompress(data);
      return decompressedData;
    }
    return data;
  }
  /**
   * Trying to get raw file data by address
   * @param path - path inside the archive
   * @returns buffer with the raw file data
   */
  async getFileBytes(path) {
    let compressedFile;
    if (this.hashTable) {
      const binaryPath = this._textEncoder.encode(path);
      const nameHash = await this._md5Hash.hash(binaryPath.buffer, "hex");
      const offset = this.hashTable[nameHash];
      if (offset === void 0) {
        return void 0;
      }
      const localFileHeader = await (0, import_zip.parseZipLocalFileHeader)(offset, this.file);
      if (!localFileHeader) {
        return void 0;
      }
      compressedFile = await (0, import_zip.readRange)(this.file, localFileHeader.fileDataOffset, localFileHeader.fileDataOffset + localFileHeader.compressedSize);
    } else {
      try {
        compressedFile = await this.getFileWithoutHash(path);
      } catch {
        compressedFile = void 0;
      }
    }
    return compressedFile;
  }
};

// dist/lib/parsers/parse-slpk/parse-slpk.js
async function parseSLPKArchive(fileProvider, cb, fileName) {
  const hashCDOffset = await (0, import_zip2.searchFromTheEnd)(fileProvider, import_zip2.CD_HEADER_SIGNATURE);
  const cdFileHeader = await (0, import_zip2.parseZipCDFileHeader)(hashCDOffset, fileProvider);
  let hashTable;
  if ((cdFileHeader == null ? void 0 : cdFileHeader.fileName) !== "@specialIndexFileHASH128@") {
    hashTable = await (0, import_zip2.makeHashTableFromZipHeaders)(fileProvider);
    cb == null ? void 0 : cb("SLPK doesnt contain hash file, hash info has been composed according to zip archive headers");
  } else {
    const localFileHeader = await (0, import_zip2.parseZipLocalFileHeader)(cdFileHeader.localHeaderOffset, fileProvider);
    if (!localFileHeader) {
      throw new Error("corrupted SLPK");
    }
    const fileDataOffset = localFileHeader.fileDataOffset;
    const hashFile = await (0, import_zip2.readRange)(fileProvider, fileDataOffset, fileDataOffset + localFileHeader.compressedSize);
    hashTable = (0, import_zip2.parseHashTable)(hashFile);
  }
  return new SLPKArchive(fileProvider, hashTable, fileName);
}

// dist/i3s-slpk-loader.js
var VERSION4 = true ? "4.4.2" : "latest";
var SLPKLoader = {
  dataType: null,
  batchType: null,
  name: "I3S SLPK (Scene Layer Package)",
  id: "slpk",
  module: "i3s",
  version: VERSION4,
  mimeTypes: ["application/octet-stream"],
  extensions: ["slpk"],
  options: {
    slpk: {
      path: "",
      pathMode: void 0
    }
  },
  parse: async (data, options = {}) => {
    var _a, _b;
    const archive = await parseSLPKArchive(new import_zip3.DataViewReadableFile(new DataView(data)));
    return archive.getFile(((_a = options.slpk) == null ? void 0 : _a.path) ?? "", (_b = options.slpk) == null ? void 0 : _b.pathMode);
  }
};

// dist/i3s-attribute-loader.js
var import_core6 = require("@loaders.gl/core");

// dist/lib/parsers/parse-i3s-attribute.js
function parseI3STileAttribute(arrayBuffer, options) {
  const { attributeName, attributeType } = options;
  if (!attributeName) {
    return {};
  }
  return {
    [attributeName]: attributeType ? parseAttribute(attributeType, arrayBuffer) : null
  };
}
function parseAttribute(attributeType, arrayBuffer) {
  switch (attributeType) {
    case STRING_ATTRIBUTE_TYPE:
      return parseStringsAttribute(arrayBuffer);
    case OBJECT_ID_ATTRIBUTE_TYPE:
      return parseShortNumberAttribute(arrayBuffer);
    case FLOAT_64_TYPE:
      return parseFloatAttribute(arrayBuffer);
    case INT_16_ATTRIBUTE_TYPE:
      return parseInt16ShortNumberAttribute(arrayBuffer);
    default:
      return parseShortNumberAttribute(arrayBuffer);
  }
}
function parseShortNumberAttribute(arrayBuffer) {
  const countOffset = 4;
  return new Uint32Array(arrayBuffer, countOffset);
}
function parseInt16ShortNumberAttribute(arrayBuffer) {
  const countOffset = 4;
  return new Int16Array(arrayBuffer, countOffset);
}
function parseFloatAttribute(arrayBuffer) {
  const countOffset = 8;
  return new Float64Array(arrayBuffer, countOffset);
}
function parseStringsAttribute(arrayBuffer) {
  const stringsCountOffset = 0;
  const dataOffset = 8;
  const bytesPerStringSize = 4;
  const stringsArray = [];
  try {
    const stringsCount = new DataView(arrayBuffer, stringsCountOffset, bytesPerStringSize).getUint32(stringsCountOffset, true);
    const stringSizes = new Uint32Array(arrayBuffer, dataOffset, stringsCount);
    let stringOffset = dataOffset + stringsCount * bytesPerStringSize;
    for (const stringByteSize of stringSizes) {
      const textDecoder = new TextDecoder("utf-8");
      const stringAttribute = new Uint8Array(arrayBuffer, stringOffset, stringByteSize);
      stringsArray.push(textDecoder.decode(stringAttribute));
      stringOffset += stringByteSize;
    }
  } catch (error) {
    console.error("Parse string attribute error: ", error.message);
  }
  return stringsArray;
}

// dist/i3s-attribute-loader.js
var VERSION5 = true ? "4.4.2" : "latest";
var EMPTY_VALUE = "";
var REJECTED_STATUS = "rejected";
var I3SAttributeLoader = {
  dataType: null,
  batchType: null,
  name: "I3S Attribute",
  id: "i3s-attribute",
  module: "i3s",
  version: VERSION5,
  mimeTypes: ["application/binary"],
  parse: async (arrayBuffer, options) => parseI3STileAttribute(arrayBuffer, options),
  extensions: ["bin"],
  options: {},
  binary: true
};
async function loadFeatureAttributes(tile, featureId, options = {}) {
  var _a;
  const { attributeStorageInfo, attributeUrls, tilesetFields } = getAttributesData(tile);
  if (!attributeStorageInfo || !attributeUrls || featureId < 0) {
    return null;
  }
  let attributes = [];
  const attributeLoadPromises = [];
  for (let index = 0; index < attributeStorageInfo.length; index++) {
    const url = getUrlWithToken(attributeUrls[index], (_a = options.i3s) == null ? void 0 : _a.token);
    const attributeName = attributeStorageInfo[index].name;
    const attributeType = getAttributeValueType(attributeStorageInfo[index]);
    const loadOptions = { ...options, attributeName, attributeType };
    const promise = (0, import_core6.load)(url, I3SAttributeLoader, loadOptions);
    attributeLoadPromises.push(promise);
  }
  try {
    attributes = await Promise.allSettled(attributeLoadPromises);
  } catch (error) {
  }
  if (!attributes.length) {
    return null;
  }
  return generateAttributesByFeatureId(attributes, attributeStorageInfo, featureId, tilesetFields);
}
function getAttributesData(tile) {
  var _a, _b, _c, _d, _e;
  const attributeStorageInfo = (_b = (_a = tile.tileset) == null ? void 0 : _a.tileset) == null ? void 0 : _b.attributeStorageInfo;
  const attributeUrls = (_c = tile.header) == null ? void 0 : _c.attributeUrls;
  const tilesetFields = ((_e = (_d = tile.tileset) == null ? void 0 : _d.tileset) == null ? void 0 : _e.fields) || [];
  return { attributeStorageInfo, attributeUrls, tilesetFields };
}
function getAttributeValueType(attribute) {
  if (attribute.hasOwnProperty("objectIds")) {
    return "Oid32";
  } else if (attribute.hasOwnProperty("attributeValues")) {
    return attribute.attributeValues.valueType;
  }
  return "";
}
function getFeatureIdsAttributeName(attributeStorageInfo) {
  const objectIdsAttribute = attributeStorageInfo.find((attribute) => attribute.name.includes("OBJECTID"));
  return objectIdsAttribute == null ? void 0 : objectIdsAttribute.name;
}
function generateAttributesByFeatureId(attributes, attributeStorageInfo, featureId, tilesetFields) {
  const objectIdsAttributeName = getFeatureIdsAttributeName(attributeStorageInfo);
  const objectIds = attributes.find((attribute) => attribute.value[objectIdsAttributeName]);
  if (!objectIds) {
    return null;
  }
  const attributeIndex = objectIds.value[objectIdsAttributeName].indexOf(featureId);
  if (attributeIndex < 0) {
    return null;
  }
  return getFeatureAttributesByIndex(attributes, attributeIndex, attributeStorageInfo, tilesetFields);
}
function getFeatureAttributesByIndex(attributes, featureIdIndex, attributeStorageInfo, tilesetFields) {
  const attributesObject = {};
  for (let index = 0; index < attributeStorageInfo.length; index++) {
    const attributeName = attributeStorageInfo[index].name;
    const codedValues = getAttributeCodedValues(attributeName, tilesetFields);
    const attribute = getAttributeByIndexAndAttributeName(attributes, index, attributeName);
    attributesObject[attributeName] = formatAttributeValue(attribute, featureIdIndex, codedValues);
  }
  return attributesObject;
}
function getAttributeCodedValues(attributeName, tilesetFields) {
  var _a;
  const attributeField = tilesetFields.find((field) => field.name === attributeName || field.alias === attributeName);
  return ((_a = attributeField == null ? void 0 : attributeField.domain) == null ? void 0 : _a.codedValues) || [];
}
function getAttributeByIndexAndAttributeName(attributes, index, attributesName) {
  const attributeObject = attributes[index];
  if (attributeObject.status === REJECTED_STATUS) {
    return null;
  }
  return attributeObject.value[attributesName];
}
function formatAttributeValue(attribute, featureIdIndex, codedValues) {
  let value = EMPTY_VALUE;
  if (attribute && featureIdIndex in attribute) {
    value = String(attribute[featureIdIndex]).replace(/\u0000|NaN/g, "").trim();
  }
  if (codedValues.length) {
    const codeValue = codedValues.find((codedValue) => codedValue.code === Number(value));
    value = (codeValue == null ? void 0 : codeValue.name) || EMPTY_VALUE;
  }
  return value;
}

// dist/lib/parsers/parse-i3s-building-scene-layer.js
var OBJECT_3D_LAYER_TYPE = "3DObject";
async function parseBuildingSceneLayer(data, url) {
  const layer0 = JSON.parse(new TextDecoder().decode(data));
  const { sublayers } = layer0;
  return {
    header: layer0,
    sublayers: parseSublayersTree(sublayers, url)
  };
}
function parseSublayersTree(sublayers, url) {
  var _a;
  let layers = [];
  for (let index = 0; index < sublayers.length; index++) {
    const subLayer = sublayers[index];
    const { id, layerType, visibility = true, ...rest } = subLayer;
    if (layerType === OBJECT_3D_LAYER_TYPE) {
      const sublayerUrl = `${url}/sublayers/${id}`;
      layers.push({
        url: sublayerUrl,
        id,
        layerType,
        visibility,
        ...rest
      });
    }
    if ((_a = subLayer == null ? void 0 : subLayer.sublayers) == null ? void 0 : _a.length) {
      layers = [...layers, ...parseSublayersTree(subLayer.sublayers, url)];
    }
  }
  return layers;
}

// dist/i3s-building-scene-layer-loader.js
var VERSION6 = true ? "4.4.2" : "latest";
var I3SBuildingSceneLayerLoader = {
  dataType: null,
  batchType: null,
  name: "I3S Building Scene Layer",
  id: "i3s-building-scene-layer",
  module: "i3s",
  version: VERSION6,
  mimeTypes: ["application/json"],
  parse: parse4,
  extensions: ["json"],
  options: {}
};
async function parse4(data, options, context) {
  if (!(context == null ? void 0 : context.url)) {
    throw new Error("Url is not provided");
  }
  return parseBuildingSceneLayer(data, context.url);
}

// dist/lib/parsers/parse-arcgis-webscene.js
var import_core7 = require("@loaders.gl/core");
var SUPPORTED_WKID = 4326;
var ARCGIS_SCENE_SERVER_LAYER_TYPE = "ArcGISSceneServiceLayer";
var BUILDING_SCENE_LAYER = "BuildingSceneLayer";
var INTEGRATED_MESH_LAYER = "IntegratedMeshLayer";
var GROUP_LAYER = "GroupLayer";
var SUPPORTED_LAYERS_TYPES = [
  ARCGIS_SCENE_SERVER_LAYER_TYPE,
  INTEGRATED_MESH_LAYER,
  BUILDING_SCENE_LAYER,
  GROUP_LAYER
];
var NO_AVAILABLE_SUPPORTED_LAYERS_ERROR = "NO_AVAILABLE_SUPPORTED_LAYERS_ERROR";
var NOT_SUPPORTED_CRS_ERROR = "NOT_SUPPORTED_CRS_ERROR";
var LayerError = class extends Error {
  details;
  constructor(message, details) {
    super(message);
    this.details = details;
    this.name = "LayerError";
  }
};
async function parseWebscene(data) {
  const layer0 = JSON.parse(new TextDecoder().decode(data));
  const { operationalLayers } = layer0;
  const { layers, unsupportedLayers } = await parseOperationalLayers(operationalLayers, true);
  if (!layers.length) {
    throw new LayerError(NO_AVAILABLE_SUPPORTED_LAYERS_ERROR, unsupportedLayers);
  }
  return {
    header: layer0,
    layers,
    unsupportedLayers
  };
}
async function parseOperationalLayers(layersList, needToCheckCRS) {
  var _a;
  const layers = [];
  let unsupportedLayers = [];
  for (let index = 0; index < layersList.length; index++) {
    const layer = layersList[index];
    const isLayerSupported = SUPPORTED_LAYERS_TYPES.includes(layer.layerType);
    if (isLayerSupported) {
      if (needToCheckCRS && layer.layerType !== GROUP_LAYER) {
        await checkSupportedIndexCRS(layer);
        needToCheckCRS = false;
      }
      layers.push(layer);
    } else {
      unsupportedLayers.push(layer);
    }
    if ((_a = layer.layers) == null ? void 0 : _a.length) {
      const { layers: childLayers, unsupportedLayers: childUnsupportedLayers } = await parseOperationalLayers(layer.layers, needToCheckCRS);
      layer.layers = childLayers;
      unsupportedLayers = [...unsupportedLayers, ...childUnsupportedLayers];
    }
  }
  return { layers, unsupportedLayers };
}
async function checkSupportedIndexCRS(layer) {
  var _a;
  try {
    const layerJson = await (0, import_core7.load)(layer.url, import_core7.JSONLoader);
    const wkid = (_a = layerJson == null ? void 0 : layerJson.spatialReference) == null ? void 0 : _a.wkid;
    if (wkid !== SUPPORTED_WKID) {
      throw new Error(NOT_SUPPORTED_CRS_ERROR);
    }
  } catch (error) {
    throw error;
  }
}

// dist/arcgis-webscene-loader.js
var VERSION7 = true ? "4.4.2" : "latest";
var ArcGISWebSceneLoader = {
  dataType: null,
  batchType: null,
  name: "ArcGIS Web Scene Loader",
  id: "arcgis-web-scene",
  module: "i3s",
  version: VERSION7,
  mimeTypes: ["application/json"],
  parse: parse5,
  extensions: ["json"],
  options: {}
};
async function parse5(data) {
  return parseWebscene(data);
}

// dist/lib/utils/customize-colors.js
var import_core8 = require("@loaders.gl/core");
async function customizeColors(colors, featureIds, attributeUrls, fields, attributeStorageInfo, colorsByAttribute, token) {
  if (!colorsByAttribute) {
    return colors;
  }
  const resultColors = {
    ...colors,
    value: new Uint8Array(colors.value)
  };
  const colorizeAttributeField = fields.find(({ name }) => name === (colorsByAttribute == null ? void 0 : colorsByAttribute.attributeName));
  if (!colorizeAttributeField || !["esriFieldTypeDouble", "esriFieldTypeInteger", "esriFieldTypeSmallInteger"].includes(colorizeAttributeField.type)) {
    return colors;
  }
  const colorizeAttributeData = await loadFeatureAttributeData(colorizeAttributeField.name, attributeUrls, attributeStorageInfo, token);
  if (!colorizeAttributeData) {
    return colors;
  }
  const objectIdField = fields.find(({ type }) => type === "esriFieldTypeOID");
  if (!objectIdField) {
    return colors;
  }
  const objectIdAttributeData = await loadFeatureAttributeData(objectIdField.name, attributeUrls, attributeStorageInfo, token);
  if (!objectIdAttributeData) {
    return colors;
  }
  const attributeValuesMap = {};
  for (let i = 0; i < objectIdAttributeData[objectIdField.name].length; i++) {
    attributeValuesMap[objectIdAttributeData[objectIdField.name][i]] = calculateColorForAttribute(
      // @ts-expect-error
      colorizeAttributeData[colorizeAttributeField.name][i],
      colorsByAttribute
    );
  }
  for (let i = 0; i < featureIds.length; i++) {
    const color = attributeValuesMap[featureIds[i]];
    if (!color) {
      continue;
    }
    if (colorsByAttribute.mode === "multiply") {
      color.forEach((colorItem, index) => {
        resultColors.value[i * 4 + index] = resultColors.value[i * 4 + index] * colorItem / 255;
      });
    } else {
      resultColors.value.set(color, i * 4);
    }
  }
  return resultColors;
}
function calculateColorForAttribute(attributeValue, colorsByAttribute) {
  if (!colorsByAttribute) {
    return [255, 255, 255, 255];
  }
  const { minValue, maxValue, minColor, maxColor } = colorsByAttribute;
  const rate = (attributeValue - minValue) / (maxValue - minValue);
  const color = [255, 255, 255, 255];
  for (let i = 0; i < minColor.length; i++) {
    color[i] = Math.round((maxColor[i] - minColor[i]) * rate + minColor[i]);
  }
  return color;
}
async function loadFeatureAttributeData(attributeName, attributeUrls, attributeStorageInfo, token) {
  const attributeIndex = attributeStorageInfo.findIndex(({ name }) => attributeName === name);
  if (attributeIndex === -1) {
    return null;
  }
  const objectIdAttributeUrl = getUrlWithToken(attributeUrls[attributeIndex], token);
  const attributeType = getAttributeValueType(attributeStorageInfo[attributeIndex]);
  const objectIdAttributeData = await (0, import_core8.load)(objectIdAttributeUrl, I3SAttributeLoader, {
    i3s: {
      attributeName,
      attributeType
    }
  });
  return objectIdAttributeData;
}
//# sourceMappingURL=index.cjs.map
