{"version":3,"file":"maplibre-gl-shared.mjs","names":["unitBezier","create","glMatrix.ARRAY_TYPE","create","glMatrix.ARRAY_TYPE","clone","multiply","translate","scale","rotateX","rotateY","rotateZ","equals","create","glMatrix.ARRAY_TYPE","clone","length","fromValues","scale","normalize","dot","transformMat4","zero","forEach","create","glMatrix.ARRAY_TYPE","fromValues","multiply","scale","normalize","forEach","create","glMatrix.ARRAY_TYPE","fromValues","vec4.fromValues","vec4.normalize","vec3.create","vec3.fromValues","vec3.dot","vec3.len","mat3.create","glMatrix.ARRAY_TYPE","dot","EXTENT","EXTENT","mat3.determinant","vec3.cross","vec3.scale","clamp","unitBezierFactory","wrap","deepEqual","vec2.fromValues","vec2.dot","clamp","mercatorXfromLng","mercatorYfromLat","latFromMercatorY","TinyQueue","swap","classifyRings","styleSpec","interpolates","createVisibilityExpression","paint","getPaint","styleSpec","properties","align","layout","members","size","alignment","clamp","murmur3","sort","swap","clamp","EXTENT","clamp","layoutAttributes","projectQueryGeometry","layout","getLayout","styleSpec","paint","getPaint","properties","projectQueryGeometry","paint","getPaint","styleSpec","properties","paint","getPaint","styleSpec","properties","paint","getPaint","styleSpec","properties","layout","members","size","alignment","signedArea","EXTENT","EARCUT_MAX_RINGS","layoutAttributes","classifyRings","layout","getLayout","styleSpec","paint","getPaint","properties","layout","members","size","alignment","EXTENT","wrap","EXTENT","clamp","EXTENT","addVertex","layoutAttributes","classifyRings","layout","getLayout","styleSpec","paint","getPaint","properties","clipPoints","clipLine","clipLines","addFeature","members","size","alignment","layoutAttributesExt","layoutAttributes","EXTENT","layout","getLayout","styleSpec","paint","getPaint","properties","TEXT_DECODER_MIN_LENGTH","utf8TextDecoder","readUtf8","interpolates","clamp","styleSpec","paint","getPaint","properties","styleSpec","properties","EXTENT","decodeString","decodeString","decodeString","decodeString","decodeString","decodeString","decodeString","EXTENT","interpolates","Queue","EXTENT","classifyRings","murmur3"],"sources":["../node_modules/@mapbox/point-geometry/index.js","../node_modules/@mapbox/unitbezier/index.js","../src/util/offscreen_canvas_supported.ts","../src/util/offscreen_canvas_distorted.ts","../node_modules/gl-matrix/esm/common.js","../node_modules/gl-matrix/esm/mat3.js","../node_modules/gl-matrix/esm/mat4.js","../node_modules/gl-matrix/esm/vec3.js","../node_modules/gl-matrix/esm/vec4.js","../node_modules/gl-matrix/esm/quat.js","../node_modules/gl-matrix/esm/vec2.js","../src/data/extent.ts","../src/source/pixels_to_tile_units.ts","../src/util/util.ts","../src/util/abort_error.ts","../src/util/config.ts","../src/source/protocol_crud.ts","../src/util/ajax.ts","../src/util/evented.ts","../node_modules/@maplibre/maplibre-gl-style-spec/dist/index.mjs","../src/style/validate_style.ts","../src/util/transferable_grid_index.ts","../src/util/web_worker_transfer.ts","../src/style/zoom_history.ts","../src/util/unicode_properties.g.ts","../src/util/script_detection.ts","../src/source/rtl_text_plugin_worker.ts","../src/style/evaluation_parameters.ts","../src/style/properties.ts","../src/style/style_layer.ts","../src/style/style_layer/raster_style_layer_properties.g.ts","../src/style/style_layer/raster_style_layer.ts","../src/util/struct_array.ts","../src/data/array_types.g.ts","../src/data/bucket/circle_attributes.ts","../src/data/segment.ts","../src/shaders/encode_attribute.ts","../src/data/bucket/pattern_attributes.ts","../src/data/bucket/dash_attributes.ts","../node_modules/murmurhash-js/murmurhash3_gc.js","../node_modules/murmurhash-js/murmurhash2_gc.js","../node_modules/murmurhash-js/index.js","../src/data/feature_position_map.ts","../src/webgl/uniform_binding.ts","../src/data/program_configuration.ts","../src/data/load_geometry.ts","../src/data/evaluation_feature.ts","../src/data/bucket/circle_bucket.ts","../src/util/intersection_tests.ts","../src/style/query_utils.ts","../src/style/style_layer/circle_style_layer_properties.g.ts","../src/style/style_layer/circle_style_layer.ts","../src/data/bucket/heatmap_bucket.ts","../src/style/style_layer/heatmap_style_layer_properties.g.ts","../src/util/image.ts","../src/util/color_ramp.ts","../src/style/style_layer/heatmap_style_layer.ts","../src/style/style_layer/hillshade_style_layer_properties.g.ts","../src/style/style_layer/hillshade_style_layer.ts","../src/style/style_layer/color_relief_style_layer_properties.g.ts","../src/webgl/texture.ts","../src/data/dem_data.ts","../src/style/style_layer/color_relief_style_layer.ts","../src/data/bucket/fill_attributes.ts","../src/data/bucket/pattern_bucket_features.ts","../node_modules/earcut/src/earcut.js","../src/render/subdivision_granularity_settings.ts","../src/render/subdivision.ts","../src/render/fill_large_mesh_arrays.ts","../src/data/bucket/fill_bucket.ts","../src/style/style_layer/fill_style_layer_properties.g.ts","../src/style/style_layer/fill_style_layer.ts","../src/data/bucket/fill_extrusion_attributes.ts","../src/geo/bounds.ts","../src/data/extent_bounds.ts","../node_modules/@mapbox/vector-tile/index.js","../src/geo/lng_lat.ts","../src/geo/mercator_coordinate.ts","../src/geo/projection/mercator_utils.ts","../src/data/bucket/round_polygon_corners.ts","../src/data/bucket/fill_extrusion_bucket.ts","../src/style/style_layer/fill_extrusion_style_layer_properties.g.ts","../src/style/style_layer/fill_extrusion_style_layer.ts","../node_modules/@maplibre/geojson-vt/dist/geojson-vt.mjs","../src/data/bucket/line_attributes.ts","../src/data/bucket/line_attributes_ext.ts","../src/data/bucket/line_bucket.ts","../src/style/style_layer/line_style_layer_properties.g.ts","../src/style/style_layer/line_style_layer.ts","../src/data/bucket/symbol_attributes.ts","../src/symbol/transform_text.ts","../src/symbol/merge_lines.ts","../src/util/verticalize_punctuation.ts","../src/symbol/tagged_string.ts","../node_modules/pbf/index.js","../src/style/parse_glyph_pbf.ts","../src/style/style_image.ts","../node_modules/potpack/index.js","../src/render/image_atlas.ts","../src/symbol/shaping.ts","../src/symbol/symbol_size.ts","../src/style/style_layer/overlap_mode.ts","../src/data/bucket/symbol_bucket.ts","../src/util/resolve_tokens.ts","../src/style/style_layer/symbol_style_layer_properties.g.ts","../src/style/format_section_override.ts","../src/style/style_layer/symbol_style_layer.ts","../src/style/style_layer/background_style_layer_properties.g.ts","../src/style/style_layer/background_style_layer.ts","../src/style/style_layer/custom_style_layer.ts","../src/style/create_style_layer.ts","../src/util/throttled_invoker.ts","../src/util/actor.ts","../src/util/world_bounds.ts","../src/tile/tile_id.ts","../node_modules/@maplibre/vt-pbf/dist/index.es.js","../src/util/dictionary_coder.ts","../src/util/vectortile_to_geojson.ts","../node_modules/@maplibre/mlt/dist/vector/vector.js","../node_modules/@maplibre/mlt/dist/vector/fixedSizeVector.js","../node_modules/@maplibre/mlt/dist/vector/flat/int32FlatVector.js","../node_modules/@maplibre/mlt/dist/vector/flat/doubleFlatVector.js","../node_modules/@maplibre/mlt/dist/vector/sequence/sequenceVector.js","../node_modules/@maplibre/mlt/dist/vector/sequence/int32SequenceVector.js","../node_modules/@maplibre/mlt/dist/vector/constant/int32ConstVector.js","../node_modules/@maplibre/mlt/dist/vector/featureTable.js","../node_modules/@maplibre/mlt/dist/metadata/tileset/tilesetMetadata.js","../node_modules/@maplibre/mlt/dist/decoding/intWrapper.js","../node_modules/@maplibre/mlt/dist/metadata/tile/logicalLevelTechnique.js","../node_modules/@maplibre/mlt/dist/metadata/tile/physicalLevelTechnique.js","../node_modules/@maplibre/mlt/dist/decoding/fastPforShared.js","../node_modules/@maplibre/mlt/dist/decoding/fastPforUnpack.js","../node_modules/@maplibre/mlt/dist/decoding/fastPforDecoder.js","../node_modules/@maplibre/mlt/dist/decoding/bigEndianDecode.js","../node_modules/@maplibre/mlt/dist/decoding/integerDecodingUtils.js","../node_modules/@maplibre/mlt/dist/metadata/tile/physicalStreamType.js","../node_modules/@maplibre/mlt/dist/metadata/tile/dictionaryType.js","../node_modules/@maplibre/mlt/dist/metadata/tile/offsetType.js","../node_modules/@maplibre/mlt/dist/metadata/tile/lengthType.js","../node_modules/@maplibre/mlt/dist/metadata/tile/streamMetadataDecoder.js","../node_modules/@maplibre/mlt/dist/vector/vectorType.js","../node_modules/@maplibre/mlt/dist/vector/flat/bitVector.js","../node_modules/@maplibre/mlt/dist/decoding/unpackNullableUtils.js","../node_modules/@maplibre/mlt/dist/decoding/decodingUtils.js","../node_modules/@maplibre/mlt/dist/decoding/integerStreamDecoder.js","../node_modules/@maplibre/mlt/dist/vector/flat/int64FlatVector.js","../node_modules/@maplibre/mlt/dist/vector/sequence/int64SequenceVector.js","../node_modules/@maplibre/mlt/dist/vector/geometry/zOrderCurve.js","../node_modules/@maplibre/mlt/dist/vector/geometry/geometryType.js","../node_modules/@maplibre/mlt/dist/vector/geometry/vertexBufferType.js","../node_modules/@maplibre/mlt/dist/vector/geometry/geometryVectorConverter.js","../node_modules/@maplibre/mlt/dist/vector/geometry/geometryVector.js","../node_modules/@maplibre/mlt/dist/vector/geometry/constGeometryVector.js","../node_modules/@maplibre/mlt/dist/vector/geometry/flatGeometryVector.js","../node_modules/@maplibre/mlt/dist/vector/geometry/gpuVector.js","../node_modules/@maplibre/mlt/dist/vector/geometry/constGpuVector.js","../node_modules/@maplibre/mlt/dist/vector/geometry/flatGpuVector.js","../node_modules/@maplibre/mlt/dist/decoding/geometryDecoder.js","../node_modules/@maplibre/mlt/dist/vector/flat/booleanFlatVector.js","../node_modules/@maplibre/mlt/dist/vector/flat/floatFlatVector.js","../node_modules/@maplibre/mlt/dist/vector/constant/int64ConstVector.js","../node_modules/@maplibre/mlt/dist/vector/variableSizeVector.js","../node_modules/@maplibre/mlt/dist/vector/flat/stringFlatVector.js","../node_modules/@maplibre/mlt/dist/vector/dictionary/stringDictionaryVector.js","../node_modules/@maplibre/mlt/dist/decoding/fsstDecoder.js","../node_modules/@maplibre/mlt/dist/vector/fsst-dictionary/stringFsstDictionaryVector.js","../node_modules/@maplibre/mlt/dist/decoding/stringDecoder.js","../node_modules/@maplibre/mlt/dist/vector/flat/objectFlatVector.js","../node_modules/@maplibre/mlt/dist/metadata/tile/mapMask.js","../node_modules/@maplibre/mlt/dist/metadata/tile/mapControlValue.js","../node_modules/@maplibre/mlt/dist/decoding/mapPropertyDecoder.js","../node_modules/@maplibre/mlt/dist/decoding/propertyDecoder.js","../node_modules/@maplibre/mlt/dist/metadata/tileset/typeMap.js","../node_modules/@maplibre/mlt/dist/metadata/tileset/embeddedTilesetMetadataDecoder.js","../node_modules/@maplibre/mlt/dist/mltDecoder.js","../src/source/vector_tile_mlt.ts","../src/data/feature_index.ts","../src/tile/tile_cache.ts","../src/symbol/clip_line.ts","../src/symbol/anchor.ts","../src/symbol/check_max_angle.ts","../src/symbol/get_anchors.ts","../src/symbol/quads.ts","../src/symbol/collision_feature.ts","../node_modules/tinyqueue/index.js","../src/util/find_pole_of_inaccessibility.ts","../src/style/style_layer/variable_text_anchor.ts","../src/symbol/symbol_layout.ts"],"sourcesContent":["/**\n * A standalone point geometry with useful accessor, comparison, and\n * modification methods.\n *\n * @class\n * @param {number} x the x-coordinate. This could be longitude or screen pixels, or any other sort of unit.\n * @param {number} y the y-coordinate. This could be latitude or screen pixels, or any other sort of unit.\n *\n * @example\n * const point = new Point(-77, 38);\n */\nexport default function Point(x, y) {\n this.x = x;\n this.y = y;\n}\n\nPoint.prototype = {\n /**\n * Clone this point, returning a new point that can be modified\n * without affecting the old one.\n * @return {Point} the clone\n */\n clone() { return new Point(this.x, this.y); },\n\n /**\n * Add this point's x & y coordinates to another point,\n * yielding a new point.\n * @param {Point} p the other point\n * @return {Point} output point\n */\n add(p) { return this.clone()._add(p); },\n\n /**\n * Subtract this point's x & y coordinates to from point,\n * yielding a new point.\n * @param {Point} p the other point\n * @return {Point} output point\n */\n sub(p) { return this.clone()._sub(p); },\n\n /**\n * Multiply this point's x & y coordinates by point,\n * yielding a new point.\n * @param {Point} p the other point\n * @return {Point} output point\n */\n multByPoint(p) { return this.clone()._multByPoint(p); },\n\n /**\n * Divide this point's x & y coordinates by point,\n * yielding a new point.\n * @param {Point} p the other point\n * @return {Point} output point\n */\n divByPoint(p) { return this.clone()._divByPoint(p); },\n\n /**\n * Multiply this point's x & y coordinates by a factor,\n * yielding a new point.\n * @param {number} k factor\n * @return {Point} output point\n */\n mult(k) { return this.clone()._mult(k); },\n\n /**\n * Divide this point's x & y coordinates by a factor,\n * yielding a new point.\n * @param {number} k factor\n * @return {Point} output point\n */\n div(k) { return this.clone()._div(k); },\n\n /**\n * Rotate this point around the 0, 0 origin by an angle a,\n * given in radians\n * @param {number} a angle to rotate around, in radians\n * @return {Point} output point\n */\n rotate(a) { return this.clone()._rotate(a); },\n\n /**\n * Rotate this point around p point by an angle a,\n * given in radians\n * @param {number} a angle to rotate around, in radians\n * @param {Point} p Point to rotate around\n * @return {Point} output point\n */\n rotateAround(a, p) { return this.clone()._rotateAround(a, p); },\n\n /**\n * Multiply this point by a 4x1 transformation matrix\n * @param {[number, number, number, number]} m transformation matrix\n * @return {Point} output point\n */\n matMult(m) { return this.clone()._matMult(m); },\n\n /**\n * Calculate this point but as a unit vector from 0, 0, meaning\n * that the distance from the resulting point to the 0, 0\n * coordinate will be equal to 1 and the angle from the resulting\n * point to the 0, 0 coordinate will be the same as before.\n * @return {Point} unit vector point\n */\n unit() { return this.clone()._unit(); },\n\n /**\n * Compute a perpendicular point, where the new y coordinate\n * is the old x coordinate and the new x coordinate is the old y\n * coordinate multiplied by -1\n * @return {Point} perpendicular point\n */\n perp() { return this.clone()._perp(); },\n\n /**\n * Return a version of this point with the x & y coordinates\n * rounded to integers.\n * @return {Point} rounded point\n */\n round() { return this.clone()._round(); },\n\n /**\n * Return the magnitude of this point: this is the Euclidean\n * distance from the 0, 0 coordinate to this point's x and y\n * coordinates.\n * @return {number} magnitude\n */\n mag() {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n },\n\n /**\n * Judge whether this point is equal to another point, returning\n * true or false.\n * @param {Point} other the other point\n * @return {boolean} whether the points are equal\n */\n equals(other) {\n return this.x === other.x &&\n this.y === other.y;\n },\n\n /**\n * Calculate the distance from this point to another point\n * @param {Point} p the other point\n * @return {number} distance\n */\n dist(p) {\n return Math.sqrt(this.distSqr(p));\n },\n\n /**\n * Calculate the distance from this point to another point,\n * without the square root step. Useful if you're comparing\n * relative distances.\n * @param {Point} p the other point\n * @return {number} distance\n */\n distSqr(p) {\n const dx = p.x - this.x,\n dy = p.y - this.y;\n return dx * dx + dy * dy;\n },\n\n /**\n * Get the angle from the 0, 0 coordinate to this point, in radians\n * coordinates.\n * @return {number} angle\n */\n angle() {\n return Math.atan2(this.y, this.x);\n },\n\n /**\n * Get the angle from this point to another point, in radians\n * @param {Point} b the other point\n * @return {number} angle\n */\n angleTo(b) {\n return Math.atan2(this.y - b.y, this.x - b.x);\n },\n\n /**\n * Get the angle between this point and another point, in radians\n * @param {Point} b the other point\n * @return {number} angle\n */\n angleWith(b) {\n return this.angleWithSep(b.x, b.y);\n },\n\n /**\n * Find the angle of the two vectors, solving the formula for\n * the cross product a x b = |a||b|sin(θ) for θ.\n * @param {number} x the x-coordinate\n * @param {number} y the y-coordinate\n * @return {number} the angle in radians\n */\n angleWithSep(x, y) {\n return Math.atan2(\n this.x * y - this.y * x,\n this.x * x + this.y * y);\n },\n\n /** @param {[number, number, number, number]} m */\n _matMult(m) {\n const x = m[0] * this.x + m[1] * this.y,\n y = m[2] * this.x + m[3] * this.y;\n this.x = x;\n this.y = y;\n return this;\n },\n\n /** @param {Point} p */\n _add(p) {\n this.x += p.x;\n this.y += p.y;\n return this;\n },\n\n /** @param {Point} p */\n _sub(p) {\n this.x -= p.x;\n this.y -= p.y;\n return this;\n },\n\n /** @param {number} k */\n _mult(k) {\n this.x *= k;\n this.y *= k;\n return this;\n },\n\n /** @param {number} k */\n _div(k) {\n this.x /= k;\n this.y /= k;\n return this;\n },\n\n /** @param {Point} p */\n _multByPoint(p) {\n this.x *= p.x;\n this.y *= p.y;\n return this;\n },\n\n /** @param {Point} p */\n _divByPoint(p) {\n this.x /= p.x;\n this.y /= p.y;\n return this;\n },\n\n _unit() {\n this._div(this.mag());\n return this;\n },\n\n _perp() {\n const y = this.y;\n this.y = this.x;\n this.x = -y;\n return this;\n },\n\n /** @param {number} angle */\n _rotate(angle) {\n const cos = Math.cos(angle),\n sin = Math.sin(angle),\n x = cos * this.x - sin * this.y,\n y = sin * this.x + cos * this.y;\n this.x = x;\n this.y = y;\n return this;\n },\n\n /**\n * @param {number} angle\n * @param {Point} p\n */\n _rotateAround(angle, p) {\n const cos = Math.cos(angle),\n sin = Math.sin(angle),\n x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y),\n y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);\n this.x = x;\n this.y = y;\n return this;\n },\n\n _round() {\n this.x = Math.round(this.x);\n this.y = Math.round(this.y);\n return this;\n },\n\n constructor: Point\n};\n\n/**\n * Construct a point from an array if necessary, otherwise if the input\n * is already a Point, return it unchanged.\n * @param {Point | [number, number] | {x: number, y: number}} p input value\n * @return {Point} constructed point.\n * @example\n * // this\n * var point = Point.convert([0, 1]);\n * // is equivalent to\n * var point = new Point(0, 1);\n */\nPoint.convert = function (p) {\n if (p instanceof Point) {\n return /** @type {Point} */ (p);\n }\n if (Array.isArray(p)) {\n return new Point(+p[0], +p[1]);\n }\n if (p.x !== undefined && p.y !== undefined) {\n return new Point(+p.x, +p.y);\n }\n throw new Error('Expected [x, y] or {x, y} point format');\n};\n","\nexport default function unitBezier(p1x, p1y, p2x, p2y) {\n // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).\n const cx = 3 * p1x;\n const bx = 3 * (p2x - p1x) - cx;\n const ax = 1 - cx - bx;\n\n const cy = 3 * p1y;\n const by = 3 * (p2y - p1y) - cy;\n const ay = 1 - cy - by;\n\n return function solve(x, epsilon = 1e-6) {\n if (x <= 0) return 0;\n if (x >= 1) return 1;\n\n let t = x;\n\n // First try a few iterations of Newton's method - normally very fast.\n // `ax t^3 + bx t^2 + cx t` expanded using Horner's rule.\n for (let i = 0; i < 8; i++) {\n const x2 = ((ax * t + bx) * t + cx) * t - x;\n if (Math.abs(x2) < epsilon) return ((ay * t + by) * t + cy) * t;\n\n const d2 = (3 * ax * t + 2 * bx) * t + cx;\n if (Math.abs(d2) < 1e-6) break;\n\n t -= x2 / d2;\n }\n\n // Fall back to the bisection method for reliability.\n let t0 = 0;\n let t1 = 1;\n t = x;\n\n for (let i = 0; i < 20; i++) {\n const x2 = ((ax * t + bx) * t + cx) * t;\n if (Math.abs(x2 - x) < epsilon) break;\n\n if (x > x2) t0 = t;\n else t1 = t;\n\n t = (t0 + t1) * 0.5;\n }\n\n return ((ay * t + by) * t + cy) * t;\n };\n}\n","let supportsOffscreenCanvas: boolean;\n\nexport function offscreenCanvasSupported(): boolean {\n supportsOffscreenCanvas ??= typeof OffscreenCanvas !== 'undefined' &&\n new OffscreenCanvas(1, 1).getContext('2d') &&\n typeof createImageBitmap === 'function';\n\n return supportsOffscreenCanvas;\n}\n","import {offscreenCanvasSupported} from './offscreen_canvas_supported.ts';\n\nlet offscreenCanvasDistorted: boolean;\n\n/**\n * Some browsers don't return the exact pixels from a canvas to prevent user fingerprinting (see #3185).\n * This function writes pixels to an OffscreenCanvas and reads them back using getImageData, returning false\n * if they don't match.\n *\n * @returns true if the browser supports OffscreenCanvas but it distorts getImageData results, false otherwise.\n */\nexport function isOffscreenCanvasDistorted(): boolean {\n if (offscreenCanvasDistorted == null) {\n offscreenCanvasDistorted = false;\n if (offscreenCanvasSupported()) {\n const size = 5;\n const canvas = new OffscreenCanvas(size, size);\n const context = canvas.getContext('2d', {willReadFrequently: true});\n if (context) {\n // fill each pixel with an RGB value that should make the byte at index i equal to i (except alpha channel):\n // [0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 10, 255, ...]\n for (let i = 0; i < size * size; i++) {\n const base = i * 4;\n context.fillStyle = `rgb(${base},${base + 1},${base + 2})`;\n context.fillRect(i % size, Math.floor(i / size), 1, 1);\n }\n const data = context.getImageData(0, 0, size, size).data;\n for (let i = 0; i < size * size * 4; i++) {\n if (i % 4 !== 3 && data[i] !== i) {\n offscreenCanvasDistorted = true;\n break;\n }\n }\n }\n }\n }\n\n return offscreenCanvasDistorted || false;\n}\n","/**\n * Common utilities\n * @module glMatrix\n */\n\n// Configuration Constants\nexport var EPSILON = 0.000001;\nexport var ARRAY_TYPE = typeof Float32Array !== \"undefined\" ? Float32Array : Array;\nexport var RANDOM = Math.random;\nexport var ANGLE_ORDER = \"zyx\";\n\n/**\n * Symmetric round\n * see https://www.npmjs.com/package/round-half-up-symmetric#user-content-detailed-background\n *\n * @param {Number} a value to round\n */\nexport function round(a) {\n if (a >= 0) return Math.round(a);\n return a % 0.5 === 0 ? Math.floor(a) : Math.round(a);\n}\n\n/**\n * Sets the type of array used when creating new vectors and matrices\n *\n * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array\n */\nexport function setMatrixArrayType(type) {\n ARRAY_TYPE = type;\n}\nvar degree = Math.PI / 180;\nvar radian = 180 / Math.PI;\n\n/**\n * Convert Degree To Radian\n *\n * @param {Number} a Angle in Degrees\n */\nexport function toRadian(a) {\n return a * degree;\n}\n\n/**\n * Convert Radian To Degree\n *\n * @param {Number} a Angle in Radians\n */\nexport function toDegree(a) {\n return a * radian;\n}\n\n/**\n * Tests whether or not the arguments have approximately the same value, within an absolute\n * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less\n * than or equal to 1.0, and a relative tolerance is used for larger values)\n *\n * @param {Number} a The first number to test.\n * @param {Number} b The second number to test.\n * @param {Number} tolerance Absolute or relative tolerance (default glMatrix.EPSILON)\n * @returns {Boolean} True if the numbers are approximately equal, false otherwise.\n */\nexport function equals(a, b) {\n var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EPSILON;\n return Math.abs(a - b) <= tolerance * Math.max(1, Math.abs(a), Math.abs(b));\n}","import * as glMatrix from \"./common.js\";\n\n/**\n * 3x3 Matrix\n * @module mat3\n */\n\n/**\n * Creates a new identity mat3\n *\n * @returns {mat3} a new 3x3 matrix\n */\nexport function create() {\n var out = new glMatrix.ARRAY_TYPE(9);\n if (glMatrix.ARRAY_TYPE != Float32Array) {\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n }\n out[0] = 1;\n out[4] = 1;\n out[8] = 1;\n return out;\n}\n\n/**\n * Copies the upper-left 3x3 values into the given mat3.\n *\n * @param {mat3} out the receiving 3x3 matrix\n * @param {ReadonlyMat4} a the source 4x4 matrix\n * @returns {mat3} out\n */\nexport function fromMat4(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[4];\n out[4] = a[5];\n out[5] = a[6];\n out[6] = a[8];\n out[7] = a[9];\n out[8] = a[10];\n return out;\n}\n\n/**\n * Creates a new mat3 initialized with values from an existing matrix\n *\n * @param {ReadonlyMat3} a matrix to clone\n * @returns {mat3} a new 3x3 matrix\n */\nexport function clone(a) {\n var out = new glMatrix.ARRAY_TYPE(9);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n return out;\n}\n\n/**\n * Copy the values from one mat3 to another\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\nexport function copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n return out;\n}\n\n/**\n * Create a new mat3 with the given values\n *\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m10 Component in column 1, row 0 position (index 3)\n * @param {Number} m11 Component in column 1, row 1 position (index 4)\n * @param {Number} m12 Component in column 1, row 2 position (index 5)\n * @param {Number} m20 Component in column 2, row 0 position (index 6)\n * @param {Number} m21 Component in column 2, row 1 position (index 7)\n * @param {Number} m22 Component in column 2, row 2 position (index 8)\n * @returns {mat3} A new mat3\n */\nexport function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) {\n var out = new glMatrix.ARRAY_TYPE(9);\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m10;\n out[4] = m11;\n out[5] = m12;\n out[6] = m20;\n out[7] = m21;\n out[8] = m22;\n return out;\n}\n\n/**\n * Set the components of a mat3 to the given values\n *\n * @param {mat3} out the receiving matrix\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m10 Component in column 1, row 0 position (index 3)\n * @param {Number} m11 Component in column 1, row 1 position (index 4)\n * @param {Number} m12 Component in column 1, row 2 position (index 5)\n * @param {Number} m20 Component in column 2, row 0 position (index 6)\n * @param {Number} m21 Component in column 2, row 1 position (index 7)\n * @param {Number} m22 Component in column 2, row 2 position (index 8)\n * @returns {mat3} out\n */\nexport function set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m10;\n out[4] = m11;\n out[5] = m12;\n out[6] = m20;\n out[7] = m21;\n out[8] = m22;\n return out;\n}\n\n/**\n * Set a mat3 to the identity matrix\n *\n * @param {mat3} out the receiving matrix\n * @returns {mat3} out\n */\nexport function identity(out) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 1;\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 1;\n return out;\n}\n\n/**\n * Transpose the values of a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\nexport function transpose(out, a) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n if (out === a) {\n var a01 = a[1],\n a02 = a[2],\n a12 = a[5];\n out[1] = a[3];\n out[2] = a[6];\n out[3] = a01;\n out[5] = a[7];\n out[6] = a02;\n out[7] = a12;\n } else {\n out[0] = a[0];\n out[1] = a[3];\n out[2] = a[6];\n out[3] = a[1];\n out[4] = a[4];\n out[5] = a[7];\n out[6] = a[2];\n out[7] = a[5];\n out[8] = a[8];\n }\n return out;\n}\n\n/**\n * Inverts a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3 | null} out, or null if source matrix is not invertible\n */\nexport function invert(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n var b01 = a22 * a11 - a12 * a21;\n var b11 = -a22 * a10 + a12 * a20;\n var b21 = a21 * a10 - a11 * a20;\n\n // Calculate the determinant\n var det = a00 * b01 + a01 * b11 + a02 * b21;\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n out[0] = b01 * det;\n out[1] = (-a22 * a01 + a02 * a21) * det;\n out[2] = (a12 * a01 - a02 * a11) * det;\n out[3] = b11 * det;\n out[4] = (a22 * a00 - a02 * a20) * det;\n out[5] = (-a12 * a00 + a02 * a10) * det;\n out[6] = b21 * det;\n out[7] = (-a21 * a00 + a01 * a20) * det;\n out[8] = (a11 * a00 - a01 * a10) * det;\n return out;\n}\n\n/**\n * Calculates the adjugate of a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\nexport function adjoint(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n out[0] = a11 * a22 - a12 * a21;\n out[1] = a02 * a21 - a01 * a22;\n out[2] = a01 * a12 - a02 * a11;\n out[3] = a12 * a20 - a10 * a22;\n out[4] = a00 * a22 - a02 * a20;\n out[5] = a02 * a10 - a00 * a12;\n out[6] = a10 * a21 - a11 * a20;\n out[7] = a01 * a20 - a00 * a21;\n out[8] = a00 * a11 - a01 * a10;\n return out;\n}\n\n/**\n * Calculates the determinant of a mat3\n *\n * @param {ReadonlyMat3} a the source matrix\n * @returns {Number} determinant of a\n */\nexport function determinant(a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);\n}\n\n/**\n * Multiplies two mat3's\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @returns {mat3} out\n */\nexport function multiply(out, a, b) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n var b00 = b[0],\n b01 = b[1],\n b02 = b[2];\n var b10 = b[3],\n b11 = b[4],\n b12 = b[5];\n var b20 = b[6],\n b21 = b[7],\n b22 = b[8];\n out[0] = b00 * a00 + b01 * a10 + b02 * a20;\n out[1] = b00 * a01 + b01 * a11 + b02 * a21;\n out[2] = b00 * a02 + b01 * a12 + b02 * a22;\n out[3] = b10 * a00 + b11 * a10 + b12 * a20;\n out[4] = b10 * a01 + b11 * a11 + b12 * a21;\n out[5] = b10 * a02 + b11 * a12 + b12 * a22;\n out[6] = b20 * a00 + b21 * a10 + b22 * a20;\n out[7] = b20 * a01 + b21 * a11 + b22 * a21;\n out[8] = b20 * a02 + b21 * a12 + b22 * a22;\n return out;\n}\n\n/**\n * Translate a mat3 by the given vector\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to translate\n * @param {ReadonlyVec2} v vector to translate by\n * @returns {mat3} out\n */\nexport function translate(out, a, v) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a10 = a[3],\n a11 = a[4],\n a12 = a[5],\n a20 = a[6],\n a21 = a[7],\n a22 = a[8],\n x = v[0],\n y = v[1];\n out[0] = a00;\n out[1] = a01;\n out[2] = a02;\n out[3] = a10;\n out[4] = a11;\n out[5] = a12;\n out[6] = x * a00 + y * a10 + a20;\n out[7] = x * a01 + y * a11 + a21;\n out[8] = x * a02 + y * a12 + a22;\n return out;\n}\n\n/**\n * Rotates a mat3 by the given angle\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat3} out\n */\nexport function rotate(out, a, rad) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a10 = a[3],\n a11 = a[4],\n a12 = a[5],\n a20 = a[6],\n a21 = a[7],\n a22 = a[8],\n s = Math.sin(rad),\n c = Math.cos(rad);\n out[0] = c * a00 + s * a10;\n out[1] = c * a01 + s * a11;\n out[2] = c * a02 + s * a12;\n out[3] = c * a10 - s * a00;\n out[4] = c * a11 - s * a01;\n out[5] = c * a12 - s * a02;\n out[6] = a20;\n out[7] = a21;\n out[8] = a22;\n return out;\n}\n\n/**\n * Scales the mat3 by the dimensions in the given vec2\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to scale\n * @param {ReadonlyVec2} v the vec2 to scale the matrix by\n * @returns {mat3} out\n **/\nexport function scale(out, a, v) {\n var x = v[0],\n y = v[1];\n out[0] = x * a[0];\n out[1] = x * a[1];\n out[2] = x * a[2];\n out[3] = y * a[3];\n out[4] = y * a[4];\n out[5] = y * a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n return out;\n}\n\n/**\n * Creates a matrix from a vector translation\n * This is equivalent to (but much faster than):\n *\n * mat3.identity(dest);\n * mat3.translate(dest, dest, vec);\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyVec2} v Translation vector\n * @returns {mat3} out\n */\nexport function fromTranslation(out, v) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 1;\n out[5] = 0;\n out[6] = v[0];\n out[7] = v[1];\n out[8] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from a given angle\n * This is equivalent to (but much faster than):\n *\n * mat3.identity(dest);\n * mat3.rotate(dest, dest, rad);\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat3} out\n */\nexport function fromRotation(out, rad) {\n var s = Math.sin(rad),\n c = Math.cos(rad);\n out[0] = c;\n out[1] = s;\n out[2] = 0;\n out[3] = -s;\n out[4] = c;\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from a vector scaling\n * This is equivalent to (but much faster than):\n *\n * mat3.identity(dest);\n * mat3.scale(dest, dest, vec);\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyVec2} v Scaling vector\n * @returns {mat3} out\n */\nexport function fromScaling(out, v) {\n out[0] = v[0];\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = v[1];\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 1;\n return out;\n}\n\n/**\n * Copies the values from a mat2d into a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat2d} a the matrix to copy\n * @returns {mat3} out\n **/\nexport function fromMat2d(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = 0;\n out[3] = a[2];\n out[4] = a[3];\n out[5] = 0;\n out[6] = a[4];\n out[7] = a[5];\n out[8] = 1;\n return out;\n}\n\n/**\n * Calculates a 3x3 matrix from the given quaternion\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyQuat} q Quaternion to create matrix from\n *\n * @returns {mat3} out\n */\nexport function fromQuat(out, q) {\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var yx = y * x2;\n var yy = y * y2;\n var zx = z * x2;\n var zy = z * y2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n out[0] = 1 - yy - zz;\n out[3] = yx - wz;\n out[6] = zx + wy;\n out[1] = yx + wz;\n out[4] = 1 - xx - zz;\n out[7] = zy - wx;\n out[2] = zx - wy;\n out[5] = zy + wx;\n out[8] = 1 - xx - yy;\n return out;\n}\n\n/**\n * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from\n *\n * @returns {mat3} out\n */\nexport function normalFromMat4(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n var b00 = a00 * a11 - a01 * a10;\n var b01 = a00 * a12 - a02 * a10;\n var b02 = a00 * a13 - a03 * a10;\n var b03 = a01 * a12 - a02 * a11;\n var b04 = a01 * a13 - a03 * a11;\n var b05 = a02 * a13 - a03 * a12;\n var b06 = a20 * a31 - a21 * a30;\n var b07 = a20 * a32 - a22 * a30;\n var b08 = a20 * a33 - a23 * a30;\n var b09 = a21 * a32 - a22 * a31;\n var b10 = a21 * a33 - a23 * a31;\n var b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n return out;\n}\n\n/**\n * Generates a 2D projection matrix with the given bounds\n *\n * @param {mat3} out mat3 frustum matrix will be written into\n * @param {number} width Width of your gl context\n * @param {number} height Height of gl context\n * @returns {mat3} out\n */\nexport function projection(out, width, height) {\n out[0] = 2 / width;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = -2 / height;\n out[5] = 0;\n out[6] = -1;\n out[7] = 1;\n out[8] = 1;\n return out;\n}\n\n/**\n * Returns a string representation of a mat3\n *\n * @param {ReadonlyMat3} a matrix to represent as a string\n * @returns {String} string representation of the matrix\n */\nexport function str(a) {\n return \"mat3(\" + a[0] + \", \" + a[1] + \", \" + a[2] + \", \" + a[3] + \", \" + a[4] + \", \" + a[5] + \", \" + a[6] + \", \" + a[7] + \", \" + a[8] + \")\";\n}\n\n/**\n * Returns Frobenius norm of a mat3\n *\n * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of\n * @returns {Number} Frobenius norm\n */\nexport function frob(a) {\n return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3] + a[4] * a[4] + a[5] * a[5] + a[6] * a[6] + a[7] * a[7] + a[8] * a[8]);\n}\n\n/**\n * Adds two mat3's\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @returns {mat3} out\n */\nexport function add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n out[3] = a[3] + b[3];\n out[4] = a[4] + b[4];\n out[5] = a[5] + b[5];\n out[6] = a[6] + b[6];\n out[7] = a[7] + b[7];\n out[8] = a[8] + b[8];\n return out;\n}\n\n/**\n * Subtracts matrix b from matrix a\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @returns {mat3} out\n */\nexport function subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n out[3] = a[3] - b[3];\n out[4] = a[4] - b[4];\n out[5] = a[5] - b[5];\n out[6] = a[6] - b[6];\n out[7] = a[7] - b[7];\n out[8] = a[8] - b[8];\n return out;\n}\n\n/**\n * Multiply each element of the matrix by a scalar.\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to scale\n * @param {Number} b amount to scale the matrix's elements by\n * @returns {mat3} out\n */\nexport function multiplyScalar(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n out[3] = a[3] * b;\n out[4] = a[4] * b;\n out[5] = a[5] * b;\n out[6] = a[6] * b;\n out[7] = a[7] * b;\n out[8] = a[8] * b;\n return out;\n}\n\n/**\n * Adds two mat3's after multiplying each element of the second operand by a scalar value.\n *\n * @param {mat3} out the receiving vector\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @param {Number} scale the amount to scale b's elements by before adding\n * @returns {mat3} out\n */\nexport function multiplyScalarAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n out[3] = a[3] + b[3] * scale;\n out[4] = a[4] + b[4] * scale;\n out[5] = a[5] + b[5] * scale;\n out[6] = a[6] + b[6] * scale;\n out[7] = a[7] + b[7] * scale;\n out[8] = a[8] + b[8] * scale;\n return out;\n}\n\n/**\n * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyMat3} a The first matrix.\n * @param {ReadonlyMat3} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8];\n}\n\n/**\n * Returns whether or not the matrices have approximately the same elements in the same position.\n *\n * @param {ReadonlyMat3} a The first matrix.\n * @param {ReadonlyMat3} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\nexport function equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3],\n a4 = a[4],\n a5 = a[5],\n a6 = a[6],\n a7 = a[7],\n a8 = a[8];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3],\n b4 = b[4],\n b5 = b[5],\n b6 = b[6],\n b7 = b[7],\n b8 = b[8];\n return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8));\n}\n\n/**\n * Alias for {@link mat3.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Alias for {@link mat3.subtract}\n * @function\n */\nexport var sub = subtract;","import * as glMatrix from \"./common.js\";\n\n/**\n * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied.\n * @module mat4\n */\n\n/**\n * Creates a new identity mat4\n *\n * @returns {mat4} a new 4x4 matrix\n */\nexport function create() {\n var out = new glMatrix.ARRAY_TYPE(16);\n if (glMatrix.ARRAY_TYPE != Float32Array) {\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n }\n out[0] = 1;\n out[5] = 1;\n out[10] = 1;\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a new mat4 initialized with values from an existing matrix\n *\n * @param {ReadonlyMat4} a matrix to clone\n * @returns {mat4} a new 4x4 matrix\n */\nexport function clone(a) {\n var out = new glMatrix.ARRAY_TYPE(16);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n out[9] = a[9];\n out[10] = a[10];\n out[11] = a[11];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n return out;\n}\n\n/**\n * Copy the values from one mat4 to another\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\nexport function copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n out[9] = a[9];\n out[10] = a[10];\n out[11] = a[11];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n return out;\n}\n\n/**\n * Create a new mat4 with the given values\n *\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m03 Component in column 0, row 3 position (index 3)\n * @param {Number} m10 Component in column 1, row 0 position (index 4)\n * @param {Number} m11 Component in column 1, row 1 position (index 5)\n * @param {Number} m12 Component in column 1, row 2 position (index 6)\n * @param {Number} m13 Component in column 1, row 3 position (index 7)\n * @param {Number} m20 Component in column 2, row 0 position (index 8)\n * @param {Number} m21 Component in column 2, row 1 position (index 9)\n * @param {Number} m22 Component in column 2, row 2 position (index 10)\n * @param {Number} m23 Component in column 2, row 3 position (index 11)\n * @param {Number} m30 Component in column 3, row 0 position (index 12)\n * @param {Number} m31 Component in column 3, row 1 position (index 13)\n * @param {Number} m32 Component in column 3, row 2 position (index 14)\n * @param {Number} m33 Component in column 3, row 3 position (index 15)\n * @returns {mat4} A new mat4\n */\nexport function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n var out = new glMatrix.ARRAY_TYPE(16);\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m03;\n out[4] = m10;\n out[5] = m11;\n out[6] = m12;\n out[7] = m13;\n out[8] = m20;\n out[9] = m21;\n out[10] = m22;\n out[11] = m23;\n out[12] = m30;\n out[13] = m31;\n out[14] = m32;\n out[15] = m33;\n return out;\n}\n\n/**\n * Set the components of a mat4 to the given values\n *\n * @param {mat4} out the receiving matrix\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m03 Component in column 0, row 3 position (index 3)\n * @param {Number} m10 Component in column 1, row 0 position (index 4)\n * @param {Number} m11 Component in column 1, row 1 position (index 5)\n * @param {Number} m12 Component in column 1, row 2 position (index 6)\n * @param {Number} m13 Component in column 1, row 3 position (index 7)\n * @param {Number} m20 Component in column 2, row 0 position (index 8)\n * @param {Number} m21 Component in column 2, row 1 position (index 9)\n * @param {Number} m22 Component in column 2, row 2 position (index 10)\n * @param {Number} m23 Component in column 2, row 3 position (index 11)\n * @param {Number} m30 Component in column 3, row 0 position (index 12)\n * @param {Number} m31 Component in column 3, row 1 position (index 13)\n * @param {Number} m32 Component in column 3, row 2 position (index 14)\n * @param {Number} m33 Component in column 3, row 3 position (index 15)\n * @returns {mat4} out\n */\nexport function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m03;\n out[4] = m10;\n out[5] = m11;\n out[6] = m12;\n out[7] = m13;\n out[8] = m20;\n out[9] = m21;\n out[10] = m22;\n out[11] = m23;\n out[12] = m30;\n out[13] = m31;\n out[14] = m32;\n out[15] = m33;\n return out;\n}\n\n/**\n * Set a mat4 to the identity matrix\n *\n * @param {mat4} out the receiving matrix\n * @returns {mat4} out\n */\nexport function identity(out) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = 1;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n\n/**\n * Transpose the values of a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\nexport function transpose(out, a) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n if (out === a) {\n var a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a12 = a[6],\n a13 = a[7];\n var a23 = a[11];\n out[1] = a[4];\n out[2] = a[8];\n out[3] = a[12];\n out[4] = a01;\n out[6] = a[9];\n out[7] = a[13];\n out[8] = a02;\n out[9] = a12;\n out[11] = a[14];\n out[12] = a03;\n out[13] = a13;\n out[14] = a23;\n } else {\n out[0] = a[0];\n out[1] = a[4];\n out[2] = a[8];\n out[3] = a[12];\n out[4] = a[1];\n out[5] = a[5];\n out[6] = a[9];\n out[7] = a[13];\n out[8] = a[2];\n out[9] = a[6];\n out[10] = a[10];\n out[11] = a[14];\n out[12] = a[3];\n out[13] = a[7];\n out[14] = a[11];\n out[15] = a[15];\n }\n return out;\n}\n\n/**\n * Inverts a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4 | null} out, or null if source matrix is not invertible\n */\nexport function invert(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n var b00 = a00 * a11 - a01 * a10;\n var b01 = a00 * a12 - a02 * a10;\n var b02 = a00 * a13 - a03 * a10;\n var b03 = a01 * a12 - a02 * a11;\n var b04 = a01 * a13 - a03 * a11;\n var b05 = a02 * a13 - a03 * a12;\n var b06 = a20 * a31 - a21 * a30;\n var b07 = a20 * a32 - a22 * a30;\n var b08 = a20 * a33 - a23 * a30;\n var b09 = a21 * a32 - a22 * a31;\n var b10 = a21 * a33 - a23 * a31;\n var b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n return out;\n}\n\n/**\n * Calculates the adjugate of a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\nexport function adjoint(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n var b00 = a00 * a11 - a01 * a10;\n var b01 = a00 * a12 - a02 * a10;\n var b02 = a00 * a13 - a03 * a10;\n var b03 = a01 * a12 - a02 * a11;\n var b04 = a01 * a13 - a03 * a11;\n var b05 = a02 * a13 - a03 * a12;\n var b06 = a20 * a31 - a21 * a30;\n var b07 = a20 * a32 - a22 * a30;\n var b08 = a20 * a33 - a23 * a30;\n var b09 = a21 * a32 - a22 * a31;\n var b10 = a21 * a33 - a23 * a31;\n var b11 = a22 * a33 - a23 * a32;\n out[0] = a11 * b11 - a12 * b10 + a13 * b09;\n out[1] = a02 * b10 - a01 * b11 - a03 * b09;\n out[2] = a31 * b05 - a32 * b04 + a33 * b03;\n out[3] = a22 * b04 - a21 * b05 - a23 * b03;\n out[4] = a12 * b08 - a10 * b11 - a13 * b07;\n out[5] = a00 * b11 - a02 * b08 + a03 * b07;\n out[6] = a32 * b02 - a30 * b05 - a33 * b01;\n out[7] = a20 * b05 - a22 * b02 + a23 * b01;\n out[8] = a10 * b10 - a11 * b08 + a13 * b06;\n out[9] = a01 * b08 - a00 * b10 - a03 * b06;\n out[10] = a30 * b04 - a31 * b02 + a33 * b00;\n out[11] = a21 * b02 - a20 * b04 - a23 * b00;\n out[12] = a11 * b07 - a10 * b09 - a12 * b06;\n out[13] = a00 * b09 - a01 * b07 + a02 * b06;\n out[14] = a31 * b01 - a30 * b03 - a32 * b00;\n out[15] = a20 * b03 - a21 * b01 + a22 * b00;\n return out;\n}\n\n/**\n * Calculates the determinant of a mat4\n *\n * @param {ReadonlyMat4} a the source matrix\n * @returns {Number} determinant of a\n */\nexport function determinant(a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n var b0 = a00 * a11 - a01 * a10;\n var b1 = a00 * a12 - a02 * a10;\n var b2 = a01 * a12 - a02 * a11;\n var b3 = a20 * a31 - a21 * a30;\n var b4 = a20 * a32 - a22 * a30;\n var b5 = a21 * a32 - a22 * a31;\n var b6 = a00 * b5 - a01 * b4 + a02 * b3;\n var b7 = a10 * b5 - a11 * b4 + a12 * b3;\n var b8 = a20 * b2 - a21 * b1 + a22 * b0;\n var b9 = a30 * b2 - a31 * b1 + a32 * b0;\n\n // Calculate the determinant\n return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9;\n}\n\n/**\n * Multiplies two mat4s\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\nexport function multiply(out, a, b) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n\n // Cache only the current line of the second matrix\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3];\n out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n b0 = b[4];\n b1 = b[5];\n b2 = b[6];\n b3 = b[7];\n out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n b0 = b[8];\n b1 = b[9];\n b2 = b[10];\n b3 = b[11];\n out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n b0 = b[12];\n b1 = b[13];\n b2 = b[14];\n b3 = b[15];\n out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n return out;\n}\n\n/**\n * Translate a mat4 by the given vector\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to translate\n * @param {ReadonlyVec3} v vector to translate by\n * @returns {mat4} out\n */\nexport function translate(out, a, v) {\n var x = v[0],\n y = v[1],\n z = v[2];\n var a00, a01, a02, a03;\n var a10, a11, a12, a13;\n var a20, a21, a22, a23;\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0];\n a01 = a[1];\n a02 = a[2];\n a03 = a[3];\n a10 = a[4];\n a11 = a[5];\n a12 = a[6];\n a13 = a[7];\n a20 = a[8];\n a21 = a[9];\n a22 = a[10];\n a23 = a[11];\n out[0] = a00;\n out[1] = a01;\n out[2] = a02;\n out[3] = a03;\n out[4] = a10;\n out[5] = a11;\n out[6] = a12;\n out[7] = a13;\n out[8] = a20;\n out[9] = a21;\n out[10] = a22;\n out[11] = a23;\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n return out;\n}\n\n/**\n * Scales the mat4 by the dimensions in the given vec3 not using vectorization\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to scale\n * @param {ReadonlyVec3} v the vec3 to scale the matrix by\n * @returns {mat4} out\n **/\nexport function scale(out, a, v) {\n var x = v[0],\n y = v[1],\n z = v[2];\n out[0] = a[0] * x;\n out[1] = a[1] * x;\n out[2] = a[2] * x;\n out[3] = a[3] * x;\n out[4] = a[4] * y;\n out[5] = a[5] * y;\n out[6] = a[6] * y;\n out[7] = a[7] * y;\n out[8] = a[8] * z;\n out[9] = a[9] * z;\n out[10] = a[10] * z;\n out[11] = a[11] * z;\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n return out;\n}\n\n/**\n * Rotates a mat4 by the given angle around the given axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @param {ReadonlyVec3} axis the axis to rotate around\n * @returns {mat4} out\n */\nexport function rotate(out, a, rad, axis) {\n var x = axis[0],\n y = axis[1],\n z = axis[2];\n var len = Math.sqrt(x * x + y * y + z * z);\n var s, c, t;\n var a00, a01, a02, a03;\n var a10, a11, a12, a13;\n var a20, a21, a22, a23;\n var b00, b01, b02;\n var b10, b11, b12;\n var b20, b21, b22;\n if (len < glMatrix.EPSILON) {\n return null;\n }\n len = 1 / len;\n x *= len;\n y *= len;\n z *= len;\n s = Math.sin(rad);\n c = Math.cos(rad);\n t = 1 - c;\n a00 = a[0];\n a01 = a[1];\n a02 = a[2];\n a03 = a[3];\n a10 = a[4];\n a11 = a[5];\n a12 = a[6];\n a13 = a[7];\n a20 = a[8];\n a21 = a[9];\n a22 = a[10];\n a23 = a[11];\n\n // Construct the elements of the rotation matrix\n b00 = x * x * t + c;\n b01 = y * x * t + z * s;\n b02 = z * x * t - y * s;\n b10 = x * y * t - z * s;\n b11 = y * y * t + c;\n b12 = z * y * t + x * s;\n b20 = x * z * t + y * s;\n b21 = y * z * t - x * s;\n b22 = z * z * t + c;\n\n // Perform rotation-specific matrix multiplication\n out[0] = a00 * b00 + a10 * b01 + a20 * b02;\n out[1] = a01 * b00 + a11 * b01 + a21 * b02;\n out[2] = a02 * b00 + a12 * b01 + a22 * b02;\n out[3] = a03 * b00 + a13 * b01 + a23 * b02;\n out[4] = a00 * b10 + a10 * b11 + a20 * b12;\n out[5] = a01 * b10 + a11 * b11 + a21 * b12;\n out[6] = a02 * b10 + a12 * b11 + a22 * b12;\n out[7] = a03 * b10 + a13 * b11 + a23 * b12;\n out[8] = a00 * b20 + a10 * b21 + a20 * b22;\n out[9] = a01 * b20 + a11 * b21 + a21 * b22;\n out[10] = a02 * b20 + a12 * b21 + a22 * b22;\n out[11] = a03 * b20 + a13 * b21 + a23 * b22;\n if (a !== out) {\n // If the source and destination differ, copy the unchanged last row\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n }\n return out;\n}\n\n/**\n * Rotates a matrix by the given angle around the X axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function rotateX(out, a, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n var a10 = a[4];\n var a11 = a[5];\n var a12 = a[6];\n var a13 = a[7];\n var a20 = a[8];\n var a21 = a[9];\n var a22 = a[10];\n var a23 = a[11];\n if (a !== out) {\n // If the source and destination differ, copy the unchanged rows\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n }\n\n // Perform axis-specific matrix multiplication\n out[4] = a10 * c + a20 * s;\n out[5] = a11 * c + a21 * s;\n out[6] = a12 * c + a22 * s;\n out[7] = a13 * c + a23 * s;\n out[8] = a20 * c - a10 * s;\n out[9] = a21 * c - a11 * s;\n out[10] = a22 * c - a12 * s;\n out[11] = a23 * c - a13 * s;\n return out;\n}\n\n/**\n * Rotates a matrix by the given angle around the Y axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function rotateY(out, a, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n var a00 = a[0];\n var a01 = a[1];\n var a02 = a[2];\n var a03 = a[3];\n var a20 = a[8];\n var a21 = a[9];\n var a22 = a[10];\n var a23 = a[11];\n if (a !== out) {\n // If the source and destination differ, copy the unchanged rows\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n }\n\n // Perform axis-specific matrix multiplication\n out[0] = a00 * c - a20 * s;\n out[1] = a01 * c - a21 * s;\n out[2] = a02 * c - a22 * s;\n out[3] = a03 * c - a23 * s;\n out[8] = a00 * s + a20 * c;\n out[9] = a01 * s + a21 * c;\n out[10] = a02 * s + a22 * c;\n out[11] = a03 * s + a23 * c;\n return out;\n}\n\n/**\n * Rotates a matrix by the given angle around the Z axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function rotateZ(out, a, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n var a00 = a[0];\n var a01 = a[1];\n var a02 = a[2];\n var a03 = a[3];\n var a10 = a[4];\n var a11 = a[5];\n var a12 = a[6];\n var a13 = a[7];\n if (a !== out) {\n // If the source and destination differ, copy the unchanged last row\n out[8] = a[8];\n out[9] = a[9];\n out[10] = a[10];\n out[11] = a[11];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n }\n\n // Perform axis-specific matrix multiplication\n out[0] = a00 * c + a10 * s;\n out[1] = a01 * c + a11 * s;\n out[2] = a02 * c + a12 * s;\n out[3] = a03 * c + a13 * s;\n out[4] = a10 * c - a00 * s;\n out[5] = a11 * c - a01 * s;\n out[6] = a12 * c - a02 * s;\n out[7] = a13 * c - a03 * s;\n return out;\n}\n\n/**\n * Creates a matrix from a vector translation\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, dest, vec);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyVec3} v Translation vector\n * @returns {mat4} out\n */\nexport function fromTranslation(out, v) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = 1;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from a vector scaling\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.scale(dest, dest, vec);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyVec3} v Scaling vector\n * @returns {mat4} out\n */\nexport function fromScaling(out, v) {\n out[0] = v[0];\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = v[1];\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = v[2];\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from a given angle around a given axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotate(dest, dest, rad, axis);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @param {ReadonlyVec3} axis the axis to rotate around\n * @returns {mat4} out\n */\nexport function fromRotation(out, rad, axis) {\n var x = axis[0],\n y = axis[1],\n z = axis[2];\n var len = Math.sqrt(x * x + y * y + z * z);\n var s, c, t;\n if (len < glMatrix.EPSILON) {\n return null;\n }\n len = 1 / len;\n x *= len;\n y *= len;\n z *= len;\n s = Math.sin(rad);\n c = Math.cos(rad);\n t = 1 - c;\n\n // Perform rotation-specific matrix multiplication\n out[0] = x * x * t + c;\n out[1] = y * x * t + z * s;\n out[2] = z * x * t - y * s;\n out[3] = 0;\n out[4] = x * y * t - z * s;\n out[5] = y * y * t + c;\n out[6] = z * y * t + x * s;\n out[7] = 0;\n out[8] = x * z * t + y * s;\n out[9] = y * z * t - x * s;\n out[10] = z * z * t + c;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from the given angle around the X axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotateX(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function fromXRotation(out, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n\n // Perform axis-specific matrix multiplication\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = c;\n out[6] = s;\n out[7] = 0;\n out[8] = 0;\n out[9] = -s;\n out[10] = c;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from the given angle around the Y axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotateY(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function fromYRotation(out, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n\n // Perform axis-specific matrix multiplication\n out[0] = c;\n out[1] = 0;\n out[2] = -s;\n out[3] = 0;\n out[4] = 0;\n out[5] = 1;\n out[6] = 0;\n out[7] = 0;\n out[8] = s;\n out[9] = 0;\n out[10] = c;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from the given angle around the Z axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotateZ(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function fromZRotation(out, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n\n // Perform axis-specific matrix multiplication\n out[0] = c;\n out[1] = s;\n out[2] = 0;\n out[3] = 0;\n out[4] = -s;\n out[5] = c;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from a quaternion rotation and vector translation\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, dest, vec);\n * let quatMat = mat4.create();\n * mat4.fromQuat(quatMat, quat);\n * mat4.multiply(dest, dest, quatMat);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @returns {mat4} out\n */\nexport function fromRotationTranslation(out, q, v) {\n // Quaternion math\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var xy = x * y2;\n var xz = x * z2;\n var yy = y * y2;\n var yz = y * z2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a new mat4 from a dual quat.\n *\n * @param {mat4} out Matrix\n * @param {ReadonlyQuat2} a Dual Quaternion\n * @returns {mat4} mat4 receiving operation result\n */\nexport function fromQuat2(out, a) {\n var translation = new glMatrix.ARRAY_TYPE(3);\n var bx = -a[0],\n by = -a[1],\n bz = -a[2],\n bw = a[3],\n ax = a[4],\n ay = a[5],\n az = a[6],\n aw = a[7];\n var magnitude = bx * bx + by * by + bz * bz + bw * bw;\n //Only scale if it makes sense\n if (magnitude > 0) {\n translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;\n translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;\n translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude;\n } else {\n translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;\n translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;\n translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;\n }\n fromRotationTranslation(out, a, translation);\n return out;\n}\n\n/**\n * Returns the translation vector component of a transformation\n * matrix. If a matrix is built with fromRotationTranslation,\n * the returned vector will be the same as the translation vector\n * originally supplied.\n * @param {vec3} out Vector to receive translation component\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\nexport function getTranslation(out, mat) {\n out[0] = mat[12];\n out[1] = mat[13];\n out[2] = mat[14];\n return out;\n}\n\n/**\n * Returns the scaling factor component of a transformation\n * matrix. If a matrix is built with fromRotationTranslationScale\n * with a normalized Quaternion parameter, the returned vector will be\n * the same as the scaling vector\n * originally supplied.\n * @param {vec3} out Vector to receive scaling factor component\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\nexport function getScaling(out, mat) {\n var m11 = mat[0];\n var m12 = mat[1];\n var m13 = mat[2];\n var m21 = mat[4];\n var m22 = mat[5];\n var m23 = mat[6];\n var m31 = mat[8];\n var m32 = mat[9];\n var m33 = mat[10];\n out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);\n out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);\n out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);\n return out;\n}\n\n/**\n * Returns a quaternion representing the rotational component\n * of a transformation matrix. If a matrix is built with\n * fromRotationTranslation, the returned quaternion will be the\n * same as the quaternion originally supplied.\n * @param {quat} out Quaternion to receive the rotation component\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {quat} out\n */\nexport function getRotation(out, mat) {\n var scaling = new glMatrix.ARRAY_TYPE(3);\n getScaling(scaling, mat);\n var is1 = 1 / scaling[0];\n var is2 = 1 / scaling[1];\n var is3 = 1 / scaling[2];\n var sm11 = mat[0] * is1;\n var sm12 = mat[1] * is2;\n var sm13 = mat[2] * is3;\n var sm21 = mat[4] * is1;\n var sm22 = mat[5] * is2;\n var sm23 = mat[6] * is3;\n var sm31 = mat[8] * is1;\n var sm32 = mat[9] * is2;\n var sm33 = mat[10] * is3;\n var trace = sm11 + sm22 + sm33;\n var S = 0;\n if (trace > 0) {\n S = Math.sqrt(trace + 1.0) * 2;\n out[3] = 0.25 * S;\n out[0] = (sm23 - sm32) / S;\n out[1] = (sm31 - sm13) / S;\n out[2] = (sm12 - sm21) / S;\n } else if (sm11 > sm22 && sm11 > sm33) {\n S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;\n out[3] = (sm23 - sm32) / S;\n out[0] = 0.25 * S;\n out[1] = (sm12 + sm21) / S;\n out[2] = (sm31 + sm13) / S;\n } else if (sm22 > sm33) {\n S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;\n out[3] = (sm31 - sm13) / S;\n out[0] = (sm12 + sm21) / S;\n out[1] = 0.25 * S;\n out[2] = (sm23 + sm32) / S;\n } else {\n S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;\n out[3] = (sm12 - sm21) / S;\n out[0] = (sm31 + sm13) / S;\n out[1] = (sm23 + sm32) / S;\n out[2] = 0.25 * S;\n }\n return out;\n}\n\n/**\n * Decomposes a transformation matrix into its rotation, translation\n * and scale components. Returns only the rotation component\n * @param {quat} out_r Quaternion to receive the rotation component\n * @param {vec3} out_t Vector to receive the translation vector\n * @param {vec3} out_s Vector to receive the scaling factor\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @returns {quat} out_r\n */\nexport function decompose(out_r, out_t, out_s, mat) {\n out_t[0] = mat[12];\n out_t[1] = mat[13];\n out_t[2] = mat[14];\n var m11 = mat[0];\n var m12 = mat[1];\n var m13 = mat[2];\n var m21 = mat[4];\n var m22 = mat[5];\n var m23 = mat[6];\n var m31 = mat[8];\n var m32 = mat[9];\n var m33 = mat[10];\n out_s[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);\n out_s[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);\n out_s[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);\n var is1 = 1 / out_s[0];\n var is2 = 1 / out_s[1];\n var is3 = 1 / out_s[2];\n var sm11 = m11 * is1;\n var sm12 = m12 * is2;\n var sm13 = m13 * is3;\n var sm21 = m21 * is1;\n var sm22 = m22 * is2;\n var sm23 = m23 * is3;\n var sm31 = m31 * is1;\n var sm32 = m32 * is2;\n var sm33 = m33 * is3;\n var trace = sm11 + sm22 + sm33;\n var S = 0;\n if (trace > 0) {\n S = Math.sqrt(trace + 1.0) * 2;\n out_r[3] = 0.25 * S;\n out_r[0] = (sm23 - sm32) / S;\n out_r[1] = (sm31 - sm13) / S;\n out_r[2] = (sm12 - sm21) / S;\n } else if (sm11 > sm22 && sm11 > sm33) {\n S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;\n out_r[3] = (sm23 - sm32) / S;\n out_r[0] = 0.25 * S;\n out_r[1] = (sm12 + sm21) / S;\n out_r[2] = (sm31 + sm13) / S;\n } else if (sm22 > sm33) {\n S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;\n out_r[3] = (sm31 - sm13) / S;\n out_r[0] = (sm12 + sm21) / S;\n out_r[1] = 0.25 * S;\n out_r[2] = (sm23 + sm32) / S;\n } else {\n S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;\n out_r[3] = (sm12 - sm21) / S;\n out_r[0] = (sm31 + sm13) / S;\n out_r[1] = (sm23 + sm32) / S;\n out_r[2] = 0.25 * S;\n }\n return out_r;\n}\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation and vector scale\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, dest, vec);\n * let quatMat = mat4.create();\n * mat4.fromQuat(quatMat, quat);\n * mat4.multiply(dest, dest, quatMat);\n * mat4.scale(dest, dest, scale)\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @param {ReadonlyVec3} s Scaling vector\n * @returns {mat4} out\n */\nexport function fromRotationTranslationScale(out, q, v, s) {\n // Quaternion math\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var xy = x * y2;\n var xz = x * z2;\n var yy = y * y2;\n var yz = y * z2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n var sx = s[0];\n var sy = s[1];\n var sz = s[2];\n out[0] = (1 - (yy + zz)) * sx;\n out[1] = (xy + wz) * sx;\n out[2] = (xz - wy) * sx;\n out[3] = 0;\n out[4] = (xy - wz) * sy;\n out[5] = (1 - (xx + zz)) * sy;\n out[6] = (yz + wx) * sy;\n out[7] = 0;\n out[8] = (xz + wy) * sz;\n out[9] = (yz - wx) * sz;\n out[10] = (1 - (xx + yy)) * sz;\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n return out;\n}\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, dest, vec);\n * mat4.translate(dest, dest, origin);\n * let quatMat = mat4.create();\n * mat4.fromQuat(quatMat, quat);\n * mat4.multiply(dest, dest, quatMat);\n * mat4.scale(dest, dest, scale)\n * mat4.translate(dest, dest, negativeOrigin);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @param {ReadonlyVec3} s Scaling vector\n * @param {ReadonlyVec3} o The origin vector around which to scale and rotate\n * @returns {mat4} out\n */\nexport function fromRotationTranslationScaleOrigin(out, q, v, s, o) {\n // Quaternion math\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var xy = x * y2;\n var xz = x * z2;\n var yy = y * y2;\n var yz = y * z2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n var sx = s[0];\n var sy = s[1];\n var sz = s[2];\n var ox = o[0];\n var oy = o[1];\n var oz = o[2];\n var out0 = (1 - (yy + zz)) * sx;\n var out1 = (xy + wz) * sx;\n var out2 = (xz - wy) * sx;\n var out4 = (xy - wz) * sy;\n var out5 = (1 - (xx + zz)) * sy;\n var out6 = (yz + wx) * sy;\n var out8 = (xz + wy) * sz;\n var out9 = (yz - wx) * sz;\n var out10 = (1 - (xx + yy)) * sz;\n out[0] = out0;\n out[1] = out1;\n out[2] = out2;\n out[3] = 0;\n out[4] = out4;\n out[5] = out5;\n out[6] = out6;\n out[7] = 0;\n out[8] = out8;\n out[9] = out9;\n out[10] = out10;\n out[11] = 0;\n out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);\n out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);\n out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);\n out[15] = 1;\n return out;\n}\n\n/**\n * Calculates a 4x4 matrix from the given quaternion\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyQuat} q Quaternion to create matrix from\n *\n * @returns {mat4} out\n */\nexport function fromQuat(out, q) {\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var yx = y * x2;\n var yy = y * y2;\n var zx = z * x2;\n var zy = z * y2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n out[0] = 1 - yy - zz;\n out[1] = yx + wz;\n out[2] = zx - wy;\n out[3] = 0;\n out[4] = yx - wz;\n out[5] = 1 - xx - zz;\n out[6] = zy + wx;\n out[7] = 0;\n out[8] = zx + wy;\n out[9] = zy - wx;\n out[10] = 1 - xx - yy;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n\n/**\n * Generates a frustum matrix with the given bounds\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {Number} left Left bound of the frustum\n * @param {Number} right Right bound of the frustum\n * @param {Number} bottom Bottom bound of the frustum\n * @param {Number} top Top bound of the frustum\n * @param {Number} near Near bound of the frustum\n * @param {Number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function frustum(out, left, right, bottom, top, near, far) {\n var rl = 1 / (right - left);\n var tb = 1 / (top - bottom);\n var nf = 1 / (near - far);\n out[0] = near * 2 * rl;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = near * 2 * tb;\n out[6] = 0;\n out[7] = 0;\n out[8] = (right + left) * rl;\n out[9] = (top + bottom) * tb;\n out[10] = (far + near) * nf;\n out[11] = -1;\n out[12] = 0;\n out[13] = 0;\n out[14] = far * near * 2 * nf;\n out[15] = 0;\n return out;\n}\n\n/**\n * Generates a perspective projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],\n * which matches WebGL/OpenGL's clip volume.\n * Passing null/undefined/no value for far will generate infinite projection matrix.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} fovy Vertical field of view in radians\n * @param {number} aspect Aspect ratio. typically viewport width/height\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum, can be null or Infinity\n * @returns {mat4} out\n */\nexport function perspectiveNO(out, fovy, aspect, near, far) {\n var f = 1.0 / Math.tan(fovy / 2);\n out[0] = f / aspect;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = f;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[11] = -1;\n out[12] = 0;\n out[13] = 0;\n out[15] = 0;\n if (far != null && far !== Infinity) {\n var nf = 1 / (near - far);\n out[10] = (far + near) * nf;\n out[14] = 2 * far * near * nf;\n } else {\n out[10] = -1;\n out[14] = -2 * near;\n }\n return out;\n}\n\n/**\n * Alias for {@link mat4.perspectiveNO}\n * @function\n */\nexport var perspective = perspectiveNO;\n\n/**\n * Generates a perspective projection matrix suitable for WebGPU with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],\n * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.\n * Passing null/undefined/no value for far will generate infinite projection matrix.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} fovy Vertical field of view in radians\n * @param {number} aspect Aspect ratio. typically viewport width/height\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum, can be null or Infinity\n * @returns {mat4} out\n */\nexport function perspectiveZO(out, fovy, aspect, near, far) {\n var f = 1.0 / Math.tan(fovy / 2);\n out[0] = f / aspect;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = f;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[11] = -1;\n out[12] = 0;\n out[13] = 0;\n out[15] = 0;\n if (far != null && far !== Infinity) {\n var nf = 1 / (near - far);\n out[10] = far * nf;\n out[14] = far * near * nf;\n } else {\n out[10] = -1;\n out[14] = -near;\n }\n return out;\n}\n\n/**\n * Generates a perspective projection matrix with the given field of view.\n * This is primarily useful for generating projection matrices to be used\n * with the still experiemental WebVR API.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function perspectiveFromFieldOfView(out, fov, near, far) {\n var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);\n var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);\n var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);\n var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);\n var xScale = 2.0 / (leftTan + rightTan);\n var yScale = 2.0 / (upTan + downTan);\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = (upTan - downTan) * yScale * 0.5;\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = far * near / (near - far);\n out[15] = 0.0;\n return out;\n}\n\n/**\n * Generates a orthogonal projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],\n * which matches WebGL/OpenGL's clip volume.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} left Left bound of the frustum\n * @param {number} right Right bound of the frustum\n * @param {number} bottom Bottom bound of the frustum\n * @param {number} top Top bound of the frustum\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function orthoNO(out, left, right, bottom, top, near, far) {\n var lr = 1 / (left - right);\n var bt = 1 / (bottom - top);\n var nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n}\n\n/**\n * Alias for {@link mat4.orthoNO}\n * @function\n */\nexport var ortho = orthoNO;\n\n/**\n * Generates a orthogonal projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],\n * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} left Left bound of the frustum\n * @param {number} right Right bound of the frustum\n * @param {number} bottom Bottom bound of the frustum\n * @param {number} top Top bound of the frustum\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function orthoZO(out, left, right, bottom, top, near, far) {\n var lr = 1 / (left - right);\n var bt = 1 / (bottom - top);\n var nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = near * nf;\n out[15] = 1;\n return out;\n}\n\n/**\n * Generates a look-at matrix with the given eye position, focal point, and up axis.\n * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {ReadonlyVec3} eye Position of the viewer\n * @param {ReadonlyVec3} center Point the viewer is looking at\n * @param {ReadonlyVec3} up vec3 pointing up\n * @returns {mat4} out\n */\nexport function lookAt(out, eye, center, up) {\n var x0, x1, x2, y0, y1, y2, z0, z1, z2, len;\n var eyex = eye[0];\n var eyey = eye[1];\n var eyez = eye[2];\n var upx = up[0];\n var upy = up[1];\n var upz = up[2];\n var centerx = center[0];\n var centery = center[1];\n var centerz = center[2];\n if (Math.abs(eyex - centerx) < glMatrix.EPSILON && Math.abs(eyey - centery) < glMatrix.EPSILON && Math.abs(eyez - centerz) < glMatrix.EPSILON) {\n return identity(out);\n }\n z0 = eyex - centerx;\n z1 = eyey - centery;\n z2 = eyez - centerz;\n len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n x0 = upy * z2 - upz * z1;\n x1 = upz * z0 - upx * z2;\n x2 = upx * z1 - upy * z0;\n len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);\n if (!len) {\n x0 = 0;\n x1 = 0;\n x2 = 0;\n } else {\n len = 1 / len;\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n y0 = z1 * x2 - z2 * x1;\n y1 = z2 * x0 - z0 * x2;\n y2 = z0 * x1 - z1 * x0;\n len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);\n if (!len) {\n y0 = 0;\n y1 = 0;\n y2 = 0;\n } else {\n len = 1 / len;\n y0 *= len;\n y1 *= len;\n y2 *= len;\n }\n out[0] = x0;\n out[1] = y0;\n out[2] = z0;\n out[3] = 0;\n out[4] = x1;\n out[5] = y1;\n out[6] = z1;\n out[7] = 0;\n out[8] = x2;\n out[9] = y2;\n out[10] = z2;\n out[11] = 0;\n out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);\n out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);\n out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);\n out[15] = 1;\n return out;\n}\n\n/**\n * Generates a matrix that makes something look at something else.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {ReadonlyVec3} eye Position of the viewer\n * @param {ReadonlyVec3} target Point the viewer is looking at\n * @param {ReadonlyVec3} up vec3 pointing up\n * @returns {mat4} out\n */\nexport function targetTo(out, eye, target, up) {\n var eyex = eye[0],\n eyey = eye[1],\n eyez = eye[2],\n upx = up[0],\n upy = up[1],\n upz = up[2];\n var z0 = eyex - target[0],\n z1 = eyey - target[1],\n z2 = eyez - target[2];\n var len = z0 * z0 + z1 * z1 + z2 * z2;\n if (len > 0) {\n len = 1 / Math.sqrt(len);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n }\n var x0 = upy * z2 - upz * z1,\n x1 = upz * z0 - upx * z2,\n x2 = upx * z1 - upy * z0;\n len = x0 * x0 + x1 * x1 + x2 * x2;\n if (len > 0) {\n len = 1 / Math.sqrt(len);\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n out[0] = x0;\n out[1] = x1;\n out[2] = x2;\n out[3] = 0;\n out[4] = z1 * x2 - z2 * x1;\n out[5] = z2 * x0 - z0 * x2;\n out[6] = z0 * x1 - z1 * x0;\n out[7] = 0;\n out[8] = z0;\n out[9] = z1;\n out[10] = z2;\n out[11] = 0;\n out[12] = eyex;\n out[13] = eyey;\n out[14] = eyez;\n out[15] = 1;\n return out;\n}\n\n/**\n * Returns a string representation of a mat4\n *\n * @param {ReadonlyMat4} a matrix to represent as a string\n * @returns {String} string representation of the matrix\n */\nexport function str(a) {\n return \"mat4(\" + a[0] + \", \" + a[1] + \", \" + a[2] + \", \" + a[3] + \", \" + a[4] + \", \" + a[5] + \", \" + a[6] + \", \" + a[7] + \", \" + a[8] + \", \" + a[9] + \", \" + a[10] + \", \" + a[11] + \", \" + a[12] + \", \" + a[13] + \", \" + a[14] + \", \" + a[15] + \")\";\n}\n\n/**\n * Returns Frobenius norm of a mat4\n *\n * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of\n * @returns {Number} Frobenius norm\n */\nexport function frob(a) {\n return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3] + a[4] * a[4] + a[5] * a[5] + a[6] * a[6] + a[7] * a[7] + a[8] * a[8] + a[9] * a[9] + a[10] * a[10] + a[11] * a[11] + a[12] * a[12] + a[13] * a[13] + a[14] * a[14] + a[15] * a[15]);\n}\n\n/**\n * Adds two mat4's\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\nexport function add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n out[3] = a[3] + b[3];\n out[4] = a[4] + b[4];\n out[5] = a[5] + b[5];\n out[6] = a[6] + b[6];\n out[7] = a[7] + b[7];\n out[8] = a[8] + b[8];\n out[9] = a[9] + b[9];\n out[10] = a[10] + b[10];\n out[11] = a[11] + b[11];\n out[12] = a[12] + b[12];\n out[13] = a[13] + b[13];\n out[14] = a[14] + b[14];\n out[15] = a[15] + b[15];\n return out;\n}\n\n/**\n * Subtracts matrix b from matrix a\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\nexport function subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n out[3] = a[3] - b[3];\n out[4] = a[4] - b[4];\n out[5] = a[5] - b[5];\n out[6] = a[6] - b[6];\n out[7] = a[7] - b[7];\n out[8] = a[8] - b[8];\n out[9] = a[9] - b[9];\n out[10] = a[10] - b[10];\n out[11] = a[11] - b[11];\n out[12] = a[12] - b[12];\n out[13] = a[13] - b[13];\n out[14] = a[14] - b[14];\n out[15] = a[15] - b[15];\n return out;\n}\n\n/**\n * Multiply each element of the matrix by a scalar.\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to scale\n * @param {Number} b amount to scale the matrix's elements by\n * @returns {mat4} out\n */\nexport function multiplyScalar(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n out[3] = a[3] * b;\n out[4] = a[4] * b;\n out[5] = a[5] * b;\n out[6] = a[6] * b;\n out[7] = a[7] * b;\n out[8] = a[8] * b;\n out[9] = a[9] * b;\n out[10] = a[10] * b;\n out[11] = a[11] * b;\n out[12] = a[12] * b;\n out[13] = a[13] * b;\n out[14] = a[14] * b;\n out[15] = a[15] * b;\n return out;\n}\n\n/**\n * Adds two mat4's after multiplying each element of the second operand by a scalar value.\n *\n * @param {mat4} out the receiving vector\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @param {Number} scale the amount to scale b's elements by before adding\n * @returns {mat4} out\n */\nexport function multiplyScalarAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n out[3] = a[3] + b[3] * scale;\n out[4] = a[4] + b[4] * scale;\n out[5] = a[5] + b[5] * scale;\n out[6] = a[6] + b[6] * scale;\n out[7] = a[7] + b[7] * scale;\n out[8] = a[8] + b[8] * scale;\n out[9] = a[9] + b[9] * scale;\n out[10] = a[10] + b[10] * scale;\n out[11] = a[11] + b[11] * scale;\n out[12] = a[12] + b[12] * scale;\n out[13] = a[13] + b[13] * scale;\n out[14] = a[14] + b[14] * scale;\n out[15] = a[15] + b[15] * scale;\n return out;\n}\n\n/**\n * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyMat4} a The first matrix.\n * @param {ReadonlyMat4} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];\n}\n\n/**\n * Returns whether or not the matrices have approximately the same elements in the same position.\n *\n * @param {ReadonlyMat4} a The first matrix.\n * @param {ReadonlyMat4} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\nexport function equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3];\n var a4 = a[4],\n a5 = a[5],\n a6 = a[6],\n a7 = a[7];\n var a8 = a[8],\n a9 = a[9],\n a10 = a[10],\n a11 = a[11];\n var a12 = a[12],\n a13 = a[13],\n a14 = a[14],\n a15 = a[15];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3];\n var b4 = b[4],\n b5 = b[5],\n b6 = b[6],\n b7 = b[7];\n var b8 = b[8],\n b9 = b[9],\n b10 = b[10],\n b11 = b[11];\n var b12 = b[12],\n b13 = b[13],\n b14 = b[14],\n b15 = b[15];\n return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15));\n}\n\n/**\n * Alias for {@link mat4.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Alias for {@link mat4.subtract}\n * @function\n */\nexport var sub = subtract;","import * as glMatrix from \"./common.js\";\n\n/**\n * 3 Dimensional Vector\n * @module vec3\n */\n\n/**\n * Creates a new, empty vec3\n *\n * @returns {vec3} a new 3D vector\n */\nexport function create() {\n var out = new glMatrix.ARRAY_TYPE(3);\n if (glMatrix.ARRAY_TYPE != Float32Array) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n }\n return out;\n}\n\n/**\n * Creates a new vec3 initialized with values from an existing vector\n *\n * @param {ReadonlyVec3} a vector to clone\n * @returns {vec3} a new 3D vector\n */\nexport function clone(a) {\n var out = new glMatrix.ARRAY_TYPE(3);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n return out;\n}\n\n/**\n * Calculates the length of a vec3\n *\n * @param {ReadonlyVec3} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport function length(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n return Math.sqrt(x * x + y * y + z * z);\n}\n\n/**\n * Creates a new vec3 initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @returns {vec3} a new 3D vector\n */\nexport function fromValues(x, y, z) {\n var out = new glMatrix.ARRAY_TYPE(3);\n out[0] = x;\n out[1] = y;\n out[2] = z;\n return out;\n}\n\n/**\n * Copy the values from one vec3 to another\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the source vector\n * @returns {vec3} out\n */\nexport function copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n return out;\n}\n\n/**\n * Set the components of a vec3 to the given values\n *\n * @param {vec3} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @returns {vec3} out\n */\nexport function set(out, x, y, z) {\n out[0] = x;\n out[1] = y;\n out[2] = z;\n return out;\n}\n\n/**\n * Adds two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n return out;\n}\n\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n return out;\n}\n\n/**\n * Multiplies two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function multiply(out, a, b) {\n out[0] = a[0] * b[0];\n out[1] = a[1] * b[1];\n out[2] = a[2] * b[2];\n return out;\n}\n\n/**\n * Divides two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function divide(out, a, b) {\n out[0] = a[0] / b[0];\n out[1] = a[1] / b[1];\n out[2] = a[2] / b[2];\n return out;\n}\n\n/**\n * Math.ceil the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to ceil\n * @returns {vec3} out\n */\nexport function ceil(out, a) {\n out[0] = Math.ceil(a[0]);\n out[1] = Math.ceil(a[1]);\n out[2] = Math.ceil(a[2]);\n return out;\n}\n\n/**\n * Math.floor the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to floor\n * @returns {vec3} out\n */\nexport function floor(out, a) {\n out[0] = Math.floor(a[0]);\n out[1] = Math.floor(a[1]);\n out[2] = Math.floor(a[2]);\n return out;\n}\n\n/**\n * Returns the minimum of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function min(out, a, b) {\n out[0] = Math.min(a[0], b[0]);\n out[1] = Math.min(a[1], b[1]);\n out[2] = Math.min(a[2], b[2]);\n return out;\n}\n\n/**\n * Returns the maximum of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function max(out, a, b) {\n out[0] = Math.max(a[0], b[0]);\n out[1] = Math.max(a[1], b[1]);\n out[2] = Math.max(a[2], b[2]);\n return out;\n}\n\n/**\n * symmetric round the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to round\n * @returns {vec3} out\n */\nexport function round(out, a) {\n out[0] = glMatrix.round(a[0]);\n out[1] = glMatrix.round(a[1]);\n out[2] = glMatrix.round(a[2]);\n return out;\n}\n\n/**\n * Scales a vec3 by a scalar number\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec3} out\n */\nexport function scale(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n return out;\n}\n\n/**\n * Adds two vec3's after scaling the second operand by a scalar value\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} scale the amount to scale b by before adding\n * @returns {vec3} out\n */\nexport function scaleAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n return out;\n}\n\n/**\n * Calculates the euclidian distance between two vec3's\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} distance between a and b\n */\nexport function distance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n return Math.sqrt(x * x + y * y + z * z);\n}\n\n/**\n * Calculates the squared euclidian distance between two vec3's\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} squared distance between a and b\n */\nexport function squaredDistance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n return x * x + y * y + z * z;\n}\n\n/**\n * Calculates the squared length of a vec3\n *\n * @param {ReadonlyVec3} a vector to calculate squared length of\n * @returns {Number} squared length of a\n */\nexport function squaredLength(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n return x * x + y * y + z * z;\n}\n\n/**\n * Negates the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to negate\n * @returns {vec3} out\n */\nexport function negate(out, a) {\n out[0] = -a[0];\n out[1] = -a[1];\n out[2] = -a[2];\n return out;\n}\n\n/**\n * Returns the inverse of the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to invert\n * @returns {vec3} out\n */\nexport function inverse(out, a) {\n out[0] = 1.0 / a[0];\n out[1] = 1.0 / a[1];\n out[2] = 1.0 / a[2];\n return out;\n}\n\n/**\n * Normalize a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to normalize\n * @returns {vec3} out\n */\nexport function normalize(out, a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var len = x * x + y * y + z * z;\n if (len > 0) {\n //TODO: evaluate use of glm_invsqrt here?\n len = 1 / Math.sqrt(len);\n }\n out[0] = a[0] * len;\n out[1] = a[1] * len;\n out[2] = a[2] * len;\n return out;\n}\n\n/**\n * Calculates the dot product of two vec3's\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} dot product of a and b\n */\nexport function dot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\n/**\n * Computes the cross product of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function cross(out, a, b) {\n var ax = a[0],\n ay = a[1],\n az = a[2];\n var bx = b[0],\n by = b[1],\n bz = b[2];\n out[0] = ay * bz - az * by;\n out[1] = az * bx - ax * bz;\n out[2] = ax * by - ay * bx;\n return out;\n}\n\n/**\n * Performs a linear interpolation between two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function lerp(out, a, b, t) {\n var ax = a[0];\n var ay = a[1];\n var az = a[2];\n out[0] = ax + t * (b[0] - ax);\n out[1] = ay + t * (b[1] - ay);\n out[2] = az + t * (b[2] - az);\n return out;\n}\n\n/**\n * Performs a spherical linear interpolation between two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function slerp(out, a, b, t) {\n var angle = Math.acos(Math.min(Math.max(dot(a, b), -1), 1));\n var sinTotal = Math.sin(angle);\n var ratioA = Math.sin((1 - t) * angle) / sinTotal;\n var ratioB = Math.sin(t * angle) / sinTotal;\n out[0] = ratioA * a[0] + ratioB * b[0];\n out[1] = ratioA * a[1] + ratioB * b[1];\n out[2] = ratioA * a[2] + ratioB * b[2];\n return out;\n}\n\n/**\n * Performs a hermite interpolation with two control points\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {ReadonlyVec3} c the third operand\n * @param {ReadonlyVec3} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function hermite(out, a, b, c, d, t) {\n var factorTimes2 = t * t;\n var factor1 = factorTimes2 * (2 * t - 3) + 1;\n var factor2 = factorTimes2 * (t - 2) + t;\n var factor3 = factorTimes2 * (t - 1);\n var factor4 = factorTimes2 * (3 - 2 * t);\n out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;\n out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;\n out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;\n return out;\n}\n\n/**\n * Performs a bezier interpolation with two control points\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {ReadonlyVec3} c the third operand\n * @param {ReadonlyVec3} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function bezier(out, a, b, c, d, t) {\n var inverseFactor = 1 - t;\n var inverseFactorTimesTwo = inverseFactor * inverseFactor;\n var factorTimes2 = t * t;\n var factor1 = inverseFactorTimesTwo * inverseFactor;\n var factor2 = 3 * t * inverseFactorTimesTwo;\n var factor3 = 3 * factorTimes2 * inverseFactor;\n var factor4 = factorTimes2 * t;\n out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;\n out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;\n out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;\n return out;\n}\n\n/**\n * Generates a random vector with the given scale\n *\n * @param {vec3} out the receiving vector\n * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned\n * @returns {vec3} out\n */\nexport function random(out, scale) {\n scale = scale === undefined ? 1.0 : scale;\n var r = glMatrix.RANDOM() * 2.0 * Math.PI;\n var z = glMatrix.RANDOM() * 2.0 - 1.0;\n var zScale = Math.sqrt(1.0 - z * z) * scale;\n out[0] = Math.cos(r) * zScale;\n out[1] = Math.sin(r) * zScale;\n out[2] = z * scale;\n return out;\n}\n\n/**\n * Transforms the vec3 with a mat4.\n * 4th vector component is implicitly '1'\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat4} m matrix to transform with\n * @returns {vec3} out\n */\nexport function transformMat4(out, a, m) {\n var x = a[0],\n y = a[1],\n z = a[2];\n var w = m[3] * x + m[7] * y + m[11] * z + m[15];\n w = w || 1.0;\n out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;\n out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;\n out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;\n return out;\n}\n\n/**\n * Transforms the vec3 with a mat3.\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat3} m the 3x3 matrix to transform with\n * @returns {vec3} out\n */\nexport function transformMat3(out, a, m) {\n var x = a[0],\n y = a[1],\n z = a[2];\n out[0] = x * m[0] + y * m[3] + z * m[6];\n out[1] = x * m[1] + y * m[4] + z * m[7];\n out[2] = x * m[2] + y * m[5] + z * m[8];\n return out;\n}\n\n/**\n * Transforms the vec3 with a quat\n * Can also be used for dual quaternions. (Multiply it with the real part)\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyQuat} q normalized quaternion to transform with\n * @returns {vec3} out\n */\nexport function transformQuat(out, a, q) {\n // Fast Vector Rotation using Quaternions by Robert Eisele\n // https://raw.org/proof/vector-rotation-using-quaternions/\n\n var qx = q[0],\n qy = q[1],\n qz = q[2],\n qw = q[3];\n var vx = a[0],\n vy = a[1],\n vz = a[2];\n\n // t = q x v\n var tx = qy * vz - qz * vy;\n var ty = qz * vx - qx * vz;\n var tz = qx * vy - qy * vx;\n\n // t = 2t\n tx = tx + tx;\n ty = ty + ty;\n tz = tz + tz;\n\n // v + w t + q x t\n out[0] = vx + qw * tx + qy * tz - qz * ty;\n out[1] = vy + qw * ty + qz * tx - qx * tz;\n out[2] = vz + qw * tz + qx * ty - qy * tx;\n return out;\n}\n\n/**\n * Rotate a 3D vector around the x-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nexport function rotateX(out, a, b, rad) {\n var p = [],\n r = [];\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0];\n r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);\n r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad);\n\n //translate to correct position\n out[0] = r[0] + b[0];\n out[1] = r[1] + b[1];\n out[2] = r[2] + b[2];\n return out;\n}\n\n/**\n * Rotate a 3D vector around the y-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nexport function rotateY(out, a, b, rad) {\n var p = [],\n r = [];\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);\n r[1] = p[1];\n r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad);\n\n //translate to correct position\n out[0] = r[0] + b[0];\n out[1] = r[1] + b[1];\n out[2] = r[2] + b[2];\n return out;\n}\n\n/**\n * Rotate a 3D vector around the z-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nexport function rotateZ(out, a, b, rad) {\n var p = [],\n r = [];\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);\n r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);\n r[2] = p[2];\n\n //translate to correct position\n out[0] = r[0] + b[0];\n out[1] = r[1] + b[1];\n out[2] = r[2] + b[2];\n return out;\n}\n\n/**\n * Get the angle between two 3D vectors\n * @param {ReadonlyVec3} a The first operand\n * @param {ReadonlyVec3} b The second operand\n * @returns {Number} The angle in radians\n */\nexport function angle(a, b) {\n var ax = a[0],\n ay = a[1],\n az = a[2],\n bx = b[0],\n by = b[1],\n bz = b[2],\n mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)),\n cosine = mag && dot(a, b) / mag;\n return Math.acos(Math.min(Math.max(cosine, -1), 1));\n}\n\n/**\n * Set the components of a vec3 to zero\n *\n * @param {vec3} out the receiving vector\n * @returns {vec3} out\n */\nexport function zero(out) {\n out[0] = 0.0;\n out[1] = 0.0;\n out[2] = 0.0;\n return out;\n}\n\n/**\n * Returns a string representation of a vector\n *\n * @param {ReadonlyVec3} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\nexport function str(a) {\n return \"vec3(\" + a[0] + \", \" + a[1] + \", \" + a[2] + \")\";\n}\n\n/**\n * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyVec3} a The first vector.\n * @param {ReadonlyVec3} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];\n}\n\n/**\n * Returns whether or not the vectors have approximately the same elements in the same position.\n *\n * @param {ReadonlyVec3} a The first vector.\n * @param {ReadonlyVec3} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2];\n return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2));\n}\n\n/**\n * Alias for {@link vec3.subtract}\n * @function\n */\nexport var sub = subtract;\n\n/**\n * Alias for {@link vec3.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Alias for {@link vec3.divide}\n * @function\n */\nexport var div = divide;\n\n/**\n * Alias for {@link vec3.distance}\n * @function\n */\nexport var dist = distance;\n\n/**\n * Alias for {@link vec3.squaredDistance}\n * @function\n */\nexport var sqrDist = squaredDistance;\n\n/**\n * Alias for {@link vec3.length}\n * @function\n */\nexport var len = length;\n\n/**\n * Alias for {@link vec3.squaredLength}\n * @function\n */\nexport var sqrLen = squaredLength;\n\n/**\n * Perform some operation over an array of vec3s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\nexport var forEach = function () {\n var vec = create();\n return function (a, stride, offset, count, fn, arg) {\n var i, l;\n if (!stride) {\n stride = 3;\n }\n if (!offset) {\n offset = 0;\n }\n if (count) {\n l = Math.min(count * stride + offset, a.length);\n } else {\n l = a.length;\n }\n for (i = offset; i < l; i += stride) {\n vec[0] = a[i];\n vec[1] = a[i + 1];\n vec[2] = a[i + 2];\n fn(vec, vec, arg);\n a[i] = vec[0];\n a[i + 1] = vec[1];\n a[i + 2] = vec[2];\n }\n return a;\n };\n}();","import * as glMatrix from \"./common.js\";\n\n/**\n * 4 Dimensional Vector\n * @module vec4\n */\n\n/**\n * Creates a new, empty vec4\n *\n * @returns {vec4} a new 4D vector\n */\nexport function create() {\n var out = new glMatrix.ARRAY_TYPE(4);\n if (glMatrix.ARRAY_TYPE != Float32Array) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n }\n return out;\n}\n\n/**\n * Creates a new vec4 initialized with values from an existing vector\n *\n * @param {ReadonlyVec4} a vector to clone\n * @returns {vec4} a new 4D vector\n */\nexport function clone(a) {\n var out = new glMatrix.ARRAY_TYPE(4);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n return out;\n}\n\n/**\n * Creates a new vec4 initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {vec4} a new 4D vector\n */\nexport function fromValues(x, y, z, w) {\n var out = new glMatrix.ARRAY_TYPE(4);\n out[0] = x;\n out[1] = y;\n out[2] = z;\n out[3] = w;\n return out;\n}\n\n/**\n * Copy the values from one vec4 to another\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the source vector\n * @returns {vec4} out\n */\nexport function copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n return out;\n}\n\n/**\n * Set the components of a vec4 to the given values\n *\n * @param {vec4} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {vec4} out\n */\nexport function set(out, x, y, z, w) {\n out[0] = x;\n out[1] = y;\n out[2] = z;\n out[3] = w;\n return out;\n}\n\n/**\n * Adds two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\nexport function add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n out[3] = a[3] + b[3];\n return out;\n}\n\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\nexport function subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n out[3] = a[3] - b[3];\n return out;\n}\n\n/**\n * Multiplies two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\nexport function multiply(out, a, b) {\n out[0] = a[0] * b[0];\n out[1] = a[1] * b[1];\n out[2] = a[2] * b[2];\n out[3] = a[3] * b[3];\n return out;\n}\n\n/**\n * Divides two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\nexport function divide(out, a, b) {\n out[0] = a[0] / b[0];\n out[1] = a[1] / b[1];\n out[2] = a[2] / b[2];\n out[3] = a[3] / b[3];\n return out;\n}\n\n/**\n * Math.ceil the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to ceil\n * @returns {vec4} out\n */\nexport function ceil(out, a) {\n out[0] = Math.ceil(a[0]);\n out[1] = Math.ceil(a[1]);\n out[2] = Math.ceil(a[2]);\n out[3] = Math.ceil(a[3]);\n return out;\n}\n\n/**\n * Math.floor the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to floor\n * @returns {vec4} out\n */\nexport function floor(out, a) {\n out[0] = Math.floor(a[0]);\n out[1] = Math.floor(a[1]);\n out[2] = Math.floor(a[2]);\n out[3] = Math.floor(a[3]);\n return out;\n}\n\n/**\n * Returns the minimum of two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\nexport function min(out, a, b) {\n out[0] = Math.min(a[0], b[0]);\n out[1] = Math.min(a[1], b[1]);\n out[2] = Math.min(a[2], b[2]);\n out[3] = Math.min(a[3], b[3]);\n return out;\n}\n\n/**\n * Returns the maximum of two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\nexport function max(out, a, b) {\n out[0] = Math.max(a[0], b[0]);\n out[1] = Math.max(a[1], b[1]);\n out[2] = Math.max(a[2], b[2]);\n out[3] = Math.max(a[3], b[3]);\n return out;\n}\n\n/**\n * symmetric round the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to round\n * @returns {vec4} out\n */\nexport function round(out, a) {\n out[0] = glMatrix.round(a[0]);\n out[1] = glMatrix.round(a[1]);\n out[2] = glMatrix.round(a[2]);\n out[3] = glMatrix.round(a[3]);\n return out;\n}\n\n/**\n * Scales a vec4 by a scalar number\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec4} out\n */\nexport function scale(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n out[3] = a[3] * b;\n return out;\n}\n\n/**\n * Adds two vec4's after scaling the second operand by a scalar value\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @param {Number} scale the amount to scale b by before adding\n * @returns {vec4} out\n */\nexport function scaleAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n out[3] = a[3] + b[3] * scale;\n return out;\n}\n\n/**\n * Calculates the euclidian distance between two vec4's\n *\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {Number} distance between a and b\n */\nexport function distance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n var w = b[3] - a[3];\n return Math.sqrt(x * x + y * y + z * z + w * w);\n}\n\n/**\n * Calculates the squared euclidian distance between two vec4's\n *\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {Number} squared distance between a and b\n */\nexport function squaredDistance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n var w = b[3] - a[3];\n return x * x + y * y + z * z + w * w;\n}\n\n/**\n * Calculates the length of a vec4\n *\n * @param {ReadonlyVec4} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport function length(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var w = a[3];\n return Math.sqrt(x * x + y * y + z * z + w * w);\n}\n\n/**\n * Calculates the squared length of a vec4\n *\n * @param {ReadonlyVec4} a vector to calculate squared length of\n * @returns {Number} squared length of a\n */\nexport function squaredLength(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var w = a[3];\n return x * x + y * y + z * z + w * w;\n}\n\n/**\n * Negates the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to negate\n * @returns {vec4} out\n */\nexport function negate(out, a) {\n out[0] = -a[0];\n out[1] = -a[1];\n out[2] = -a[2];\n out[3] = -a[3];\n return out;\n}\n\n/**\n * Returns the inverse of the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to invert\n * @returns {vec4} out\n */\nexport function inverse(out, a) {\n out[0] = 1.0 / a[0];\n out[1] = 1.0 / a[1];\n out[2] = 1.0 / a[2];\n out[3] = 1.0 / a[3];\n return out;\n}\n\n/**\n * Normalize a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to normalize\n * @returns {vec4} out\n */\nexport function normalize(out, a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var w = a[3];\n var len = x * x + y * y + z * z + w * w;\n if (len > 0) {\n len = 1 / Math.sqrt(len);\n }\n out[0] = x * len;\n out[1] = y * len;\n out[2] = z * len;\n out[3] = w * len;\n return out;\n}\n\n/**\n * Calculates the dot product of two vec4's\n *\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {Number} dot product of a and b\n */\nexport function dot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];\n}\n\n/**\n * Returns the cross-product of three vectors in a 4-dimensional space\n *\n * @param {ReadonlyVec4} out the receiving vector\n * @param {ReadonlyVec4} u the first vector\n * @param {ReadonlyVec4} v the second vector\n * @param {ReadonlyVec4} w the third vector\n * @returns {vec4} result\n */\nexport function cross(out, u, v, w) {\n var A = v[0] * w[1] - v[1] * w[0],\n B = v[0] * w[2] - v[2] * w[0],\n C = v[0] * w[3] - v[3] * w[0],\n D = v[1] * w[2] - v[2] * w[1],\n E = v[1] * w[3] - v[3] * w[1],\n F = v[2] * w[3] - v[3] * w[2];\n var G = u[0];\n var H = u[1];\n var I = u[2];\n var J = u[3];\n out[0] = H * F - I * E + J * D;\n out[1] = -(G * F) + I * C - J * B;\n out[2] = G * E - H * C + J * A;\n out[3] = -(G * D) + H * B - I * A;\n return out;\n}\n\n/**\n * Performs a linear interpolation between two vec4's\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec4} out\n */\nexport function lerp(out, a, b, t) {\n var ax = a[0];\n var ay = a[1];\n var az = a[2];\n var aw = a[3];\n out[0] = ax + t * (b[0] - ax);\n out[1] = ay + t * (b[1] - ay);\n out[2] = az + t * (b[2] - az);\n out[3] = aw + t * (b[3] - aw);\n return out;\n}\n\n/**\n * Generates a random vector with the given scale\n *\n * @param {vec4} out the receiving vector\n * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned\n * @returns {vec4} out\n */\nexport function random(out, scale) {\n scale = scale === undefined ? 1.0 : scale;\n\n // Marsaglia, George. Choosing a Point from the Surface of a\n // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646.\n // http://projecteuclid.org/euclid.aoms/1177692644;\n var v1, v2, v3, v4;\n var s1, s2;\n var rand;\n rand = glMatrix.RANDOM();\n v1 = rand * 2 - 1;\n v2 = (4 * glMatrix.RANDOM() - 2) * Math.sqrt(rand * -rand + rand);\n s1 = v1 * v1 + v2 * v2;\n rand = glMatrix.RANDOM();\n v3 = rand * 2 - 1;\n v4 = (4 * glMatrix.RANDOM() - 2) * Math.sqrt(rand * -rand + rand);\n s2 = v3 * v3 + v4 * v4;\n var d = Math.sqrt((1 - s1) / s2);\n out[0] = scale * v1;\n out[1] = scale * v2;\n out[2] = scale * v3 * d;\n out[3] = scale * v4 * d;\n return out;\n}\n\n/**\n * Transforms the vec4 with a mat4.\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the vector to transform\n * @param {ReadonlyMat4} m matrix to transform with\n * @returns {vec4} out\n */\nexport function transformMat4(out, a, m) {\n var x = a[0],\n y = a[1],\n z = a[2],\n w = a[3];\n out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;\n out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;\n out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;\n out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;\n return out;\n}\n\n/**\n * Transforms the vec4 with a quat\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the vector to transform\n * @param {ReadonlyQuat} q normalized quaternion to transform with\n * @returns {vec4} out\n */\nexport function transformQuat(out, a, q) {\n // Fast Vector Rotation using Quaternions by Robert Eisele\n // https://raw.org/proof/vector-rotation-using-quaternions/\n\n var qx = q[0],\n qy = q[1],\n qz = q[2],\n qw = q[3];\n var vx = a[0],\n vy = a[1],\n vz = a[2];\n\n // t = q x v\n var tx = qy * vz - qz * vy;\n var ty = qz * vx - qx * vz;\n var tz = qx * vy - qy * vx;\n\n // t = 2t\n tx = tx + tx;\n ty = ty + ty;\n tz = tz + tz;\n\n // v + w t + q x t\n out[0] = vx + qw * tx + qy * tz - qz * ty;\n out[1] = vy + qw * ty + qz * tx - qx * tz;\n out[2] = vz + qw * tz + qx * ty - qy * tx;\n out[3] = a[3];\n return out;\n}\n\n/**\n * Set the components of a vec4 to zero\n *\n * @param {vec4} out the receiving vector\n * @returns {vec4} out\n */\nexport function zero(out) {\n out[0] = 0.0;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n return out;\n}\n\n/**\n * Returns a string representation of a vector\n *\n * @param {ReadonlyVec4} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\nexport function str(a) {\n return \"vec4(\" + a[0] + \", \" + a[1] + \", \" + a[2] + \", \" + a[3] + \")\";\n}\n\n/**\n * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyVec4} a The first vector.\n * @param {ReadonlyVec4} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];\n}\n\n/**\n * Returns whether or not the vectors have approximately the same elements in the same position.\n *\n * @param {ReadonlyVec4} a The first vector.\n * @param {ReadonlyVec4} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3];\n return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3));\n}\n\n/**\n * Alias for {@link vec4.subtract}\n * @function\n */\nexport var sub = subtract;\n\n/**\n * Alias for {@link vec4.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Alias for {@link vec4.divide}\n * @function\n */\nexport var div = divide;\n\n/**\n * Alias for {@link vec4.distance}\n * @function\n */\nexport var dist = distance;\n\n/**\n * Alias for {@link vec4.squaredDistance}\n * @function\n */\nexport var sqrDist = squaredDistance;\n\n/**\n * Alias for {@link vec4.length}\n * @function\n */\nexport var len = length;\n\n/**\n * Alias for {@link vec4.squaredLength}\n * @function\n */\nexport var sqrLen = squaredLength;\n\n/**\n * Perform some operation over an array of vec4s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\nexport var forEach = function () {\n var vec = create();\n return function (a, stride, offset, count, fn, arg) {\n var i, l;\n if (!stride) {\n stride = 4;\n }\n if (!offset) {\n offset = 0;\n }\n if (count) {\n l = Math.min(count * stride + offset, a.length);\n } else {\n l = a.length;\n }\n for (i = offset; i < l; i += stride) {\n vec[0] = a[i];\n vec[1] = a[i + 1];\n vec[2] = a[i + 2];\n vec[3] = a[i + 3];\n fn(vec, vec, arg);\n a[i] = vec[0];\n a[i + 1] = vec[1];\n a[i + 2] = vec[2];\n a[i + 3] = vec[3];\n }\n return a;\n };\n}();","import * as glMatrix from \"./common.js\";\nimport * as mat3 from \"./mat3.js\";\nimport * as vec3 from \"./vec3.js\";\nimport * as vec4 from \"./vec4.js\";\n\n/**\n * Quaternion in the format XYZW\n * @module quat\n */\n\n/**\n * Creates a new identity quat\n *\n * @returns {quat} a new quaternion\n */\nexport function create() {\n var out = new glMatrix.ARRAY_TYPE(4);\n if (glMatrix.ARRAY_TYPE != Float32Array) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n }\n out[3] = 1;\n return out;\n}\n\n/**\n * Set a quat to the identity quaternion\n *\n * @param {quat} out the receiving quaternion\n * @returns {quat} out\n */\nexport function identity(out) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n out[3] = 1;\n return out;\n}\n\n/**\n * Sets a quat from the given angle and rotation axis,\n * then returns it.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyVec3} axis the axis around which to rotate\n * @param {Number} rad the angle in radians\n * @returns {quat} out\n **/\nexport function setAxisAngle(out, axis, rad) {\n rad = rad * 0.5;\n var s = Math.sin(rad);\n out[0] = s * axis[0];\n out[1] = s * axis[1];\n out[2] = s * axis[2];\n out[3] = Math.cos(rad);\n return out;\n}\n\n/**\n * Gets the rotation axis and angle for a given\n * quaternion. If a quaternion is created with\n * setAxisAngle, this method will return the same\n * values as providied in the original parameter list\n * OR functionally equivalent values.\n * Example: The quaternion formed by axis [0, 0, 1] and\n * angle -90 is the same as the quaternion formed by\n * [0, 0, 1] and 270. This method favors the latter.\n * @param {vec3} out_axis Vector receiving the axis of rotation\n * @param {ReadonlyQuat} q Quaternion to be decomposed\n * @return {Number} Angle, in radians, of the rotation\n */\nexport function getAxisAngle(out_axis, q) {\n var rad = Math.acos(q[3]) * 2.0;\n var s = Math.sin(rad / 2.0);\n if (s > glMatrix.EPSILON) {\n out_axis[0] = q[0] / s;\n out_axis[1] = q[1] / s;\n out_axis[2] = q[2] / s;\n } else {\n // If s is zero, return any axis (no rotation - axis does not matter)\n out_axis[0] = 1;\n out_axis[1] = 0;\n out_axis[2] = 0;\n }\n return rad;\n}\n\n/**\n * Gets the angular distance between two unit quaternions\n *\n * @param {ReadonlyQuat} a Origin unit quaternion\n * @param {ReadonlyQuat} b Destination unit quaternion\n * @return {Number} Angle, in radians, between the two quaternions\n */\nexport function getAngle(a, b) {\n var dotproduct = dot(a, b);\n return Math.acos(2 * dotproduct * dotproduct - 1);\n}\n\n/**\n * Multiplies two quat's\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @returns {quat} out\n */\nexport function multiply(out, a, b) {\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bx = b[0],\n by = b[1],\n bz = b[2],\n bw = b[3];\n out[0] = ax * bw + aw * bx + ay * bz - az * by;\n out[1] = ay * bw + aw * by + az * bx - ax * bz;\n out[2] = az * bw + aw * bz + ax * by - ay * bx;\n out[3] = aw * bw - ax * bx - ay * by - az * bz;\n return out;\n}\n\n/**\n * Rotates a quaternion by the given angle about the X axis\n *\n * @param {quat} out quat receiving operation result\n * @param {ReadonlyQuat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\nexport function rotateX(out, a, rad) {\n rad *= 0.5;\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bx = Math.sin(rad),\n bw = Math.cos(rad);\n out[0] = ax * bw + aw * bx;\n out[1] = ay * bw + az * bx;\n out[2] = az * bw - ay * bx;\n out[3] = aw * bw - ax * bx;\n return out;\n}\n\n/**\n * Rotates a quaternion by the given angle about the Y axis\n *\n * @param {quat} out quat receiving operation result\n * @param {ReadonlyQuat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\nexport function rotateY(out, a, rad) {\n rad *= 0.5;\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var by = Math.sin(rad),\n bw = Math.cos(rad);\n out[0] = ax * bw - az * by;\n out[1] = ay * bw + aw * by;\n out[2] = az * bw + ax * by;\n out[3] = aw * bw - ay * by;\n return out;\n}\n\n/**\n * Rotates a quaternion by the given angle about the Z axis\n *\n * @param {quat} out quat receiving operation result\n * @param {ReadonlyQuat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\nexport function rotateZ(out, a, rad) {\n rad *= 0.5;\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bz = Math.sin(rad),\n bw = Math.cos(rad);\n out[0] = ax * bw + ay * bz;\n out[1] = ay * bw - ax * bz;\n out[2] = az * bw + aw * bz;\n out[3] = aw * bw - az * bz;\n return out;\n}\n\n/**\n * Calculates the W component of a quat from the X, Y, and Z components.\n * Assumes that quaternion is 1 unit in length.\n * Any existing W component will be ignored.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate W component of\n * @returns {quat} out\n */\nexport function calculateW(out, a) {\n var x = a[0],\n y = a[1],\n z = a[2];\n out[0] = x;\n out[1] = y;\n out[2] = z;\n out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));\n return out;\n}\n\n/**\n * Calculate the exponential of a unit quaternion.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate the exponential of\n * @returns {quat} out\n */\nexport function exp(out, a) {\n var x = a[0],\n y = a[1],\n z = a[2],\n w = a[3];\n var r = Math.sqrt(x * x + y * y + z * z);\n var et = Math.exp(w);\n var s = r > 0 ? et * Math.sin(r) / r : 0;\n out[0] = x * s;\n out[1] = y * s;\n out[2] = z * s;\n out[3] = et * Math.cos(r);\n return out;\n}\n\n/**\n * Calculate the natural logarithm of a unit quaternion.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate the exponential of\n * @returns {quat} out\n */\nexport function ln(out, a) {\n var x = a[0],\n y = a[1],\n z = a[2],\n w = a[3];\n var r = Math.sqrt(x * x + y * y + z * z);\n var t = r > 0 ? Math.atan2(r, w) / r : 0;\n out[0] = x * t;\n out[1] = y * t;\n out[2] = z * t;\n out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w);\n return out;\n}\n\n/**\n * Calculate the scalar power of a unit quaternion.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate the exponential of\n * @param {Number} b amount to scale the quaternion by\n * @returns {quat} out\n */\nexport function pow(out, a, b) {\n ln(out, a);\n scale(out, out, b);\n exp(out, out);\n return out;\n}\n\n/**\n * Performs a spherical linear interpolation between two quat\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {quat} out\n */\nexport function slerp(out, a, b, t) {\n // benchmarks:\n // http://jsperf.com/quaternion-slerp-implementations\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bx = b[0],\n by = b[1],\n bz = b[2],\n bw = b[3];\n var omega, cosom, sinom, scale0, scale1;\n\n // calc cosine\n cosom = ax * bx + ay * by + az * bz + aw * bw;\n // adjust signs (if necessary)\n if (cosom < 0.0) {\n cosom = -cosom;\n bx = -bx;\n by = -by;\n bz = -bz;\n bw = -bw;\n }\n // calculate coefficients\n if (1.0 - cosom > glMatrix.EPSILON) {\n // standard case (slerp)\n omega = Math.acos(cosom);\n sinom = Math.sin(omega);\n scale0 = Math.sin((1.0 - t) * omega) / sinom;\n scale1 = Math.sin(t * omega) / sinom;\n } else {\n // \"from\" and \"to\" quaternions are very close\n // ... so we can do a linear interpolation\n scale0 = 1.0 - t;\n scale1 = t;\n }\n // calculate final values\n out[0] = scale0 * ax + scale1 * bx;\n out[1] = scale0 * ay + scale1 * by;\n out[2] = scale0 * az + scale1 * bz;\n out[3] = scale0 * aw + scale1 * bw;\n return out;\n}\n\n/**\n * Generates a random unit quaternion\n *\n * @param {quat} out the receiving quaternion\n * @returns {quat} out\n */\nexport function random(out) {\n // Implementation of http://planning.cs.uiuc.edu/node198.html\n // TODO: Calling random 3 times is probably not the fastest solution\n var u1 = glMatrix.RANDOM();\n var u2 = glMatrix.RANDOM();\n var u3 = glMatrix.RANDOM();\n var sqrt1MinusU1 = Math.sqrt(1 - u1);\n var sqrtU1 = Math.sqrt(u1);\n out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2);\n out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2);\n out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3);\n out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3);\n return out;\n}\n\n/**\n * Calculates the inverse of a quat\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate inverse of\n * @returns {quat} out\n */\nexport function invert(out, a) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3];\n var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;\n var invDot = dot ? 1.0 / dot : 0;\n\n // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0\n\n out[0] = -a0 * invDot;\n out[1] = -a1 * invDot;\n out[2] = -a2 * invDot;\n out[3] = a3 * invDot;\n return out;\n}\n\n/**\n * Calculates the conjugate of a quat\n * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate conjugate of\n * @returns {quat} out\n */\nexport function conjugate(out, a) {\n out[0] = -a[0];\n out[1] = -a[1];\n out[2] = -a[2];\n out[3] = a[3];\n return out;\n}\n\n/**\n * Creates a quaternion from the given 3x3 rotation matrix.\n *\n * NOTE: The resultant quaternion is not normalized, so you should be sure\n * to renormalize the quaternion yourself where necessary.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyMat3} m rotation matrix\n * @returns {quat} out\n * @function\n */\nexport function fromMat3(out, m) {\n // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes\n // article \"Quaternion Calculus and Fast Animation\".\n var fTrace = m[0] + m[4] + m[8];\n var fRoot;\n if (fTrace > 0.0) {\n // |w| > 1/2, may as well choose w > 1/2\n fRoot = Math.sqrt(fTrace + 1.0); // 2w\n out[3] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot; // 1/(4w)\n out[0] = (m[5] - m[7]) * fRoot;\n out[1] = (m[6] - m[2]) * fRoot;\n out[2] = (m[1] - m[3]) * fRoot;\n } else {\n // |w| <= 1/2\n var i = 0;\n if (m[4] > m[0]) i = 1;\n if (m[8] > m[i * 3 + i]) i = 2;\n var j = (i + 1) % 3;\n var k = (i + 2) % 3;\n fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0);\n out[i] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot;\n out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot;\n out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;\n out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;\n }\n return out;\n}\n\n/**\n * Creates a quaternion from the given euler angle x, y, z using the provided intrinsic order for the conversion.\n *\n * @param {quat} out the receiving quaternion\n * @param {Number} x Angle to rotate around X axis in degrees.\n * @param {Number} y Angle to rotate around Y axis in degrees.\n * @param {Number} z Angle to rotate around Z axis in degrees.\n * @param {'xyz'|'xzy'|'yxz'|'yzx'|'zxy'|'zyx'} order Intrinsic order for conversion, default is zyx.\n * @returns {quat} out\n * @function\n */\nexport function fromEuler(out, x, y, z) {\n var order = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : glMatrix.ANGLE_ORDER;\n var halfToRad = Math.PI / 360;\n x *= halfToRad;\n z *= halfToRad;\n y *= halfToRad;\n var sx = Math.sin(x);\n var cx = Math.cos(x);\n var sy = Math.sin(y);\n var cy = Math.cos(y);\n var sz = Math.sin(z);\n var cz = Math.cos(z);\n switch (order) {\n case \"xyz\":\n out[0] = sx * cy * cz + cx * sy * sz;\n out[1] = cx * sy * cz - sx * cy * sz;\n out[2] = cx * cy * sz + sx * sy * cz;\n out[3] = cx * cy * cz - sx * sy * sz;\n break;\n case \"xzy\":\n out[0] = sx * cy * cz - cx * sy * sz;\n out[1] = cx * sy * cz - sx * cy * sz;\n out[2] = cx * cy * sz + sx * sy * cz;\n out[3] = cx * cy * cz + sx * sy * sz;\n break;\n case \"yxz\":\n out[0] = sx * cy * cz + cx * sy * sz;\n out[1] = cx * sy * cz - sx * cy * sz;\n out[2] = cx * cy * sz - sx * sy * cz;\n out[3] = cx * cy * cz + sx * sy * sz;\n break;\n case \"yzx\":\n out[0] = sx * cy * cz + cx * sy * sz;\n out[1] = cx * sy * cz + sx * cy * sz;\n out[2] = cx * cy * sz - sx * sy * cz;\n out[3] = cx * cy * cz - sx * sy * sz;\n break;\n case \"zxy\":\n out[0] = sx * cy * cz - cx * sy * sz;\n out[1] = cx * sy * cz + sx * cy * sz;\n out[2] = cx * cy * sz + sx * sy * cz;\n out[3] = cx * cy * cz - sx * sy * sz;\n break;\n case \"zyx\":\n out[0] = sx * cy * cz - cx * sy * sz;\n out[1] = cx * sy * cz + sx * cy * sz;\n out[2] = cx * cy * sz - sx * sy * cz;\n out[3] = cx * cy * cz + sx * sy * sz;\n break;\n default:\n throw new Error('Unknown angle order ' + order);\n }\n return out;\n}\n\n/**\n * Returns a string representation of a quaternion\n *\n * @param {ReadonlyQuat} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\nexport function str(a) {\n return \"quat(\" + a[0] + \", \" + a[1] + \", \" + a[2] + \", \" + a[3] + \")\";\n}\n\n/**\n * Creates a new quat initialized with values from an existing quaternion\n *\n * @param {ReadonlyQuat} a quaternion to clone\n * @returns {quat} a new quaternion\n * @function\n */\nexport var clone = vec4.clone;\n\n/**\n * Creates a new quat initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {quat} a new quaternion\n * @function\n */\nexport var fromValues = vec4.fromValues;\n\n/**\n * Copy the values from one quat to another\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the source quaternion\n * @returns {quat} out\n * @function\n */\nexport var copy = vec4.copy;\n\n/**\n * Set the components of a quat to the given values\n *\n * @param {quat} out the receiving quaternion\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {quat} out\n * @function\n */\nexport var set = vec4.set;\n\n/**\n * Adds two quat's\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @returns {quat} out\n * @function\n */\nexport var add = vec4.add;\n\n/**\n * Alias for {@link quat.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Scales a quat by a scalar number\n *\n * @param {quat} out the receiving vector\n * @param {ReadonlyQuat} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {quat} out\n * @function\n */\nexport var scale = vec4.scale;\n\n/**\n * Calculates the dot product of two quat's\n *\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @returns {Number} dot product of a and b\n * @function\n */\nexport var dot = vec4.dot;\n\n/**\n * Performs a linear interpolation between two quat's\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {quat} out\n * @function\n */\nexport var lerp = vec4.lerp;\n\n/**\n * Calculates the length of a quat\n *\n * @param {ReadonlyQuat} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport var length = vec4.length;\n\n/**\n * Alias for {@link quat.length}\n * @function\n */\nexport var len = length;\n\n/**\n * Calculates the squared length of a quat\n *\n * @param {ReadonlyQuat} a vector to calculate squared length of\n * @returns {Number} squared length of a\n * @function\n */\nexport var squaredLength = vec4.squaredLength;\n\n/**\n * Alias for {@link quat.squaredLength}\n * @function\n */\nexport var sqrLen = squaredLength;\n\n/**\n * Normalize a quat\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quaternion to normalize\n * @returns {quat} out\n * @function\n */\nexport var normalize = vec4.normalize;\n\n/**\n * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyQuat} a The first quaternion.\n * @param {ReadonlyQuat} b The second quaternion.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport var exactEquals = vec4.exactEquals;\n\n/**\n * Returns whether or not the quaternions point approximately to the same direction.\n *\n * Both quaternions are assumed to be unit length.\n *\n * @param {ReadonlyQuat} a The first unit quaternion.\n * @param {ReadonlyQuat} b The second unit quaternion.\n * @returns {Boolean} True if the quaternions are equal, false otherwise.\n */\nexport function equals(a, b) {\n return Math.abs(vec4.dot(a, b)) >= 1 - glMatrix.EPSILON;\n}\n\n/**\n * Sets a quaternion to represent the shortest rotation from one\n * vector to another.\n *\n * Both vectors are assumed to be unit length.\n *\n * @param {quat} out the receiving quaternion.\n * @param {ReadonlyVec3} a the initial vector\n * @param {ReadonlyVec3} b the destination vector\n * @returns {quat} out\n */\nexport var rotationTo = function () {\n var tmpvec3 = vec3.create();\n var xUnitVec3 = vec3.fromValues(1, 0, 0);\n var yUnitVec3 = vec3.fromValues(0, 1, 0);\n return function (out, a, b) {\n var dot = vec3.dot(a, b);\n if (dot < -0.999999) {\n vec3.cross(tmpvec3, xUnitVec3, a);\n if (vec3.len(tmpvec3) < 0.000001) vec3.cross(tmpvec3, yUnitVec3, a);\n vec3.normalize(tmpvec3, tmpvec3);\n setAxisAngle(out, tmpvec3, Math.PI);\n return out;\n } else if (dot > 0.999999) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n out[3] = 1;\n return out;\n } else {\n vec3.cross(tmpvec3, a, b);\n out[0] = tmpvec3[0];\n out[1] = tmpvec3[1];\n out[2] = tmpvec3[2];\n out[3] = 1 + dot;\n return normalize(out, out);\n }\n };\n}();\n\n/**\n * Performs a spherical linear interpolation with two control points\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @param {ReadonlyQuat} c the third operand\n * @param {ReadonlyQuat} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {quat} out\n */\nexport var sqlerp = function () {\n var temp1 = create();\n var temp2 = create();\n return function (out, a, b, c, d, t) {\n slerp(temp1, a, d, t);\n slerp(temp2, b, c, t);\n slerp(out, temp1, temp2, 2 * t * (1 - t));\n return out;\n };\n}();\n\n/**\n * Sets the specified quaternion with values corresponding to the given\n * axes. Each axis is a vec3 and is expected to be unit length and\n * perpendicular to all other specified axes.\n *\n * @param {ReadonlyVec3} view the vector representing the viewing direction\n * @param {ReadonlyVec3} right the vector representing the local \"right\" direction\n * @param {ReadonlyVec3} up the vector representing the local \"up\" direction\n * @returns {quat} out\n */\nexport var setAxes = function () {\n var matr = mat3.create();\n return function (out, view, right, up) {\n matr[0] = right[0];\n matr[3] = right[1];\n matr[6] = right[2];\n matr[1] = up[0];\n matr[4] = up[1];\n matr[7] = up[2];\n matr[2] = -view[0];\n matr[5] = -view[1];\n matr[8] = -view[2];\n return normalize(out, fromMat3(out, matr));\n };\n}();","import * as glMatrix from \"./common.js\";\n\n/**\n * 2 Dimensional Vector\n * @module vec2\n */\n\n/**\n * Creates a new, empty vec2\n *\n * @returns {vec2} a new 2D vector\n */\nexport function create() {\n var out = new glMatrix.ARRAY_TYPE(2);\n if (glMatrix.ARRAY_TYPE != Float32Array) {\n out[0] = 0;\n out[1] = 0;\n }\n return out;\n}\n\n/**\n * Creates a new vec2 initialized with values from an existing vector\n *\n * @param {ReadonlyVec2} a vector to clone\n * @returns {vec2} a new 2D vector\n */\nexport function clone(a) {\n var out = new glMatrix.ARRAY_TYPE(2);\n out[0] = a[0];\n out[1] = a[1];\n return out;\n}\n\n/**\n * Creates a new vec2 initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @returns {vec2} a new 2D vector\n */\nexport function fromValues(x, y) {\n var out = new glMatrix.ARRAY_TYPE(2);\n out[0] = x;\n out[1] = y;\n return out;\n}\n\n/**\n * Copy the values from one vec2 to another\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the source vector\n * @returns {vec2} out\n */\nexport function copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n return out;\n}\n\n/**\n * Set the components of a vec2 to the given values\n *\n * @param {vec2} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @returns {vec2} out\n */\nexport function set(out, x, y) {\n out[0] = x;\n out[1] = y;\n return out;\n}\n\n/**\n * Adds two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {vec2} out\n */\nexport function add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n return out;\n}\n\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {vec2} out\n */\nexport function subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n return out;\n}\n\n/**\n * Multiplies two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {vec2} out\n */\nexport function multiply(out, a, b) {\n out[0] = a[0] * b[0];\n out[1] = a[1] * b[1];\n return out;\n}\n\n/**\n * Divides two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {vec2} out\n */\nexport function divide(out, a, b) {\n out[0] = a[0] / b[0];\n out[1] = a[1] / b[1];\n return out;\n}\n\n/**\n * Math.ceil the components of a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a vector to ceil\n * @returns {vec2} out\n */\nexport function ceil(out, a) {\n out[0] = Math.ceil(a[0]);\n out[1] = Math.ceil(a[1]);\n return out;\n}\n\n/**\n * Math.floor the components of a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a vector to floor\n * @returns {vec2} out\n */\nexport function floor(out, a) {\n out[0] = Math.floor(a[0]);\n out[1] = Math.floor(a[1]);\n return out;\n}\n\n/**\n * Returns the minimum of two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {vec2} out\n */\nexport function min(out, a, b) {\n out[0] = Math.min(a[0], b[0]);\n out[1] = Math.min(a[1], b[1]);\n return out;\n}\n\n/**\n * Returns the maximum of two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {vec2} out\n */\nexport function max(out, a, b) {\n out[0] = Math.max(a[0], b[0]);\n out[1] = Math.max(a[1], b[1]);\n return out;\n}\n\n/**\n * symmetric round the components of a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a vector to round\n * @returns {vec2} out\n */\nexport function round(out, a) {\n out[0] = glMatrix.round(a[0]);\n out[1] = glMatrix.round(a[1]);\n return out;\n}\n\n/**\n * Scales a vec2 by a scalar number\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec2} out\n */\nexport function scale(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n return out;\n}\n\n/**\n * Adds two vec2's after scaling the second operand by a scalar value\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @param {Number} scale the amount to scale b by before adding\n * @returns {vec2} out\n */\nexport function scaleAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n return out;\n}\n\n/**\n * Calculates the euclidian distance between two vec2's\n *\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {Number} distance between a and b\n */\nexport function distance(a, b) {\n var x = b[0] - a[0],\n y = b[1] - a[1];\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * Calculates the squared euclidian distance between two vec2's\n *\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {Number} squared distance between a and b\n */\nexport function squaredDistance(a, b) {\n var x = b[0] - a[0],\n y = b[1] - a[1];\n return x * x + y * y;\n}\n\n/**\n * Calculates the length of a vec2\n *\n * @param {ReadonlyVec2} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport function length(a) {\n var x = a[0],\n y = a[1];\n return Math.sqrt(x * x + y * y);\n}\n\n/**\n * Calculates the squared length of a vec2\n *\n * @param {ReadonlyVec2} a vector to calculate squared length of\n * @returns {Number} squared length of a\n */\nexport function squaredLength(a) {\n var x = a[0],\n y = a[1];\n return x * x + y * y;\n}\n\n/**\n * Negates the components of a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a vector to negate\n * @returns {vec2} out\n */\nexport function negate(out, a) {\n out[0] = -a[0];\n out[1] = -a[1];\n return out;\n}\n\n/**\n * Returns the inverse of the components of a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a vector to invert\n * @returns {vec2} out\n */\nexport function inverse(out, a) {\n out[0] = 1.0 / a[0];\n out[1] = 1.0 / a[1];\n return out;\n}\n\n/**\n * Normalize a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a vector to normalize\n * @returns {vec2} out\n */\nexport function normalize(out, a) {\n var x = a[0],\n y = a[1];\n var len = x * x + y * y;\n if (len > 0) {\n //TODO: evaluate use of glm_invsqrt here?\n len = 1 / Math.sqrt(len);\n }\n out[0] = a[0] * len;\n out[1] = a[1] * len;\n return out;\n}\n\n/**\n * Calculates the dot product of two vec2's\n *\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {Number} dot product of a and b\n */\nexport function dot(a, b) {\n return a[0] * b[0] + a[1] * b[1];\n}\n\n/**\n * Computes the cross product of two vec2's\n * Note that the cross product must by definition produce a 3D vector\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @returns {vec3} out\n */\nexport function cross(out, a, b) {\n var z = a[0] * b[1] - a[1] * b[0];\n out[0] = out[1] = 0;\n out[2] = z;\n return out;\n}\n\n/**\n * Performs a linear interpolation between two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the first operand\n * @param {ReadonlyVec2} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec2} out\n */\nexport function lerp(out, a, b, t) {\n var ax = a[0],\n ay = a[1];\n out[0] = ax + t * (b[0] - ax);\n out[1] = ay + t * (b[1] - ay);\n return out;\n}\n\n/**\n * Generates a random vector with the given scale\n *\n * @param {vec2} out the receiving vector\n * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned\n * @returns {vec2} out\n */\nexport function random(out, scale) {\n scale = scale === undefined ? 1.0 : scale;\n var r = glMatrix.RANDOM() * 2.0 * Math.PI;\n out[0] = Math.cos(r) * scale;\n out[1] = Math.sin(r) * scale;\n return out;\n}\n\n/**\n * Transforms the vec2 with a mat2\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the vector to transform\n * @param {ReadonlyMat2} m matrix to transform with\n * @returns {vec2} out\n */\nexport function transformMat2(out, a, m) {\n var x = a[0],\n y = a[1];\n out[0] = m[0] * x + m[2] * y;\n out[1] = m[1] * x + m[3] * y;\n return out;\n}\n\n/**\n * Transforms the vec2 with a mat2d\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the vector to transform\n * @param {ReadonlyMat2d} m matrix to transform with\n * @returns {vec2} out\n */\nexport function transformMat2d(out, a, m) {\n var x = a[0],\n y = a[1];\n out[0] = m[0] * x + m[2] * y + m[4];\n out[1] = m[1] * x + m[3] * y + m[5];\n return out;\n}\n\n/**\n * Transforms the vec2 with a mat3\n * 3rd vector component is implicitly '1'\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the vector to transform\n * @param {ReadonlyMat3} m matrix to transform with\n * @returns {vec2} out\n */\nexport function transformMat3(out, a, m) {\n var x = a[0],\n y = a[1];\n out[0] = m[0] * x + m[3] * y + m[6];\n out[1] = m[1] * x + m[4] * y + m[7];\n return out;\n}\n\n/**\n * Transforms the vec2 with a mat4\n * 3rd vector component is implicitly '0'\n * 4th vector component is implicitly '1'\n *\n * @param {vec2} out the receiving vector\n * @param {ReadonlyVec2} a the vector to transform\n * @param {ReadonlyMat4} m matrix to transform with\n * @returns {vec2} out\n */\nexport function transformMat4(out, a, m) {\n var x = a[0];\n var y = a[1];\n out[0] = m[0] * x + m[4] * y + m[12];\n out[1] = m[1] * x + m[5] * y + m[13];\n return out;\n}\n\n/**\n * Rotate a 2D vector\n * @param {vec2} out The receiving vec2\n * @param {ReadonlyVec2} a The vec2 point to rotate\n * @param {ReadonlyVec2} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec2} out\n */\nexport function rotate(out, a, b, rad) {\n //Translate point to the origin\n var p0 = a[0] - b[0],\n p1 = a[1] - b[1],\n sinC = Math.sin(rad),\n cosC = Math.cos(rad);\n\n //perform rotation and translate to correct position\n out[0] = p0 * cosC - p1 * sinC + b[0];\n out[1] = p0 * sinC + p1 * cosC + b[1];\n return out;\n}\n\n/**\n * Get the smallest angle between two 2D vectors\n * @param {ReadonlyVec2} a The first operand\n * @param {ReadonlyVec2} b The second operand\n * @returns {Number} The angle in radians\n */\nexport function angle(a, b) {\n var ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1];\n return Math.abs(Math.atan2(ay * bx - ax * by, ax * bx + ay * by));\n}\n\n/**\n * Get the signed angle in the interval [-pi,pi] between two 2D vectors (positive if `a` is to the right of `b`)\n * \n * @param {ReadonlyVec2} a The first vector\n * @param {ReadonlyVec2} b The second vector\n * @returns {number} The signed angle in radians\n */\nexport function signedAngle(a, b) {\n var ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1];\n return Math.atan2(ax * by - ay * bx, ax * bx + ay * by);\n}\n\n/**\n * Set the components of a vec2 to zero\n *\n * @param {vec2} out the receiving vector\n * @returns {vec2} out\n */\nexport function zero(out) {\n out[0] = 0.0;\n out[1] = 0.0;\n return out;\n}\n\n/**\n * Returns a string representation of a vector\n *\n * @param {ReadonlyVec2} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\nexport function str(a) {\n return \"vec2(\" + a[0] + \", \" + a[1] + \")\";\n}\n\n/**\n * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyVec2} a The first vector.\n * @param {ReadonlyVec2} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1];\n}\n\n/**\n * Returns whether or not the vectors have approximately the same elements in the same position.\n *\n * @param {ReadonlyVec2} a The first vector.\n * @param {ReadonlyVec2} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function equals(a, b) {\n var a0 = a[0],\n a1 = a[1];\n var b0 = b[0],\n b1 = b[1];\n return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1));\n}\n\n/**\n * Alias for {@link vec2.length}\n * @function\n */\nexport var len = length;\n\n/**\n * Alias for {@link vec2.subtract}\n * @function\n */\nexport var sub = subtract;\n\n/**\n * Alias for {@link vec2.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Alias for {@link vec2.divide}\n * @function\n */\nexport var div = divide;\n\n/**\n * Alias for {@link vec2.distance}\n * @function\n */\nexport var dist = distance;\n\n/**\n * Alias for {@link vec2.squaredDistance}\n * @function\n */\nexport var sqrDist = squaredDistance;\n\n/**\n * Alias for {@link vec2.squaredLength}\n * @function\n */\nexport var sqrLen = squaredLength;\n\n/**\n * Perform some operation over an array of vec2s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\nexport var forEach = function () {\n var vec = create();\n return function (a, stride, offset, count, fn, arg) {\n var i, l;\n if (!stride) {\n stride = 2;\n }\n if (!offset) {\n offset = 0;\n }\n if (count) {\n l = Math.min(count * stride + offset, a.length);\n } else {\n l = a.length;\n }\n for (i = offset; i < l; i += stride) {\n vec[0] = a[i];\n vec[1] = a[i + 1];\n fn(vec, vec, arg);\n a[i] = vec[0];\n a[i + 1] = vec[1];\n }\n return a;\n };\n}();","/**\n * The maximum value of a coordinate in the internal tile coordinate system. Coordinates of\n * all source features normalized to this extent upon load.\n *\n * The value is a consequence of the following:\n *\n * * Vertex buffer store positions as signed 16 bit integers.\n * * One bit is lost for signedness to support tile buffers.\n * * One bit is lost because the line vertex buffer used to pack 1 bit of other data into the int.\n * * One bit is lost to support features extending past the extent on the right edge of the tile.\n * * This leaves us with 2^13 = 8192\n */\nexport const EXTENT = 8192;","import {EXTENT} from '../data/extent.ts';\n\nimport type {OverscaledTileID} from '../tile/tile_id.ts';\n\n/**\n * Converts a pixel value at a the given zoom level to tile units.\n *\n * The shaders mostly calculate everything in tile units so style\n * properties need to be converted from pixels to tile units using this.\n *\n * For example, a translation by 30 pixels at zoom 6.5 will be a\n * translation by pixelsToTileUnits(30, 6.5) tile units.\n *\n * @returns value in tile units\n */\nexport function pixelsToTileUnits(\n tile: {\n tileID: OverscaledTileID;\n tileSize: number;\n },\n pixelValue: number,\n z: number\n): number {\n return pixelValue * (EXTENT / (tile.tileSize * Math.pow(2, z - tile.tileID.overscaledZ)));\n}\n","import Point from '@mapbox/point-geometry';\nimport unitBezierFactory from '@mapbox/unitbezier';\nimport {isOffscreenCanvasDistorted} from './offscreen_canvas_distorted.ts';\nimport type {Size} from './image.ts';\nimport type {WorkerGlobalScopeInterface} from './web_worker.ts';\nimport {mat3, mat4, quat, vec2, vec3, type vec4} from 'gl-matrix';\nimport {pixelsToTileUnits} from '../source/pixels_to_tile_units.ts';\nimport type {OverscaledTileID} from '../tile/tile_id.ts';\nimport type {Event} from './evented.ts';\n\n/**\n * A 4x4 gl-matrix matrix backed by 32-bit floats.\n */\nexport type Mat4f32 = mat4 & Float32Array;\n/**\n * A 4x4 gl-matrix matrix backed by 64-bit floats.\n */\nexport type Mat4f64 = mat4 & Float64Array;\n\nexport const JSON_PREFIX = '__$json__:';\n\n/**\n * Ensures that a value is an `Error` instance.\n * If the value is already an `Error`, it is returned as-is.\n * Otherwise, a new `Error` is created from its string representation.\n */\nexport function ensureError(e: unknown): Error {\n if (e instanceof Error) return e;\n return new Error(typeof e === 'string' ? e : String(e));\n}\n\n/**\n * Returns a new 64 bit float vec4 of zeroes.\n */\nexport function createVec4f64(): vec4 { return new Float64Array(4); }\n/**\n * Returns a new 64 bit float vec3 of zeroes.\n */\nexport function createVec3f64(): vec3 { return new Float64Array(3); }\n/**\n * Returns a new 64 bit float mat4 of zeroes.\n */\nexport function createMat4f64(): Mat4f64 { return new Float64Array(16); }\n/**\n * Returns a new 32 bit float mat4 of zeroes.\n */\nexport function createMat4f32(): Mat4f32 { return new Float32Array(16); }\n/**\n * Returns a new 64 bit float mat4 set to identity.\n */\nexport function createIdentityMat4f64(): Mat4f64 {\n const m: Mat4f64 = new Float64Array(16);\n mat4.identity(m);\n return m;\n}\n/**\n * Returns a new 32 bit float mat4 set to identity.\n */\nexport function createIdentityMat4f32(): Mat4f32 {\n const m: Mat4f32 = new Float32Array(16);\n mat4.identity(m);\n return m;\n}\n\n/**\n * Returns a translation in tile units that correctly incorporates the view angle and the *-translate and *-translate-anchor properties.\n * @param inViewportPixelUnitsUnits - True when the units accepted by the matrix are in viewport pixels instead of tile units.\n */\nexport function translatePosition(\n transform: { bearingInRadians: number; zoom: number },\n tile: { tileID: OverscaledTileID; tileSize: number },\n translate: [number, number],\n translateAnchor: 'map' | 'viewport',\n inViewportPixelUnitsUnits: boolean = false\n): [number, number] {\n if (!translate[0] && !translate[1]) return [0, 0];\n\n const angle = inViewportPixelUnitsUnits ?\n (translateAnchor === 'map' ? -transform.bearingInRadians : 0) :\n (translateAnchor === 'viewport' ? transform.bearingInRadians : 0);\n\n if (angle) {\n const sinA = Math.sin(angle);\n const cosA = Math.cos(angle);\n translate = [\n translate[0] * cosA - translate[1] * sinA,\n translate[0] * sinA + translate[1] * cosA\n ];\n }\n\n return [\n inViewportPixelUnitsUnits ? translate[0] : pixelsToTileUnits(tile, translate[0], transform.zoom),\n inViewportPixelUnitsUnits ? translate[1] : pixelsToTileUnits(tile, translate[1], transform.zoom)];\n}\n\n/**\n * Returns the signed distance between a point and a plane.\n * @param plane - The plane equation, in the form where the first three components are the normal and the fourth component is the plane's distance from origin along normal.\n * @param point - The point whose distance from plane is returned.\n * @returns Signed distance of the point from the plane. Positive distances are in the half space where the plane normal points to, negative otherwise.\n */\nexport function pointPlaneSignedDistance(\n plane: vec4 | [number, number, number, number],\n point: vec3 | [number, number, number]\n): number {\n return plane[0] * point[0] + plane[1] * point[1] + plane[2] * point[2] + plane[3];\n}\n\n/**\n * Finds an intersection points of three planes. Returns `null` if no such (single) point exists.\n * The planes *must* be in Hessian normal form - their xyz components must form a unit vector.\n */\nexport function threePlaneIntersection(plane0: vec4, plane1: vec4, plane2: vec4): vec3 | null {\n // https://mathworld.wolfram.com/Plane-PlaneIntersection.html\n const det = mat3.determinant([\n plane0[0], plane0[1], plane0[2],\n plane1[0], plane1[1], plane1[2],\n plane2[0], plane2[1], plane2[2]\n ] as mat3);\n if (det === 0) {\n return null;\n }\n const cross12 = vec3.cross([], [plane1[0], plane1[1], plane1[2]], [plane2[0], plane2[1], plane2[2]]);\n const cross20 = vec3.cross([], [plane2[0], plane2[1], plane2[2]], [plane0[0], plane0[1], plane0[2]]);\n const cross01 = vec3.cross([], [plane0[0], plane0[1], plane0[2]], [plane1[0], plane1[1], plane1[2]]);\n const sum = vec3.scale([], cross12, -plane0[3]);\n vec3.add(sum, sum, vec3.scale([], cross20, -plane1[3]));\n vec3.add(sum, sum, vec3.scale([], cross01, -plane2[3]));\n vec3.scale(sum, sum, 1.0 / det);\n return sum;\n}\n\n/**\n * Returns a parameter `t` such that the point obtained by\n * `origin + direction * t` lies on the given plane.\n * If the ray is parallel to the plane, returns null.\n * Returns a negative value if the ray is pointing away from the plane.\n * Direction does not need to be normalized.\n */\nexport function rayPlaneIntersection(origin: vec3, direction: vec3, plane: vec4): number | null {\n const dotOriginPlane = origin[0] * plane[0] + origin[1] * plane[1] + origin[2] * plane[2];\n const dotDirectionPlane = direction[0] * plane[0] + direction[1] * plane[1] + direction[2] * plane[2];\n if (dotDirectionPlane === 0) {\n return null;\n }\n return (-dotOriginPlane -plane[3]) / dotDirectionPlane;\n}\n\n/**\n * Solves a quadratic equation in the form ax^2 + bx + c = 0 and returns its roots in no particular order.\n * Returns null if the equation has no roots or if it has infinitely many roots.\n */\nexport function solveQuadratic(a: number, b: number, c: number): {\n t0: number;\n t1: number;\n} {\n const d = b * b - 4 * a * c;\n if (d < 0 || (a === 0 && b === 0)) {\n return null;\n }\n\n // Uses a more precise solution from the book Ray Tracing Gems, chapter 7.\n // https://www.realtimerendering.com/raytracinggems/rtg/index.html\n const q = -0.5 * (b + Math.sign(b) * Math.sqrt(d));\n if (Math.abs(q) > 1e-12) {\n return {\n t0: c / q,\n t1: q / a\n };\n } else {\n // Use the schoolbook way if q is too small\n return {\n t0: (-b + Math.sqrt(d)) * 0.5 / a,\n t1: (-b + Math.sqrt(d)) * 0.5 / a\n };\n }\n}\n\n/**\n * Returns the angle in radians between two 2D vectors.\n * The angle is signed and describes how much the first vector would need to be be rotated clockwise\n * (assuming X is right and Y is down) so that it points in the same direction as the second vector.\n * @param vec1x - The X component of the first vector.\n * @param vec1y - The Y component of the first vector.\n * @param vec2x - The X component of the second vector.\n * @param vec2y - The Y component of the second vector.\n * @returns The signed angle between the two vectors, in range -PI..PI.\n */\nexport function angleToRotateBetweenVectors2D(vec1x: number, vec1y: number, vec2x: number, vec2y: number): number {\n // Normalize both vectors\n const length1 = Math.sqrt(vec1x * vec1x + vec1y * vec1y);\n const length2 = Math.sqrt(vec2x * vec2x + vec2y * vec2y);\n vec1x /= length1;\n vec1y /= length1;\n vec2x /= length2;\n vec2y /= length2;\n const dot = vec1x * vec2x + vec1y * vec2y;\n const angle = Math.acos(dot);\n // dot second vector with vector to the right of first (-vec1y, vec1x)\n const isVec2RightOfVec1 = (-vec1y * vec2x + vec1x * vec2y) > 0;\n if (isVec2RightOfVec1) {\n return angle;\n } else {\n return -angle;\n }\n}\n\n/**\n * For two angles in degrees, returns how many degrees to add to the first angle in order to obtain the second angle.\n * The returned difference value is always the shorted of the two - its absolute value is never greater than 180°.\n */\nexport function differenceOfAnglesDegrees(degreesA: number, degreesB: number): number {\n const a = mod(degreesA, 360);\n const b = mod(degreesB, 360);\n const diff1 = b - a;\n const diff2 = (b > a) ? (diff1 - 360) : (diff1 + 360);\n if (Math.abs(diff1) < Math.abs(diff2)) {\n return diff1;\n } else {\n return diff2;\n }\n}\n\n/**\n * For two angles in radians, returns how many radians to add to the first angle in order to obtain the second angle.\n * The returned difference value is always the shorted of the two - its absolute value is never greater than PI.\n */\nexport function differenceOfAnglesRadians(degreesA: number, degreesB: number): number {\n const a = mod(degreesA, Math.PI * 2);\n const b = mod(degreesB, Math.PI * 2);\n const diff1 = b - a;\n const diff2 = (b > a) ? (diff1 - Math.PI * 2) : (diff1 + Math.PI * 2);\n if (Math.abs(diff1) < Math.abs(diff2)) {\n return diff1;\n } else {\n return diff2;\n }\n}\n\n/**\n * When given two angles in degrees, returns the angular distance between them - the shorter one of the two possible arcs.\n */\nexport function distanceOfAnglesDegrees(degreesA: number, degreesB: number): number {\n const a = mod(degreesA, 360);\n const b = mod(degreesB, 360);\n return Math.min(\n Math.abs(a - b),\n Math.abs(a - b + 360),\n Math.abs(a - b - 360)\n );\n}\n\n/**\n * When given two angles in radians, returns the angular distance between them - the shorter one of the two possible arcs.\n */\nexport function distanceOfAnglesRadians(radiansA: number, radiansB: number): number {\n const a = mod(radiansA, Math.PI * 2);\n const b = mod(radiansB, Math.PI * 2);\n return Math.min(\n Math.abs(a - b),\n Math.abs(a - b + Math.PI * 2),\n Math.abs(a - b - Math.PI * 2)\n );\n}\n\n/**\n * Modulo function, as opposed to javascript's `%`, which is a remainder.\n * This functions will return positive values, even if the first operand is negative.\n */\nexport function mod(n: number, m: number): number {\n return ((n % m) + m) % m;\n}\n\n/**\n * Takes a value in *old range*, linearly maps that range to *new range*, and returns the value in that new range.\n * Additionally, if the value is outside *old range*, it is clamped inside it.\n * Also works if one of the ranges is flipped (its `min` being larger than `max`).\n */\nexport function remapSaturate(value: number, oldRangeMin: number, oldRangeMax: number, newRangeMin: number, newRangeMax: number): number {\n const inOldRange = clamp((value - oldRangeMin) / (oldRangeMax - oldRangeMin), 0.0, 1.0);\n return lerp(newRangeMin, newRangeMax, inOldRange);\n}\n\n/**\n * Linearly interpolate between two values, similar to `mix` function from GLSL. No clamping is done.\n * @param a - The first value to interpolate. This value is returned when mix=0.\n * @param b - The second value to interpolate. This value is returned when mix=1.\n * @param mix - The interpolation factor. Range 0..1 interpolates between `a` and `b`, but values outside this range are also accepted.\n */\nexport function lerp(a: number, b: number, mix: number): number {\n return a * (1.0 - mix) + b * mix;\n}\n\n/**\n * For a given collection of 2D points, returns their axis-aligned bounding box,\n * in the format [minX, minY, maxX, maxY].\n */\nexport function getAABB(points: Point[]): [number, number, number, number] {\n let tlX = Infinity;\n let tlY = Infinity;\n let brX = -Infinity;\n let brY = -Infinity;\n\n for (const p of points) {\n tlX = Math.min(tlX, p.x);\n tlY = Math.min(tlY, p.y);\n brX = Math.max(brX, p.x);\n brY = Math.max(brY, p.y);\n }\n\n return [tlX, tlY, brX, brY];\n}\n\n/**\n * For a given set of tile ids, returns the edge tile ids for the bounding box.\n */\nexport function getEdgeTiles(tileIDs: OverscaledTileID[]): Set {\n if (!tileIDs.length) return new Set();\n\n // set a common zoom for calculation (highest zoom) to reproject all tiles to this same zoom\n const targetZ = Math.max(...tileIDs.map(id => id.canonical.z));\n\n // vars to store the min and max tile x/y coordinates for edge finding\n let minX = Infinity, maxX = -Infinity;\n let minY = Infinity, maxY = -Infinity;\n\n // project all tiles to targetZ while maintaining the reference to the original tile\n const projected: Array<{id: OverscaledTileID; x: number; y: number}> = [];\n for (const id of tileIDs) {\n const {x, y, z} = id.canonical;\n const scale = Math.pow(2, targetZ - z);\n const px = x * scale;\n const py = y * scale;\n\n projected.push({id, x: px, y: py});\n\n if (px < minX) minX = px;\n if (px > maxX) maxX = px;\n if (py < minY) minY = py;\n if (py > maxY) maxY = py;\n }\n\n // find edge tiles using the reprojected tile ids\n const edgeTiles: Set = new Set();\n for (const p of projected) {\n if (p.x === minX || p.x === maxX || p.y === minY || p.y === maxY) {\n edgeTiles.add(p.id);\n }\n }\n\n return edgeTiles;\n}\n\n/**\n * Given a value `t` that varies between 0 and 1, return\n * an interpolation function that eases between 0 and 1 in a pleasing\n * cubic in-out fashion.\n */\nexport function easeCubicInOut(t: number): number {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n const t2 = t * t,\n t3 = t2 * t;\n return 4 * (t < 0.5 ? t3 : 3 * (t - t2) + t3 - 0.75);\n}\n\n/**\n * Given given (x, y), (x1, y1) control points for a bezier curve,\n * return a function that interpolates along that curve.\n *\n * @param p1x - control point 1 x coordinate\n * @param p1y - control point 1 y coordinate\n * @param p2x - control point 2 x coordinate\n * @param p2y - control point 2 y coordinate\n */\nexport function bezier(p1x: number, p1y: number, p2x: number, p2y: number): (t: number) => number {\n return unitBezierFactory(p1x, p1y, p2x, p2y);\n}\n\n/**\n * A default bezier-curve powered easing function with\n * control points (0.25, 0.1) and (0.25, 1)\n */\nexport const defaultEasing: (t: number) => number = bezier(0.25, 0.1, 0.25, 1);\n\n/**\n * constrain n to the given range via min + max\n *\n * @param n - value\n * @param min - the minimum value to be returned\n * @param max - the maximum value to be returned\n * @returns the clamped value\n */\nexport function clamp(n: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, n));\n}\n\n/**\n * constrain n to the given range, excluding the minimum, via modular arithmetic\n *\n * @param n - value\n * @param min - the minimum value to be returned, exclusive\n * @param max - the maximum value to be returned, inclusive\n * @returns constrained number\n */\nexport function wrap(n: number, min: number, max: number): number {\n const d = max - min;\n const w = ((n - min) % d + d) % d + min;\n return (w === min) ? max : w;\n}\n\n/**\n * Compute the difference between the keys in one object and the keys\n * in another object.\n *\n * @returns keys difference\n */\nexport function keysDifference(\n obj: {[key: string]: S},\n other: {[key: string]: T}\n): string[] {\n const difference = [];\n for (const i in obj) {\n if (!(i in other)) {\n difference.push(i);\n }\n }\n return difference;\n}\n\n/**\n * Given a destination object and optionally many source objects,\n * copy all properties from the source objects into the destination.\n * The last source object given overrides properties from previous\n * source objects.\n *\n * @param dest - destination object\n * @param sources - sources from which properties are pulled\n */\nexport function extend(dest: T, source: U): T & U;\nexport function extend(dest: T, source1: U, source2: V): T & U & V;\nexport function extend(dest: T, source1: U, source2: V, source3: W): T & U & V & W;\nexport function extend(dest: object, ...sources: any[]): any;\nexport function extend(dest: object, ...sources: any[]): any {\n for (const src of sources) {\n for (const k in src) {\n dest[k] = src[k];\n }\n }\n return dest;\n}\n\n// See https://stackoverflow.com/questions/49401866/all-possible-keys-of-an-union-type\ntype KeysOfUnion = T extends T ? keyof T: never;\n\n/**\n * Given an object and a number of properties as strings, return version\n * of that object with only those properties.\n *\n * @param src - the object\n * @param properties - an array of property names chosen\n * to appear on the resulting object.\n * @returns object with limited properties.\n * @example\n * ```ts\n * let foo = { name: 'Charlie', age: 10 };\n * let justName = pick(foo, ['name']); // justName = { name: 'Charlie' }\n * ```\n */\nexport function pick(src: T, properties: Array>): Partial {\n const result: Partial = {};\n for (const k of properties) {\n if (k in src) {\n result[k] = src[k];\n }\n }\n return result;\n}\n\nlet id = 1;\n\n/**\n * Return a unique numeric id, starting at 1 and incrementing with\n * each call.\n *\n * @returns unique numeric id.\n */\nexport function uniqueId(): number {\n return id++;\n}\n\n/**\n * Return whether a given value is a power of two\n */\nexport function isPowerOfTwo(value: number): boolean {\n return (Math.log(value) / Math.LN2) % 1 === 0;\n}\n\n/**\n * Return the next power of two, or the input value if already a power of two\n */\nexport function nextPowerOfTwo(value: number): number {\n if (value <= 1) return 1;\n return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));\n}\n\n/**\n * Computes scaling from zoom level.\n */\nexport function zoomScale(zoom: number): number { return Math.pow(2, zoom); }\n\n/**\n * Computes zoom level from scaling.\n */\nexport function scaleZoom(scale: number): number { return Math.log(scale) / Math.LN2; }\n\n/**\n * Evaluates the snapped zoom level based on zoomSnap. If zoomSnap is 0 or less, the zoom level is returned unchanged.\n * If delta is provided, it performs directional snapping (ceil for zoom-in, floor for zoom-out).\n * @param zoom - The input zoom level\n * @param zoomSnap - The grid interval to snap to, e.g. 1.0 for 1.0 zoom levels, 0.5 for 0.5 zoom levels, etc.\n * @param delta - Optional scroll delta or direction. If positive, snaps up; if negative, snaps down.\n * @returns The snapped zoom level\n */\nexport function evaluateZoomSnap(zoom: number, zoomSnap: number, delta?: number): number {\n if (zoomSnap <= 0) return zoom;\n const inv = 1 / zoomSnap;\n if (delta === undefined || Math.abs(delta) < 1e-10) {\n return Math.round(zoom * inv) / inv;\n }\n return (delta > 0 ? Math.ceil(zoom * inv - 1e-9) : Math.floor(zoom * inv + 1e-10)) / inv;\n}\n\n/**\n * Create an object by mapping all the values of an existing object while\n * preserving their keys.\n */\nexport function mapObject(input: any, iterator: Function, context?: any): any {\n const output = {};\n for (const key in input) {\n output[key] = iterator.call(context || this, input[key], key, input);\n }\n return output;\n}\n\n/**\n * Create an object by filtering out values of an existing object.\n */\nexport function filterObject(input: any, iterator: Function, context?: any): any {\n const output = {};\n for (const key in input) {\n if (iterator.call(context || this, input[key], key, input)) {\n output[key] = input[key];\n }\n }\n return output;\n}\n\n/**\n * Deeply compares two object literals.\n * @param a - first object literal to be compared\n * @param b - second object literal to be compared\n * @returns true if the two object literals are deeply equal, false otherwise\n */\nexport function deepEqual(a?: unknown | null, b?: unknown | null): boolean {\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n if (typeof a === 'object' && a !== null && b !== null) {\n if (!(typeof b === 'object')) return false;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n for (const key in a) {\n if (!deepEqual(a[key], b[key])) return false;\n }\n return true;\n }\n return a === b;\n}\n\n/**\n * Deeply clones two objects.\n */\nexport function clone(input: T): T {\n if (Array.isArray(input)) {\n return input.map(clone) as any as T;\n } else if (typeof input === 'object' && input) {\n return mapObject(input, clone) as T;\n } else {\n return input;\n }\n}\n\n/**\n * Check if two arrays have at least one common element.\n */\nexport function arraysIntersect(a: T[], b: T[]): boolean {\n for (const element of a) {\n if (b.includes(element)) return true;\n }\n return false;\n}\n\n/**\n * Print a warning message to the console and ensure duplicate warning messages\n * are not printed.\n */\nconst warnOnceHistory: {[key: string]: boolean} = {};\n\nexport function warnOnce(message: string): void {\n if (!warnOnceHistory[message]) {\n // console isn't defined in some WebWorkers, see #2558\n if (typeof console !== 'undefined') console.warn(message);\n warnOnceHistory[message] = true;\n }\n}\n\n/**\n * Indicates if the provided Points are in a counter clockwise (true) or clockwise (false) order\n *\n * @returns true for a counter clockwise set of points\n */\n// https://bryceboe.com/2006/10/23/line-segment-intersection-algorithm/\nexport function isCounterClockwise(a: Point, b: Point, c: Point): boolean {\n return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x);\n}\n\n/**\n * For two lines a and b in 2d space, defined by any two points along the lines,\n * find the intersection point, or return null if the lines are parallel\n *\n * @param a1 - First point on line a\n * @param a2 - Second point on line a\n * @param b1 - First point on line b\n * @param b2 - Second point on line b\n *\n * @returns the intersection point of the two lines or null if they are parallel\n */\nexport function findLineIntersection(a1: Point, a2: Point, b1: Point, b2: Point): Point | null {\n const aDeltaY = a2.y - a1.y;\n const aDeltaX = a2.x - a1.x;\n const bDeltaY = b2.y - b1.y;\n const bDeltaX = b2.x - b1.x;\n\n const denominator = (bDeltaY * aDeltaX) - (bDeltaX * aDeltaY);\n\n if (denominator === 0) {\n // Lines are parallel\n return null;\n }\n\n const originDeltaY = a1.y - b1.y;\n const originDeltaX = a1.x - b1.x;\n const aInterpolation = (bDeltaX * originDeltaY - bDeltaY * originDeltaX) / denominator;\n\n // Find intersection by projecting out from origin of first segment\n return new Point(a1.x + (aInterpolation * aDeltaX), a1.y + (aInterpolation * aDeltaY));\n}\n\n/**\n * Converts spherical coordinates to cartesian coordinates.\n *\n * @param spherical - Spherical coordinates, in [radial, azimuthal, polar]\n * @returns cartesian coordinates in [x, y, z]\n */\nexport function sphericalToCartesian([r, azimuthal, polar]: [number, number, number]): vec3 {\n // We abstract \"north\"/\"up\" (compass-wise) to be 0° when really this is 90° (π/2):\n // correct for that here\n azimuthal += 90;\n\n // Convert azimuthal and polar angles to radians\n azimuthal *= Math.PI / 180;\n polar *= Math.PI / 180;\n\n return [\n r * Math.cos(azimuthal) * Math.sin(polar),\n r * Math.sin(azimuthal) * Math.sin(polar),\n r * Math.cos(polar)\n ];\n}\n\n/**\n * Returns true if the when run in the web-worker context.\n *\n * @returns `true` if the when run in the web-worker context.\n */\nexport function isWorker(self: any): self is WorkerGlobalScopeInterface {\n // @ts-ignore\n return typeof WorkerGlobalScope !== 'undefined' && typeof self !== 'undefined' && self instanceof WorkerGlobalScope;\n}\n\n/**\n * Parses data from 'Cache-Control' headers.\n *\n * @param cacheControl - Value of 'Cache-Control' header\n * @returns object containing parsed header info.\n */\n\nexport function parseCacheControl(cacheControl: string): any {\n // Taken from [Wreck](https://github.com/hapijs/wreck)\n const re = /(?:^|(?:\\s*\\,\\s*))([^\\x00-\\x20\\(\\)<>@\\,;\\:\\\\\"\\/\\[\\]\\?\\=\\{\\}\\x7F]+)(?:\\=(?:([^\\x00-\\x20\\(\\)<>@\\,;\\:\\\\\"\\/\\[\\]\\?\\=\\{\\}\\x7F]+)|(?:\\\"((?:[^\"\\\\]|\\\\.)*)\\\")))?/g;\n\n const header = {};\n cacheControl.replace(re, ($0, $1, $2, $3) => {\n const value = $2 || $3;\n header[$1] = value ? value.toLowerCase() : true;\n return '';\n });\n\n if (header['max-age']) {\n const maxAge = parseInt(header['max-age'], 10);\n if (isNaN(maxAge)) delete header['max-age'];\n else header['max-age'] = maxAge;\n }\n\n return header;\n}\n\nlet _isSafari = null;\n\n/**\n * Returns true when run in WebKit derived browsers.\n * This is used as a workaround for a memory leak in Safari caused by using Transferable objects to\n * transfer data between WebWorkers and the main thread.\n * https://github.com/mapbox/mapbox-gl-js/issues/8771\n *\n * This should be removed once the underlying Safari issue is fixed.\n *\n * @param scope - Since this function is used both on the main thread and WebWorker context,\n * let the calling scope pass in the global scope object.\n * @returns `true` when run in WebKit derived browsers.\n */\nexport function isSafari(scope: any): boolean {\n if (_isSafari == null) {\n const userAgent = scope.navigator ? scope.navigator.userAgent : null;\n _isSafari = !!scope.safari ||\n !!(userAgent && (/\\b(iPad|iPhone|iPod)\\b/.test(userAgent) || (!!userAgent.match('Safari') && !userAgent.match('Chrome'))));\n }\n return _isSafari;\n}\n\n// The following methods are from https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem\n//Unicode compliant base64 encoder for strings\nexport function b64EncodeUnicode(str: string): string {\n return btoa(\n encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,\n (match, p1) => {\n return String.fromCharCode(Number('0x' + p1)); //eslint-disable-line\n }\n )\n );\n}\n\n// Unicode compliant decoder for base64-encoded strings\nexport function b64DecodeUnicode(str: string): string {\n return decodeURIComponent(atob(str).split('').map((c) => {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); //eslint-disable-line\n }).join(''));\n}\n\nexport function isImageBitmap(image: any): image is ImageBitmap {\n return typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap;\n}\n\n/**\n * Converts an ArrayBuffer to an ImageBitmap.\n *\n * Used mostly for testing purposes only, because mocking libs don't know how to work with ArrayBuffers, but work\n * perfectly fine with ImageBitmaps. Might also be used for environments (other than testing) not supporting\n * ArrayBuffers.\n *\n * @param data - Data to convert\n * @returns - A promise resolved when the conversion is finished\n */\nexport const arrayBufferToImageBitmap = async (data: ArrayBuffer, options?: ImageBitmapOptions): Promise => {\n if (data.byteLength === 0) {\n return createImageBitmap(new ImageData(1, 1), options);\n }\n const blob: Blob = new Blob([new Uint8Array(data)], {type: 'image/png'});\n try {\n return createImageBitmap(blob, options);\n } catch (e) {\n throw new Error(`Could not load image because of ${ensureError(e).message}. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.`);\n }\n};\n\nconst transparentPngUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=';\n\n/**\n * Converts an ArrayBuffer to an HTMLImageElement.\n *\n * Used mostly for testing purposes only, because mocking libs don't know how to work with ArrayBuffers, but work\n * perfectly fine with ImageBitmaps. Might also be used for environments (other than testing) not supporting\n * ArrayBuffers.\n *\n * @param data - Data to convert\n * @returns - A promise resolved when the conversion is finished\n */\nexport const arrayBufferToImage = (data: ArrayBuffer): Promise => {\n return new Promise((resolve, reject) => {\n const img: HTMLImageElement = new Image();\n img.onload = () => {\n resolve(img);\n URL.revokeObjectURL(img.src);\n // prevent image dataURI memory leak in Safari;\n // but don't free the image immediately because it might be uploaded in the next frame\n // https://github.com/mapbox/mapbox-gl-js/issues/10226\n img.onload = null;\n window.requestAnimationFrame(() => img.src = transparentPngUrl);\n };\n img.onerror = () => reject(new Error('Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.'));\n const blob: Blob = new Blob([new Uint8Array(data)], {type: 'image/png'});\n img.src = data.byteLength ? URL.createObjectURL(blob) : transparentPngUrl;\n });\n};\n\n/**\n * Computes the webcodecs VideoFrame API options to select a rectangle out of\n * an image and write it into the destination rectangle.\n *\n * Rect (x/y/width/height) select the overlapping rectangle from the source image\n * and layout (offset/stride) write that overlapping rectangle to the correct place\n * in the destination image.\n *\n * Offset is the byte offset in the dest image that the first pixel appears at\n * and stride is the number of bytes to the start of the next row:\n * ┌───────────┐\n * │ dest │\n * │ ┌───┼───────┐\n * │offset→│▓▓▓│ source│\n * │ │▓▓▓│ │\n * │ └───┼───────┘\n * │stride ⇠╌╌╌│\n * │╌╌╌╌╌╌→ │\n * └───────────┘\n *\n * @param image - source image containing a width and height attribute\n * @param x - top-left x coordinate to read from the image\n * @param y - top-left y coordinate to read from the image\n * @param width - width of the rectangle to read from the image\n * @param height - height of the rectangle to read from the image\n * @returns the layout and rect options to pass into VideoFrame API\n */\nfunction computeVideoFrameParameters(image: Size, x: number, y: number, width: number, height: number): VideoFrameCopyToOptions {\n const destRowOffset = Math.max(-x, 0) * 4;\n const firstSourceRow = Math.max(0, y);\n const firstDestRow = firstSourceRow - y;\n const offset = firstDestRow * width * 4 + destRowOffset;\n const stride = width * 4;\n\n const sourceLeft = Math.max(0, x);\n const sourceTop = Math.max(0, y);\n const sourceRight = Math.min(image.width, x + width);\n const sourceBottom = Math.min(image.height, y + height);\n return {\n rect: {\n x: sourceLeft,\n y: sourceTop,\n width: sourceRight - sourceLeft,\n height: sourceBottom - sourceTop\n },\n layout: [{offset, stride}]\n };\n}\n\n/**\n * Reads pixels from an ImageBitmap/Image/canvas using webcodec VideoFrame API.\n *\n * @param data - image, imagebitmap, or canvas to parse\n * @param x - top-left x coordinate to read from the image\n * @param y - top-left y coordinate to read from the image\n * @param width - width of the rectangle to read from the image\n * @param height - height of the rectangle to read from the image\n * @returns a promise containing the parsed RGBA pixel values of the image, or the error if an error occurred\n */\nexport async function readImageUsingVideoFrame(\n image: HTMLImageElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas,\n x: number, y: number, width: number, height: number\n): Promise {\n if (typeof VideoFrame === 'undefined') {\n throw new Error('VideoFrame not supported');\n }\n const frame = new VideoFrame(image, {timestamp: 0});\n try {\n const format = frame?.format;\n if (!format || !(format.startsWith('BGR') || format.startsWith('RGB'))) {\n throw new Error(`Unrecognized format ${format}`);\n }\n const swapBR = format.startsWith('BGR');\n const result = new Uint8ClampedArray(width * height * 4);\n await frame.copyTo(result, computeVideoFrameParameters(image, x, y, width, height));\n if (swapBR) {\n for (let i = 0; i < result.length; i += 4) {\n const tmp = result[i];\n result[i] = result[i + 2];\n result[i + 2] = tmp;\n }\n }\n return result;\n } finally {\n frame.close();\n }\n}\n\nlet offscreenCanvas: OffscreenCanvas;\nlet offscreenCanvasContext: OffscreenCanvasRenderingContext2D;\n\n/**\n * Reads pixels from an ImageBitmap/Image/canvas using OffscreenCanvas\n *\n * @param data - image, imagebitmap, or canvas to parse\n * @param x - top-left x coordinate to read from the image\n * @param y - top-left y coordinate to read from the image\n * @param width - width of the rectangle to read from the image\n * @param height - height of the rectangle to read from the image\n * @returns a promise containing the parsed RGBA pixel values of the image, or the error if an error occurred\n */\nexport function readImageDataUsingOffscreenCanvas(\n imgBitmap: HTMLImageElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas,\n x: number, y: number, width: number, height: number\n): Uint8ClampedArray {\n const origWidth = imgBitmap.width;\n const origHeight = imgBitmap.height;\n // Lazily initialize OffscreenCanvas\n if (!offscreenCanvas || !offscreenCanvasContext) {\n // Dem tiles are typically 256x256\n offscreenCanvas = new OffscreenCanvas(origWidth, origHeight);\n offscreenCanvasContext = offscreenCanvas.getContext('2d', {willReadFrequently: true});\n }\n\n offscreenCanvas.width = origWidth;\n offscreenCanvas.height = origHeight;\n\n offscreenCanvasContext.drawImage(imgBitmap, 0, 0, origWidth, origHeight);\n const imgData = offscreenCanvasContext.getImageData(x, y, width, height);\n offscreenCanvasContext.clearRect(0, 0, origWidth, origHeight);\n return imgData.data;\n}\n\n/**\n * Reads RGBA pixels from an preferring OffscreenCanvas, but falling back to VideoFrame if supported and\n * the browser is mangling OffscreenCanvas getImageData results.\n *\n * @param data - image, imagebitmap, or canvas to parse\n * @param x - top-left x coordinate to read from the image\n * @param y - top-left y coordinate to read from the image\n * @param width - width of the rectangle to read from the image\n * @param height - height of the rectangle to read from the image\n * @returns a promise containing the parsed RGBA pixel values of the image\n */\nexport async function getImageData(\n image: HTMLImageElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas,\n x: number, y: number, width: number, height: number\n): Promise {\n if (isOffscreenCanvasDistorted()) {\n try {\n return await readImageUsingVideoFrame(image, x, y, width, height);\n } catch {\n // fall back to OffscreenCanvas\n }\n }\n return readImageDataUsingOffscreenCanvas(image, x, y, width, height);\n}\n\n/**\n * Allows to unsubscribe from events without the need to store the method reference.\n */\nexport interface Subscription {\n /**\n * Unsubscribes from the event.\n */\n unsubscribe(): void;\n}\n\nexport interface Subscriber {\n addEventListener: typeof window.addEventListener;\n removeEventListener: typeof window.removeEventListener;\n}\n\n/**\n * This method is used in order to register an event listener using a lambda function.\n * The return value will allow unsubscribing from the event, without the need to store the method reference.\n * @param target - The target\n * @param message - The message\n * @param listener - The listener\n * @param options - The options\n * @returns a subscription object that can be used to unsubscribe from the event\n */\nexport function subscribe(target: Subscriber, message: keyof WindowEventMap, listener: (...args: any) => void, options: boolean | AddEventListenerOptions): Subscription {\n target.addEventListener(message, listener, options);\n return {\n unsubscribe: () => {\n target.removeEventListener(message, listener, options);\n }\n };\n}\n\n/**\n * This method converts degrees to radians.\n * The return value is the radian value.\n * @param degrees - The number of degrees\n * @returns radians\n */\nexport function degreesToRadians(degrees: number): number {\n return degrees * Math.PI / 180;\n}\n\n/**\n * This method converts radians to degrees.\n * The return value is the degrees value.\n * @param degrees - The number of radians\n * @returns degrees\n */\nexport function radiansToDegrees(degrees: number): number {\n return degrees / Math.PI * 180;\n}\n\nexport type RollPitchBearing = {\n roll: number;\n pitch: number;\n bearing: number;\n};\n\nexport function rollPitchBearingEqual(a: RollPitchBearing, b: RollPitchBearing): boolean {\n return a.roll == b.roll && a.pitch == b.pitch && a.bearing == b.bearing;\n}\n\n/**\n * This method converts a rotation quaternion to roll, pitch, and bearing angles in degrees.\n * @param rotation - The rotation quaternion\n * @returns roll, pitch, and bearing angles in degrees\n */\nexport function getRollPitchBearing(rotation: quat): RollPitchBearing {\n const m: mat3 = new Float64Array(9);\n mat3.fromQuat(m, rotation);\n\n const xAngle = radiansToDegrees(-Math.asin(clamp(m[2], -1, 1)));\n let roll: number;\n let bearing: number;\n if (Math.hypot(m[5], m[8]) < 1.0e-3) {\n roll = 0.0;\n bearing = -radiansToDegrees(Math.atan2(m[3], m[4]));\n } else {\n roll = radiansToDegrees((m[5] === 0.0 && m[8] === 0.0) ? 0.0 : Math.atan2(m[5], m[8]));\n bearing = radiansToDegrees((m[1] === 0.0 && m[0] === 0.0) ? 0.0 : Math.atan2(m[1], m[0]));\n }\n\n return {roll, pitch: xAngle + 90.0, bearing};\n}\n\nexport function getAngleDelta(lastPoint: Point, currentPoint: Point, center: Point): number {\n const pointVect = vec2.fromValues(currentPoint.x - center.x, currentPoint.y - center.y);\n const lastPointVec = vec2.fromValues(lastPoint.x - center.x, lastPoint.y - center.y);\n\n const crossProduct = pointVect[0] * lastPointVec[1] - pointVect[1] * lastPointVec[0];\n const angleRadians = Math.atan2(crossProduct, vec2.dot(pointVect, lastPointVec));\n return radiansToDegrees(angleRadians);\n}\n\n/**\n * This method converts roll, pitch, and bearing angles in degrees to a rotation quaternion.\n * @param roll - Roll angle in degrees\n * @param pitch - Pitch angle in degrees\n * @param bearing - Bearing angle in degrees\n * @returns The rotation quaternion\n */\nexport function rollPitchBearingToQuat(roll: number, pitch: number, bearing: number): quat {\n const rotation: quat = new Float64Array(4);\n quat.fromEuler(rotation, roll, pitch - 90.0, bearing);\n return rotation;\n}\n\n/**\n * Makes optional keys required and add the the undefined type.\n *\n * ```\n * interface Test {\n * foo: number;\n * bar?: number;\n * baz: number | undefined;\n * }\n *\n * Complete {\n * foo: number;\n * bar: number | undefined;\n * baz: number | undefined;\n * }\n *\n * ```\n *\n * See https://medium.com/terria/typescript-transforming-optional-properties-to-required-properties-that-may-be-undefined-7482cb4e1585\n */\n\nexport type Complete = {\n [P in keyof Required]: Pick extends Required> ? T[P] : (T[P] | undefined);\n};\n\n/**\n * A helper to allow require of at least one property\n */\nexport type RequireAtLeastOne = { [K in keyof T]-?: Required> & Partial>>; }[keyof T];\n\n/**\n* A helper to allow require exactly one one property\n */\nexport type ExactlyOne = {\n [K in Keys]: Required> & { [P in Exclude]?: never }\n}[Keys];\n\nexport type TileJSON = {\n tilejson: '2.2.0' | '2.1.0' | '2.0.1' | '2.0.0' | '1.0.0';\n name?: string;\n description?: string;\n version?: string;\n attribution?: string;\n template?: string;\n tiles: string[];\n grids?: string[];\n data?: string[];\n minzoom?: number;\n maxzoom?: number;\n bounds?: [number, number, number, number];\n center?: [number, number, number];\n vector_layers: [{id: string}]; // this is partial but enough for what we need\n};\n\n/**\n * The maximum world tile zoom (Z).\n * In other words, the upper bound supported for tile zoom.\n */\nexport const MAX_TILE_ZOOM = 25;\n\n/**\n * The minimum world tile zoom (Z).\n * In other words, the lower bound supported for tile zoom.\n */\nexport const MIN_TILE_ZOOM = 0;\n\nexport const MAX_VALID_LATITUDE = 85.051129;\n\nconst touchableEvents = {\n touchstart: true,\n touchmove: true,\n touchmoveWindow: true,\n touchend: true,\n touchcancel: true\n};\n\nconst pointableEvents = {\n dblclick: true,\n click: true,\n mouseover: true,\n mouseout: true,\n mousedown: true,\n mousemove: true,\n mousemoveWindow: true,\n mouseup: true,\n mouseupWindow: true,\n contextmenu: true,\n wheel: true\n};\n\nexport function isTouchableEvent(event: Event, eventType: string): event is TouchEvent {\n return touchableEvents[eventType] && 'touches' in event;\n}\n\n/**\n * Checks if an event is a pointable event (mouse or wheel event).\n * Uses the event target's window context for cross-window support.\n */\nexport function isPointableEvent(event: Event, eventType: string): event is MouseEvent {\n if (!pointableEvents[eventType]) return false;\n\n // Get the window context from the event target to use the correct constructor.\n const domEvent = event as globalThis.Event;\n const target = domEvent?.target as Element | null;\n const targetWindow = target?.ownerDocument?.defaultView || window;\n return domEvent instanceof targetWindow.MouseEvent || domEvent instanceof targetWindow.WheelEvent;\n}\n\nexport function isTouchableOrPointableType(eventType: string): boolean {\n return touchableEvents[eventType] || pointableEvents[eventType];\n}\n","/**\n * An error message to use when an operation is aborted\n */\nexport const ABORT_ERROR = 'AbortError';\n\nexport class AbortError extends Error {\n name: string = ABORT_ERROR;\n\n constructor(messageOrError: string | Error = ABORT_ERROR) {\n super(messageOrError instanceof Error ? messageOrError.message : messageOrError);\n if (messageOrError instanceof Error && messageOrError.stack) {\n this.stack = messageOrError.stack;\n }\n }\n}\n\n/**\n * Check if an error is an abort error\n * @param error - An error object\n * @returns - true if the error is an abort error\n */\nexport function isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === ABORT_ERROR;\n}\n\n/**\n * Throws an AbortError if the provided abort signal has already been aborted.\n *\n * @param signal - The abort signal to check.\n * @throws AbortError If the signal is aborted.\n */\nexport function throwIfAborted(signal: AbortSignal): void {\n if (signal.aborted) {\n throw new AbortError(signal.reason);\n }\n}\n","import type {RequestParameters, GetResourceResponse} from './ajax.ts';\n\n/**\n * This method type is used to register a protocol handler.\n * Use the abort controller for aborting requests.\n * Return a promise with the relevant resource response.\n */\nexport type AddProtocolAction = (requestParameters: RequestParameters, abortController: AbortController) => Promise>;\n\n/**\n * This is a global config object used to store the configuration\n * It is available in the workers as well.\n * Only serializable data should be stored in it.\n */\ntype Config = {\n MAX_PARALLEL_IMAGE_REQUESTS: number;\n MAX_PARALLEL_IMAGE_REQUESTS_PER_FRAME: number;\n MAX_TILE_CACHE_ZOOM_LEVELS: number;\n REGISTERED_PROTOCOLS: {[x: string]: AddProtocolAction };\n WORKER_URL: string;\n};\n\nexport const config: Config = {\n MAX_PARALLEL_IMAGE_REQUESTS: 16,\n MAX_PARALLEL_IMAGE_REQUESTS_PER_FRAME: 8,\n MAX_TILE_CACHE_ZOOM_LEVELS: 5,\n REGISTERED_PROTOCOLS: {},\n WORKER_URL: ''\n};\n","import {type AddProtocolAction, config} from '../util/config.ts';\n\nexport function getProtocol(url: string): AddProtocolAction {\n return config.REGISTERED_PROTOCOLS[url.substring(0, url.indexOf('://'))];\n}\n/**\n * Adds a custom load resource function that will be called when using a URL that starts with a custom url schema.\n * This will happen in the main thread, and workers might call it if they don't know how to handle the protocol.\n * The example below will be triggered for custom:// urls defined in the sources list in the style definitions.\n * The function passed will receive the request parameters and should return with the resulting resource,\n * for example a pbf vector tile, non-compressed, represented as ArrayBuffer.\n *\n * @param customProtocol - the protocol to hook, for example 'custom'\n * @param loadFn - the function to use when trying to fetch a tile specified by the customProtocol\n * @example\n * ```ts\n * // This will fetch a file using the fetch API (this is obviously a non interesting example...)\n * addProtocol('custom', async (params, abortController) => {\n * const t = await fetch(`https://${params.url.split(\"://\")[1]}`);\n * if (t.status == 200) {\n * const buffer = await t.arrayBuffer();\n * return {data: buffer}\n * } else {\n * throw new Error(`Tile fetch error: ${t.statusText}`);\n * }\n * });\n * // the following is an example of a way to return an error when trying to load a tile\n * addProtocol('custom2', async (params, abortController) => {\n * throw new Error('someErrorMessage');\n * });\n * ```\n * @see [Add a COG raster source](https://maplibre.org/maplibre-gl-js/docs/examples/add-a-cog-raster-source/)\n * @see [Add Contour Lines](https://maplibre.org/maplibre-gl-js/docs/examples/add-contour-lines/)\n * @see [PMTiles source and protocol](https://maplibre.org/maplibre-gl-js/docs/examples/pmtiles-source-and-protocol/)\n * @see [Use addProtocol to Transform Feature Properties](https://maplibre.org/maplibre-gl-js/docs/examples/use-addprotocol-to-transform-feature-properties/)\n */\nexport function addProtocol(customProtocol: string, loadFn: AddProtocolAction): void {\n config.REGISTERED_PROTOCOLS[customProtocol] = loadFn;\n}\n\n/**\n * Removes a previously added protocol in the main thread.\n *\n * @param customProtocol - the custom protocol to remove registration for\n * @example\n * ```ts\n * removeProtocol('custom');\n * ```\n */\nexport function removeProtocol(customProtocol: string): void {\n delete config.REGISTERED_PROTOCOLS[customProtocol];\n}\n","import {ensureError, extend, isWorker} from './util.ts';\nimport {AbortError, isAbortError, throwIfAborted} from './abort_error.ts';\nimport {getProtocol} from '../source/protocol_crud.ts';\nimport {MessageType} from './actor_messages.ts';\n\n/**\n * This is used to identify the global dispatcher id when sending a message from the worker without a target map id.\n */\nexport const GLOBAL_DISPATCHER_ID = 'global-dispatcher';\n\n/**\n * A type used to store the tile's expiration date and cache control definition\n */\nexport type ExpiryData = {cacheControl?: string | null; expires?: Date | string | null; etag?: string};\n\n/**\n * A `RequestParameters` object to be returned from Map.options.transformRequest callbacks.\n * @example\n * ```ts\n * // use transformRequest to modify requests that begin with `http://myHost`\n * transformRequest: function(url, resourceType) {\n * if (resourceType === 'Source' && url.indexOf('http://myHost') > -1) {\n * return {\n * url: url.replace('http', 'https'),\n * headers: { 'my-custom-header': true },\n * credentials: 'include' // Include cookies for cross-origin requests\n * }\n * }\n * }\n * ```\n */\nexport type RequestParameters = {\n /**\n * The URL to be requested.\n */\n url: string;\n /**\n * The headers to be sent with the request.\n */\n headers?: any;\n /**\n * Request method `'GET' | 'POST' | 'PUT'`.\n */\n method?: 'GET' | 'POST' | 'PUT';\n /**\n * Request body.\n */\n body?: string;\n /**\n * Response body type to be returned.\n */\n type?: 'string' | 'json' | 'arrayBuffer' | 'image';\n /**\n * `'same-origin'|'include'` Use 'include' to send cookies with cross-origin requests.\n */\n credentials?: 'same-origin' | 'include';\n /**\n * If `true`, Resource Timing API information will be collected for these transformed requests and returned in a resourceTiming property of relevant data events.\n */\n collectResourceTiming?: boolean;\n /**\n * Parameters supported only by browser fetch API. Property of the Request interface contains the cache mode of the request. It controls how the request will interact with the browser's HTTP cache. (https://developer.mozilla.org/en-US/docs/Web/API/Request/cache)\n */\n cache?: RequestCache;\n /**\n * The referrer policy to use for the request. Controls how much referrer information is sent. (https://developer.mozilla.org/en-US/docs/Web/API/Request/referrerPolicy)\n */\n referrerPolicy?: ReferrerPolicy;\n};\n\n/**\n * The response object returned from a successful AJAx request\n */\nexport type GetResourceResponse = ExpiryData & {\n data: T;\n};\n\n/**\n * The response callback used in various places\n */\nexport type ResponseCallback = (\n error?: Error | null,\n data?: T | null,\n cacheControl?: string | null,\n expires?: string | Date | null\n) => void;\n\n/**\n * An error thrown when a HTTP request results in an error response.\n */\nexport class AJAXError extends Error {\n /**\n * The response's HTTP status code.\n */\n status: number;\n\n /**\n * The response's HTTP status text.\n */\n statusText: string;\n\n /**\n * The request's URL.\n */\n url: string;\n\n /**\n * The response's body.\n */\n body: Blob;\n\n /**\n * @param status - The response's HTTP status code.\n * @param statusText - The response's HTTP status text.\n * @param url - The request's URL.\n * @param body - The response's body.\n */\n constructor(status: number, statusText: string, url: string, body: Blob) {\n super(`AJAXError: ${statusText} (${status}): ${url}`);\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n this.body = body;\n }\n}\n\n/**\n * Ensure that we're sending the correct referrer from blob URL worker bundles.\n * For files loaded from the local file system, `location.origin` will be set\n * to the string(!) \"null\" (Firefox), or \"file://\" (Chrome, Safari, Edge),\n * and we will set an empty referrer. Otherwise, we're using the document's URL.\n * If we're on a blob URL and parent window is cross-origin, parent.location throws\n * SecurityError DOMException, this means we are probably not in blob URL worker bundle.\n */\nexport function getReferrer(): string {\n if (isWorker(self)) return self.worker?.referrer;\n if (window.location.protocol === 'blob:') {\n try {\n return window.parent.location.href;\n } catch {}\n }\n return window.location.href;\n}\n\n/**\n * Determines whether a URL is a file:// URL. This is obviously the case if it begins\n * with file://. Relative URLs are also file:// URLs iff the original document was loaded\n * via a file:// URL.\n * @param url - The URL to check\n * @returns `true` if the URL is a file:// URL, `false` otherwise\n */\nconst isFileURL = url => url.startsWith('file:') || (getReferrer()?.startsWith('file:') && !/^\\w+:/.test(url));\n\nasync function makeFetchRequest(requestParameters: RequestParameters, abortController: AbortController): Promise> {\n const request = new Request(requestParameters.url, {\n method: requestParameters.method || 'GET',\n body: requestParameters.body,\n credentials: requestParameters.credentials,\n headers: requestParameters.headers,\n cache: requestParameters.cache,\n referrer: getReferrer(),\n referrerPolicy: requestParameters.referrerPolicy,\n signal: abortController.signal\n });\n\n // If the user has already set an Accept header, do not overwrite it here\n if (requestParameters.type === 'json' && !request.headers.has('Accept')) {\n request.headers.set('Accept', 'application/json');\n }\n\n let response: Response;\n try {\n response = await fetch(request);\n } catch (e) {\n // Pass through AbortErrors for upstream handling\n if (isAbortError(e)) {\n throw e;\n }\n\n // When the error is due to CORS policy, DNS issue or malformed URL, the fetch call does not resolve but throws a generic TypeError instead.\n // It is preferable to throw an AJAXError so that the Map event \"error\" can catch it and still have\n // access to the faulty url. In such case, we provide the arbitrary HTTP error code of `0`.\n throw new AJAXError(0, ensureError(e).message, requestParameters.url, new Blob());\n }\n\n if (!response.ok) {\n const body = await response.blob();\n throw new AJAXError(response.status, response.statusText, requestParameters.url, body);\n }\n let parsePromise: Promise;\n if ((requestParameters.type === 'arrayBuffer' || requestParameters.type === 'image')) {\n parsePromise = response.arrayBuffer();\n } else if (requestParameters.type === 'json') {\n parsePromise = response.json();\n } else {\n parsePromise = response.text();\n }\n const result = await parsePromise;\n throwIfAborted(abortController.signal);\n return {data: result, cacheControl: response.headers.get('Cache-Control'), expires: response.headers.get('Expires'), etag: response.headers.get('ETag')};\n}\n\nfunction makeXMLHttpRequest(requestParameters: RequestParameters, abortController: AbortController): Promise> {\n return new Promise((resolve, reject) => {\n const xhr: XMLHttpRequest = new XMLHttpRequest();\n\n xhr.open(requestParameters.method || 'GET', requestParameters.url, true);\n if (requestParameters.type === 'arrayBuffer' || requestParameters.type === 'image') {\n xhr.responseType = 'arraybuffer';\n }\n for (const k in requestParameters.headers) {\n xhr.setRequestHeader(k, requestParameters.headers[k]);\n }\n if (requestParameters.type === 'json') {\n xhr.responseType = 'text';\n // Do not overwrite the user-provided Accept header\n if (!requestParameters.headers?.Accept) {\n xhr.setRequestHeader('Accept', 'application/json');\n }\n }\n xhr.withCredentials = requestParameters.credentials === 'include';\n xhr.onerror = () => {\n reject(new Error(xhr.statusText));\n };\n xhr.onload = () => {\n if (abortController.signal.aborted) {\n return;\n }\n if (((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) && xhr.response !== null) {\n let data: unknown = xhr.response;\n if (requestParameters.type === 'json') {\n // We're manually parsing JSON here to get better error messages.\n try {\n data = JSON.parse(xhr.response);\n } catch (err) {\n reject(err);\n return;\n }\n }\n resolve({data, cacheControl: xhr.getResponseHeader('Cache-Control'), expires: xhr.getResponseHeader('Expires'), etag: xhr.getResponseHeader('ETag')});\n } else {\n const body = new Blob([xhr.response], {type: xhr.getResponseHeader('Content-Type')});\n reject(new AJAXError(xhr.status, xhr.statusText, requestParameters.url, body));\n }\n };\n abortController.signal.addEventListener('abort', () => {\n xhr.abort();\n reject(new AbortError(abortController.signal.reason));\n });\n xhr.send(requestParameters.body);\n });\n}\n\n/**\n * We're trying to use the Fetch API if possible. However, requests for resources with the file:// URI scheme don't work with the Fetch API.\n * In this case we unconditionally use XHR on the current thread since referrers don't matter.\n * This method can also use the registered method if `addProtocol` was called.\n * @param requestParameters - The request parameters\n * @param abortController - The abort controller allowing to cancel the request\n * @returns a promise resolving to the response, including cache control and expiry data\n */\nexport const makeRequest = async function(requestParameters: RequestParameters, abortController: AbortController): Promise> {\n if (requestParameters.url.includes('://') && !(/^https?:|^file:/.test(requestParameters.url))) {\n const protocolLoadFn = getProtocol(requestParameters.url);\n if (protocolLoadFn) {\n const response = await protocolLoadFn(requestParameters, abortController);\n if (!response.data && requestParameters.type === 'arrayBuffer') {\n // A successful array buffer request should always return data even if empty\n return extend(response, {data: new ArrayBuffer(0)});\n }\n return response;\n }\n if (isWorker(self) && self.worker?.actor) {\n return self.worker.actor.sendAsync({type: MessageType.getResource, data: requestParameters, targetMapId: GLOBAL_DISPATCHER_ID}, abortController);\n }\n }\n if (!isFileURL(requestParameters.url)) {\n if (fetch && Request && AbortController && Object.hasOwn(Request.prototype, 'signal')) {\n return makeFetchRequest(requestParameters, abortController);\n }\n if (isWorker(self) && self.worker?.actor) {\n return self.worker.actor.sendAsync({type: MessageType.getResource, data: requestParameters, mustQueue: true, targetMapId: GLOBAL_DISPATCHER_ID}, abortController);\n }\n }\n return makeXMLHttpRequest(requestParameters, abortController);\n};\n\nexport const getJSON = (requestParameters: RequestParameters, abortController: AbortController): Promise<{data: T} & ExpiryData> => {\n return makeRequest(extend(requestParameters, {type: 'json'}), abortController);\n};\n\nexport const getArrayBuffer = (requestParameters: RequestParameters, abortController: AbortController): Promise<{data: ArrayBuffer} & ExpiryData> => {\n return makeRequest(extend(requestParameters, {type: 'arrayBuffer'}), abortController);\n};\n\n/** \n * Determines whether a URL is same origin as the current location. Supports relative URLs too.\n * \n * A relative URL \"/foo\" or \"./foo\" will throw exception in URL's ctor,\n * try-catch is expansive so just use a heuristic check to avoid it\n * \n * - Relative URL and empty URL are always same origin.\n * - data URL containing an image is always same origin.\n * - blob URL is checked using `URL` constructor by its parent URL; opaque blob URL is never same origin.\n * - Absolute URL is checked using `URL` constructor.\n * \n * Checks blob URL before relative URL because opaque blob URL does not contain `://` too.\n * \n * @param inComingUrl - The URL to check\n * @returns `true` if the URL is same origin as current location, `false` otherwise\n */\nexport function sameOrigin(inComingUrl: string): boolean {\n if (!inComingUrl) return true; // empty URL\n if (inComingUrl.startsWith('data:image/')) return true; // data image URL\n if (inComingUrl.startsWith('blob:')) { // blob URL\n inComingUrl = inComingUrl.slice(5);\n if (inComingUrl.startsWith('null')) return false; // opaque blob URL\n }\n if (inComingUrl.indexOf('://') <= 0) return true; // relative URL\n const urlObj = new URL(inComingUrl);\n const locationObj = window.location;\n return urlObj.protocol === locationObj.protocol && urlObj.host === locationObj.host;\n}\n\nexport const getVideo = (urls: string[]): Promise => {\n const video: HTMLVideoElement = window.document.createElement('video');\n video.muted = true;\n return new Promise((resolve) => {\n video.onloadstart = () => {\n resolve(video);\n };\n for (const url of urls) {\n const s: HTMLSourceElement = window.document.createElement('source');\n if (!sameOrigin(url)) {\n video.crossOrigin = 'Anonymous';\n }\n s.src = url;\n video.appendChild(s);\n }\n });\n};\n","import {extend, type Subscription} from './util.ts';\n\n/**\n * A listener method used as a callback to events\n */\nexport type Listener = (event: E) => any;\n\n/**\n * A mapping between event names and the event each of them carries.\n */\nexport type EventTypeMap = Record;\n\n/**\n * The event names of an {@link EventTypeMap}.\n */\nexport type EventNames = Extract;\n\n/**\n * Properties merged into every event bubbled up to an evented parent.\n */\nexport type EventedParentData = Record;\n\ntype Listeners = {[K in keyof EventType]?: Array>};\n\nfunction _addEventListener>(type: K, listener: Listener, listenerList: Listeners) {\n const listenerExists = listenerList[type]?.includes(listener);\n if (!listenerExists) {\n listenerList[type] ||= [];\n listenerList[type].push(listener);\n }\n}\n\nfunction _removeEventListener>(type: K, listener: Listener, listenerList: Listeners) {\n if (listenerList?.[type]) {\n const index = listenerList[type].indexOf(listener);\n if (index !== -1) {\n listenerList[type].splice(index, 1);\n }\n }\n}\n\n/**\n * The event class\n */\nexport class Event {\n readonly type: TType;\n /**\n * The object that fired the event. Set when the event is fired, and narrowed to a more\n * specific type (e.g. `Map`, `Marker`) by the event subclasses.\n */\n target?: unknown;\n\n constructor(type: TType, data: object = {}) {\n extend(this, data);\n this.type = type;\n }\n}\n\ntype ErrorLike = {\n message: string;\n};\n\n/**\n * An error event\n */\nexport class ErrorEvent extends Event<'error'> {\n error: ErrorLike;\n\n constructor(error: ErrorLike, data: object = {}) {\n super('error', extend({error}, data));\n }\n}\n\n/**\n * The event map of an {@link Evented} that only reports errors.\n */\nexport type ErrorEventType = {\n error: ErrorEvent;\n};\n\n/**\n * Methods mixed in to other classes for event capabilities.\n *\n * @group Event Related\n */\nexport abstract class Evented {\n _listeners?: Listeners;\n _oneTimeListeners?: Listeners;\n _eventedParent?: Evented;\n _eventedParentData?: EventedParentData | (() => EventedParentData);\n\n /**\n * Adds a listener to a specified event type.\n *\n * @param type - The event type to add a listen for.\n * @param listener - The function to be called when the event is fired.\n * The listener function is called with the data object passed to `fire`,\n * extended with `target` and `type` properties.\n */\n on>(type: T, listener: (event: EventType[T]) => void): Subscription {\n this._listeners ||= {};\n _addEventListener(type, listener, this._listeners);\n\n return {\n unsubscribe: () => {\n this.off(type, listener);\n }\n };\n }\n\n /**\n * Removes a previously registered event listener.\n *\n * @param type - The event type to remove listeners for.\n * @param listener - The listener function to remove.\n */\n off>(type: T, listener: (event: EventType[T]) => void): this {\n _removeEventListener(type, listener, this._listeners);\n _removeEventListener(type, listener, this._oneTimeListeners);\n\n return this;\n }\n\n /**\n * Adds a listener that will be called only once to a specified event type.\n *\n * The listener will be called first time the event fires after the listener is registered.\n *\n * @param type - The event type to listen for.\n * @returns a promise that resolves with the event\n */\n once>(type: T): Promise;\n /**\n * Adds a listener that will be called only once to a specified event type.\n *\n * The listener will be called first time the event fires after the listener is registered.\n *\n * @param type - The event type to listen for.\n * @param listener - The function to be called when the event is fired the first time.\n * @returns `this` when a listener is provided\n */\n once>(type: T, listener: (event: EventType[T]) => void): this;\n once>(type: T, listener?: (event: EventType[T]) => void): this | Promise {\n if (!listener) {\n return new Promise((resolve) => this.once(type, resolve));\n }\n this._oneTimeListeners ||= {};\n _addEventListener(type, listener, this._oneTimeListeners);\n\n return this;\n }\n\n /**\n * Calls every listener registered for the event's type.\n */\n fire(event: EventType[EventNames]): this;\n /**\n * Compatibility with the (type: string, properties: Object) signature from previous versions.\n * See https://github.com/mapbox/mapbox-gl-js/issues/6522,\n * https://github.com/mapbox/mapbox-gl-draw/issues/766\n */\n fire(type: EventNames, properties?: object): this;\n fire(event: EventType[EventNames] | EventNames, properties?: object): this {\n const firedEvent: Event = typeof event === 'string' ? new Event(event, properties || {}) : event;\n const type = firedEvent.type as EventNames;\n\n if (this.listens(type)) {\n firedEvent.target = this;\n\n // make sure adding or removing listeners inside other listeners won't cause an infinite loop\n const listeners = this._listeners?.[type]?.slice() ?? [];\n for (const listener of listeners) {\n listener.call(this, firedEvent);\n }\n\n const oneTimeListeners = this._oneTimeListeners?.[type]?.slice() ?? [];\n for (const listener of oneTimeListeners) {\n _removeEventListener(type, listener, this._oneTimeListeners);\n listener.call(this, firedEvent);\n }\n\n const parent = this._eventedParent;\n if (parent) {\n extend(\n firedEvent,\n typeof this._eventedParentData === 'function' ? this._eventedParentData() : this._eventedParentData\n );\n parent.fire(firedEvent);\n }\n\n // To ensure that no error events are dropped, print them to the\n // console if they have no listeners.\n } else if (firedEvent instanceof ErrorEvent) {\n console.error(firedEvent.error);\n }\n\n return this;\n }\n\n /**\n * Returns a true if this instance of Evented or any forwardeed instances of Evented have a listener for the specified type.\n *\n * @param type - The event type\n * @returns `true` if there is at least one registered listener for specified event type, `false` otherwise\n */\n listens(type: EventNames): boolean {\n return Boolean(\n this._listeners?.[type]?.length ||\n this._oneTimeListeners?.[type]?.length ||\n this._eventedParent?.listens(type)\n );\n }\n\n /**\n * Bubble all events fired by this instance of Evented to this parent instance of Evented.\n */\n setEventedParent(parent?: Evented | null, data?: EventedParentData | (() => EventedParentData)): this {\n this._eventedParent = parent;\n this._eventedParentData = data;\n\n return this;\n }\n}\n","//#region src/reference/v8.json\nvar v8_default = {\n\t$version: 8,\n\t$root: {\n\t\t\"version\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": [8]\n\t\t},\n\t\t\"name\": { \"type\": \"string\" },\n\t\t\"metadata\": { \"type\": \"*\" },\n\t\t\"center\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2\n\t\t},\n\t\t\"centerAltitude\": { \"type\": \"number\" },\n\t\t\"zoom\": { \"type\": \"number\" },\n\t\t\"bearing\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"period\": 360,\n\t\t\t\"units\": \"degrees\"\n\t\t},\n\t\t\"pitch\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"units\": \"degrees\"\n\t\t},\n\t\t\"roll\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"units\": \"degrees\"\n\t\t},\n\t\t\"state\": {\n\t\t\t\"type\": \"state\",\n\t\t\t\"default\": {}\n\t\t},\n\t\t\"light\": { \"type\": \"light\" },\n\t\t\"sky\": { \"type\": \"sky\" },\n\t\t\"projection\": { \"type\": \"projection\" },\n\t\t\"terrain\": { \"type\": \"terrain\" },\n\t\t\"sources\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"sources\"\n\t\t},\n\t\t\"sprite\": { \"type\": \"sprite\" },\n\t\t\"glyphs\": { \"type\": \"string\" },\n\t\t\"font-faces\": { \"type\": \"fontFaces\" },\n\t\t\"transition\": { \"type\": \"transition\" },\n\t\t\"layers\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"layer\"\n\t\t}\n\t},\n\tsources: { \"*\": { \"type\": \"source\" } },\n\tsource: [\n\t\t\"source_vector\",\n\t\t\"source_raster\",\n\t\t\"source_raster_dem\",\n\t\t\"source_geojson\",\n\t\t\"source_video\",\n\t\t\"source_image\"\n\t],\n\tsource_vector: {\n\t\t\"type\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": { \"vector\": {} }\n\t\t},\n\t\t\"url\": { \"type\": \"string\" },\n\t\t\"tiles\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"string\"\n\t\t},\n\t\t\"bounds\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 4,\n\t\t\t\"default\": [\n\t\t\t\t-180,\n\t\t\t\t-85.051129,\n\t\t\t\t180,\n\t\t\t\t85.051129\n\t\t\t]\n\t\t},\n\t\t\"scheme\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"xyz\": {},\n\t\t\t\t\"tms\": {}\n\t\t\t},\n\t\t\t\"default\": \"xyz\"\n\t\t},\n\t\t\"minzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0\n\t\t},\n\t\t\"maxzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 22\n\t\t},\n\t\t\"attribution\": { \"type\": \"string\" },\n\t\t\"promoteId\": { \"type\": \"promoteId\" },\n\t\t\"volatile\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false\n\t\t},\n\t\t\"encoding\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"mvt\": {},\n\t\t\t\t\"mlt\": {}\n\t\t\t},\n\t\t\t\"default\": \"mvt\"\n\t\t},\n\t\t\"*\": { \"type\": \"*\" }\n\t},\n\tsource_raster: {\n\t\t\"type\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": { \"raster\": {} }\n\t\t},\n\t\t\"url\": { \"type\": \"string\" },\n\t\t\"tiles\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"string\"\n\t\t},\n\t\t\"bounds\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 4,\n\t\t\t\"default\": [\n\t\t\t\t-180,\n\t\t\t\t-85.051129,\n\t\t\t\t180,\n\t\t\t\t85.051129\n\t\t\t]\n\t\t},\n\t\t\"minzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0\n\t\t},\n\t\t\"maxzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 22\n\t\t},\n\t\t\"tileSize\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 512,\n\t\t\t\"units\": \"pixels\"\n\t\t},\n\t\t\"scheme\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"xyz\": {},\n\t\t\t\t\"tms\": {}\n\t\t\t},\n\t\t\t\"default\": \"xyz\"\n\t\t},\n\t\t\"attribution\": { \"type\": \"string\" },\n\t\t\"volatile\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false\n\t\t},\n\t\t\"*\": { \"type\": \"*\" }\n\t},\n\tsource_raster_dem: {\n\t\t\"type\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": { \"raster-dem\": {} }\n\t\t},\n\t\t\"url\": { \"type\": \"string\" },\n\t\t\"tiles\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"string\"\n\t\t},\n\t\t\"bounds\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 4,\n\t\t\t\"default\": [\n\t\t\t\t-180,\n\t\t\t\t-85.051129,\n\t\t\t\t180,\n\t\t\t\t85.051129\n\t\t\t]\n\t\t},\n\t\t\"minzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0\n\t\t},\n\t\t\"maxzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 22\n\t\t},\n\t\t\"tileSize\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 512,\n\t\t\t\"units\": \"pixels\"\n\t\t},\n\t\t\"attribution\": { \"type\": \"string\" },\n\t\t\"encoding\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"terrarium\": {},\n\t\t\t\t\"mapbox\": {},\n\t\t\t\t\"custom\": {}\n\t\t\t},\n\t\t\t\"default\": \"mapbox\"\n\t\t},\n\t\t\"redFactor\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1\n\t\t},\n\t\t\"blueFactor\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1\n\t\t},\n\t\t\"greenFactor\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1\n\t\t},\n\t\t\"baseShift\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0\n\t\t},\n\t\t\"volatile\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false\n\t\t},\n\t\t\"*\": { \"type\": \"*\" }\n\t},\n\tsource_geojson: {\n\t\t\"type\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": { \"geojson\": {} }\n\t\t},\n\t\t\"data\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"*\"\n\t\t},\n\t\t\"maxzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 18\n\t\t},\n\t\t\"attribution\": { \"type\": \"string\" },\n\t\t\"buffer\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 128,\n\t\t\t\"maximum\": 512,\n\t\t\t\"minimum\": 0\n\t\t},\n\t\t\"filter\": { \"type\": \"filter\" },\n\t\t\"tolerance\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": .375\n\t\t},\n\t\t\"cluster\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false\n\t\t},\n\t\t\"clusterRadius\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 50,\n\t\t\t\"minimum\": 0\n\t\t},\n\t\t\"clusterMaxZoom\": { \"type\": \"number\" },\n\t\t\"clusterMinPoints\": { \"type\": \"number\" },\n\t\t\"clusterProperties\": { \"type\": \"*\" },\n\t\t\"lineMetrics\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false\n\t\t},\n\t\t\"generateId\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false\n\t\t},\n\t\t\"promoteId\": { \"type\": \"promoteId\" }\n\t},\n\tsource_video: {\n\t\t\"type\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": { \"video\": {} }\n\t\t},\n\t\t\"urls\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"string\"\n\t\t},\n\t\t\"coordinates\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"array\",\n\t\t\t\"length\": 4,\n\t\t\t\"value\": {\n\t\t\t\t\"type\": \"array\",\n\t\t\t\t\"length\": 2,\n\t\t\t\t\"value\": \"number\"\n\t\t\t}\n\t\t}\n\t},\n\tsource_image: {\n\t\t\"type\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": { \"image\": {} }\n\t\t},\n\t\t\"url\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"string\"\n\t\t},\n\t\t\"coordinates\": {\n\t\t\t\"required\": true,\n\t\t\t\"type\": \"array\",\n\t\t\t\"length\": 4,\n\t\t\t\"value\": {\n\t\t\t\t\"type\": \"array\",\n\t\t\t\t\"length\": 2,\n\t\t\t\t\"value\": \"number\"\n\t\t\t}\n\t\t}\n\t},\n\tlayer: {\n\t\t\"id\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"required\": true\n\t\t},\n\t\t\"type\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"fill\": {},\n\t\t\t\t\"line\": {},\n\t\t\t\t\"symbol\": {},\n\t\t\t\t\"circle\": {},\n\t\t\t\t\"heatmap\": {},\n\t\t\t\t\"fill-extrusion\": {},\n\t\t\t\t\"raster\": {},\n\t\t\t\t\"hillshade\": {},\n\t\t\t\t\"color-relief\": {},\n\t\t\t\t\"background\": {}\n\t\t\t},\n\t\t\t\"required\": true\n\t\t},\n\t\t\"metadata\": { \"type\": \"*\" },\n\t\t\"source\": { \"type\": \"string\" },\n\t\t\"source-layer\": { \"type\": \"string\" },\n\t\t\"minzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 24\n\t\t},\n\t\t\"maxzoom\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 24\n\t\t},\n\t\t\"filter\": { \"type\": \"filter\" },\n\t\t\"layout\": { \"type\": \"layout\" },\n\t\t\"paint\": { \"type\": \"paint\" }\n\t},\n\tlayout: [\n\t\t\"layout_fill\",\n\t\t\"layout_line\",\n\t\t\"layout_circle\",\n\t\t\"layout_heatmap\",\n\t\t\"layout_fill-extrusion\",\n\t\t\"layout_symbol\",\n\t\t\"layout_raster\",\n\t\t\"layout_hillshade\",\n\t\t\"layout_color-relief\",\n\t\t\"layout_background\"\n\t],\n\tlayout_background: { \"visibility\": {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"visible\": {},\n\t\t\t\"none\": {}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"expression\": {\n\t\t\t\"interpolated\": false,\n\t\t\t\"parameters\": [\"global-state\"]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t} },\n\tlayout_fill: {\n\t\t\"fill-sort-key\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"visibility\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"visible\": {},\n\t\t\t\t\"none\": {}\n\t\t\t},\n\t\t\t\"default\": \"visible\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"global-state\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tlayout_circle: {\n\t\t\"circle-sort-key\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"visibility\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"visible\": {},\n\t\t\t\t\"none\": {}\n\t\t\t},\n\t\t\t\"default\": \"visible\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"global-state\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tlayout_heatmap: { \"visibility\": {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"visible\": {},\n\t\t\t\"none\": {}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"expression\": {\n\t\t\t\"interpolated\": false,\n\t\t\t\"parameters\": [\"global-state\"]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t} },\n\t\"layout_fill-extrusion\": {\n\t\t\"visibility\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"visible\": {},\n\t\t\t\t\"none\": {}\n\t\t\t},\n\t\t\t\"default\": \"visible\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"global-state\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-extrusion-rounded-corner-distance\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"meters\",\n\t\t\t\"property-type\": \"constant\"\n\t\t}\n\t},\n\tlayout_line: {\n\t\t\"line-cap\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"butt\": {},\n\t\t\t\t\"round\": {},\n\t\t\t\t\"square\": {}\n\t\t\t},\n\t\t\t\"default\": \"butt\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-join\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"bevel\": {},\n\t\t\t\t\"round\": {},\n\t\t\t\t\"miter\": {}\n\t\t\t},\n\t\t\t\"default\": \"miter\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-miter-limit\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 2,\n\t\t\t\"requires\": [{ \"line-join\": \"miter\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-round-limit\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1.05,\n\t\t\t\"requires\": [{ \"line-join\": \"round\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-sort-key\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"visibility\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"visible\": {},\n\t\t\t\t\"none\": {}\n\t\t\t},\n\t\t\t\"default\": \"visible\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"global-state\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tlayout_symbol: {\n\t\t\"symbol-placement\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"point\": {},\n\t\t\t\t\"line\": {},\n\t\t\t\t\"line-center\": {}\n\t\t\t},\n\t\t\t\"default\": \"point\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"symbol-spacing\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 250,\n\t\t\t\"minimum\": 1,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [{ \"symbol-placement\": \"line\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"symbol-avoid-edges\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"symbol-sort-key\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"symbol-z-order\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"auto\": {},\n\t\t\t\t\"viewport-y\": {},\n\t\t\t\t\"source\": {}\n\t\t\t},\n\t\t\t\"default\": \"auto\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-allow-overlap\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"requires\": [\"icon-image\", { \"!\": \"icon-overlap\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-overlap\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"never\": {},\n\t\t\t\t\"always\": {},\n\t\t\t\t\"cooperative\": {}\n\t\t\t},\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-ignore-placement\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-optional\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"requires\": [\"icon-image\", \"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-rotation-alignment\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {},\n\t\t\t\t\"auto\": {}\n\t\t\t},\n\t\t\t\"default\": \"auto\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-size\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"factor of the original icon size\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-text-fit\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"none\": {},\n\t\t\t\t\"width\": {},\n\t\t\t\t\"height\": {},\n\t\t\t\t\"both\": {}\n\t\t\t},\n\t\t\t\"default\": \"none\",\n\t\t\t\"requires\": [\"icon-image\", \"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-text-fit-padding\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 4,\n\t\t\t\"default\": [\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0\n\t\t\t],\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\n\t\t\t\t\"icon-image\",\n\t\t\t\t\"text-field\",\n\t\t\t\t{ \"icon-text-fit\": [\n\t\t\t\t\t\"both\",\n\t\t\t\t\t\"width\",\n\t\t\t\t\t\"height\"\n\t\t\t\t] }\n\t\t\t],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-image\": {\n\t\t\t\"type\": \"resolvedImage\",\n\t\t\t\"tokens\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-rotate\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"period\": 360,\n\t\t\t\"units\": \"degrees\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-padding\": {\n\t\t\t\"type\": \"padding\",\n\t\t\t\"default\": [2],\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-keep-upright\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"requires\": [\n\t\t\t\t\"icon-image\",\n\t\t\t\t{ \"icon-rotation-alignment\": \"map\" },\n\t\t\t\t{ \"symbol-placement\": [\"line\", \"line-center\"] }\n\t\t\t],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-offset\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"center\": {},\n\t\t\t\t\"left\": {},\n\t\t\t\t\"right\": {},\n\t\t\t\t\"top\": {},\n\t\t\t\t\"bottom\": {},\n\t\t\t\t\"top-left\": {},\n\t\t\t\t\"top-right\": {},\n\t\t\t\t\"bottom-left\": {},\n\t\t\t\t\"bottom-right\": {}\n\t\t\t},\n\t\t\t\"default\": \"center\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-pitch-alignment\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {},\n\t\t\t\t\"auto\": {}\n\t\t\t},\n\t\t\t\"default\": \"auto\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-pitch-alignment\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {},\n\t\t\t\t\"auto\": {}\n\t\t\t},\n\t\t\t\"default\": \"auto\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-rotation-alignment\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {},\n\t\t\t\t\"viewport-glyph\": {},\n\t\t\t\t\"auto\": {}\n\t\t\t},\n\t\t\t\"default\": \"auto\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-field\": {\n\t\t\t\"type\": \"formatted\",\n\t\t\t\"default\": \"\",\n\t\t\t\"tokens\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-font\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"string\",\n\t\t\t\"default\": [\"Open Sans Regular\", \"Arial Unicode MS Regular\"],\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-size\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 16,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-max-width\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 10,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"ems\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-line-height\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1.2,\n\t\t\t\"units\": \"ems\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-letter-spacing\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"units\": \"ems\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-justify\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"auto\": {},\n\t\t\t\t\"left\": {},\n\t\t\t\t\"center\": {},\n\t\t\t\t\"right\": {}\n\t\t\t},\n\t\t\t\"default\": \"center\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-radial-offset\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"units\": \"ems\",\n\t\t\t\"default\": 0,\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"property-type\": \"data-driven\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t}\n\t\t},\n\t\t\"text-variable-anchor\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"center\": {},\n\t\t\t\t\"left\": {},\n\t\t\t\t\"right\": {},\n\t\t\t\t\"top\": {},\n\t\t\t\t\"bottom\": {},\n\t\t\t\t\"top-left\": {},\n\t\t\t\t\"top-right\": {},\n\t\t\t\t\"bottom-left\": {},\n\t\t\t\t\"bottom-right\": {}\n\t\t\t},\n\t\t\t\"requires\": [\"text-field\", { \"symbol-placement\": [\"point\"] }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-variable-anchor-offset\": {\n\t\t\t\"type\": \"variableAnchorOffsetCollection\",\n\t\t\t\"requires\": [\"text-field\", { \"symbol-placement\": [\"point\"] }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"center\": {},\n\t\t\t\t\"left\": {},\n\t\t\t\t\"right\": {},\n\t\t\t\t\"top\": {},\n\t\t\t\t\"bottom\": {},\n\t\t\t\t\"top-left\": {},\n\t\t\t\t\"top-right\": {},\n\t\t\t\t\"bottom-left\": {},\n\t\t\t\t\"bottom-right\": {}\n\t\t\t},\n\t\t\t\"default\": \"center\",\n\t\t\t\"requires\": [\"text-field\", { \"!\": \"text-variable-anchor\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-max-angle\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 45,\n\t\t\t\"units\": \"degrees\",\n\t\t\t\"requires\": [\"text-field\", { \"symbol-placement\": [\"line\", \"line-center\"] }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-writing-mode\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"horizontal\": {},\n\t\t\t\t\"vertical\": {}\n\t\t\t},\n\t\t\t\"requires\": [\"text-field\", { \"symbol-placement\": [\"point\"] }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-rotate\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"period\": 360,\n\t\t\t\"units\": \"degrees\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-padding\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 2,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-keep-upright\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": true,\n\t\t\t\"requires\": [\n\t\t\t\t\"text-field\",\n\t\t\t\t{ \"text-rotation-alignment\": \"map\" },\n\t\t\t\t{ \"symbol-placement\": [\"line\", \"line-center\"] }\n\t\t\t],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-transform\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"none\": {},\n\t\t\t\t\"uppercase\": {},\n\t\t\t\t\"lowercase\": {}\n\t\t\t},\n\t\t\t\"default\": \"none\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-offset\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"units\": \"ems\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"requires\": [\"text-field\", { \"!\": \"text-radial-offset\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-allow-overlap\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"requires\": [\"text-field\", { \"!\": \"text-overlap\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-overlap\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"never\": {},\n\t\t\t\t\"always\": {},\n\t\t\t\t\"cooperative\": {}\n\t\t\t},\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-ignore-placement\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-optional\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": false,\n\t\t\t\"requires\": [\"text-field\", \"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"symbol-height-offset\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"units\": \"meters\",\n\t\t\t\"requires\": [{ \"symbol-placement\": [\"point\"] }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"symbol-height-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"ground\": {},\n\t\t\t\t\"absolute\": {}\n\t\t\t},\n\t\t\t\"default\": \"ground\",\n\t\t\t\"requires\": [\"symbol-height-offset\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"visibility\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"visible\": {},\n\t\t\t\t\"none\": {}\n\t\t\t},\n\t\t\t\"default\": \"visible\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"global-state\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tlayout_raster: { \"visibility\": {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"visible\": {},\n\t\t\t\"none\": {}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"expression\": {\n\t\t\t\"interpolated\": false,\n\t\t\t\"parameters\": [\"global-state\"]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t} },\n\tlayout_hillshade: { \"visibility\": {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"visible\": {},\n\t\t\t\"none\": {}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"expression\": {\n\t\t\t\"interpolated\": false,\n\t\t\t\"parameters\": [\"global-state\"]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t} },\n\t\"layout_color-relief\": { \"visibility\": {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"visible\": {},\n\t\t\t\"none\": {}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"expression\": {\n\t\t\t\"interpolated\": false,\n\t\t\t\"parameters\": [\"global-state\"]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t} },\n\tfilter: {\n\t\t\"type\": \"boolean\",\n\t\t\"expression\": {\n\t\t\t\"interpolated\": false,\n\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\tfilter_operator: {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"==\": {},\n\t\t\t\"!=\": {},\n\t\t\t\">\": {},\n\t\t\t\">=\": {},\n\t\t\t\"<\": {},\n\t\t\t\"<=\": {},\n\t\t\t\"in\": {},\n\t\t\t\"!in\": {},\n\t\t\t\"all\": {},\n\t\t\t\"any\": {},\n\t\t\t\"none\": {},\n\t\t\t\"has\": {},\n\t\t\t\"!has\": {}\n\t\t}\n\t},\n\tgeometry_type: {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"Point\": {},\n\t\t\t\"LineString\": {},\n\t\t\t\"Polygon\": {}\n\t\t}\n\t},\n\t\"function\": {\n\t\t\"expression\": { \"type\": \"expression\" },\n\t\t\"stops\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"function_stop\"\n\t\t},\n\t\t\"base\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0\n\t\t},\n\t\t\"property\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"default\": \"$zoom\"\n\t\t},\n\t\t\"type\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"identity\": {},\n\t\t\t\t\"exponential\": {},\n\t\t\t\t\"interval\": {},\n\t\t\t\t\"categorical\": {}\n\t\t\t},\n\t\t\t\"default\": \"exponential\"\n\t\t},\n\t\t\"colorSpace\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"rgb\": {},\n\t\t\t\t\"lab\": {},\n\t\t\t\t\"hcl\": {}\n\t\t\t},\n\t\t\t\"default\": \"rgb\"\n\t\t},\n\t\t\"default\": {\n\t\t\t\"type\": \"*\",\n\t\t\t\"required\": false\n\t\t}\n\t},\n\tfunction_stop: {\n\t\t\"type\": \"array\",\n\t\t\"minimum\": 0,\n\t\t\"maximum\": 24,\n\t\t\"value\": [\"number\", \"color\"],\n\t\t\"length\": 2\n\t},\n\texpression: {\n\t\t\"type\": \"array\",\n\t\t\"value\": \"expression_name\",\n\t\t\"minimum\": 1\n\t},\n\tlight: {\n\t\t\"anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"default\": \"viewport\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"transition\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t}\n\t\t},\n\t\t\"position\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"default\": [\n\t\t\t\t1.15,\n\t\t\t\t210,\n\t\t\t\t30\n\t\t\t],\n\t\t\t\"length\": 3,\n\t\t\t\"value\": \"number\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t}\n\t\t},\n\t\t\"color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": \"#ffffff\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t},\n\t\t\"intensity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": .5,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t}\n\t},\n\tsky: {\n\t\t\"sky-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": \"#88C6FC\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t},\n\t\t\"horizon-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": \"#ffffff\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t},\n\t\t\"fog-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": \"#ffffff\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t},\n\t\t\"fog-ground-blend\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": .5,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t},\n\t\t\"horizon-fog-blend\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": .8,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t},\n\t\t\"sky-horizon-blend\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": .8,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t},\n\t\t\"atmosphere-blend\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"property-type\": \"data-constant\",\n\t\t\t\"default\": .8,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"transition\": true\n\t\t}\n\t},\n\tterrain: {\n\t\t\"source\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"required\": true\n\t\t},\n\t\t\"exaggeration\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"minimum\": 0,\n\t\t\t\"default\": 1\n\t\t}\n\t},\n\tprojection: { \"type\": {\n\t\t\"type\": \"projectionDefinition\",\n\t\t\"default\": \"mercator\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"transition\": false,\n\t\t\"expression\": {\n\t\t\t\"interpolated\": true,\n\t\t\t\"parameters\": [\"zoom\"]\n\t\t}\n\t} },\n\tpaint: [\n\t\t\"paint_fill\",\n\t\t\"paint_line\",\n\t\t\"paint_circle\",\n\t\t\"paint_heatmap\",\n\t\t\"paint_fill-extrusion\",\n\t\t\"paint_symbol\",\n\t\t\"paint_raster\",\n\t\t\"paint_hillshade\",\n\t\t\"paint_color-relief\",\n\t\t\"paint_background\"\n\t],\n\tpaint_fill: {\n\t\t\"fill-antialias\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"fill-layer-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"global-state\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"fill-outline-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [{ \"!\": \"fill-pattern\" }, { \"fill-antialias\": true }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"fill-translate\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-translate-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"map\",\n\t\t\t\"requires\": [\"fill-translate\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-pattern\": {\n\t\t\t\"type\": \"resolvedImage\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"cross-faded-data-driven\"\n\t\t}\n\t},\n\t\"paint_fill-extrusion\": {\n\t\t\"fill-extrusion-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-extrusion-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [{ \"!\": \"fill-extrusion-pattern\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"fill-extrusion-translate\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-extrusion-translate-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"map\",\n\t\t\t\"requires\": [\"fill-extrusion-translate\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"fill-extrusion-pattern\": {\n\t\t\t\"type\": \"resolvedImage\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"cross-faded-data-driven\"\n\t\t},\n\t\t\"fill-extrusion-height\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"meters\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"fill-extrusion-base\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"meters\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [\"fill-extrusion-height\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"fill-extrusion-vertical-gradient\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"default\": true,\n\t\t\t\"transition\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tpaint_line: {\n\t\t\"line-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-layer-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\", \"global-state\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"line-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [{ \"!\": \"line-pattern\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-translate\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"line-translate-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"map\",\n\t\t\t\"requires\": [\"line-translate\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"line-width\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-gap-width\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-offset\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-blur\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"line-dasharray\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"line widths\",\n\t\t\t\"requires\": [{ \"!\": \"line-pattern\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"cross-faded-data-driven\"\n\t\t},\n\t\t\"line-pattern\": {\n\t\t\t\"type\": \"resolvedImage\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\", \"feature\"]\n\t\t\t},\n\t\t\t\"property-type\": \"cross-faded-data-driven\"\n\t\t},\n\t\t\"line-gradient\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"transition\": false,\n\t\t\t\"requires\": [\n\t\t\t\t{ \"!\": \"line-dasharray\" },\n\t\t\t\t{ \"!\": \"line-pattern\" },\n\t\t\t\t{\n\t\t\t\t\t\"source\": \"geojson\",\n\t\t\t\t\t\"has\": { \"lineMetrics\": true }\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"line-progress\"]\n\t\t\t},\n\t\t\t\"property-type\": \"color-ramp\"\n\t\t}\n\t},\n\tpaint_circle: {\n\t\t\"circle-radius\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 5,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"circle-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"circle-blur\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"circle-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"circle-translate\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"circle-translate-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"map\",\n\t\t\t\"requires\": [\"circle-translate\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"circle-pitch-scale\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"map\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"circle-pitch-alignment\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"viewport\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"circle-stroke-width\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"circle-stroke-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"circle-stroke-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t}\n\t},\n\tpaint_heatmap: {\n\t\t\"heatmap-radius\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 30,\n\t\t\t\"minimum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"heatmap-weight\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"heatmap-intensity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"heatmap-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": [\n\t\t\t\t\"interpolate\",\n\t\t\t\t[\"linear\"],\n\t\t\t\t[\"heatmap-density\"],\n\t\t\t\t0,\n\t\t\t\t\"rgba(0, 0, 255, 0)\",\n\t\t\t\t.1,\n\t\t\t\t\"royalblue\",\n\t\t\t\t.3,\n\t\t\t\t\"cyan\",\n\t\t\t\t.5,\n\t\t\t\t\"lime\",\n\t\t\t\t.7,\n\t\t\t\t\"yellow\",\n\t\t\t\t1,\n\t\t\t\t\"red\"\n\t\t\t],\n\t\t\t\"transition\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"heatmap-density\"]\n\t\t\t},\n\t\t\t\"property-type\": \"color-ramp\"\n\t\t},\n\t\t\"heatmap-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tpaint_symbol: {\n\t\t\"icon-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-halo-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"rgba(0, 0, 0, 0)\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-halo-width\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-halo-blur\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"icon-translate\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"icon-image\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"icon-translate-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"map\",\n\t\t\t\"requires\": [\"icon-image\", \"icon-translate\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"overridable\": true,\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-halo-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"rgba(0, 0, 0, 0)\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-halo-width\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-halo-blur\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t\"zoom\",\n\t\t\t\t\t\"feature\",\n\t\t\t\t\t\"feature-state\"\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"property-type\": \"data-driven\"\n\t\t},\n\t\t\"text-translate\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"value\": \"number\",\n\t\t\t\"length\": 2,\n\t\t\t\"default\": [0, 0],\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"pixels\",\n\t\t\t\"requires\": [\"text-field\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"text-translate-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"map\",\n\t\t\t\"requires\": [\"text-field\", \"text-translate\"],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tpaint_raster: {\n\t\t\"raster-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"raster-hue-rotate\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"period\": 360,\n\t\t\t\"transition\": true,\n\t\t\t\"units\": \"degrees\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"raster-brightness-min\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"raster-brightness-max\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"raster-saturation\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": -1,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"raster-contrast\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": -1,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"resampling\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"linear\": {},\n\t\t\t\t\"nearest\": {}\n\t\t\t},\n\t\t\t\"default\": \"linear\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"raster-resampling\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"linear\": {},\n\t\t\t\t\"nearest\": {}\n\t\t\t},\n\t\t\t\"default\": \"linear\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"raster-fade-duration\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 300,\n\t\t\t\"minimum\": 0,\n\t\t\t\"transition\": false,\n\t\t\t\"units\": \"milliseconds\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tpaint_hillshade: {\n\t\t\"hillshade-illumination-direction\": {\n\t\t\t\"type\": \"numberArray\",\n\t\t\t\"default\": 335,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 359,\n\t\t\t\"transition\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"hillshade-illumination-altitude\": {\n\t\t\t\"type\": \"numberArray\",\n\t\t\t\"default\": 45,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 90,\n\t\t\t\"transition\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"hillshade-illumination-anchor\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"map\": {},\n\t\t\t\t\"viewport\": {}\n\t\t\t},\n\t\t\t\"default\": \"viewport\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"hillshade-exaggeration\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": .5,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"hillshade-shadow-color\": {\n\t\t\t\"type\": \"colorArray\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"hillshade-highlight-color\": {\n\t\t\t\"type\": \"colorArray\",\n\t\t\t\"default\": \"#FFFFFF\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"hillshade-accent-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"hillshade-method\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"standard\": {},\n\t\t\t\t\"basic\": {},\n\t\t\t\t\"combined\": {},\n\t\t\t\t\"igor\": {},\n\t\t\t\t\"multidirectional\": {}\n\t\t\t},\n\t\t\t\"default\": \"standard\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"resampling\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"linear\": {},\n\t\t\t\t\"nearest\": {}\n\t\t\t},\n\t\t\t\"default\": \"linear\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\t\"paint_color-relief\": {\n\t\t\"color-relief-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"color-relief-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"transition\": false,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"elevation\"]\n\t\t\t},\n\t\t\t\"property-type\": \"color-ramp\"\n\t\t},\n\t\t\"resampling\": {\n\t\t\t\"type\": \"enum\",\n\t\t\t\"values\": {\n\t\t\t\t\"linear\": {},\n\t\t\t\t\"nearest\": {}\n\t\t\t},\n\t\t\t\"default\": \"linear\",\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\tpaint_background: {\n\t\t\"background-color\": {\n\t\t\t\"type\": \"color\",\n\t\t\t\"default\": \"#000000\",\n\t\t\t\"transition\": true,\n\t\t\t\"requires\": [{ \"!\": \"background-pattern\" }],\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t},\n\t\t\"background-pattern\": {\n\t\t\t\"type\": \"resolvedImage\",\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": false,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"cross-faded\"\n\t\t},\n\t\t\"background-opacity\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 1,\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1,\n\t\t\t\"transition\": true,\n\t\t\t\"expression\": {\n\t\t\t\t\"interpolated\": true,\n\t\t\t\t\"parameters\": [\"zoom\"]\n\t\t\t},\n\t\t\t\"property-type\": \"data-constant\"\n\t\t}\n\t},\n\ttransition: {\n\t\t\"duration\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 300,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"milliseconds\"\n\t\t},\n\t\t\"delay\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"default\": 0,\n\t\t\t\"minimum\": 0,\n\t\t\t\"units\": \"milliseconds\"\n\t\t}\n\t},\n\t\"property-type\": {\n\t\t\"data-driven\": { \"type\": \"property-type\" },\n\t\t\"cross-faded\": { \"type\": \"property-type\" },\n\t\t\"cross-faded-data-driven\": { \"type\": \"property-type\" },\n\t\t\"color-ramp\": { \"type\": \"property-type\" },\n\t\t\"data-constant\": { \"type\": \"property-type\" },\n\t\t\"constant\": { \"type\": \"property-type\" }\n\t},\n\tpromoteId: { \"*\": { \"type\": \"string\" } },\n\tinterpolation: {\n\t\t\"type\": \"array\",\n\t\t\"value\": \"interpolation_name\",\n\t\t\"minimum\": 1\n\t},\n\tinterpolation_name: {\n\t\t\"type\": \"enum\",\n\t\t\"values\": {\n\t\t\t\"linear\": { \"syntax\": {\n\t\t\t\t\"overloads\": [{\n\t\t\t\t\t\"parameters\": [],\n\t\t\t\t\t\"output-type\": \"interpolation\"\n\t\t\t\t}],\n\t\t\t\t\"parameters\": []\n\t\t\t} },\n\t\t\t\"exponential\": { \"syntax\": {\n\t\t\t\t\"overloads\": [{\n\t\t\t\t\t\"parameters\": [\"base\"],\n\t\t\t\t\t\"output-type\": \"interpolation\"\n\t\t\t\t}],\n\t\t\t\t\"parameters\": [{\n\t\t\t\t\t\"name\": \"base\",\n\t\t\t\t\t\"type\": \"number literal\"\n\t\t\t\t}]\n\t\t\t} },\n\t\t\t\"cubic-bezier\": { \"syntax\": {\n\t\t\t\t\"overloads\": [{\n\t\t\t\t\t\"parameters\": [\n\t\t\t\t\t\t\"x1\",\n\t\t\t\t\t\t\"y1\",\n\t\t\t\t\t\t\"x2\",\n\t\t\t\t\t\t\"y2\"\n\t\t\t\t\t],\n\t\t\t\t\t\"output-type\": \"interpolation\"\n\t\t\t\t}],\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"x1\",\n\t\t\t\t\t\t\"type\": \"number literal\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"y1\",\n\t\t\t\t\t\t\"type\": \"number literal\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"x2\",\n\t\t\t\t\t\t\"type\": \"number literal\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"y2\",\n\t\t\t\t\t\t\"type\": \"number literal\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t} }\n\t\t}\n\t}\n};\n//#endregion\n//#region src/reference/latest.ts\nconst latest = v8_default;\n//#endregion\n//#region src/util/ref_properties.ts\nconst refProperties = [\n\t\"type\",\n\t\"source\",\n\t\"source-layer\",\n\t\"minzoom\",\n\t\"maxzoom\",\n\t\"filter\",\n\t\"layout\"\n];\n//#endregion\n//#region src/deref.ts\nfunction deref(layer, parent) {\n\tconst result = {};\n\tfor (const k in layer) if (k !== \"ref\") result[k] = layer[k];\n\trefProperties.forEach((k) => {\n\t\tif (k in parent) result[k] = parent[k];\n\t});\n\treturn result;\n}\n/**\n*\n* The input is not modified. The output may contain references to portions\n* of the input.\n*\n* @param layers - array of layers, some of which may contain `ref` properties\n* whose value is the `id` of another property\n* @returns a new array where such layers have been augmented with the 'type', 'source', etc. properties\n* from the parent layer, and the `ref` property has been removed.\n*/\nfunction derefLayers(layers) {\n\tlayers = layers.slice();\n\tconst map = Object.create(null);\n\tfor (let i = 0; i < layers.length; i++) map[layers[i].id] = layers[i];\n\tfor (let i = 0; i < layers.length; i++) if (\"ref\" in layers[i]) layers[i] = deref(layers[i], map[layers[i].ref]);\n\treturn layers;\n}\n//#endregion\n//#region src/util/deep_equal.ts\n/**\n* Deeply compares two object literals.\n*\n* @private\n*/\nfunction deepEqual(a, b) {\n\tif (Array.isArray(a)) {\n\t\tif (!Array.isArray(b) || a.length !== b.length) return false;\n\t\tfor (let i = 0; i < a.length; i++) if (!deepEqual(a[i], b[i])) return false;\n\t\treturn true;\n\t}\n\tif (typeof a === \"object\" && a !== null && b !== null) {\n\t\tif (!(typeof b === \"object\")) return false;\n\t\tif (Object.keys(a).length !== Object.keys(b).length) return false;\n\t\tfor (const key in a) if (!deepEqual(a[key], b[key])) return false;\n\t\treturn true;\n\t}\n\treturn a === b;\n}\n//#endregion\n//#region src/diff.ts\n/**\n* The main reason for this method is to allow type check when adding a command to the array.\n* @param commands - The commands array to add to\n* @param command - The command to add\n*/\nfunction addCommand(commands, command) {\n\tcommands.push(command);\n}\nfunction addSource(sourceId, after, commands) {\n\taddCommand(commands, {\n\t\tcommand: \"addSource\",\n\t\targs: [sourceId, after[sourceId]]\n\t});\n}\nfunction removeSource(sourceId, commands, sourcesRemoved) {\n\taddCommand(commands, {\n\t\tcommand: \"removeSource\",\n\t\targs: [sourceId]\n\t});\n\tsourcesRemoved[sourceId] = true;\n}\nfunction updateSource(sourceId, after, commands, sourcesRemoved) {\n\tremoveSource(sourceId, commands, sourcesRemoved);\n\taddSource(sourceId, after, commands);\n}\nfunction canUpdateGeoJSON(before, after, sourceId) {\n\tlet prop;\n\tfor (prop in before[sourceId]) {\n\t\tif (!Object.prototype.hasOwnProperty.call(before[sourceId], prop)) continue;\n\t\tif (prop !== \"data\" && !deepEqual(before[sourceId][prop], after[sourceId][prop])) return false;\n\t}\n\tfor (prop in after[sourceId]) {\n\t\tif (!Object.prototype.hasOwnProperty.call(after[sourceId], prop)) continue;\n\t\tif (prop !== \"data\" && !deepEqual(before[sourceId][prop], after[sourceId][prop])) return false;\n\t}\n\treturn true;\n}\nfunction diffSources(before, after, commands, sourcesRemoved) {\n\tbefore = before || {};\n\tafter = after || {};\n\tlet sourceId;\n\tfor (sourceId in before) {\n\t\tif (!Object.prototype.hasOwnProperty.call(before, sourceId)) continue;\n\t\tif (!Object.prototype.hasOwnProperty.call(after, sourceId)) removeSource(sourceId, commands, sourcesRemoved);\n\t}\n\tfor (sourceId in after) {\n\t\tif (!Object.prototype.hasOwnProperty.call(after, sourceId)) continue;\n\t\tif (!Object.prototype.hasOwnProperty.call(before, sourceId)) addSource(sourceId, after, commands);\n\t\telse if (!deepEqual(before[sourceId], after[sourceId])) {\n\t\t\tif (before[sourceId].type === \"geojson\" && after[sourceId].type === \"geojson\" && canUpdateGeoJSON(before, after, sourceId)) addCommand(commands, {\n\t\t\t\tcommand: \"setGeoJSONSourceData\",\n\t\t\t\targs: [sourceId, after[sourceId].data]\n\t\t\t});\n\t\t\telse updateSource(sourceId, after, commands, sourcesRemoved);\n\t\t}\n\t}\n}\nfunction diffLayerPropertyChanges(before, after, commands, layerId, klass, command) {\n\tbefore = before || {};\n\tafter = after || {};\n\tfor (const prop in before) {\n\t\tif (!Object.prototype.hasOwnProperty.call(before, prop)) continue;\n\t\tif (!deepEqual(before[prop], after[prop])) commands.push({\n\t\t\tcommand,\n\t\t\targs: [\n\t\t\t\tlayerId,\n\t\t\t\tprop,\n\t\t\t\tafter[prop],\n\t\t\t\tklass\n\t\t\t]\n\t\t});\n\t}\n\tfor (const prop in after) {\n\t\tif (!Object.prototype.hasOwnProperty.call(after, prop) || Object.prototype.hasOwnProperty.call(before, prop)) continue;\n\t\tif (!deepEqual(before[prop], after[prop])) commands.push({\n\t\t\tcommand,\n\t\t\targs: [\n\t\t\t\tlayerId,\n\t\t\t\tprop,\n\t\t\t\tafter[prop],\n\t\t\t\tklass\n\t\t\t]\n\t\t});\n\t}\n}\nfunction pluckId(layer) {\n\treturn layer.id;\n}\nfunction indexById(group, layer) {\n\tgroup[layer.id] = layer;\n\treturn group;\n}\nfunction diffLayers(before, after, commands) {\n\tbefore = before || [];\n\tafter = after || [];\n\tconst beforeOrder = before.map(pluckId);\n\tconst afterOrder = after.map(pluckId);\n\tconst beforeIndex = before.reduce(indexById, {});\n\tconst afterIndex = after.reduce(indexById, {});\n\tconst tracker = beforeOrder.slice();\n\tconst clean = Object.create(null);\n\tlet layerId;\n\tlet beforeLayer;\n\tlet afterLayer;\n\tlet insertBeforeLayerId;\n\tlet prop;\n\tfor (let i = 0, d = 0; i < beforeOrder.length; i++) {\n\t\tlayerId = beforeOrder[i];\n\t\tif (!Object.prototype.hasOwnProperty.call(afterIndex, layerId)) {\n\t\t\taddCommand(commands, {\n\t\t\t\tcommand: \"removeLayer\",\n\t\t\t\targs: [layerId]\n\t\t\t});\n\t\t\ttracker.splice(tracker.indexOf(layerId, d), 1);\n\t\t} else d++;\n\t}\n\tfor (let i = 0, d = 0; i < afterOrder.length; i++) {\n\t\tlayerId = afterOrder[afterOrder.length - 1 - i];\n\t\tif (tracker[tracker.length - 1 - i] === layerId) continue;\n\t\tif (Object.prototype.hasOwnProperty.call(beforeIndex, layerId)) {\n\t\t\taddCommand(commands, {\n\t\t\t\tcommand: \"removeLayer\",\n\t\t\t\targs: [layerId]\n\t\t\t});\n\t\t\ttracker.splice(tracker.lastIndexOf(layerId, tracker.length - d), 1);\n\t\t} else d++;\n\t\tinsertBeforeLayerId = tracker[tracker.length - i];\n\t\taddCommand(commands, {\n\t\t\tcommand: \"addLayer\",\n\t\t\targs: [afterIndex[layerId], insertBeforeLayerId]\n\t\t});\n\t\ttracker.splice(tracker.length - i, 0, layerId);\n\t\tclean[layerId] = true;\n\t}\n\tfor (let i = 0; i < afterOrder.length; i++) {\n\t\tlayerId = afterOrder[i];\n\t\tbeforeLayer = beforeIndex[layerId];\n\t\tafterLayer = afterIndex[layerId];\n\t\tif (clean[layerId] || deepEqual(beforeLayer, afterLayer)) continue;\n\t\tif (!deepEqual(beforeLayer.source, afterLayer.source) || !deepEqual(beforeLayer[\"source-layer\"], afterLayer[\"source-layer\"]) || !deepEqual(beforeLayer.type, afterLayer.type)) {\n\t\t\taddCommand(commands, {\n\t\t\t\tcommand: \"removeLayer\",\n\t\t\t\targs: [layerId]\n\t\t\t});\n\t\t\tinsertBeforeLayerId = tracker[tracker.lastIndexOf(layerId) + 1];\n\t\t\taddCommand(commands, {\n\t\t\t\tcommand: \"addLayer\",\n\t\t\t\targs: [afterLayer, insertBeforeLayerId]\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tdiffLayerPropertyChanges(beforeLayer.layout, afterLayer.layout, commands, layerId, null, \"setLayoutProperty\");\n\t\tdiffLayerPropertyChanges(beforeLayer.paint, afterLayer.paint, commands, layerId, null, \"setPaintProperty\");\n\t\tif (!deepEqual(beforeLayer.filter, afterLayer.filter)) addCommand(commands, {\n\t\t\tcommand: \"setFilter\",\n\t\t\targs: [layerId, afterLayer.filter]\n\t\t});\n\t\tif (!deepEqual(beforeLayer.minzoom, afterLayer.minzoom) || !deepEqual(beforeLayer.maxzoom, afterLayer.maxzoom)) addCommand(commands, {\n\t\t\tcommand: \"setLayerZoomRange\",\n\t\t\targs: [\n\t\t\t\tlayerId,\n\t\t\t\tafterLayer.minzoom,\n\t\t\t\tafterLayer.maxzoom\n\t\t\t]\n\t\t});\n\t\tfor (prop in beforeLayer) {\n\t\t\tif (!Object.prototype.hasOwnProperty.call(beforeLayer, prop)) continue;\n\t\t\tif (prop === \"layout\" || prop === \"paint\" || prop === \"filter\" || prop === \"metadata\" || prop === \"minzoom\" || prop === \"maxzoom\") continue;\n\t\t\tif (prop.indexOf(\"paint.\") === 0) diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), \"setPaintProperty\");\n\t\t\telse if (!deepEqual(beforeLayer[prop], afterLayer[prop])) addCommand(commands, {\n\t\t\t\tcommand: \"setLayerProperty\",\n\t\t\t\targs: [\n\t\t\t\t\tlayerId,\n\t\t\t\t\tprop,\n\t\t\t\t\tafterLayer[prop]\n\t\t\t\t]\n\t\t\t});\n\t\t}\n\t\tfor (prop in afterLayer) {\n\t\t\tif (!Object.prototype.hasOwnProperty.call(afterLayer, prop) || Object.prototype.hasOwnProperty.call(beforeLayer, prop)) continue;\n\t\t\tif (prop === \"layout\" || prop === \"paint\" || prop === \"filter\" || prop === \"metadata\" || prop === \"minzoom\" || prop === \"maxzoom\") continue;\n\t\t\tif (prop.indexOf(\"paint.\") === 0) diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), \"setPaintProperty\");\n\t\t\telse if (!deepEqual(beforeLayer[prop], afterLayer[prop])) addCommand(commands, {\n\t\t\t\tcommand: \"setLayerProperty\",\n\t\t\t\targs: [\n\t\t\t\t\tlayerId,\n\t\t\t\t\tprop,\n\t\t\t\t\tafterLayer[prop]\n\t\t\t\t]\n\t\t\t});\n\t\t}\n\t}\n}\n/**\n* Diff two stylesheet\n*\n* Creates semanticly aware diffs that can easily be applied at runtime.\n* Operations produced by the diff closely resemble the maplibre-gl-js API. Any\n* error creating the diff will fall back to the 'setStyle' operation.\n*\n* Example diff:\n* [\n* { command: 'setConstant', args: ['@water', '#0000FF'] },\n* { command: 'setPaintProperty', args: ['background', 'background-color', 'black'] }\n* ]\n*\n* @private\n* @param {*} [before] stylesheet to compare from\n* @param {*} after stylesheet to compare to\n* @returns Array list of changes\n*/\nfunction diff(before, after) {\n\tif (!before) return [{\n\t\tcommand: \"setStyle\",\n\t\targs: [after]\n\t}];\n\tlet commands = [];\n\ttry {\n\t\tif (!deepEqual(before.version, after.version)) return [{\n\t\t\tcommand: \"setStyle\",\n\t\t\targs: [after]\n\t\t}];\n\t\tif (!deepEqual(before.center, after.center)) commands.push({\n\t\t\tcommand: \"setCenter\",\n\t\t\targs: [after.center]\n\t\t});\n\t\tif (!deepEqual(before.state, after.state)) commands.push({\n\t\t\tcommand: \"setGlobalState\",\n\t\t\targs: [after.state]\n\t\t});\n\t\tif (!deepEqual(before.centerAltitude, after.centerAltitude)) commands.push({\n\t\t\tcommand: \"setCenterAltitude\",\n\t\t\targs: [after.centerAltitude]\n\t\t});\n\t\tif (!deepEqual(before.zoom, after.zoom)) commands.push({\n\t\t\tcommand: \"setZoom\",\n\t\t\targs: [after.zoom]\n\t\t});\n\t\tif (!deepEqual(before.bearing, after.bearing)) commands.push({\n\t\t\tcommand: \"setBearing\",\n\t\t\targs: [after.bearing]\n\t\t});\n\t\tif (!deepEqual(before.pitch, after.pitch)) commands.push({\n\t\t\tcommand: \"setPitch\",\n\t\t\targs: [after.pitch]\n\t\t});\n\t\tif (!deepEqual(before.roll, after.roll)) commands.push({\n\t\t\tcommand: \"setRoll\",\n\t\t\targs: [after.roll]\n\t\t});\n\t\tif (!deepEqual(before.sprite, after.sprite)) commands.push({\n\t\t\tcommand: \"setSprite\",\n\t\t\targs: [after.sprite]\n\t\t});\n\t\tif (!deepEqual(before.glyphs, after.glyphs)) commands.push({\n\t\t\tcommand: \"setGlyphs\",\n\t\t\targs: [after.glyphs]\n\t\t});\n\t\tif (!deepEqual(before.transition, after.transition)) commands.push({\n\t\t\tcommand: \"setTransition\",\n\t\t\targs: [after.transition]\n\t\t});\n\t\tif (!deepEqual(before.light, after.light)) commands.push({\n\t\t\tcommand: \"setLight\",\n\t\t\targs: [after.light]\n\t\t});\n\t\tif (!deepEqual(before.terrain, after.terrain)) commands.push({\n\t\t\tcommand: \"setTerrain\",\n\t\t\targs: [after.terrain]\n\t\t});\n\t\tif (!deepEqual(before.sky, after.sky)) commands.push({\n\t\t\tcommand: \"setSky\",\n\t\t\targs: [after.sky]\n\t\t});\n\t\tif (!deepEqual(before.projection, after.projection)) commands.push({\n\t\t\tcommand: \"setProjection\",\n\t\t\targs: [after.projection]\n\t\t});\n\t\tconst sourcesRemoved = {};\n\t\tconst removeOrAddSourceCommands = [];\n\t\tdiffSources(before.sources, after.sources, removeOrAddSourceCommands, sourcesRemoved);\n\t\tconst beforeLayers = [];\n\t\tif (before.layers) before.layers.forEach((layer) => {\n\t\t\tif (\"source\" in layer && sourcesRemoved[layer.source]) commands.push({\n\t\t\t\tcommand: \"removeLayer\",\n\t\t\t\targs: [layer.id]\n\t\t\t});\n\t\t\telse beforeLayers.push(layer);\n\t\t});\n\t\tcommands = commands.concat(removeOrAddSourceCommands);\n\t\tdiffLayers(beforeLayers, after.layers, commands);\n\t} catch (e) {\n\t\tconsole.warn(\"Unable to compute style diff:\", e);\n\t\tcommands = [{\n\t\t\tcommand: \"setStyle\",\n\t\t\targs: [after]\n\t\t}];\n\t}\n\treturn commands;\n}\n//#endregion\n//#region src/error/validation_error.ts\nvar ValidationError = class {\n\tconstructor(key, value, message, identifier, severity = \"error\") {\n\t\tthis.message = (key ? `${key}: ` : \"\") + message;\n\t\tif (identifier) this.identifier = identifier;\n\t\tthis.severity = severity;\n\t\tif (value !== null && value !== void 0 && value.__line__) this.line = value.__line__;\n\t}\n};\n//#endregion\n//#region src/error/parsing_error.ts\nvar ParsingError = class {\n\tconstructor(error) {\n\t\tthis.error = error;\n\t\tthis.message = error.message;\n\t\tconst match = error.message.match(/line (\\d+)/);\n\t\tthis.line = match ? parseInt(match[1], 10) : 0;\n\t}\n};\n//#endregion\n//#region src/expression/parsing_error.ts\nvar ExpressionParsingError = class extends Error {\n\tconstructor(key, message) {\n\t\tsuper(message);\n\t\tthis.message = message;\n\t\tthis.key = key;\n\t}\n};\n//#endregion\n//#region src/expression/scope.ts\n/**\n* Tracks `let` bindings during expression parsing.\n* @private\n*/\nvar Scope = class Scope {\n\tconstructor(parent, bindings = []) {\n\t\tthis.parent = parent;\n\t\tthis.bindings = {};\n\t\tfor (const [name, expression] of bindings) this.bindings[name] = expression;\n\t}\n\tconcat(bindings) {\n\t\treturn new Scope(this, bindings);\n\t}\n\tget(name) {\n\t\tif (this.bindings[name]) return this.bindings[name];\n\t\tif (this.parent) return this.parent.get(name);\n\t\tthrow new Error(`${name} not found in scope.`);\n\t}\n\thas(name) {\n\t\tif (this.bindings[name]) return true;\n\t\treturn this.parent ? this.parent.has(name) : false;\n\t}\n};\n//#endregion\n//#region src/expression/types.ts\nconst NullType = { kind: \"null\" };\nconst NumberType = { kind: \"number\" };\nconst StringType = { kind: \"string\" };\nconst BooleanType = { kind: \"boolean\" };\nconst ColorType = { kind: \"color\" };\nconst ProjectionDefinitionType = { kind: \"projectionDefinition\" };\nconst ObjectType = { kind: \"object\" };\nconst ValueType = { kind: \"value\" };\nconst ErrorType = { kind: \"error\" };\nconst CollatorType = { kind: \"collator\" };\nconst FormattedType = { kind: \"formatted\" };\nconst PaddingType = { kind: \"padding\" };\nconst ColorArrayType = { kind: \"colorArray\" };\nconst NumberArrayType = { kind: \"numberArray\" };\nconst ResolvedImageType = { kind: \"resolvedImage\" };\nconst VariableAnchorOffsetCollectionType = { kind: \"variableAnchorOffsetCollection\" };\nfunction array(itemType, N) {\n\treturn {\n\t\tkind: \"array\",\n\t\titemType,\n\t\tN\n\t};\n}\nfunction typeToString(type) {\n\tif (type.kind === \"array\") {\n\t\tconst itemType = typeToString(type.itemType);\n\t\treturn typeof type.N === \"number\" ? `array<${itemType}, ${type.N}>` : type.itemType.kind === \"value\" ? \"array\" : `array<${itemType}>`;\n\t} else return type.kind;\n}\nconst valueMemberTypes = [\n\tNullType,\n\tNumberType,\n\tStringType,\n\tBooleanType,\n\tColorType,\n\tProjectionDefinitionType,\n\tFormattedType,\n\tObjectType,\n\tarray(ValueType),\n\tPaddingType,\n\tNumberArrayType,\n\tColorArrayType,\n\tResolvedImageType,\n\tVariableAnchorOffsetCollectionType\n];\n/**\n* Returns null if `t` is a subtype of `expected`; otherwise returns an\n* error message.\n* @private\n*/\nfunction checkSubtype(expected, t) {\n\tif (t.kind === \"error\") return null;\n\telse if (expected.kind === \"array\") {\n\t\tif (t.kind === \"array\" && (t.N === 0 && t.itemType.kind === \"value\" || !checkSubtype(expected.itemType, t.itemType)) && (typeof expected.N !== \"number\" || expected.N === t.N)) return null;\n\t} else if (expected.kind === t.kind) return null;\n\telse if (expected.kind === \"value\") {\n\t\tfor (const memberType of valueMemberTypes) if (!checkSubtype(memberType, t)) return null;\n\t}\n\treturn `Expected ${typeToString(expected)} but found ${typeToString(t)} instead.`;\n}\nfunction isValidType(provided, allowedTypes) {\n\treturn allowedTypes.some((t) => t.kind === provided.kind);\n}\nfunction isValidNativeType(provided, allowedTypes) {\n\treturn allowedTypes.some((t) => {\n\t\tif (t === \"null\") return provided === null;\n\t\telse if (t === \"array\") return Array.isArray(provided);\n\t\telse if (t === \"object\") return provided && !Array.isArray(provided) && typeof provided === \"object\";\n\t\telse return t === typeof provided;\n\t});\n}\n/**\n* Verify whether the specified type is of the same type as the specified sample.\n*\n* @param provided Type to verify\n* @param sample Sample type to reference\n* @returns `true` if both objects are of the same type, `false` otherwise\n* @example basic types\n* if (verifyType(outputType, ValueType)) {\n* // type narrowed to:\n* outputType.kind; // 'value'\n* }\n* @example array types\n* if (verifyType(outputType, array(NumberType))) {\n* // type narrowed to:\n* outputType.kind; // 'array'\n* outputType.itemType; // NumberTypeT\n* outputType.itemType.kind; // 'number'\n* }\n*/\nfunction verifyType(provided, sample) {\n\tif (provided.kind === \"array\" && sample.kind === \"array\") return provided.itemType.kind === sample.itemType.kind && typeof provided.N === \"number\";\n\treturn provided.kind === sample.kind;\n}\n//#endregion\n//#region src/expression/types/color_spaces.ts\nconst Xn = .96422;\nconst Yn = 1;\nconst Zn = .82521;\nconst t0 = 4 / 29;\nconst t1 = 6 / 29;\nconst t2 = 3 * t1 * t1;\nconst t3 = t1 * t1 * t1;\nconst deg2rad = Math.PI / 180;\nconst rad2deg = 180 / Math.PI;\nfunction constrainAngle(angle) {\n\tangle = angle % 360;\n\tif (angle < 0) angle += 360;\n\treturn angle;\n}\nfunction rgbToLab([r, g, b, alpha]) {\n\tr = rgb2xyz(r);\n\tg = rgb2xyz(g);\n\tb = rgb2xyz(b);\n\tlet x, z;\n\tconst y = xyz2lab((.2225045 * r + .7168786 * g + .0606169 * b) / Yn);\n\tif (r === g && g === b) x = z = y;\n\telse {\n\t\tx = xyz2lab((.4360747 * r + .3850649 * g + .1430804 * b) / Xn);\n\t\tz = xyz2lab((.0139322 * r + .0971045 * g + .7141733 * b) / Zn);\n\t}\n\tconst l = 116 * y - 16;\n\treturn [\n\t\tl < 0 ? 0 : l,\n\t\t500 * (x - y),\n\t\t200 * (y - z),\n\t\talpha\n\t];\n}\nfunction rgb2xyz(x) {\n\treturn x <= .04045 ? x / 12.92 : Math.pow((x + .055) / 1.055, 2.4);\n}\nfunction xyz2lab(t) {\n\treturn t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\nfunction labToRgb([l, a, b, alpha]) {\n\tlet y = (l + 16) / 116, x = isNaN(a) ? y : y + a / 500, z = isNaN(b) ? y : y - b / 200;\n\ty = Yn * lab2xyz(y);\n\tx = Xn * lab2xyz(x);\n\tz = Zn * lab2xyz(z);\n\treturn [\n\t\txyz2rgb(3.1338561 * x - 1.6168667 * y - .4906146 * z),\n\t\txyz2rgb(-.9787684 * x + 1.9161415 * y + .033454 * z),\n\t\txyz2rgb(.0719453 * x - .2289914 * y + 1.4052427 * z),\n\t\talpha\n\t];\n}\nfunction xyz2rgb(x) {\n\tx = x <= .00304 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - .055;\n\treturn x < 0 ? 0 : x > 1 ? 1 : x;\n}\nfunction lab2xyz(t) {\n\treturn t > t1 ? t * t * t : t2 * (t - t0);\n}\nfunction rgbToHcl(rgbColor) {\n\tconst [l, a, b, alpha] = rgbToLab(rgbColor);\n\tconst c = Math.sqrt(a * a + b * b);\n\treturn [\n\t\tMath.round(c * 1e4) ? constrainAngle(Math.atan2(b, a) * rad2deg) : NaN,\n\t\tc,\n\t\tl,\n\t\talpha\n\t];\n}\nfunction hclToRgb([h, c, l, alpha]) {\n\th = isNaN(h) ? 0 : h * deg2rad;\n\treturn labToRgb([\n\t\tl,\n\t\tMath.cos(h) * c,\n\t\tMath.sin(h) * c,\n\t\talpha\n\t]);\n}\nfunction hslToRgb([h, s, l, alpha]) {\n\th = constrainAngle(h);\n\ts /= 100;\n\tl /= 100;\n\tfunction f(n) {\n\t\tconst k = (n + h / 30) % 12;\n\t\tconst a = s * Math.min(l, 1 - l);\n\t\treturn l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n\t}\n\treturn [\n\t\tf(0),\n\t\tf(8),\n\t\tf(4),\n\t\talpha\n\t];\n}\n//#endregion\n//#region src/util/get_own.ts\nconst hasOwnProperty = Object.hasOwn || function hasOwnProperty(object, key) {\n\treturn Object.prototype.hasOwnProperty.call(object, key);\n};\nfunction getOwn(object, key) {\n\treturn hasOwnProperty(object, key) ? object[key] : void 0;\n}\n//#endregion\n//#region src/expression/types/parse_css_color.ts\n/**\n* CSS color parser compliant with CSS Color 4 Specification.\n* Supports: named colors, `transparent` keyword, all rgb hex notations,\n* rgb(), rgba(), hsl() and hsla() functions.\n* Does not round the parsed values to integers from the range 0..255.\n*\n* Syntax:\n*\n* = | \n* = | \n*\n* rgb() = rgb( {3} [ / ]? ) | rgb( {3} [ / ]? )\n* rgb() = rgb( #{3} , ? ) | rgb( #{3} , ? )\n*\n* hsl() = hsl( [ / ]? )\n* hsl() = hsl( , , , ? )\n*\n* Caveats:\n* - - with optional `deg` suffix; `grad`, `rad`, `turn` are not supported\n* - `none` keyword is not supported\n* - comments inside rgb()/hsl() are not supported\n* - legacy color syntax rgba() is supported with an identical grammar and behavior to rgb()\n* - legacy color syntax hsla() is supported with an identical grammar and behavior to hsl()\n*\n* @param input CSS color string to parse.\n* @returns Color in sRGB color space, with `red`, `green`, `blue`\n* and `alpha` channels normalized to the range 0..1,\n* or `undefined` if the input is not a valid color string.\n*/\nfunction parseCssColor(input) {\n\tinput = input.toLowerCase().trim();\n\tif (input === \"transparent\") return [\n\t\t0,\n\t\t0,\n\t\t0,\n\t\t0\n\t];\n\tconst namedColorsMatch = getOwn(namedColors, input);\n\tif (namedColorsMatch) {\n\t\tconst [r, g, b] = namedColorsMatch;\n\t\treturn [\n\t\t\tr / 255,\n\t\t\tg / 255,\n\t\t\tb / 255,\n\t\t\t1\n\t\t];\n\t}\n\tif (input.startsWith(\"#\")) {\n\t\tif (/^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.test(input)) {\n\t\t\tconst step = input.length < 6 ? 1 : 2;\n\t\t\tlet i = 1;\n\t\t\treturn [\n\t\t\t\tparseHex(input.slice(i, i += step)),\n\t\t\t\tparseHex(input.slice(i, i += step)),\n\t\t\t\tparseHex(input.slice(i, i += step)),\n\t\t\t\tparseHex(input.slice(i, i + step) || \"ff\")\n\t\t\t];\n\t\t}\n\t}\n\tif (input.startsWith(\"rgb\")) {\n\t\tconst rgbMatch = input.match(/^rgba?\\(\\s*([\\de.+-]+)(%)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)(%)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)(%)?(?:\\s*([,\\/])\\s*([\\de.+-]+)(%)?)?\\s*\\)$/);\n\t\tif (rgbMatch) {\n\t\t\tconst [_, r, rp, f1, g, gp, f2, b, bp, f3, a, ap] = rgbMatch;\n\t\t\tconst argFormat = [\n\t\t\t\tf1 || \" \",\n\t\t\t\tf2 || \" \",\n\t\t\t\tf3\n\t\t\t].join(\"\");\n\t\t\tif (argFormat === \" \" || argFormat === \" /\" || argFormat === \",,\" || argFormat === \",,,\") {\n\t\t\t\tconst valFormat = [\n\t\t\t\t\trp,\n\t\t\t\t\tgp,\n\t\t\t\t\tbp\n\t\t\t\t].join(\"\");\n\t\t\t\tconst maxValue = valFormat === \"%%%\" ? 100 : valFormat === \"\" ? 255 : 0;\n\t\t\t\tif (maxValue) {\n\t\t\t\t\tconst rgba = [\n\t\t\t\t\t\tclamp(+r / maxValue, 0, 1),\n\t\t\t\t\t\tclamp(+g / maxValue, 0, 1),\n\t\t\t\t\t\tclamp(+b / maxValue, 0, 1),\n\t\t\t\t\t\ta ? parseAlpha(+a, ap) : 1\n\t\t\t\t\t];\n\t\t\t\t\tif (validateNumbers(rgba)) return rgba;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n\tconst hslMatch = input.match(/^hsla?\\(\\s*([\\de.+-]+)(?:deg)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)%(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)%(?:\\s*([,\\/])\\s*([\\de.+-]+)(%)?)?\\s*\\)$/);\n\tif (hslMatch) {\n\t\tconst [_, h, f1, s, f2, l, f3, a, ap] = hslMatch;\n\t\tconst argFormat = [\n\t\t\tf1 || \" \",\n\t\t\tf2 || \" \",\n\t\t\tf3\n\t\t].join(\"\");\n\t\tif (argFormat === \" \" || argFormat === \" /\" || argFormat === \",,\" || argFormat === \",,,\") {\n\t\t\tconst hsla = [\n\t\t\t\t+h,\n\t\t\t\tclamp(+s, 0, 100),\n\t\t\t\tclamp(+l, 0, 100),\n\t\t\t\ta ? parseAlpha(+a, ap) : 1\n\t\t\t];\n\t\t\tif (validateNumbers(hsla)) return hslToRgb(hsla);\n\t\t}\n\t}\n}\nfunction parseHex(hex) {\n\treturn parseInt(hex.padEnd(2, hex), 16) / 255;\n}\nfunction parseAlpha(a, asPercentage) {\n\treturn clamp(asPercentage ? a / 100 : a, 0, 1);\n}\nfunction clamp(n, min, max) {\n\treturn Math.min(Math.max(min, n), max);\n}\n/**\n* The regular expression for numeric values is not super specific, and it may\n* happen that it will accept a value that is not a valid number. In order to\n* detect and eliminate such values this function exists.\n*\n* @param array Array of uncertain numbers.\n* @returns `true` if the specified array contains only valid numbers, `false` otherwise.\n*/\nfunction validateNumbers(array) {\n\treturn !array.some(Number.isNaN);\n}\n/**\n* To generate:\n* - visit {@link https://www.w3.org/TR/css-color-4/#named-colors}\n* - run in the console:\n* @example\n* copy(`{\\n${[...document.querySelector('.named-color-table tbody').children].map((tr) => `${tr.cells[2].textContent.trim()}: [${tr.cells[4].textContent.trim().split(/\\s+/).join(', ')}],`).join('\\n')}\\n}`);\n*/\nconst namedColors = {\n\taliceblue: [\n\t\t240,\n\t\t248,\n\t\t255\n\t],\n\tantiquewhite: [\n\t\t250,\n\t\t235,\n\t\t215\n\t],\n\taqua: [\n\t\t0,\n\t\t255,\n\t\t255\n\t],\n\taquamarine: [\n\t\t127,\n\t\t255,\n\t\t212\n\t],\n\tazure: [\n\t\t240,\n\t\t255,\n\t\t255\n\t],\n\tbeige: [\n\t\t245,\n\t\t245,\n\t\t220\n\t],\n\tbisque: [\n\t\t255,\n\t\t228,\n\t\t196\n\t],\n\tblack: [\n\t\t0,\n\t\t0,\n\t\t0\n\t],\n\tblanchedalmond: [\n\t\t255,\n\t\t235,\n\t\t205\n\t],\n\tblue: [\n\t\t0,\n\t\t0,\n\t\t255\n\t],\n\tblueviolet: [\n\t\t138,\n\t\t43,\n\t\t226\n\t],\n\tbrown: [\n\t\t165,\n\t\t42,\n\t\t42\n\t],\n\tburlywood: [\n\t\t222,\n\t\t184,\n\t\t135\n\t],\n\tcadetblue: [\n\t\t95,\n\t\t158,\n\t\t160\n\t],\n\tchartreuse: [\n\t\t127,\n\t\t255,\n\t\t0\n\t],\n\tchocolate: [\n\t\t210,\n\t\t105,\n\t\t30\n\t],\n\tcoral: [\n\t\t255,\n\t\t127,\n\t\t80\n\t],\n\tcornflowerblue: [\n\t\t100,\n\t\t149,\n\t\t237\n\t],\n\tcornsilk: [\n\t\t255,\n\t\t248,\n\t\t220\n\t],\n\tcrimson: [\n\t\t220,\n\t\t20,\n\t\t60\n\t],\n\tcyan: [\n\t\t0,\n\t\t255,\n\t\t255\n\t],\n\tdarkblue: [\n\t\t0,\n\t\t0,\n\t\t139\n\t],\n\tdarkcyan: [\n\t\t0,\n\t\t139,\n\t\t139\n\t],\n\tdarkgoldenrod: [\n\t\t184,\n\t\t134,\n\t\t11\n\t],\n\tdarkgray: [\n\t\t169,\n\t\t169,\n\t\t169\n\t],\n\tdarkgreen: [\n\t\t0,\n\t\t100,\n\t\t0\n\t],\n\tdarkgrey: [\n\t\t169,\n\t\t169,\n\t\t169\n\t],\n\tdarkkhaki: [\n\t\t189,\n\t\t183,\n\t\t107\n\t],\n\tdarkmagenta: [\n\t\t139,\n\t\t0,\n\t\t139\n\t],\n\tdarkolivegreen: [\n\t\t85,\n\t\t107,\n\t\t47\n\t],\n\tdarkorange: [\n\t\t255,\n\t\t140,\n\t\t0\n\t],\n\tdarkorchid: [\n\t\t153,\n\t\t50,\n\t\t204\n\t],\n\tdarkred: [\n\t\t139,\n\t\t0,\n\t\t0\n\t],\n\tdarksalmon: [\n\t\t233,\n\t\t150,\n\t\t122\n\t],\n\tdarkseagreen: [\n\t\t143,\n\t\t188,\n\t\t143\n\t],\n\tdarkslateblue: [\n\t\t72,\n\t\t61,\n\t\t139\n\t],\n\tdarkslategray: [\n\t\t47,\n\t\t79,\n\t\t79\n\t],\n\tdarkslategrey: [\n\t\t47,\n\t\t79,\n\t\t79\n\t],\n\tdarkturquoise: [\n\t\t0,\n\t\t206,\n\t\t209\n\t],\n\tdarkviolet: [\n\t\t148,\n\t\t0,\n\t\t211\n\t],\n\tdeeppink: [\n\t\t255,\n\t\t20,\n\t\t147\n\t],\n\tdeepskyblue: [\n\t\t0,\n\t\t191,\n\t\t255\n\t],\n\tdimgray: [\n\t\t105,\n\t\t105,\n\t\t105\n\t],\n\tdimgrey: [\n\t\t105,\n\t\t105,\n\t\t105\n\t],\n\tdodgerblue: [\n\t\t30,\n\t\t144,\n\t\t255\n\t],\n\tfirebrick: [\n\t\t178,\n\t\t34,\n\t\t34\n\t],\n\tfloralwhite: [\n\t\t255,\n\t\t250,\n\t\t240\n\t],\n\tforestgreen: [\n\t\t34,\n\t\t139,\n\t\t34\n\t],\n\tfuchsia: [\n\t\t255,\n\t\t0,\n\t\t255\n\t],\n\tgainsboro: [\n\t\t220,\n\t\t220,\n\t\t220\n\t],\n\tghostwhite: [\n\t\t248,\n\t\t248,\n\t\t255\n\t],\n\tgold: [\n\t\t255,\n\t\t215,\n\t\t0\n\t],\n\tgoldenrod: [\n\t\t218,\n\t\t165,\n\t\t32\n\t],\n\tgray: [\n\t\t128,\n\t\t128,\n\t\t128\n\t],\n\tgreen: [\n\t\t0,\n\t\t128,\n\t\t0\n\t],\n\tgreenyellow: [\n\t\t173,\n\t\t255,\n\t\t47\n\t],\n\tgrey: [\n\t\t128,\n\t\t128,\n\t\t128\n\t],\n\thoneydew: [\n\t\t240,\n\t\t255,\n\t\t240\n\t],\n\thotpink: [\n\t\t255,\n\t\t105,\n\t\t180\n\t],\n\tindianred: [\n\t\t205,\n\t\t92,\n\t\t92\n\t],\n\tindigo: [\n\t\t75,\n\t\t0,\n\t\t130\n\t],\n\tivory: [\n\t\t255,\n\t\t255,\n\t\t240\n\t],\n\tkhaki: [\n\t\t240,\n\t\t230,\n\t\t140\n\t],\n\tlavender: [\n\t\t230,\n\t\t230,\n\t\t250\n\t],\n\tlavenderblush: [\n\t\t255,\n\t\t240,\n\t\t245\n\t],\n\tlawngreen: [\n\t\t124,\n\t\t252,\n\t\t0\n\t],\n\tlemonchiffon: [\n\t\t255,\n\t\t250,\n\t\t205\n\t],\n\tlightblue: [\n\t\t173,\n\t\t216,\n\t\t230\n\t],\n\tlightcoral: [\n\t\t240,\n\t\t128,\n\t\t128\n\t],\n\tlightcyan: [\n\t\t224,\n\t\t255,\n\t\t255\n\t],\n\tlightgoldenrodyellow: [\n\t\t250,\n\t\t250,\n\t\t210\n\t],\n\tlightgray: [\n\t\t211,\n\t\t211,\n\t\t211\n\t],\n\tlightgreen: [\n\t\t144,\n\t\t238,\n\t\t144\n\t],\n\tlightgrey: [\n\t\t211,\n\t\t211,\n\t\t211\n\t],\n\tlightpink: [\n\t\t255,\n\t\t182,\n\t\t193\n\t],\n\tlightsalmon: [\n\t\t255,\n\t\t160,\n\t\t122\n\t],\n\tlightseagreen: [\n\t\t32,\n\t\t178,\n\t\t170\n\t],\n\tlightskyblue: [\n\t\t135,\n\t\t206,\n\t\t250\n\t],\n\tlightslategray: [\n\t\t119,\n\t\t136,\n\t\t153\n\t],\n\tlightslategrey: [\n\t\t119,\n\t\t136,\n\t\t153\n\t],\n\tlightsteelblue: [\n\t\t176,\n\t\t196,\n\t\t222\n\t],\n\tlightyellow: [\n\t\t255,\n\t\t255,\n\t\t224\n\t],\n\tlime: [\n\t\t0,\n\t\t255,\n\t\t0\n\t],\n\tlimegreen: [\n\t\t50,\n\t\t205,\n\t\t50\n\t],\n\tlinen: [\n\t\t250,\n\t\t240,\n\t\t230\n\t],\n\tmagenta: [\n\t\t255,\n\t\t0,\n\t\t255\n\t],\n\tmaroon: [\n\t\t128,\n\t\t0,\n\t\t0\n\t],\n\tmediumaquamarine: [\n\t\t102,\n\t\t205,\n\t\t170\n\t],\n\tmediumblue: [\n\t\t0,\n\t\t0,\n\t\t205\n\t],\n\tmediumorchid: [\n\t\t186,\n\t\t85,\n\t\t211\n\t],\n\tmediumpurple: [\n\t\t147,\n\t\t112,\n\t\t219\n\t],\n\tmediumseagreen: [\n\t\t60,\n\t\t179,\n\t\t113\n\t],\n\tmediumslateblue: [\n\t\t123,\n\t\t104,\n\t\t238\n\t],\n\tmediumspringgreen: [\n\t\t0,\n\t\t250,\n\t\t154\n\t],\n\tmediumturquoise: [\n\t\t72,\n\t\t209,\n\t\t204\n\t],\n\tmediumvioletred: [\n\t\t199,\n\t\t21,\n\t\t133\n\t],\n\tmidnightblue: [\n\t\t25,\n\t\t25,\n\t\t112\n\t],\n\tmintcream: [\n\t\t245,\n\t\t255,\n\t\t250\n\t],\n\tmistyrose: [\n\t\t255,\n\t\t228,\n\t\t225\n\t],\n\tmoccasin: [\n\t\t255,\n\t\t228,\n\t\t181\n\t],\n\tnavajowhite: [\n\t\t255,\n\t\t222,\n\t\t173\n\t],\n\tnavy: [\n\t\t0,\n\t\t0,\n\t\t128\n\t],\n\toldlace: [\n\t\t253,\n\t\t245,\n\t\t230\n\t],\n\tolive: [\n\t\t128,\n\t\t128,\n\t\t0\n\t],\n\tolivedrab: [\n\t\t107,\n\t\t142,\n\t\t35\n\t],\n\torange: [\n\t\t255,\n\t\t165,\n\t\t0\n\t],\n\torangered: [\n\t\t255,\n\t\t69,\n\t\t0\n\t],\n\torchid: [\n\t\t218,\n\t\t112,\n\t\t214\n\t],\n\tpalegoldenrod: [\n\t\t238,\n\t\t232,\n\t\t170\n\t],\n\tpalegreen: [\n\t\t152,\n\t\t251,\n\t\t152\n\t],\n\tpaleturquoise: [\n\t\t175,\n\t\t238,\n\t\t238\n\t],\n\tpalevioletred: [\n\t\t219,\n\t\t112,\n\t\t147\n\t],\n\tpapayawhip: [\n\t\t255,\n\t\t239,\n\t\t213\n\t],\n\tpeachpuff: [\n\t\t255,\n\t\t218,\n\t\t185\n\t],\n\tperu: [\n\t\t205,\n\t\t133,\n\t\t63\n\t],\n\tpink: [\n\t\t255,\n\t\t192,\n\t\t203\n\t],\n\tplum: [\n\t\t221,\n\t\t160,\n\t\t221\n\t],\n\tpowderblue: [\n\t\t176,\n\t\t224,\n\t\t230\n\t],\n\tpurple: [\n\t\t128,\n\t\t0,\n\t\t128\n\t],\n\trebeccapurple: [\n\t\t102,\n\t\t51,\n\t\t153\n\t],\n\tred: [\n\t\t255,\n\t\t0,\n\t\t0\n\t],\n\trosybrown: [\n\t\t188,\n\t\t143,\n\t\t143\n\t],\n\troyalblue: [\n\t\t65,\n\t\t105,\n\t\t225\n\t],\n\tsaddlebrown: [\n\t\t139,\n\t\t69,\n\t\t19\n\t],\n\tsalmon: [\n\t\t250,\n\t\t128,\n\t\t114\n\t],\n\tsandybrown: [\n\t\t244,\n\t\t164,\n\t\t96\n\t],\n\tseagreen: [\n\t\t46,\n\t\t139,\n\t\t87\n\t],\n\tseashell: [\n\t\t255,\n\t\t245,\n\t\t238\n\t],\n\tsienna: [\n\t\t160,\n\t\t82,\n\t\t45\n\t],\n\tsilver: [\n\t\t192,\n\t\t192,\n\t\t192\n\t],\n\tskyblue: [\n\t\t135,\n\t\t206,\n\t\t235\n\t],\n\tslateblue: [\n\t\t106,\n\t\t90,\n\t\t205\n\t],\n\tslategray: [\n\t\t112,\n\t\t128,\n\t\t144\n\t],\n\tslategrey: [\n\t\t112,\n\t\t128,\n\t\t144\n\t],\n\tsnow: [\n\t\t255,\n\t\t250,\n\t\t250\n\t],\n\tspringgreen: [\n\t\t0,\n\t\t255,\n\t\t127\n\t],\n\tsteelblue: [\n\t\t70,\n\t\t130,\n\t\t180\n\t],\n\ttan: [\n\t\t210,\n\t\t180,\n\t\t140\n\t],\n\tteal: [\n\t\t0,\n\t\t128,\n\t\t128\n\t],\n\tthistle: [\n\t\t216,\n\t\t191,\n\t\t216\n\t],\n\ttomato: [\n\t\t255,\n\t\t99,\n\t\t71\n\t],\n\tturquoise: [\n\t\t64,\n\t\t224,\n\t\t208\n\t],\n\tviolet: [\n\t\t238,\n\t\t130,\n\t\t238\n\t],\n\twheat: [\n\t\t245,\n\t\t222,\n\t\t179\n\t],\n\twhite: [\n\t\t255,\n\t\t255,\n\t\t255\n\t],\n\twhitesmoke: [\n\t\t245,\n\t\t245,\n\t\t245\n\t],\n\tyellow: [\n\t\t255,\n\t\t255,\n\t\t0\n\t],\n\tyellowgreen: [\n\t\t154,\n\t\t205,\n\t\t50\n\t]\n};\n//#endregion\n//#region src/util/interpolate-primitives.ts\nfunction interpolateNumber(from, to, t) {\n\treturn from + t * (to - from);\n}\nfunction interpolateArray(from, to, t) {\n\treturn from.map((d, i) => {\n\t\treturn interpolateNumber(d, to[i], t);\n\t});\n}\n//#endregion\n//#region src/expression/types/color.ts\n/**\n* Checks whether the specified color space is one of the supported interpolation color spaces.\n*\n* @param colorSpace Color space key to verify.\n* @returns `true` if the specified color space is one of the supported\n* interpolation color spaces, `false` otherwise\n*/\nfunction isSupportedInterpolationColorSpace(colorSpace) {\n\treturn colorSpace === \"rgb\" || colorSpace === \"hcl\" || colorSpace === \"lab\";\n}\n/**\n* Color representation used by WebGL.\n* Defined in sRGB color space and pre-blended with alpha.\n* @private\n*/\nvar Color = class Color {\n\t/**\n\t* @param r Red component premultiplied by `alpha` 0..1\n\t* @param g Green component premultiplied by `alpha` 0..1\n\t* @param b Blue component premultiplied by `alpha` 0..1\n\t* @param [alpha=1] Alpha component 0..1\n\t* @param [premultiplied=true] Whether the `r`, `g` and `b` values have already\n\t* been multiplied by alpha. If `true` nothing happens if `false` then they will\n\t* be multiplied automatically.\n\t*/\n\tconstructor(r, g, b, alpha = 1, premultiplied = true) {\n\t\tthis.r = r;\n\t\tthis.g = g;\n\t\tthis.b = b;\n\t\tthis.a = alpha;\n\t\tif (!premultiplied) {\n\t\t\tthis.r *= alpha;\n\t\t\tthis.g *= alpha;\n\t\t\tthis.b *= alpha;\n\t\t\tif (!alpha) this.overwriteGetter(\"rgb\", [\n\t\t\t\tr,\n\t\t\t\tg,\n\t\t\t\tb,\n\t\t\t\talpha\n\t\t\t]);\n\t\t}\n\t}\n\tstatic {\n\t\tthis.black = new Color(0, 0, 0, 1);\n\t}\n\tstatic {\n\t\tthis.white = new Color(1, 1, 1, 1);\n\t}\n\tstatic {\n\t\tthis.transparent = new Color(0, 0, 0, 0);\n\t}\n\tstatic {\n\t\tthis.red = new Color(1, 0, 0, 1);\n\t}\n\t/**\n\t* Parses CSS color strings and converts colors to sRGB color space if needed.\n\t* Officially supported color formats:\n\t* - keyword, e.g. 'aquamarine' or 'steelblue'\n\t* - hex (with 3, 4, 6 or 8 digits), e.g. '#f0f' or '#e9bebea9'\n\t* - rgb and rgba, e.g. 'rgb(0,240,120)' or 'rgba(0%,94%,47%,0.1)' or 'rgb(0 240 120 / .3)'\n\t* - hsl and hsla, e.g. 'hsl(0,0%,83%)' or 'hsla(0,0%,83%,.5)' or 'hsl(0 0% 83% / 20%)'\n\t*\n\t* @param input CSS color string to parse.\n\t* @returns A `Color` instance, or `undefined` if the input is not a valid color string.\n\t*/\n\tstatic parse(input) {\n\t\tif (input instanceof Color) return input;\n\t\tif (typeof input !== \"string\") return;\n\t\tconst rgba = parseCssColor(input);\n\t\tif (rgba) return new Color(...rgba, false);\n\t}\n\t/**\n\t* Used in color interpolation and by 'to-rgba' expression.\n\t*\n\t* @returns Gien color, with reversed alpha blending, in sRGB color space.\n\t*/\n\tget rgb() {\n\t\tconst { r, g, b, a } = this;\n\t\tconst f = a || Infinity;\n\t\treturn this.overwriteGetter(\"rgb\", [\n\t\t\tr / f,\n\t\t\tg / f,\n\t\t\tb / f,\n\t\t\ta\n\t\t]);\n\t}\n\t/**\n\t* Used in color interpolation.\n\t*\n\t* @returns Gien color, with reversed alpha blending, in HCL color space.\n\t*/\n\tget hcl() {\n\t\treturn this.overwriteGetter(\"hcl\", rgbToHcl(this.rgb));\n\t}\n\t/**\n\t* Used in color interpolation.\n\t*\n\t* @returns Gien color, with reversed alpha blending, in LAB color space.\n\t*/\n\tget lab() {\n\t\treturn this.overwriteGetter(\"lab\", rgbToLab(this.rgb));\n\t}\n\t/**\n\t* Lazy getter pattern. When getter is called for the first time lazy value\n\t* is calculated and then overwrites getter function in given object instance.\n\t*\n\t* @example:\n\t* const redColor = Color.parse('red');\n\t* let x = redColor.hcl; // this will invoke `get hcl()`, which will calculate\n\t* // the value of red in HCL space and invoke this `overwriteGetter` function\n\t* // which in turn will set a field with a key 'hcl' in the `redColor` object.\n\t* // In other words it will override `get hcl()` from its `Color` prototype\n\t* // with its own property: hcl = [calculated red value in hcl].\n\t* let y = redColor.hcl; // next call will no longer invoke getter but simply\n\t* // return the previously calculated value\n\t* x === y; // true - `x` is exactly the same object as `y`\n\t*\n\t* @param getterKey Getter key\n\t* @param lazyValue Lazily calculated value to be memoized by current instance\n\t* @private\n\t*/\n\toverwriteGetter(getterKey, lazyValue) {\n\t\tObject.defineProperty(this, getterKey, { value: lazyValue });\n\t\treturn lazyValue;\n\t}\n\t/**\n\t* Used by 'to-string' expression.\n\t*\n\t* @returns Serialized color in format `rgba(r,g,b,a)`\n\t* where r,g,b are numbers within 0..255 and alpha is number within 1..0\n\t*\n\t* @example\n\t* var purple = new Color.parse('purple');\n\t* purple.toString; // = \"rgba(128,0,128,1)\"\n\t* var translucentGreen = new Color.parse('rgba(26, 207, 26, .73)');\n\t* translucentGreen.toString(); // = \"rgba(26,207,26,0.73)\"\n\t*/\n\ttoString() {\n\t\tconst [r, g, b, a] = this.rgb;\n\t\treturn `rgba(${[\n\t\t\tr,\n\t\t\tg,\n\t\t\tb\n\t\t].map((n) => Math.round(n * 255)).join(\",\")},${a})`;\n\t}\n\tstatic interpolate(from, to, t, spaceKey = \"rgb\") {\n\t\tswitch (spaceKey) {\n\t\t\tcase \"rgb\": {\n\t\t\t\tconst [r, g, b, alpha] = interpolateArray(from.rgb, to.rgb, t);\n\t\t\t\treturn new Color(r, g, b, alpha, false);\n\t\t\t}\n\t\t\tcase \"hcl\": {\n\t\t\t\tconst [hue0, chroma0, light0, alphaF] = from.hcl;\n\t\t\t\tconst [hue1, chroma1, light1, alphaT] = to.hcl;\n\t\t\t\tlet hue, chroma;\n\t\t\t\tif (!isNaN(hue0) && !isNaN(hue1)) {\n\t\t\t\t\tlet dh = hue1 - hue0;\n\t\t\t\t\tif (hue1 > hue0 && dh > 180) dh -= 360;\n\t\t\t\t\telse if (hue1 < hue0 && hue0 - hue1 > 180) dh += 360;\n\t\t\t\t\thue = hue0 + t * dh;\n\t\t\t\t} else if (!isNaN(hue0)) {\n\t\t\t\t\thue = hue0;\n\t\t\t\t\tif (light1 === 1 || light1 === 0) chroma = chroma0;\n\t\t\t\t} else if (!isNaN(hue1)) {\n\t\t\t\t\thue = hue1;\n\t\t\t\t\tif (light0 === 1 || light0 === 0) chroma = chroma1;\n\t\t\t\t} else hue = NaN;\n\t\t\t\tconst [r, g, b, alpha] = hclToRgb([\n\t\t\t\t\thue,\n\t\t\t\t\tchroma ?? interpolateNumber(chroma0, chroma1, t),\n\t\t\t\t\tinterpolateNumber(light0, light1, t),\n\t\t\t\t\tinterpolateNumber(alphaF, alphaT, t)\n\t\t\t\t]);\n\t\t\t\treturn new Color(r, g, b, alpha, false);\n\t\t\t}\n\t\t\tcase \"lab\": {\n\t\t\t\tconst [r, g, b, alpha] = labToRgb(interpolateArray(from.lab, to.lab, t));\n\t\t\t\treturn new Color(r, g, b, alpha, false);\n\t\t\t}\n\t\t}\n\t}\n};\n//#endregion\n//#region src/expression/types/collator.ts\nvar Collator = class {\n\tconstructor(caseSensitive, diacriticSensitive, locale) {\n\t\tif (caseSensitive) this.sensitivity = diacriticSensitive ? \"variant\" : \"case\";\n\t\telse this.sensitivity = diacriticSensitive ? \"accent\" : \"base\";\n\t\tthis.locale = locale;\n\t\tthis.collator = new Intl.Collator(this.locale ? this.locale : [], {\n\t\t\tsensitivity: this.sensitivity,\n\t\t\tusage: \"search\"\n\t\t});\n\t}\n\tcompare(lhs, rhs) {\n\t\treturn this.collator.compare(lhs, rhs);\n\t}\n\tresolvedLocale() {\n\t\treturn new Intl.Collator(this.locale ? this.locale : []).resolvedOptions().locale;\n\t}\n};\n//#endregion\n//#region src/expression/types/formatted.ts\nconst VERTICAL_ALIGN_OPTIONS = [\n\t\"bottom\",\n\t\"center\",\n\t\"top\"\n];\nvar FormattedSection = class {\n\tconstructor(text, image, scale, fontStack, textColor, verticalAlign) {\n\t\tthis.text = text;\n\t\tthis.image = image;\n\t\tthis.scale = scale;\n\t\tthis.fontStack = fontStack;\n\t\tthis.textColor = textColor;\n\t\tthis.verticalAlign = verticalAlign;\n\t}\n};\nvar Formatted = class Formatted {\n\tconstructor(sections) {\n\t\tthis.sections = sections;\n\t}\n\tstatic fromString(unformatted) {\n\t\treturn new Formatted([new FormattedSection(unformatted, null, null, null, null, null)]);\n\t}\n\tisEmpty() {\n\t\tif (this.sections.length === 0) return true;\n\t\treturn !this.sections.some((section) => section.text.length !== 0 || section.image && section.image.name.length !== 0);\n\t}\n\tstatic factory(text) {\n\t\tif (text instanceof Formatted) return text;\n\t\telse return Formatted.fromString(text);\n\t}\n\ttoString() {\n\t\tif (this.sections.length === 0) return \"\";\n\t\treturn this.sections.map((section) => section.text).join(\"\");\n\t}\n};\n//#endregion\n//#region src/expression/types/padding.ts\n/**\n* A set of four numbers representing padding around a box. Create instances from\n* bare arrays or numeric values using the static method `Padding.parse`.\n* @private\n*/\nvar Padding = class Padding {\n\tconstructor(values) {\n\t\tthis.values = values.slice();\n\t}\n\t/**\n\t* Numeric padding values\n\t* @param input A padding value\n\t* @returns A `Padding` instance, or `undefined` if the input is not a valid padding value.\n\t*/\n\tstatic parse(input) {\n\t\tif (input instanceof Padding) return input;\n\t\tif (typeof input === \"number\") return new Padding([\n\t\t\tinput,\n\t\t\tinput,\n\t\t\tinput,\n\t\t\tinput\n\t\t]);\n\t\tif (!Array.isArray(input)) return;\n\t\tif (input.length < 1 || input.length > 4) return;\n\t\tfor (const val of input) if (typeof val !== \"number\") return;\n\t\tswitch (input.length) {\n\t\t\tcase 1:\n\t\t\t\tinput = [\n\t\t\t\t\tinput[0],\n\t\t\t\t\tinput[0],\n\t\t\t\t\tinput[0],\n\t\t\t\t\tinput[0]\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tinput = [\n\t\t\t\t\tinput[0],\n\t\t\t\t\tinput[1],\n\t\t\t\t\tinput[0],\n\t\t\t\t\tinput[1]\n\t\t\t\t];\n\t\t\t\tbreak;\n\t\t\tcase 3: input = [\n\t\t\t\tinput[0],\n\t\t\t\tinput[1],\n\t\t\t\tinput[2],\n\t\t\t\tinput[1]\n\t\t\t];\n\t\t}\n\t\treturn new Padding(input);\n\t}\n\ttoString() {\n\t\treturn JSON.stringify(this.values);\n\t}\n\tstatic interpolate(from, to, t) {\n\t\treturn new Padding(interpolateArray(from.values, to.values, t));\n\t}\n};\n//#endregion\n//#region src/expression/types/number_array.ts\n/**\n* An array of numbers. Create instances from\n* bare arrays or numeric values using the static method `NumberArray.parse`.\n* @private\n*/\nvar NumberArray = class NumberArray {\n\tconstructor(values) {\n\t\tthis.values = values.slice();\n\t}\n\t/**\n\t* Numeric NumberArray values\n\t* @param input A NumberArray value\n\t* @returns A `NumberArray` instance, or `undefined` if the input is not a valid NumberArray value.\n\t*/\n\tstatic parse(input) {\n\t\tif (input instanceof NumberArray) return input;\n\t\tif (typeof input === \"number\") return new NumberArray([input]);\n\t\tif (!Array.isArray(input)) return;\n\t\tfor (const val of input) if (typeof val !== \"number\") return;\n\t\treturn new NumberArray(input);\n\t}\n\ttoString() {\n\t\treturn JSON.stringify(this.values);\n\t}\n\tstatic interpolate(from, to, t) {\n\t\treturn new NumberArray(interpolateArray(from.values, to.values, t));\n\t}\n};\n//#endregion\n//#region src/expression/types/color_array.ts\n/**\n* An array of colors. Create instances from\n* bare arrays or strings using the static method `ColorArray.parse`.\n* @private\n*/\nvar ColorArray = class ColorArray {\n\tconstructor(values) {\n\t\tthis.values = values.slice();\n\t}\n\t/**\n\t* ColorArray values\n\t* @param input A ColorArray value\n\t* @returns A `ColorArray` instance, or `undefined` if the input is not a valid ColorArray value.\n\t*/\n\tstatic parse(input) {\n\t\tif (input instanceof ColorArray) return input;\n\t\tif (typeof input === \"string\") {\n\t\t\tconst parsed_val = Color.parse(input);\n\t\t\tif (!parsed_val) return;\n\t\t\treturn new ColorArray([parsed_val]);\n\t\t}\n\t\tif (!Array.isArray(input)) return;\n\t\tconst colors = [];\n\t\tfor (const val of input) {\n\t\t\tif (typeof val !== \"string\") return;\n\t\t\tconst parsed_val = Color.parse(val);\n\t\t\tif (!parsed_val) return;\n\t\t\tcolors.push(parsed_val);\n\t\t}\n\t\treturn new ColorArray(colors);\n\t}\n\ttoString() {\n\t\treturn JSON.stringify(this.values);\n\t}\n\tstatic interpolate(from, to, t, spaceKey = \"rgb\") {\n\t\tconst colors = [];\n\t\tif (from.values.length != to.values.length) throw new Error(`colorArray: Arrays have mismatched length (${from.values.length} vs. ${to.values.length}), cannot interpolate.`);\n\t\tfor (let i = 0; i < from.values.length; i++) colors.push(Color.interpolate(from.values[i], to.values[i], t, spaceKey));\n\t\treturn new ColorArray(colors);\n\t}\n};\n//#endregion\n//#region src/expression/runtime_error.ts\nvar RuntimeError = class extends Error {\n\tconstructor(message, path) {\n\t\tsuper(message);\n\t\tthis.name = \"RuntimeError\";\n\t\tthis.path = path;\n\t}\n\ttoJSON() {\n\t\treturn this.message;\n\t}\n};\n//#endregion\n//#region src/expression/types/variable_anchor_offset_collection.ts\n/** Set of valid anchor positions, as a set for validation */\nconst anchors = /* @__PURE__ */ new Set([\n\t\"center\",\n\t\"left\",\n\t\"right\",\n\t\"top\",\n\t\"bottom\",\n\t\"top-left\",\n\t\"top-right\",\n\t\"bottom-left\",\n\t\"bottom-right\"\n]);\n/**\n* Utility class to assist managing values for text-variable-anchor-offset property. Create instances from\n* bare arrays using the static method `VariableAnchorOffsetCollection.parse`.\n* @private\n*/\nvar VariableAnchorOffsetCollection = class VariableAnchorOffsetCollection {\n\tconstructor(values) {\n\t\tthis.values = values.slice();\n\t}\n\tstatic parse(input) {\n\t\tif (input instanceof VariableAnchorOffsetCollection) return input;\n\t\tif (!Array.isArray(input) || input.length < 1 || input.length % 2 !== 0) return;\n\t\tfor (let i = 0; i < input.length; i += 2) {\n\t\t\tconst anchorValue = input[i];\n\t\t\tconst offsetValue = input[i + 1];\n\t\t\tif (typeof anchorValue !== \"string\" || !anchors.has(anchorValue)) return;\n\t\t\tif (!Array.isArray(offsetValue) || offsetValue.length !== 2 || typeof offsetValue[0] !== \"number\" || typeof offsetValue[1] !== \"number\") return;\n\t\t}\n\t\treturn new VariableAnchorOffsetCollection(input);\n\t}\n\ttoString() {\n\t\treturn JSON.stringify(this.values);\n\t}\n\tstatic interpolate(from, to, t, key) {\n\t\tconst fromValues = from.values;\n\t\tconst toValues = to.values;\n\t\tif (fromValues.length !== toValues.length) throw new RuntimeError(`Cannot interpolate values of different length. from: ${from.toString()}, to: ${to.toString()}`, key);\n\t\tconst output = [];\n\t\tfor (let i = 0; i < fromValues.length; i += 2) {\n\t\t\tif (fromValues[i] !== toValues[i]) throw new RuntimeError(`Cannot interpolate values containing mismatched anchors. from[${i}]: ${fromValues[i]}, to[${i}]: ${toValues[i]}`, key);\n\t\t\toutput.push(fromValues[i]);\n\t\t\tconst [fx, fy] = fromValues[i + 1];\n\t\t\tconst [tx, ty] = toValues[i + 1];\n\t\t\toutput.push([interpolateNumber(fx, tx, t), interpolateNumber(fy, ty, t)]);\n\t\t}\n\t\treturn new VariableAnchorOffsetCollection(output);\n\t}\n};\n//#endregion\n//#region src/expression/types/resolved_image.ts\nvar ResolvedImage = class ResolvedImage {\n\tconstructor(options) {\n\t\tthis.name = options.name;\n\t\tthis.available = options.available;\n\t}\n\ttoString() {\n\t\treturn this.name;\n\t}\n\tstatic fromString(name) {\n\t\tif (!name) return null;\n\t\treturn new ResolvedImage({\n\t\t\tname,\n\t\t\tavailable: false\n\t\t});\n\t}\n};\n//#endregion\n//#region src/expression/types/projection_definition.ts\nvar ProjectionDefinition = class ProjectionDefinition {\n\tconstructor(from, to, transition) {\n\t\tthis.from = from;\n\t\tthis.to = to;\n\t\tthis.transition = transition;\n\t}\n\ttoString() {\n\t\tif (this.from === this.to && this.transition === 1) return this.from;\n\t\treturn JSON.stringify([\n\t\t\tthis.from,\n\t\t\tthis.to,\n\t\t\tthis.transition\n\t\t]);\n\t}\n\tstatic interpolate(from, to, t) {\n\t\treturn new ProjectionDefinition(from, to, t);\n\t}\n\tstatic parse(input) {\n\t\tif (input instanceof ProjectionDefinition) return input;\n\t\tif (Array.isArray(input) && input.length === 3 && typeof input[0] === \"string\" && typeof input[1] === \"string\" && typeof input[2] === \"number\") return new ProjectionDefinition(input[0], input[1], input[2]);\n\t\tif (typeof input === \"object\" && typeof input.from === \"string\" && typeof input.to === \"string\" && typeof input.transition === \"number\") return new ProjectionDefinition(input.from, input.to, input.transition);\n\t\tif (typeof input === \"string\") return new ProjectionDefinition(input, input, 1);\n\t}\n};\n//#endregion\n//#region src/expression/values.ts\nfunction validateRGBA(r, g, b, a) {\n\tif (!(typeof r === \"number\" && r >= 0 && r <= 255 && typeof g === \"number\" && g >= 0 && g <= 255 && typeof b === \"number\" && b >= 0 && b <= 255)) return `Invalid rgba value [${(typeof a === \"number\" ? [\n\t\tr,\n\t\tg,\n\t\tb,\n\t\ta\n\t] : [\n\t\tr,\n\t\tg,\n\t\tb\n\t]).join(\", \")}]: 'r', 'g', and 'b' must be between 0 and 255.`;\n\tif (!(typeof a === \"undefined\" || typeof a === \"number\" && a >= 0 && a <= 1)) return `Invalid rgba value [${[\n\t\tr,\n\t\tg,\n\t\tb,\n\t\ta\n\t].join(\", \")}]: 'a' must be between 0 and 1.`;\n\treturn null;\n}\nfunction isValue(mixed) {\n\tif (mixed === null || typeof mixed === \"string\" || typeof mixed === \"boolean\" || typeof mixed === \"number\" || mixed instanceof ProjectionDefinition || mixed instanceof Color || mixed instanceof Collator || mixed instanceof Formatted || mixed instanceof Padding || mixed instanceof NumberArray || mixed instanceof ColorArray || mixed instanceof VariableAnchorOffsetCollection || mixed instanceof ResolvedImage) return true;\n\telse if (Array.isArray(mixed)) {\n\t\tfor (const item of mixed) if (!isValue(item)) return false;\n\t\treturn true;\n\t} else if (typeof mixed === \"object\") {\n\t\tfor (const key in mixed) if (!isValue(mixed[key])) return false;\n\t\treturn true;\n\t} else return false;\n}\nfunction typeOf(value) {\n\tif (value === null) return NullType;\n\telse if (typeof value === \"string\") return StringType;\n\telse if (typeof value === \"boolean\") return BooleanType;\n\telse if (typeof value === \"number\") return NumberType;\n\telse if (value instanceof Color) return ColorType;\n\telse if (value instanceof ProjectionDefinition) return ProjectionDefinitionType;\n\telse if (value instanceof Collator) return CollatorType;\n\telse if (value instanceof Formatted) return FormattedType;\n\telse if (value instanceof Padding) return PaddingType;\n\telse if (value instanceof NumberArray) return NumberArrayType;\n\telse if (value instanceof ColorArray) return ColorArrayType;\n\telse if (value instanceof VariableAnchorOffsetCollection) return VariableAnchorOffsetCollectionType;\n\telse if (value instanceof ResolvedImage) return ResolvedImageType;\n\telse if (Array.isArray(value)) {\n\t\tconst length = value.length;\n\t\tlet itemType;\n\t\tfor (const item of value) {\n\t\t\tconst t = typeOf(item);\n\t\t\tif (!itemType) itemType = t;\n\t\t\telse if (itemType === t) continue;\n\t\t\telse {\n\t\t\t\titemType = ValueType;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn array(itemType || ValueType, length);\n\t} else return ObjectType;\n}\nfunction valueToString(value) {\n\tconst type = typeof value;\n\tif (value === null) return \"\";\n\telse if (type === \"string\" || type === \"number\" || type === \"boolean\") return String(value);\n\telse if (value instanceof Color || value instanceof ProjectionDefinition || value instanceof Formatted || value instanceof Padding || value instanceof NumberArray || value instanceof ColorArray || value instanceof VariableAnchorOffsetCollection || value instanceof ResolvedImage) return value.toString();\n\telse return JSON.stringify(value);\n}\n//#endregion\n//#region src/expression/definitions/literal.ts\nvar Literal = class Literal {\n\tconstructor(type, value) {\n\t\tthis.type = type;\n\t\tthis.value = value;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(`'literal' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n\t\tif (!isValue(args[1])) return context.error(`invalid value of type \"${typeof args[1]}\"`);\n\t\tconst value = args[1];\n\t\tlet type = typeOf(value);\n\t\tconst expected = context.expectedType;\n\t\tif (type.kind === \"array\" && type.N === 0 && expected && expected.kind === \"array\" && (typeof expected.N !== \"number\" || expected.N === 0)) type = expected;\n\t\treturn new Literal(type, value);\n\t}\n\tevaluate() {\n\t\treturn this.value;\n\t}\n\teachChild() {}\n\toutputDefined() {\n\t\treturn true;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/assertion.ts\nconst types$1 = {\n\tstring: StringType,\n\tnumber: NumberType,\n\tboolean: BooleanType,\n\tobject: ObjectType\n};\nvar Assertion = class Assertion {\n\tconstructor(type, args, key) {\n\t\tthis.type = type;\n\t\tthis.args = args;\n\t\tthis.key = key;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length < 2) return context.error(\"Expected at least one argument.\");\n\t\tlet i = 1;\n\t\tlet type;\n\t\tconst name = args[0];\n\t\tif (name === \"array\") {\n\t\t\tlet itemType;\n\t\t\tif (args.length > 2) {\n\t\t\t\tconst type = args[1];\n\t\t\t\tif (typeof type !== \"string\" || !(type in types$1) || type === \"object\") return context.error(\"The item type argument of \\\"array\\\" must be one of string, number, boolean\", 1);\n\t\t\t\titemType = types$1[type];\n\t\t\t\ti++;\n\t\t\t} else itemType = ValueType;\n\t\t\tlet N;\n\t\t\tif (args.length > 3) {\n\t\t\t\tif (args[2] !== null && (typeof args[2] !== \"number\" || args[2] < 0 || args[2] !== Math.floor(args[2]))) return context.error(\"The length argument to \\\"array\\\" must be a positive integer literal\", 2);\n\t\t\t\tN = args[2];\n\t\t\t\ti++;\n\t\t\t}\n\t\t\ttype = array(itemType, N);\n\t\t} else {\n\t\t\tif (!types$1[name]) throw new Error(`Types doesn't contain name = ${name}`);\n\t\t\ttype = types$1[name];\n\t\t}\n\t\tconst parsed = [];\n\t\tfor (; i < args.length; i++) {\n\t\t\tconst input = context.parse(args[i], i, ValueType);\n\t\t\tif (!input) return null;\n\t\t\tparsed.push(input);\n\t\t}\n\t\treturn new Assertion(type, parsed, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tfor (let i = 0; i < this.args.length; i++) {\n\t\t\tconst value = this.args[i].evaluate(ctx);\n\t\t\tif (!checkSubtype(this.type, typeOf(value))) return value;\n\t\t\telse if (i === this.args.length - 1) throw new RuntimeError(`Expected value to be of type ${typeToString(this.type)}, but found ${typeToString(typeOf(value))} instead.`, this.key);\n\t\t}\n\t\tthrow new Error();\n\t}\n\teachChild(fn) {\n\t\tthis.args.forEach(fn);\n\t}\n\toutputDefined() {\n\t\treturn this.args.every((arg) => arg.outputDefined());\n\t}\n};\n//#endregion\n//#region src/expression/definitions/coercion.ts\nconst types = {\n\t\"to-boolean\": BooleanType,\n\t\"to-color\": ColorType,\n\t\"to-number\": NumberType,\n\t\"to-string\": StringType\n};\n/**\n* Special form for error-coalescing coercion expressions \"to-number\",\n* \"to-color\". Since these coercions can fail at runtime, they accept multiple\n* arguments, only evaluating one at a time until one succeeds.\n*\n* @private\n*/\nvar Coercion = class Coercion {\n\tconstructor(type, args, key) {\n\t\tthis.type = type;\n\t\tthis.args = args;\n\t\tthis.key = key;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length < 2) return context.error(\"Expected at least one argument.\");\n\t\tconst name = args[0];\n\t\tif (!types[name]) throw new Error(`Can't parse ${name} as it is not part of the known types`);\n\t\tif ((name === \"to-boolean\" || name === \"to-string\") && args.length !== 2) return context.error(\"Expected one argument.\");\n\t\tconst type = types[name];\n\t\tconst parsed = [];\n\t\tfor (let i = 1; i < args.length; i++) {\n\t\t\tconst input = context.parse(args[i], i, ValueType);\n\t\t\tif (!input) return null;\n\t\t\tparsed.push(input);\n\t\t}\n\t\treturn new Coercion(type, parsed, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tswitch (this.type.kind) {\n\t\t\tcase \"boolean\": return Boolean(this.args[0].evaluate(ctx));\n\t\t\tcase \"color\": {\n\t\t\t\tlet input;\n\t\t\t\tlet error;\n\t\t\t\tfor (const arg of this.args) {\n\t\t\t\t\tinput = arg.evaluate(ctx);\n\t\t\t\t\terror = null;\n\t\t\t\t\tif (input instanceof Color) return input;\n\t\t\t\t\telse if (typeof input === \"string\") {\n\t\t\t\t\t\tconst c = ctx.parseColor(input);\n\t\t\t\t\t\tif (c) return c;\n\t\t\t\t\t} else if (Array.isArray(input)) {\n\t\t\t\t\t\tif (input.length < 3 || input.length > 4) error = `Invalid rgba value ${JSON.stringify(input)}: expected an array containing either three or four numeric values.`;\n\t\t\t\t\t\telse error = validateRGBA(input[0], input[1], input[2], input[3]);\n\t\t\t\t\t\tif (!error) return new Color(input[0] / 255, input[1] / 255, input[2] / 255, input[3]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new RuntimeError(error || `Could not parse color from value '${typeof input === \"string\" ? input : JSON.stringify(input)}'`, this.key);\n\t\t\t}\n\t\t\tcase \"padding\": {\n\t\t\t\tlet input;\n\t\t\t\tfor (const arg of this.args) {\n\t\t\t\t\tinput = arg.evaluate(ctx);\n\t\t\t\t\tconst pad = Padding.parse(input);\n\t\t\t\t\tif (pad) return pad;\n\t\t\t\t}\n\t\t\t\tthrow new RuntimeError(`Could not parse padding from value '${typeof input === \"string\" ? input : JSON.stringify(input)}'`, this.key);\n\t\t\t}\n\t\t\tcase \"numberArray\": {\n\t\t\t\tlet input;\n\t\t\t\tfor (const arg of this.args) {\n\t\t\t\t\tinput = arg.evaluate(ctx);\n\t\t\t\t\tconst val = NumberArray.parse(input);\n\t\t\t\t\tif (val) return val;\n\t\t\t\t}\n\t\t\t\tthrow new RuntimeError(`Could not parse numberArray from value '${typeof input === \"string\" ? input : JSON.stringify(input)}'`, this.key);\n\t\t\t}\n\t\t\tcase \"colorArray\": {\n\t\t\t\tlet input;\n\t\t\t\tfor (const arg of this.args) {\n\t\t\t\t\tinput = arg.evaluate(ctx);\n\t\t\t\t\tconst val = ColorArray.parse(input);\n\t\t\t\t\tif (val) return val;\n\t\t\t\t}\n\t\t\t\tthrow new RuntimeError(`Could not parse colorArray from value '${typeof input === \"string\" ? input : JSON.stringify(input)}'`, this.key);\n\t\t\t}\n\t\t\tcase \"variableAnchorOffsetCollection\": {\n\t\t\t\tlet input;\n\t\t\t\tfor (const arg of this.args) {\n\t\t\t\t\tinput = arg.evaluate(ctx);\n\t\t\t\t\tconst coll = VariableAnchorOffsetCollection.parse(input);\n\t\t\t\t\tif (coll) return coll;\n\t\t\t\t}\n\t\t\t\tthrow new RuntimeError(`Could not parse variableAnchorOffsetCollection from value '${typeof input === \"string\" ? input : JSON.stringify(input)}'`, this.key);\n\t\t\t}\n\t\t\tcase \"number\": {\n\t\t\t\tlet value = null;\n\t\t\t\tfor (const arg of this.args) {\n\t\t\t\t\tvalue = arg.evaluate(ctx);\n\t\t\t\t\tif (value === null) return 0;\n\t\t\t\t\tconst num = Number(value);\n\t\t\t\t\tif (isNaN(num)) continue;\n\t\t\t\t\treturn num;\n\t\t\t\t}\n\t\t\t\tthrow new RuntimeError(`Could not convert ${JSON.stringify(value)} to number.`, this.key);\n\t\t\t}\n\t\t\tcase \"formatted\": return Formatted.fromString(valueToString(this.args[0].evaluate(ctx)));\n\t\t\tcase \"resolvedImage\": return ResolvedImage.fromString(valueToString(this.args[0].evaluate(ctx)));\n\t\t\tcase \"projectionDefinition\": {\n\t\t\t\tconst input = this.args[0].evaluate(ctx);\n\t\t\t\tif (ProjectionDefinition.parse(input)) return input;\n\t\t\t\tthrow new RuntimeError(`Could not parse projectionDefinition from value '${typeof input === \"string\" ? input : JSON.stringify(input)}'`, this.key);\n\t\t\t}\n\t\t\tdefault: return valueToString(this.args[0].evaluate(ctx));\n\t\t}\n\t}\n\teachChild(fn) {\n\t\tthis.args.forEach(fn);\n\t}\n\toutputDefined() {\n\t\treturn this.args.every((arg) => arg.outputDefined());\n\t}\n};\n//#endregion\n//#region src/expression/evaluation_context.ts\nconst geometryTypes = [\n\t\"Unknown\",\n\t\"Point\",\n\t\"LineString\",\n\t\"Polygon\"\n];\nvar EvaluationContext = class {\n\tconstructor() {\n\t\tthis.globals = null;\n\t\tthis.feature = null;\n\t\tthis.featureState = null;\n\t\tthis.formattedSection = null;\n\t\tthis._parseColorCache = /* @__PURE__ */ new Map();\n\t\tthis.availableImages = null;\n\t\tthis.canonical = null;\n\t}\n\tid() {\n\t\treturn this.feature && \"id\" in this.feature ? this.feature.id : null;\n\t}\n\tgeometryType() {\n\t\treturn this.feature ? typeof this.feature.type === \"number\" ? geometryTypes[this.feature.type] : this.feature.type : null;\n\t}\n\tgeometry() {\n\t\treturn this.feature && \"geometry\" in this.feature ? this.feature.geometry : null;\n\t}\n\tcanonicalID() {\n\t\treturn this.canonical;\n\t}\n\tproperties() {\n\t\treturn this.feature && this.feature.properties || {};\n\t}\n\tparseColor(input) {\n\t\tlet cached = this._parseColorCache.get(input);\n\t\tif (!cached) {\n\t\t\tcached = Color.parse(input);\n\t\t\tthis._parseColorCache.set(input, cached);\n\t\t}\n\t\treturn cached;\n\t}\n};\n//#endregion\n//#region src/expression/parsing_context.ts\n/**\n* State associated parsing at a given point in an expression tree.\n* @private\n*/\nvar ParsingContext = class ParsingContext {\n\tconstructor(registry, isConstantFunc, path = [], expectedType, scope = new Scope(), errors = []) {\n\t\tthis.registry = registry;\n\t\tthis.path = path;\n\t\tthis.key = path.map((part) => `[${part}]`).join(\"\");\n\t\tthis.scope = scope;\n\t\tthis.errors = errors;\n\t\tthis.expectedType = expectedType;\n\t\tthis._isConstant = isConstantFunc;\n\t}\n\t/**\n\t* @param expr the JSON expression to parse\n\t* @param index the optional argument index if this expression is an argument of a parent expression that's being parsed\n\t* @param options\n\t* @param options.omitTypeAnnotations set true to omit inferred type annotations. Caller beware: with this option set, the parsed expression's type will NOT satisfy `expectedType` if it would normally be wrapped in an inferred annotation.\n\t* @private\n\t*/\n\tparse(expr, index, expectedType, bindings, options = {}) {\n\t\tif (index) return this.concat(index, expectedType, bindings)._parse(expr, options);\n\t\treturn this._parse(expr, options);\n\t}\n\t_parse(expr, options) {\n\t\tif (expr === null || typeof expr === \"string\" || typeof expr === \"boolean\" || typeof expr === \"number\") expr = [\"literal\", expr];\n\t\tconst key = this.key;\n\t\tfunction annotate(parsed, type, typeAnnotation) {\n\t\t\tif (typeAnnotation === \"assert\") return new Assertion(type, [parsed], key);\n\t\t\telse if (typeAnnotation === \"coerce\") return new Coercion(type, [parsed], key);\n\t\t\telse return parsed;\n\t\t}\n\t\tif (Array.isArray(expr)) {\n\t\t\tif (expr.length === 0) return this.error(\"Expected an array with at least one element. If you wanted a literal array, use [\\\"literal\\\", []].\");\n\t\t\tconst op = expr[0];\n\t\t\tif (typeof op !== \"string\") {\n\t\t\t\tthis.error(`Expression name must be a string, but found ${typeof op} instead. If you wanted a literal array, use [\"literal\", [...]].`, 0);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst Expr = this.registry[op];\n\t\t\tif (Expr) {\n\t\t\t\tlet parsed = Expr.parse(expr, this);\n\t\t\t\tif (!parsed) return null;\n\t\t\t\tif (this.expectedType) {\n\t\t\t\t\tconst expected = this.expectedType;\n\t\t\t\t\tconst actual = parsed.type;\n\t\t\t\t\tif ((expected.kind === \"string\" || expected.kind === \"number\" || expected.kind === \"boolean\" || expected.kind === \"object\" || expected.kind === \"array\") && actual.kind === \"value\") parsed = annotate(parsed, expected, options.typeAnnotation || \"assert\");\n\t\t\t\t\telse if (\"projectionDefinition\" === expected.kind && [\n\t\t\t\t\t\t\"string\",\n\t\t\t\t\t\t\"array\",\n\t\t\t\t\t\t\"value\"\n\t\t\t\t\t].includes(actual.kind) || [\n\t\t\t\t\t\t\"color\",\n\t\t\t\t\t\t\"formatted\",\n\t\t\t\t\t\t\"resolvedImage\"\n\t\t\t\t\t].includes(expected.kind) && [\"value\", \"string\"].includes(actual.kind) || [\"padding\", \"numberArray\"].includes(expected.kind) && [\n\t\t\t\t\t\t\"value\",\n\t\t\t\t\t\t\"number\",\n\t\t\t\t\t\t\"array\"\n\t\t\t\t\t].includes(actual.kind) || \"colorArray\" === expected.kind && [\n\t\t\t\t\t\t\"value\",\n\t\t\t\t\t\t\"string\",\n\t\t\t\t\t\t\"array\"\n\t\t\t\t\t].includes(actual.kind) || \"variableAnchorOffsetCollection\" === expected.kind && [\"value\", \"array\"].includes(actual.kind)) parsed = annotate(parsed, expected, options.typeAnnotation || \"coerce\");\n\t\t\t\t\telse if (this.checkSubtype(expected, actual)) return null;\n\t\t\t\t}\n\t\t\t\tif (!(parsed instanceof Literal) && parsed.type.kind !== \"resolvedImage\" && this._isConstant(parsed)) {\n\t\t\t\t\tconst ec = new EvaluationContext();\n\t\t\t\t\ttry {\n\t\t\t\t\t\tparsed = new Literal(parsed.type, parsed.evaluate(ec));\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthis.error(e.message);\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn parsed;\n\t\t\t}\n\t\t\treturn this.error(`Unknown expression \"${op}\". If you wanted a literal array, use [\"literal\", [...]].`, 0);\n\t\t} else if (typeof expr === \"undefined\") return this.error(\"'undefined' value invalid. Use null instead.\");\n\t\telse if (typeof expr === \"object\") return this.error(\"Bare objects invalid. Use [\\\"literal\\\", {...}] instead.\");\n\t\telse return this.error(`Expected an array, but found ${typeof expr} instead.`);\n\t}\n\t/**\n\t* Returns a copy of this context suitable for parsing the subexpression at\n\t* index `index`, optionally appending to 'let' binding map.\n\t*\n\t* Note that `errors` property, intended for collecting errors while\n\t* parsing, is copied by reference rather than cloned.\n\t* @private\n\t*/\n\tconcat(index, expectedType, bindings) {\n\t\tconst path = typeof index === \"number\" ? this.path.concat(index) : this.path;\n\t\tconst scope = bindings ? this.scope.concat(bindings) : this.scope;\n\t\treturn new ParsingContext(this.registry, this._isConstant, path, expectedType || null, scope, this.errors);\n\t}\n\t/**\n\t* Push a parsing (or type checking) error into the `this.errors`\n\t* @param error The message\n\t* @param keys Optionally specify the source of the error at a child\n\t* of the current expression at `this.key`.\n\t* @private\n\t*/\n\terror(error, ...keys) {\n\t\tconst key = `${this.key}${keys.map((k) => `[${k}]`).join(\"\")}`;\n\t\tthis.errors.push(new ExpressionParsingError(key, error));\n\t}\n\t/**\n\t* Returns null if `t` is a subtype of `expected`; otherwise returns an\n\t* error message and also pushes it to `this.errors`.\n\t* @param expected The expected type\n\t* @param t The actual type\n\t* @returns null if `t` is a subtype of `expected`; otherwise returns an error message\n\t*/\n\tcheckSubtype(expected, t) {\n\t\tconst error = checkSubtype(expected, t);\n\t\tif (error) this.error(error);\n\t\treturn error;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/let.ts\nvar Let = class Let {\n\tconstructor(bindings, result) {\n\t\tthis.type = result.type;\n\t\tthis.bindings = [].concat(bindings);\n\t\tthis.result = result;\n\t}\n\tevaluate(ctx) {\n\t\treturn this.result.evaluate(ctx);\n\t}\n\teachChild(fn) {\n\t\tfor (const binding of this.bindings) fn(binding[1]);\n\t\tfn(this.result);\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length < 4) return context.error(`Expected at least 3 arguments, but found ${args.length - 1} instead.`);\n\t\tconst bindings = [];\n\t\tfor (let i = 1; i < args.length - 1; i += 2) {\n\t\t\tconst name = args[i];\n\t\t\tif (typeof name !== \"string\") return context.error(`Expected string, but found ${typeof name} instead.`, i);\n\t\t\tif (/[^a-zA-Z0-9_]/.test(name)) return context.error(\"Variable names must contain only alphanumeric characters or '_'.\", i);\n\t\t\tconst value = context.parse(args[i + 1], i + 1);\n\t\t\tif (!value) return null;\n\t\t\tbindings.push([name, value]);\n\t\t}\n\t\tconst result = context.parse(args[args.length - 1], args.length - 1, context.expectedType, bindings);\n\t\tif (!result) return null;\n\t\treturn new Let(bindings, result);\n\t}\n\toutputDefined() {\n\t\treturn this.result.outputDefined();\n\t}\n};\n//#endregion\n//#region src/expression/definitions/var.ts\nvar Var = class Var {\n\tconstructor(name, boundExpression) {\n\t\tthis.type = boundExpression.type;\n\t\tthis.name = name;\n\t\tthis.boundExpression = boundExpression;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2 || typeof args[1] !== \"string\") return context.error(\"'var' expression requires exactly one string literal argument.\");\n\t\tconst name = args[1];\n\t\tif (!context.scope.has(name)) return context.error(`Unknown variable \"${name}\". Make sure \"${name}\" has been bound in an enclosing \"let\" expression before using it.`, 1);\n\t\treturn new Var(name, context.scope.get(name));\n\t}\n\tevaluate(ctx) {\n\t\treturn this.boundExpression.evaluate(ctx);\n\t}\n\teachChild() {}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/at.ts\nvar At = class At {\n\tconstructor(type, index, input, key) {\n\t\tthis.type = type;\n\t\tthis.index = index;\n\t\tthis.input = input;\n\t\tthis.key = key;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 3) return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);\n\t\tconst index = context.parse(args[1], 1, NumberType);\n\t\tconst input = context.parse(args[2], 2, array(context.expectedType || ValueType));\n\t\tif (!index || !input) return null;\n\t\tconst t = input.type;\n\t\treturn new At(t.itemType, index, input, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tconst index = this.index.evaluate(ctx);\n\t\tconst array = this.input.evaluate(ctx);\n\t\tif (index < 0) throw new RuntimeError(`Array index out of bounds: ${index} < 0.`, this.key);\n\t\tif (index >= array.length) throw new RuntimeError(`Array index out of bounds: ${index} > ${array.length - 1}.`, this.key);\n\t\tif (index !== Math.floor(index)) throw new RuntimeError(`Array index must be an integer, but found ${index} instead.`, this.key);\n\t\treturn array[index];\n\t}\n\teachChild(fn) {\n\t\tfn(this.index);\n\t\tfn(this.input);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/in.ts\nvar In = class In {\n\tconstructor(needle, haystack, key) {\n\t\tthis.needle = needle;\n\t\tthis.haystack = haystack;\n\t\tthis.key = key;\n\t\tthis.type = BooleanType;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 3) return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);\n\t\tconst needle = context.parse(args[1], 1, ValueType);\n\t\tconst haystack = context.parse(args[2], 2, ValueType);\n\t\tif (!needle || !haystack) return null;\n\t\tif (!isValidType(needle.type, [\n\t\t\tBooleanType,\n\t\t\tStringType,\n\t\t\tNumberType,\n\t\t\tNullType,\n\t\t\tValueType\n\t\t])) return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${typeToString(needle.type)} instead`);\n\t\treturn new In(needle, haystack, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tconst needle = this.needle.evaluate(ctx);\n\t\tconst haystack = this.haystack.evaluate(ctx);\n\t\tif (!haystack) return false;\n\t\tif (!isValidNativeType(needle, [\n\t\t\t\"boolean\",\n\t\t\t\"string\",\n\t\t\t\"number\",\n\t\t\t\"null\"\n\t\t])) throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${typeToString(typeOf(needle))} instead.`, this.key);\n\t\tif (!isValidNativeType(haystack, [\"string\", \"array\"])) throw new RuntimeError(`Expected second argument to be of type array or string, but found ${typeToString(typeOf(haystack))} instead.`, this.key);\n\t\treturn haystack.indexOf(needle) >= 0;\n\t}\n\teachChild(fn) {\n\t\tfn(this.needle);\n\t\tfn(this.haystack);\n\t}\n\toutputDefined() {\n\t\treturn true;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/index_of.ts\nvar IndexOf = class IndexOf {\n\tconstructor(needle, haystack, key, fromIndex) {\n\t\tthis.needle = needle;\n\t\tthis.haystack = haystack;\n\t\tthis.key = key;\n\t\tthis.fromIndex = fromIndex;\n\t\tthis.type = NumberType;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length <= 2 || args.length >= 5) return context.error(`Expected 2 or 3 arguments, but found ${args.length - 1} instead.`);\n\t\tconst needle = context.parse(args[1], 1, ValueType);\n\t\tconst haystack = context.parse(args[2], 2, ValueType);\n\t\tif (!needle || !haystack) return null;\n\t\tif (!isValidType(needle.type, [\n\t\t\tBooleanType,\n\t\t\tStringType,\n\t\t\tNumberType,\n\t\t\tNullType,\n\t\t\tValueType\n\t\t])) return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${typeToString(needle.type)} instead`);\n\t\tif (args.length === 4) {\n\t\t\tconst fromIndex = context.parse(args[3], 3, NumberType);\n\t\t\tif (!fromIndex) return null;\n\t\t\treturn new IndexOf(needle, haystack, context.key, fromIndex);\n\t\t} else return new IndexOf(needle, haystack, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tconst needle = this.needle.evaluate(ctx);\n\t\tconst haystack = this.haystack.evaluate(ctx);\n\t\tif (!isValidNativeType(needle, [\n\t\t\t\"boolean\",\n\t\t\t\"string\",\n\t\t\t\"number\",\n\t\t\t\"null\"\n\t\t])) throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${typeToString(typeOf(needle))} instead.`, this.key);\n\t\tlet fromIndex;\n\t\tif (this.fromIndex) fromIndex = this.fromIndex.evaluate(ctx);\n\t\tif (isValidNativeType(haystack, [\"string\"])) {\n\t\t\tconst rawIndex = haystack.indexOf(needle, fromIndex);\n\t\t\tif (rawIndex === -1) return -1;\n\t\t\telse return [...haystack.slice(0, rawIndex)].length;\n\t\t} else if (isValidNativeType(haystack, [\"array\"])) return haystack.indexOf(needle, fromIndex);\n\t\telse throw new RuntimeError(`Expected second argument to be of type array or string, but found ${typeToString(typeOf(haystack))} instead.`, this.key);\n\t}\n\teachChild(fn) {\n\t\tfn(this.needle);\n\t\tfn(this.haystack);\n\t\tif (this.fromIndex) fn(this.fromIndex);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/match.ts\nvar Match = class Match {\n\tconstructor(inputType, outputType, input, cases, outputs, otherwise) {\n\t\tthis.inputType = inputType;\n\t\tthis.type = outputType;\n\t\tthis.input = input;\n\t\tthis.cases = cases;\n\t\tthis.outputs = outputs;\n\t\tthis.otherwise = otherwise;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length < 5) return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n\t\tif (args.length % 2 !== 1) return context.error(\"Expected an even number of arguments.\");\n\t\tlet inputType;\n\t\tlet outputType;\n\t\tif (context.expectedType && context.expectedType.kind !== \"value\") outputType = context.expectedType;\n\t\tconst cases = {};\n\t\tconst outputs = [];\n\t\tfor (let i = 2; i < args.length - 1; i += 2) {\n\t\t\tlet labels = args[i];\n\t\t\tconst value = args[i + 1];\n\t\t\tif (!Array.isArray(labels)) labels = [labels];\n\t\t\tconst labelContext = context.concat(i);\n\t\t\tif (labels.length === 0) return labelContext.error(\"Expected at least one branch label.\");\n\t\t\tfor (const label of labels) {\n\t\t\t\tif (typeof label !== \"number\" && typeof label !== \"string\") return labelContext.error(\"Branch labels must be numbers or strings.\");\n\t\t\t\telse if (typeof label === \"number\" && Math.abs(label) > Number.MAX_SAFE_INTEGER) return labelContext.error(`Branch labels must be integers no larger than ${Number.MAX_SAFE_INTEGER}.`);\n\t\t\t\telse if (typeof label === \"number\" && Math.floor(label) !== label) return labelContext.error(\"Numeric branch labels must be integer values.\");\n\t\t\t\telse if (!inputType) inputType = typeOf(label);\n\t\t\t\telse if (labelContext.checkSubtype(inputType, typeOf(label))) return null;\n\t\t\t\tif (typeof cases[String(label)] !== \"undefined\") return labelContext.error(\"Branch labels must be unique.\");\n\t\t\t\tcases[String(label)] = outputs.length;\n\t\t\t}\n\t\t\tconst result = context.parse(value, i, outputType);\n\t\t\tif (!result) return null;\n\t\t\toutputType = outputType || result.type;\n\t\t\toutputs.push(result);\n\t\t}\n\t\tconst input = context.parse(args[1], 1, ValueType);\n\t\tif (!input) return null;\n\t\tconst otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);\n\t\tif (!otherwise) return null;\n\t\tif (input.type.kind !== \"value\" && context.concat(1).checkSubtype(inputType, input.type)) return null;\n\t\treturn new Match(inputType, outputType, input, cases, outputs, otherwise);\n\t}\n\tevaluate(ctx) {\n\t\tconst input = this.input.evaluate(ctx);\n\t\treturn (typeOf(input) === this.inputType && this.outputs[this.cases[input]] || this.otherwise).evaluate(ctx);\n\t}\n\teachChild(fn) {\n\t\tfn(this.input);\n\t\tthis.outputs.forEach(fn);\n\t\tfn(this.otherwise);\n\t}\n\toutputDefined() {\n\t\treturn this.outputs.every((out) => out.outputDefined()) && this.otherwise.outputDefined();\n\t}\n};\n//#endregion\n//#region src/expression/definitions/case.ts\nvar Case = class Case {\n\tconstructor(type, branches, otherwise) {\n\t\tthis.type = type;\n\t\tthis.branches = branches;\n\t\tthis.otherwise = otherwise;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length < 4) return context.error(`Expected at least 3 arguments, but found only ${args.length - 1}.`);\n\t\tif (args.length % 2 !== 0) return context.error(\"Expected an odd number of arguments.\");\n\t\tlet outputType;\n\t\tif (context.expectedType && context.expectedType.kind !== \"value\") outputType = context.expectedType;\n\t\tconst branches = [];\n\t\tfor (let i = 1; i < args.length - 1; i += 2) {\n\t\t\tconst test = context.parse(args[i], i, BooleanType);\n\t\t\tif (!test) return null;\n\t\t\tconst result = context.parse(args[i + 1], i + 1, outputType);\n\t\t\tif (!result) return null;\n\t\t\tbranches.push([test, result]);\n\t\t\toutputType = outputType || result.type;\n\t\t}\n\t\tconst otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);\n\t\tif (!otherwise) return null;\n\t\tif (!outputType) throw new Error(\"Can't infer output type\");\n\t\treturn new Case(outputType, branches, otherwise);\n\t}\n\tevaluate(ctx) {\n\t\tfor (const [test, expression] of this.branches) if (test.evaluate(ctx)) return expression.evaluate(ctx);\n\t\treturn this.otherwise.evaluate(ctx);\n\t}\n\teachChild(fn) {\n\t\tfor (const [test, expression] of this.branches) {\n\t\t\tfn(test);\n\t\t\tfn(expression);\n\t\t}\n\t\tfn(this.otherwise);\n\t}\n\toutputDefined() {\n\t\treturn this.branches.every(([_, out]) => out.outputDefined()) && this.otherwise.outputDefined();\n\t}\n};\n//#endregion\n//#region src/expression/definitions/slice.ts\nvar Slice = class Slice {\n\tconstructor(type, input, beginIndex, key, endIndex) {\n\t\tthis.type = type;\n\t\tthis.input = input;\n\t\tthis.beginIndex = beginIndex;\n\t\tthis.key = key;\n\t\tthis.endIndex = endIndex;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length <= 2 || args.length >= 5) return context.error(`Expected 2 or 3 arguments, but found ${args.length - 1} instead.`);\n\t\tconst input = context.parse(args[1], 1, ValueType);\n\t\tconst beginIndex = context.parse(args[2], 2, NumberType);\n\t\tif (!input || !beginIndex) return null;\n\t\tif (!isValidType(input.type, [\n\t\t\tarray(ValueType),\n\t\t\tStringType,\n\t\t\tValueType\n\t\t])) return context.error(`Expected first argument to be of type array or string, but found ${typeToString(input.type)} instead`);\n\t\tif (args.length === 4) {\n\t\t\tconst endIndex = context.parse(args[3], 3, NumberType);\n\t\t\tif (!endIndex) return null;\n\t\t\treturn new Slice(input.type, input, beginIndex, context.key, endIndex);\n\t\t} else return new Slice(input.type, input, beginIndex, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tconst input = this.input.evaluate(ctx);\n\t\tconst beginIndex = this.beginIndex.evaluate(ctx);\n\t\tlet endIndex;\n\t\tif (this.endIndex) endIndex = this.endIndex.evaluate(ctx);\n\t\tif (isValidNativeType(input, [\"string\"])) return [...input].slice(beginIndex, endIndex).join(\"\");\n\t\telse if (isValidNativeType(input, [\"array\"])) return input.slice(beginIndex, endIndex);\n\t\telse throw new RuntimeError(`Expected first argument to be of type array or string, but found ${typeToString(typeOf(input))} instead.`, this.key);\n\t}\n\teachChild(fn) {\n\t\tfn(this.input);\n\t\tfn(this.beginIndex);\n\t\tif (this.endIndex) fn(this.endIndex);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/stops.ts\n/**\n* Returns the index of the last stop <= input, or 0 if it doesn't exist.\n* @private\n*/\nfunction findStopLessThanOrEqualTo(stops, input, key) {\n\tconst lastIndex = stops.length - 1;\n\tlet lowerIndex = 0;\n\tlet upperIndex = lastIndex;\n\tlet currentIndex = 0;\n\tlet currentValue, nextValue;\n\twhile (lowerIndex <= upperIndex) {\n\t\tcurrentIndex = Math.floor((lowerIndex + upperIndex) / 2);\n\t\tcurrentValue = stops[currentIndex];\n\t\tnextValue = stops[currentIndex + 1];\n\t\tif (currentValue <= input) {\n\t\t\tif (currentIndex === lastIndex || input < nextValue) return currentIndex;\n\t\t\tlowerIndex = currentIndex + 1;\n\t\t} else if (currentValue > input) upperIndex = currentIndex - 1;\n\t\telse throw new RuntimeError(\"Input is not a number.\", key);\n\t}\n\treturn 0;\n}\n//#endregion\n//#region src/expression/definitions/step.ts\nvar Step = class Step {\n\tconstructor(type, input, stops, key) {\n\t\tthis.type = type;\n\t\tthis.input = input;\n\t\tthis.key = key;\n\t\tthis.labels = [];\n\t\tthis.outputs = [];\n\t\tfor (const [label, expression] of stops) {\n\t\t\tthis.labels.push(label);\n\t\t\tthis.outputs.push(expression);\n\t\t}\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length - 1 < 4) return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n\t\tif ((args.length - 1) % 2 !== 0) return context.error(\"Expected an even number of arguments.\");\n\t\tconst input = context.parse(args[1], 1, NumberType);\n\t\tif (!input) return null;\n\t\tconst stops = [];\n\t\tlet outputType = null;\n\t\tif (context.expectedType && context.expectedType.kind !== \"value\") outputType = context.expectedType;\n\t\tfor (let i = 1; i < args.length; i += 2) {\n\t\t\tconst label = i === 1 ? -Infinity : args[i];\n\t\t\tconst value = args[i + 1];\n\t\t\tconst labelKey = i;\n\t\t\tconst valueKey = i + 1;\n\t\t\tif (typeof label !== \"number\") return context.error(\"Input/output pairs for \\\"step\\\" expressions must be defined using literal numeric values (not computed expressions) for the input values.\", labelKey);\n\t\t\tif (stops.length && stops[stops.length - 1][0] >= label) return context.error(\"Input/output pairs for \\\"step\\\" expressions must be arranged with input values in strictly ascending order.\", labelKey);\n\t\t\tconst parsed = context.parse(value, valueKey, outputType);\n\t\t\tif (!parsed) return null;\n\t\t\toutputType = outputType || parsed.type;\n\t\t\tstops.push([label, parsed]);\n\t\t}\n\t\treturn new Step(outputType, input, stops, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tconst labels = this.labels;\n\t\tconst outputs = this.outputs;\n\t\tif (labels.length === 1) return outputs[0].evaluate(ctx);\n\t\tconst value = this.input.evaluate(ctx);\n\t\tif (value <= labels[0]) return outputs[0].evaluate(ctx);\n\t\tconst stopCount = labels.length;\n\t\tif (value >= labels[stopCount - 1]) return outputs[stopCount - 1].evaluate(ctx);\n\t\treturn outputs[findStopLessThanOrEqualTo(labels, value, this.key)].evaluate(ctx);\n\t}\n\teachChild(fn) {\n\t\tfn(this.input);\n\t\tfor (const expression of this.outputs) fn(expression);\n\t}\n\toutputDefined() {\n\t\treturn this.outputs.every((out) => out.outputDefined());\n\t}\n};\n//#endregion\n//#region node_modules/@mapbox/unitbezier/index.js\nfunction unitBezier(p1x, p1y, p2x, p2y) {\n\tconst cx = 3 * p1x;\n\tconst bx = 3 * (p2x - p1x) - cx;\n\tconst ax = 1 - cx - bx;\n\tconst cy = 3 * p1y;\n\tconst by = 3 * (p2y - p1y) - cy;\n\tconst ay = 1 - cy - by;\n\treturn function solve(x, epsilon = 1e-6) {\n\t\tif (x <= 0) return 0;\n\t\tif (x >= 1) return 1;\n\t\tlet t = x;\n\t\tfor (let i = 0; i < 8; i++) {\n\t\t\tconst x2 = ((ax * t + bx) * t + cx) * t - x;\n\t\t\tif (Math.abs(x2) < epsilon) return ((ay * t + by) * t + cy) * t;\n\t\t\tconst d2 = (3 * ax * t + 2 * bx) * t + cx;\n\t\t\tif (Math.abs(d2) < 1e-6) break;\n\t\t\tt -= x2 / d2;\n\t\t}\n\t\tlet t0 = 0;\n\t\tlet t1 = 1;\n\t\tt = x;\n\t\tfor (let i = 0; i < 20; i++) {\n\t\t\tconst x2 = ((ax * t + bx) * t + cx) * t;\n\t\t\tif (Math.abs(x2 - x) < epsilon) break;\n\t\t\tif (x > x2) t0 = t;\n\t\t\telse t1 = t;\n\t\t\tt = (t0 + t1) * .5;\n\t\t}\n\t\treturn ((ay * t + by) * t + cy) * t;\n\t};\n}\n//#endregion\n//#region src/expression/definitions/interpolate.ts\nvar Interpolate = class Interpolate {\n\tconstructor(type, operator, interpolation, input, stops, key) {\n\t\tthis.type = type;\n\t\tthis.operator = operator;\n\t\tthis.interpolation = interpolation;\n\t\tthis.input = input;\n\t\tthis.key = key;\n\t\tthis.labels = [];\n\t\tthis.outputs = [];\n\t\tfor (const [label, expression] of stops) {\n\t\t\tthis.labels.push(label);\n\t\t\tthis.outputs.push(expression);\n\t\t}\n\t}\n\tstatic interpolationFactor(interpolation, input, lower, upper) {\n\t\tlet t = 0;\n\t\tif (interpolation.name === \"exponential\") t = exponentialInterpolation(input, interpolation.base, lower, upper);\n\t\telse if (interpolation.name === \"linear\") t = exponentialInterpolation(input, 1, lower, upper);\n\t\telse if (interpolation.name === \"cubic-bezier\") {\n\t\t\tconst c = interpolation.controlPoints;\n\t\t\tt = unitBezier(c[0], c[1], c[2], c[3])(exponentialInterpolation(input, 1, lower, upper));\n\t\t}\n\t\treturn t;\n\t}\n\tstatic parse(args, context) {\n\t\tlet [operator, interpolation, input, ...rest] = args;\n\t\tif (!Array.isArray(interpolation) || interpolation.length === 0) return context.error(\"Expected an interpolation type expression.\", 1);\n\t\tif (interpolation[0] === \"linear\") interpolation = { name: \"linear\" };\n\t\telse if (interpolation[0] === \"exponential\") {\n\t\t\tconst base = interpolation[1];\n\t\t\tif (typeof base !== \"number\") return context.error(\"Exponential interpolation requires a numeric base.\", 1, 1);\n\t\t\tinterpolation = {\n\t\t\t\tname: \"exponential\",\n\t\t\t\tbase\n\t\t\t};\n\t\t} else if (interpolation[0] === \"cubic-bezier\") {\n\t\t\tconst controlPoints = interpolation.slice(1);\n\t\t\tif (controlPoints.length !== 4 || controlPoints.some((t) => typeof t !== \"number\" || t < 0 || t > 1)) return context.error(\"Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.\", 1);\n\t\t\tinterpolation = {\n\t\t\t\tname: \"cubic-bezier\",\n\t\t\t\tcontrolPoints\n\t\t\t};\n\t\t} else return context.error(`Unknown interpolation type ${String(interpolation[0])}`, 1, 0);\n\t\tif (args.length - 1 < 4) return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n\t\tif ((args.length - 1) % 2 !== 0) return context.error(\"Expected an even number of arguments.\");\n\t\tinput = context.parse(input, 2, NumberType);\n\t\tif (!input) return null;\n\t\tconst stops = [];\n\t\tlet outputType = null;\n\t\tif ((operator === \"interpolate-hcl\" || operator === \"interpolate-lab\") && context.expectedType != ColorArrayType) outputType = ColorType;\n\t\telse if (context.expectedType && context.expectedType.kind !== \"value\") outputType = context.expectedType;\n\t\tfor (let i = 0; i < rest.length; i += 2) {\n\t\t\tconst label = rest[i];\n\t\t\tconst value = rest[i + 1];\n\t\t\tconst labelKey = i + 3;\n\t\t\tconst valueKey = i + 4;\n\t\t\tif (typeof label !== \"number\") return context.error(\"Input/output pairs for \\\"interpolate\\\" expressions must be defined using literal numeric values (not computed expressions) for the input values.\", labelKey);\n\t\t\tif (stops.length && stops[stops.length - 1][0] >= label) return context.error(\"Input/output pairs for \\\"interpolate\\\" expressions must be arranged with input values in strictly ascending order.\", labelKey);\n\t\t\tconst parsed = context.parse(value, valueKey, outputType);\n\t\t\tif (!parsed) return null;\n\t\t\toutputType = outputType || parsed.type;\n\t\t\tstops.push([label, parsed]);\n\t\t}\n\t\tif (!verifyType(outputType, NumberType) && !verifyType(outputType, ProjectionDefinitionType) && !verifyType(outputType, ColorType) && !verifyType(outputType, PaddingType) && !verifyType(outputType, NumberArrayType) && !verifyType(outputType, ColorArrayType) && !verifyType(outputType, VariableAnchorOffsetCollectionType) && !verifyType(outputType, array(NumberType))) return context.error(`Type ${typeToString(outputType)} is not interpolatable.`);\n\t\treturn new Interpolate(outputType, operator, interpolation, input, stops, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tconst labels = this.labels;\n\t\tconst outputs = this.outputs;\n\t\tif (labels.length === 1) return outputs[0].evaluate(ctx);\n\t\tconst value = this.input.evaluate(ctx);\n\t\tif (value <= labels[0]) return outputs[0].evaluate(ctx);\n\t\tconst stopCount = labels.length;\n\t\tif (value >= labels[stopCount - 1]) return outputs[stopCount - 1].evaluate(ctx);\n\t\tconst index = findStopLessThanOrEqualTo(labels, value, this.key);\n\t\tconst lower = labels[index];\n\t\tconst upper = labels[index + 1];\n\t\tconst t = Interpolate.interpolationFactor(this.interpolation, value, lower, upper);\n\t\tconst outputLower = outputs[index].evaluate(ctx);\n\t\tconst outputUpper = outputs[index + 1].evaluate(ctx);\n\t\tswitch (this.operator) {\n\t\t\tcase \"interpolate\": switch (this.type.kind) {\n\t\t\t\tcase \"number\": return interpolateNumber(outputLower, outputUpper, t);\n\t\t\t\tcase \"color\": return Color.interpolate(outputLower, outputUpper, t);\n\t\t\t\tcase \"padding\": return Padding.interpolate(outputLower, outputUpper, t);\n\t\t\t\tcase \"colorArray\": return ColorArray.interpolate(outputLower, outputUpper, t);\n\t\t\t\tcase \"numberArray\": return NumberArray.interpolate(outputLower, outputUpper, t);\n\t\t\t\tcase \"variableAnchorOffsetCollection\": return VariableAnchorOffsetCollection.interpolate(outputLower, outputUpper, t, this.key);\n\t\t\t\tcase \"array\": return interpolateArray(outputLower, outputUpper, t);\n\t\t\t\tcase \"projectionDefinition\": return ProjectionDefinition.interpolate(outputLower, outputUpper, t);\n\t\t\t}\n\t\t\tcase \"interpolate-hcl\": switch (this.type.kind) {\n\t\t\t\tcase \"color\": return Color.interpolate(outputLower, outputUpper, t, \"hcl\");\n\t\t\t\tcase \"colorArray\": return ColorArray.interpolate(outputLower, outputUpper, t, \"hcl\");\n\t\t\t}\n\t\t\tcase \"interpolate-lab\": switch (this.type.kind) {\n\t\t\t\tcase \"color\": return Color.interpolate(outputLower, outputUpper, t, \"lab\");\n\t\t\t\tcase \"colorArray\": return ColorArray.interpolate(outputLower, outputUpper, t, \"lab\");\n\t\t\t}\n\t\t}\n\t}\n\teachChild(fn) {\n\t\tfn(this.input);\n\t\tfor (const expression of this.outputs) fn(expression);\n\t}\n\toutputDefined() {\n\t\treturn this.outputs.every((out) => out.outputDefined());\n\t}\n};\n/**\n* Returns a ratio that can be used to interpolate between exponential function\n* stops.\n* How it works: Two consecutive stop values define a (scaled and shifted) exponential function `f(x) = a * base^x + b`, where `base` is the user-specified base,\n* and `a` and `b` are constants affording sufficient degrees of freedom to fit\n* the function to the given stops.\n*\n* Here's a bit of algebra that lets us compute `f(x)` directly from the stop\n* values without explicitly solving for `a` and `b`:\n*\n* First stop value: `f(x0) = y0 = a * base^x0 + b`\n* Second stop value: `f(x1) = y1 = a * base^x1 + b`\n* => `y1 - y0 = a(base^x1 - base^x0)`\n* => `a = (y1 - y0)/(base^x1 - base^x0)`\n*\n* Desired value: `f(x) = y = a * base^x + b`\n* => `f(x) = y0 + a * (base^x - base^x0)`\n*\n* From the above, we can replace the `a` in `a * (base^x - base^x0)` and do a\n* little algebra:\n* ```\n* a * (base^x - base^x0) = (y1 - y0)/(base^x1 - base^x0) * (base^x - base^x0)\n* = (y1 - y0) * (base^x - base^x0) / (base^x1 - base^x0)\n* ```\n*\n* If we let `(base^x - base^x0) / (base^x1 base^x0)`, then we have\n* `f(x) = y0 + (y1 - y0) * ratio`. In other words, `ratio` may be treated as\n* an interpolation factor between the two stops' output values.\n*\n* (Note: a slightly different form for `ratio`,\n* `(base^(x-x0) - 1) / (base^(x1-x0) - 1) `, is equivalent, but requires fewer\n* expensive `Math.pow()` operations.)\n*\n* @private\n*/\nfunction exponentialInterpolation(input, base, lowerValue, upperValue) {\n\tconst difference = upperValue - lowerValue;\n\tconst progress = input - lowerValue;\n\tif (difference === 0) return 0;\n\telse if (base === 1) return progress / difference;\n\telse return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);\n}\nconst interpolateFactory = {\n\tcolor: Color.interpolate,\n\tnumber: interpolateNumber,\n\tpadding: Padding.interpolate,\n\tnumberArray: NumberArray.interpolate,\n\tcolorArray: ColorArray.interpolate,\n\tvariableAnchorOffsetCollection: VariableAnchorOffsetCollection.interpolate,\n\tarray: interpolateArray\n};\n//#endregion\n//#region src/expression/definitions/coalesce.ts\nvar Coalesce = class Coalesce {\n\tconstructor(type, args) {\n\t\tthis.type = type;\n\t\tthis.args = args;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length < 2) return context.error(\"Expected at least one argument.\");\n\t\tlet outputType = null;\n\t\tconst expectedType = context.expectedType;\n\t\tif (expectedType && expectedType.kind !== \"value\") outputType = expectedType;\n\t\tconst parsedArgs = [];\n\t\tfor (const arg of args.slice(1)) {\n\t\t\tconst parsed = context.parse(arg, 1 + parsedArgs.length, outputType, void 0, { typeAnnotation: \"omit\" });\n\t\t\tif (!parsed) return null;\n\t\t\toutputType = outputType || parsed.type;\n\t\t\tparsedArgs.push(parsed);\n\t\t}\n\t\tif (!outputType) throw new Error(\"No output type\");\n\t\treturn expectedType && parsedArgs.some((arg) => checkSubtype(expectedType, arg.type)) ? new Coalesce(ValueType, parsedArgs) : new Coalesce(outputType, parsedArgs);\n\t}\n\tevaluate(ctx) {\n\t\tlet result = null;\n\t\tlet argCount = 0;\n\t\tlet requestedImageName;\n\t\tfor (const arg of this.args) {\n\t\t\targCount++;\n\t\t\tresult = arg.evaluate(ctx);\n\t\t\tif (result && result instanceof ResolvedImage && !result.available) {\n\t\t\t\tif (!requestedImageName) requestedImageName = result.name;\n\t\t\t\tresult = null;\n\t\t\t\tif (argCount === this.args.length) result = requestedImageName;\n\t\t\t}\n\t\t\tif (result !== null) break;\n\t\t}\n\t\treturn result;\n\t}\n\teachChild(fn) {\n\t\tthis.args.forEach(fn);\n\t}\n\toutputDefined() {\n\t\treturn this.args.every((arg) => arg.outputDefined());\n\t}\n};\n//#endregion\n//#region src/expression/definitions/comparison.ts\nfunction isComparableType(op, type) {\n\tif (op === \"==\" || op === \"!=\") return type.kind === \"boolean\" || type.kind === \"string\" || type.kind === \"number\" || type.kind === \"null\" || type.kind === \"value\";\n\telse return type.kind === \"string\" || type.kind === \"number\" || type.kind === \"value\";\n}\nfunction eq(ctx, a, b) {\n\treturn a === b;\n}\nfunction neq(ctx, a, b) {\n\treturn a !== b;\n}\nfunction lt(ctx, a, b) {\n\treturn a < b;\n}\nfunction gt(ctx, a, b) {\n\treturn a > b;\n}\nfunction lteq(ctx, a, b) {\n\treturn a <= b;\n}\nfunction gteq(ctx, a, b) {\n\treturn a >= b;\n}\nfunction eqCollate(ctx, a, b, c) {\n\treturn c.compare(a, b) === 0;\n}\nfunction neqCollate(ctx, a, b, c) {\n\treturn !eqCollate(ctx, a, b, c);\n}\nfunction ltCollate(ctx, a, b, c) {\n\treturn c.compare(a, b) < 0;\n}\nfunction gtCollate(ctx, a, b, c) {\n\treturn c.compare(a, b) > 0;\n}\nfunction lteqCollate(ctx, a, b, c) {\n\treturn c.compare(a, b) <= 0;\n}\nfunction gteqCollate(ctx, a, b, c) {\n\treturn c.compare(a, b) >= 0;\n}\n/**\n* Special form for comparison operators, implementing the signatures:\n* - (T, T, ?Collator) => boolean\n* - (T, value, ?Collator) => boolean\n* - (value, T, ?Collator) => boolean\n*\n* For inequalities, T must be either value, string, or number. For ==/!=, it\n* can also be boolean or null.\n*\n* Equality semantics are equivalent to Javascript's strict equality (===/!==)\n* -- i.e., when the arguments' types don't match, == evaluates to false, != to\n* true.\n*\n* When types don't match in an ordering comparison, a runtime error is thrown.\n*\n* @private\n*/\nfunction makeComparison(op, compareBasic, compareWithCollator) {\n\tconst isOrderComparison = op !== \"==\" && op !== \"!=\";\n\treturn class Comparison {\n\t\tconstructor(lhs, rhs, key, collator) {\n\t\t\tthis.lhs = lhs;\n\t\t\tthis.rhs = rhs;\n\t\t\tthis.key = key;\n\t\t\tthis.collator = collator;\n\t\t\tthis.type = BooleanType;\n\t\t\tthis.hasUntypedArgument = lhs.type.kind === \"value\" || rhs.type.kind === \"value\";\n\t\t}\n\t\tstatic parse(args, context) {\n\t\t\tif (args.length !== 3 && args.length !== 4) return context.error(\"Expected two or three arguments.\");\n\t\t\tconst op = args[0];\n\t\t\tlet lhs = context.parse(args[1], 1, ValueType);\n\t\t\tif (!lhs) return null;\n\t\t\tif (!isComparableType(op, lhs.type)) return context.concat(1).error(`\"${op}\" comparisons are not supported for type '${typeToString(lhs.type)}'.`);\n\t\t\tlet rhs = context.parse(args[2], 2, ValueType);\n\t\t\tif (!rhs) return null;\n\t\t\tif (!isComparableType(op, rhs.type)) return context.concat(2).error(`\"${op}\" comparisons are not supported for type '${typeToString(rhs.type)}'.`);\n\t\t\tif (lhs.type.kind !== rhs.type.kind && lhs.type.kind !== \"value\" && rhs.type.kind !== \"value\") return context.error(`Cannot compare types '${typeToString(lhs.type)}' and '${typeToString(rhs.type)}'.`);\n\t\t\tif (isOrderComparison) {\n\t\t\t\tif (lhs.type.kind === \"value\" && rhs.type.kind !== \"value\") lhs = new Assertion(rhs.type, [lhs], context.key);\n\t\t\t\telse if (lhs.type.kind !== \"value\" && rhs.type.kind === \"value\") rhs = new Assertion(lhs.type, [rhs], context.key);\n\t\t\t}\n\t\t\tlet collator = null;\n\t\t\tif (args.length === 4) {\n\t\t\t\tif (lhs.type.kind !== \"string\" && rhs.type.kind !== \"string\" && lhs.type.kind !== \"value\" && rhs.type.kind !== \"value\") return context.error(\"Cannot use collator to compare non-string types.\");\n\t\t\t\tcollator = context.parse(args[3], 3, CollatorType);\n\t\t\t\tif (!collator) return null;\n\t\t\t}\n\t\t\treturn new Comparison(lhs, rhs, context.key, collator);\n\t\t}\n\t\tevaluate(ctx) {\n\t\t\tconst lhs = this.lhs.evaluate(ctx);\n\t\t\tconst rhs = this.rhs.evaluate(ctx);\n\t\t\tif (isOrderComparison && this.hasUntypedArgument) {\n\t\t\t\tconst lt = typeOf(lhs);\n\t\t\t\tconst rt = typeOf(rhs);\n\t\t\t\tif (lt.kind !== rt.kind || !(lt.kind === \"string\" || lt.kind === \"number\")) throw new RuntimeError(`Expected arguments for \"${op}\" to be (string, string) or (number, number), but found (${lt.kind}, ${rt.kind}) instead.`, this.key);\n\t\t\t}\n\t\t\tif (this.collator && !isOrderComparison && this.hasUntypedArgument) {\n\t\t\t\tconst lt = typeOf(lhs);\n\t\t\t\tconst rt = typeOf(rhs);\n\t\t\t\tif (lt.kind !== \"string\" || rt.kind !== \"string\") return compareBasic(ctx, lhs, rhs);\n\t\t\t}\n\t\t\treturn this.collator ? compareWithCollator(ctx, lhs, rhs, this.collator.evaluate(ctx)) : compareBasic(ctx, lhs, rhs);\n\t\t}\n\t\teachChild(fn) {\n\t\t\tfn(this.lhs);\n\t\t\tfn(this.rhs);\n\t\t\tif (this.collator) fn(this.collator);\n\t\t}\n\t\toutputDefined() {\n\t\t\treturn true;\n\t\t}\n\t};\n}\nconst Equals = makeComparison(\"==\", eq, eqCollate);\nconst NotEquals = makeComparison(\"!=\", neq, neqCollate);\nconst LessThan = makeComparison(\"<\", lt, ltCollate);\nconst GreaterThan = makeComparison(\">\", gt, gtCollate);\nconst LessThanOrEqual = makeComparison(\"<=\", lteq, lteqCollate);\nconst GreaterThanOrEqual = makeComparison(\">=\", gteq, gteqCollate);\n//#endregion\n//#region src/expression/definitions/collator.ts\nvar CollatorExpression = class CollatorExpression {\n\tconstructor(caseSensitive, diacriticSensitive, locale) {\n\t\tthis.type = CollatorType;\n\t\tthis.locale = locale;\n\t\tthis.caseSensitive = caseSensitive;\n\t\tthis.diacriticSensitive = diacriticSensitive;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(\"Expected one argument.\");\n\t\tconst options = args[1];\n\t\tif (typeof options !== \"object\" || Array.isArray(options)) return context.error(\"Collator options argument must be an object.\");\n\t\tconst caseSensitive = context.parse(options[\"case-sensitive\"] === void 0 ? false : options[\"case-sensitive\"], 1, BooleanType);\n\t\tif (!caseSensitive) return null;\n\t\tconst diacriticSensitive = context.parse(options[\"diacritic-sensitive\"] === void 0 ? false : options[\"diacritic-sensitive\"], 1, BooleanType);\n\t\tif (!diacriticSensitive) return null;\n\t\tlet locale = null;\n\t\tif (options[\"locale\"]) {\n\t\t\tlocale = context.parse(options[\"locale\"], 1, StringType);\n\t\t\tif (!locale) return null;\n\t\t}\n\t\treturn new CollatorExpression(caseSensitive, diacriticSensitive, locale);\n\t}\n\tevaluate(ctx) {\n\t\treturn new Collator(this.caseSensitive.evaluate(ctx), this.diacriticSensitive.evaluate(ctx), this.locale ? this.locale.evaluate(ctx) : null);\n\t}\n\teachChild(fn) {\n\t\tfn(this.caseSensitive);\n\t\tfn(this.diacriticSensitive);\n\t\tif (this.locale) fn(this.locale);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/number_format.ts\nvar NumberFormat = class NumberFormat {\n\tconstructor(number, locale, currency, unit, minFractionDigits, maxFractionDigits) {\n\t\tthis.type = StringType;\n\t\tthis.number = number;\n\t\tthis.locale = locale;\n\t\tthis.currency = currency;\n\t\tthis.unit = unit;\n\t\tthis.minFractionDigits = minFractionDigits;\n\t\tthis.maxFractionDigits = maxFractionDigits;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 3) return context.error(\"Expected two arguments.\");\n\t\tconst number = context.parse(args[1], 1, NumberType);\n\t\tif (!number) return null;\n\t\tconst options = args[2];\n\t\tif (typeof options !== \"object\" || Array.isArray(options)) return context.error(\"NumberFormat options argument must be an object.\");\n\t\tlet locale = null;\n\t\tif (options[\"locale\"]) {\n\t\t\tlocale = context.parse(options[\"locale\"], 1, StringType);\n\t\t\tif (!locale) return null;\n\t\t}\n\t\tlet currency = null;\n\t\tif (options[\"currency\"]) {\n\t\t\tcurrency = context.parse(options[\"currency\"], 1, StringType);\n\t\t\tif (!currency) return null;\n\t\t}\n\t\tlet unit = null;\n\t\tif (options[\"unit\"]) {\n\t\t\tunit = context.parse(options[\"unit\"], 1, StringType);\n\t\t\tif (!unit) return null;\n\t\t}\n\t\tif (currency && unit) return context.error(\"NumberFormat options `currency` and `unit` are mutually exclusive\");\n\t\tlet minFractionDigits = null;\n\t\tif (options[\"min-fraction-digits\"]) {\n\t\t\tminFractionDigits = context.parse(options[\"min-fraction-digits\"], 1, NumberType);\n\t\t\tif (!minFractionDigits) return null;\n\t\t}\n\t\tlet maxFractionDigits = null;\n\t\tif (options[\"max-fraction-digits\"]) {\n\t\t\tmaxFractionDigits = context.parse(options[\"max-fraction-digits\"], 1, NumberType);\n\t\t\tif (!maxFractionDigits) return null;\n\t\t}\n\t\treturn new NumberFormat(number, locale, currency, unit, minFractionDigits, maxFractionDigits);\n\t}\n\tevaluate(ctx) {\n\t\treturn new Intl.NumberFormat(this.locale ? this.locale.evaluate(ctx) : [], {\n\t\t\tstyle: this.currency ? \"currency\" : this.unit ? \"unit\" : \"decimal\",\n\t\t\tcurrency: this.currency ? this.currency.evaluate(ctx) : void 0,\n\t\t\tunit: this.unit ? this.unit.evaluate(ctx) : void 0,\n\t\t\tminimumFractionDigits: this.minFractionDigits ? this.minFractionDigits.evaluate(ctx) : void 0,\n\t\t\tmaximumFractionDigits: this.maxFractionDigits ? this.maxFractionDigits.evaluate(ctx) : void 0\n\t\t}).format(this.number.evaluate(ctx));\n\t}\n\teachChild(fn) {\n\t\tfn(this.number);\n\t\tif (this.locale) fn(this.locale);\n\t\tif (this.currency) fn(this.currency);\n\t\tif (this.unit) fn(this.unit);\n\t\tif (this.minFractionDigits) fn(this.minFractionDigits);\n\t\tif (this.maxFractionDigits) fn(this.maxFractionDigits);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/format.ts\nvar FormatExpression = class FormatExpression {\n\tconstructor(sections) {\n\t\tthis.type = FormattedType;\n\t\tthis.sections = sections;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length < 2) return context.error(\"Expected at least one argument.\");\n\t\tconst firstArg = args[1];\n\t\tif (!Array.isArray(firstArg) && typeof firstArg === \"object\") return context.error(\"First argument must be an image or text section.\");\n\t\tconst sections = [];\n\t\tlet nextTokenMayBeObject = false;\n\t\tfor (let i = 1; i <= args.length - 1; ++i) {\n\t\t\tconst arg = args[i];\n\t\t\tif (nextTokenMayBeObject && typeof arg === \"object\" && !Array.isArray(arg)) {\n\t\t\t\tnextTokenMayBeObject = false;\n\t\t\t\tlet scale = null;\n\t\t\t\tif (arg[\"font-scale\"]) {\n\t\t\t\t\tscale = context.parse(arg[\"font-scale\"], 1, NumberType);\n\t\t\t\t\tif (!scale) return null;\n\t\t\t\t}\n\t\t\t\tlet font = null;\n\t\t\t\tif (arg[\"text-font\"]) {\n\t\t\t\t\tfont = context.parse(arg[\"text-font\"], 1, array(StringType));\n\t\t\t\t\tif (!font) return null;\n\t\t\t\t}\n\t\t\t\tlet textColor = null;\n\t\t\t\tif (arg[\"text-color\"]) {\n\t\t\t\t\ttextColor = context.parse(arg[\"text-color\"], 1, ColorType);\n\t\t\t\t\tif (!textColor) return null;\n\t\t\t\t}\n\t\t\t\tlet verticalAlign = null;\n\t\t\t\tif (arg[\"vertical-align\"]) {\n\t\t\t\t\tif (typeof arg[\"vertical-align\"] === \"string\" && !VERTICAL_ALIGN_OPTIONS.includes(arg[\"vertical-align\"])) return context.error(`'vertical-align' must be one of: 'bottom', 'center', 'top' but found '${arg[\"vertical-align\"]}' instead.`);\n\t\t\t\t\tverticalAlign = context.parse(arg[\"vertical-align\"], 1, StringType);\n\t\t\t\t\tif (!verticalAlign) return null;\n\t\t\t\t}\n\t\t\t\tconst lastExpression = sections[sections.length - 1];\n\t\t\t\tlastExpression.scale = scale;\n\t\t\t\tlastExpression.font = font;\n\t\t\t\tlastExpression.textColor = textColor;\n\t\t\t\tlastExpression.verticalAlign = verticalAlign;\n\t\t\t} else {\n\t\t\t\tconst content = context.parse(args[i], 1, ValueType);\n\t\t\t\tif (!content) return null;\n\t\t\t\tconst kind = content.type.kind;\n\t\t\t\tif (kind !== \"string\" && kind !== \"value\" && kind !== \"null\" && kind !== \"resolvedImage\") return context.error(\"Formatted text type must be 'string', 'value', 'image' or 'null'.\");\n\t\t\t\tnextTokenMayBeObject = true;\n\t\t\t\tsections.push({\n\t\t\t\t\tcontent,\n\t\t\t\t\tscale: null,\n\t\t\t\t\tfont: null,\n\t\t\t\t\ttextColor: null,\n\t\t\t\t\tverticalAlign: null\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn new FormatExpression(sections);\n\t}\n\tevaluate(ctx) {\n\t\tconst evaluateSection = (section) => {\n\t\t\tconst evaluatedContent = section.content.evaluate(ctx);\n\t\t\tif (typeOf(evaluatedContent) === ResolvedImageType) return new FormattedSection(\"\", evaluatedContent, null, null, null, section.verticalAlign ? section.verticalAlign.evaluate(ctx) : null);\n\t\t\treturn new FormattedSection(valueToString(evaluatedContent), null, section.scale ? section.scale.evaluate(ctx) : null, section.font ? section.font.evaluate(ctx).join(\",\") : null, section.textColor ? section.textColor.evaluate(ctx) : null, section.verticalAlign ? section.verticalAlign.evaluate(ctx) : null);\n\t\t};\n\t\treturn new Formatted(this.sections.map(evaluateSection));\n\t}\n\teachChild(fn) {\n\t\tfor (const section of this.sections) {\n\t\t\tfn(section.content);\n\t\t\tif (section.scale) fn(section.scale);\n\t\t\tif (section.font) fn(section.font);\n\t\t\tif (section.textColor) fn(section.textColor);\n\t\t\tif (section.verticalAlign) fn(section.verticalAlign);\n\t\t}\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/image.ts\nvar ImageExpression = class ImageExpression {\n\tconstructor(input) {\n\t\tthis.type = ResolvedImageType;\n\t\tthis.input = input;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(\"Expected two arguments.\");\n\t\tconst name = context.parse(args[1], 1, StringType);\n\t\tif (!name) return context.error(\"No image name provided.\");\n\t\treturn new ImageExpression(name);\n\t}\n\tevaluate(ctx) {\n\t\tconst evaluatedImageName = this.input.evaluate(ctx);\n\t\tconst value = ResolvedImage.fromString(evaluatedImageName);\n\t\tif (value && ctx.availableImages) value.available = ctx.availableImages.indexOf(evaluatedImageName) > -1;\n\t\treturn value;\n\t}\n\teachChild(fn) {\n\t\tfn(this.input);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/length.ts\nvar Length = class Length {\n\tconstructor(input, key) {\n\t\tthis.input = input;\n\t\tthis.key = key;\n\t\tthis.type = NumberType;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(`Expected 1 argument, but found ${args.length - 1} instead.`);\n\t\tconst input = context.parse(args[1], 1);\n\t\tif (!input) return null;\n\t\tif (input.type.kind !== \"array\" && input.type.kind !== \"string\" && input.type.kind !== \"value\") return context.error(`Expected argument of type string or array, but found ${typeToString(input.type)} instead.`);\n\t\treturn new Length(input, context.key);\n\t}\n\tevaluate(ctx) {\n\t\tconst input = this.input.evaluate(ctx);\n\t\tif (typeof input === \"string\") return [...input].length;\n\t\telse if (Array.isArray(input)) return input.length;\n\t\telse throw new RuntimeError(`Expected value to be of type string or array, but found ${typeToString(typeOf(input))} instead.`, this.key);\n\t}\n\teachChild(fn) {\n\t\tfn(this.input);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/util/geometry_util.ts\nconst EXTENT = 8192;\nfunction getTileCoordinates(p, canonical) {\n\tconst x = mercatorXfromLng(p[0]);\n\tconst y = mercatorYfromLat(p[1]);\n\tconst tilesAtZoom = Math.pow(2, canonical.z);\n\treturn [Math.round(x * tilesAtZoom * EXTENT), Math.round(y * tilesAtZoom * EXTENT)];\n}\nfunction getLngLatFromTileCoord(coord, canonical) {\n\tconst tilesAtZoom = Math.pow(2, canonical.z);\n\tconst x = (coord[0] / EXTENT + canonical.x) / tilesAtZoom;\n\tconst y = (coord[1] / EXTENT + canonical.y) / tilesAtZoom;\n\treturn [lngFromMercatorXfromLng(x), latFromMercatorY(y)];\n}\nfunction mercatorXfromLng(lng) {\n\treturn (180 + lng) / 360;\n}\nfunction lngFromMercatorXfromLng(mercatorX) {\n\treturn mercatorX * 360 - 180;\n}\nfunction mercatorYfromLat(lat) {\n\treturn (180 - 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360))) / 360;\n}\nfunction latFromMercatorY(mercatorY) {\n\treturn 360 / Math.PI * Math.atan(Math.exp((180 - mercatorY * 360) * Math.PI / 180)) - 90;\n}\nfunction updateBBox(bbox, coord) {\n\tbbox[0] = Math.min(bbox[0], coord[0]);\n\tbbox[1] = Math.min(bbox[1], coord[1]);\n\tbbox[2] = Math.max(bbox[2], coord[0]);\n\tbbox[3] = Math.max(bbox[3], coord[1]);\n}\nfunction boxWithinBox(bbox1, bbox2) {\n\tif (bbox1[0] <= bbox2[0]) return false;\n\tif (bbox1[2] >= bbox2[2]) return false;\n\tif (bbox1[1] <= bbox2[1]) return false;\n\tif (bbox1[3] >= bbox2[3]) return false;\n\treturn true;\n}\nfunction rayIntersect(p, p1, p2) {\n\treturn p1[1] > p[1] !== p2[1] > p[1] && p[0] < (p2[0] - p1[0]) * (p[1] - p1[1]) / (p2[1] - p1[1]) + p1[0];\n}\nfunction pointOnBoundary(p, p1, p2) {\n\tconst x1 = p[0] - p1[0];\n\tconst y1 = p[1] - p1[1];\n\tconst x2 = p[0] - p2[0];\n\tconst y2 = p[1] - p2[1];\n\treturn x1 * y2 - x2 * y1 === 0 && x1 * x2 <= 0 && y1 * y2 <= 0;\n}\nfunction segmentIntersectSegment(a, b, c, d) {\n\tconst vectorP = [b[0] - a[0], b[1] - a[1]];\n\tif (perp([d[0] - c[0], d[1] - c[1]], vectorP) === 0) return false;\n\tif (twoSided(a, b, c, d) && twoSided(c, d, a, b)) return true;\n\treturn false;\n}\nfunction lineIntersectPolygon(p1, p2, polygon) {\n\tfor (const ring of polygon) for (let j = 0; j < ring.length - 1; ++j) if (segmentIntersectSegment(p1, p2, ring[j], ring[j + 1])) return true;\n\treturn false;\n}\nfunction pointWithinPolygon(point, rings, trueIfOnBoundary = false) {\n\tlet inside = false;\n\tfor (const ring of rings) for (let j = 0; j < ring.length - 1; j++) {\n\t\tif (pointOnBoundary(point, ring[j], ring[j + 1])) return trueIfOnBoundary;\n\t\tif (rayIntersect(point, ring[j], ring[j + 1])) inside = !inside;\n\t}\n\treturn inside;\n}\nfunction pointWithinPolygons(point, polygons) {\n\tfor (const polygon of polygons) if (pointWithinPolygon(point, polygon)) return true;\n\treturn false;\n}\nfunction lineStringWithinPolygon(line, polygon) {\n\tfor (const point of line) if (!pointWithinPolygon(point, polygon)) return false;\n\tfor (let i = 0; i < line.length - 1; ++i) if (lineIntersectPolygon(line[i], line[i + 1], polygon)) return false;\n\treturn true;\n}\nfunction lineStringWithinPolygons(line, polygons) {\n\tfor (const polygon of polygons) if (lineStringWithinPolygon(line, polygon)) return true;\n\treturn false;\n}\nfunction perp(v1, v2) {\n\treturn v1[0] * v2[1] - v1[1] * v2[0];\n}\nfunction twoSided(p1, p2, q1, q2) {\n\tconst x1 = p1[0] - q1[0];\n\tconst y1 = p1[1] - q1[1];\n\tconst x2 = p2[0] - q1[0];\n\tconst y2 = p2[1] - q1[1];\n\tconst x3 = q2[0] - q1[0];\n\tconst y3 = q2[1] - q1[1];\n\tconst det1 = x1 * y3 - x3 * y1;\n\tconst det2 = x2 * y3 - x3 * y2;\n\tif (det1 > 0 && det2 < 0 || det1 < 0 && det2 > 0) return true;\n\treturn false;\n}\n//#endregion\n//#region src/expression/definitions/within.ts\nfunction getTilePolygon(coordinates, bbox, canonical) {\n\tconst polygon = [];\n\tfor (let i = 0; i < coordinates.length; i++) {\n\t\tconst ring = [];\n\t\tfor (let j = 0; j < coordinates[i].length; j++) {\n\t\t\tconst coord = getTileCoordinates(coordinates[i][j], canonical);\n\t\t\tupdateBBox(bbox, coord);\n\t\t\tring.push(coord);\n\t\t}\n\t\tpolygon.push(ring);\n\t}\n\treturn polygon;\n}\nfunction getTilePolygons(coordinates, bbox, canonical) {\n\tconst polygons = [];\n\tfor (let i = 0; i < coordinates.length; i++) {\n\t\tconst polygon = getTilePolygon(coordinates[i], bbox, canonical);\n\t\tpolygons.push(polygon);\n\t}\n\treturn polygons;\n}\nfunction updatePoint(p, bbox, polyBBox, worldSize) {\n\tif (p[0] < polyBBox[0] || p[0] > polyBBox[2]) {\n\t\tconst halfWorldSize = worldSize * .5;\n\t\tlet shift = p[0] - polyBBox[0] > halfWorldSize ? -worldSize : polyBBox[0] - p[0] > halfWorldSize ? worldSize : 0;\n\t\tif (shift === 0) shift = p[0] - polyBBox[2] > halfWorldSize ? -worldSize : polyBBox[2] - p[0] > halfWorldSize ? worldSize : 0;\n\t\tp[0] += shift;\n\t}\n\tupdateBBox(bbox, p);\n}\nfunction resetBBox(bbox) {\n\tbbox[0] = bbox[1] = Infinity;\n\tbbox[2] = bbox[3] = -Infinity;\n}\nfunction getTilePoints(geometry, pointBBox, polyBBox, canonical) {\n\tconst worldSize = Math.pow(2, canonical.z) * EXTENT;\n\tconst shifts = [canonical.x * EXTENT, canonical.y * EXTENT];\n\tconst tilePoints = [];\n\tfor (const points of geometry) for (const point of points) {\n\t\tconst p = [point.x + shifts[0], point.y + shifts[1]];\n\t\tupdatePoint(p, pointBBox, polyBBox, worldSize);\n\t\ttilePoints.push(p);\n\t}\n\treturn tilePoints;\n}\nfunction getTileLines(geometry, lineBBox, polyBBox, canonical) {\n\tconst worldSize = Math.pow(2, canonical.z) * EXTENT;\n\tconst shifts = [canonical.x * EXTENT, canonical.y * EXTENT];\n\tconst tileLines = [];\n\tfor (const line of geometry) {\n\t\tconst tileLine = [];\n\t\tfor (const point of line) {\n\t\t\tconst p = [point.x + shifts[0], point.y + shifts[1]];\n\t\t\tupdateBBox(lineBBox, p);\n\t\t\ttileLine.push(p);\n\t\t}\n\t\ttileLines.push(tileLine);\n\t}\n\tif (lineBBox[2] - lineBBox[0] <= worldSize / 2) {\n\t\tresetBBox(lineBBox);\n\t\tfor (const line of tileLines) for (const p of line) updatePoint(p, lineBBox, polyBBox, worldSize);\n\t}\n\treturn tileLines;\n}\nfunction pointsWithinPolygons(ctx, polygonGeometry) {\n\tconst pointBBox = [\n\t\tInfinity,\n\t\tInfinity,\n\t\t-Infinity,\n\t\t-Infinity\n\t];\n\tconst polyBBox = [\n\t\tInfinity,\n\t\tInfinity,\n\t\t-Infinity,\n\t\t-Infinity\n\t];\n\tconst canonical = ctx.canonicalID();\n\tif (polygonGeometry.type === \"Polygon\") {\n\t\tconst tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);\n\t\tconst tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);\n\t\tif (!boxWithinBox(pointBBox, polyBBox)) return false;\n\t\tfor (const point of tilePoints) if (!pointWithinPolygon(point, tilePolygon)) return false;\n\t}\n\tif (polygonGeometry.type === \"MultiPolygon\") {\n\t\tconst tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);\n\t\tconst tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);\n\t\tif (!boxWithinBox(pointBBox, polyBBox)) return false;\n\t\tfor (const point of tilePoints) if (!pointWithinPolygons(point, tilePolygons)) return false;\n\t}\n\treturn true;\n}\nfunction linesWithinPolygons(ctx, polygonGeometry) {\n\tconst lineBBox = [\n\t\tInfinity,\n\t\tInfinity,\n\t\t-Infinity,\n\t\t-Infinity\n\t];\n\tconst polyBBox = [\n\t\tInfinity,\n\t\tInfinity,\n\t\t-Infinity,\n\t\t-Infinity\n\t];\n\tconst canonical = ctx.canonicalID();\n\tif (polygonGeometry.type === \"Polygon\") {\n\t\tconst tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);\n\t\tconst tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);\n\t\tif (!boxWithinBox(lineBBox, polyBBox)) return false;\n\t\tfor (const line of tileLines) if (!lineStringWithinPolygon(line, tilePolygon)) return false;\n\t}\n\tif (polygonGeometry.type === \"MultiPolygon\") {\n\t\tconst tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);\n\t\tconst tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);\n\t\tif (!boxWithinBox(lineBBox, polyBBox)) return false;\n\t\tfor (const line of tileLines) if (!lineStringWithinPolygons(line, tilePolygons)) return false;\n\t}\n\treturn true;\n}\nvar Within = class Within {\n\tconstructor(geojson, geometries) {\n\t\tthis.type = BooleanType;\n\t\tthis.geojson = geojson;\n\t\tthis.geometries = geometries;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(`'within' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n\t\tif (isValue(args[1])) {\n\t\t\tconst geojson = args[1];\n\t\t\tif (geojson.type === \"FeatureCollection\") {\n\t\t\t\tconst polygonsCoords = [];\n\t\t\t\tfor (const polygon of geojson.features) {\n\t\t\t\t\tconst { type, coordinates } = polygon.geometry;\n\t\t\t\t\tif (type === \"Polygon\") polygonsCoords.push(coordinates);\n\t\t\t\t\tif (type === \"MultiPolygon\") polygonsCoords.push(...coordinates);\n\t\t\t\t}\n\t\t\t\tif (polygonsCoords.length) return new Within(geojson, {\n\t\t\t\t\ttype: \"MultiPolygon\",\n\t\t\t\t\tcoordinates: polygonsCoords\n\t\t\t\t});\n\t\t\t} else if (geojson.type === \"Feature\") {\n\t\t\t\tconst type = geojson.geometry.type;\n\t\t\t\tif (type === \"Polygon\" || type === \"MultiPolygon\") return new Within(geojson, geojson.geometry);\n\t\t\t} else if (geojson.type === \"Polygon\" || geojson.type === \"MultiPolygon\") return new Within(geojson, geojson);\n\t\t}\n\t\treturn context.error(\"'within' expression requires valid geojson object that contains polygon geometry type.\");\n\t}\n\tevaluate(ctx) {\n\t\tif (ctx.geometry() != null && ctx.canonicalID() != null) {\n\t\t\tif (ctx.geometryType() === \"Point\") return pointsWithinPolygons(ctx, this.geometries);\n\t\t\telse if (ctx.geometryType() === \"LineString\") return linesWithinPolygons(ctx, this.geometries);\n\t\t}\n\t\treturn false;\n\t}\n\teachChild() {}\n\toutputDefined() {\n\t\treturn true;\n\t}\n};\n//#endregion\n//#region node_modules/tinyqueue/index.js\nvar TinyQueue = class {\n\tconstructor(data = [], compare = (a, b) => a < b ? -1 : a > b ? 1 : 0) {\n\t\tthis.data = data;\n\t\tthis.length = this.data.length;\n\t\tthis.compare = compare;\n\t\tif (this.length > 0) for (let i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);\n\t}\n\tpush(item) {\n\t\tthis.data.push(item);\n\t\tthis._up(this.length++);\n\t}\n\tpop() {\n\t\tif (this.length === 0) return void 0;\n\t\tconst top = this.data[0];\n\t\tconst bottom = this.data.pop();\n\t\tif (--this.length > 0) {\n\t\t\tthis.data[0] = bottom;\n\t\t\tthis._down(0);\n\t\t}\n\t\treturn top;\n\t}\n\tpeek() {\n\t\treturn this.data[0];\n\t}\n\t_up(pos) {\n\t\tconst { data, compare } = this;\n\t\tconst item = data[pos];\n\t\twhile (pos > 0) {\n\t\t\tconst parent = pos - 1 >> 1;\n\t\t\tconst current = data[parent];\n\t\t\tif (compare(item, current) >= 0) break;\n\t\t\tdata[pos] = current;\n\t\t\tpos = parent;\n\t\t}\n\t\tdata[pos] = item;\n\t}\n\t_down(pos) {\n\t\tconst { data, compare } = this;\n\t\tconst halfLength = this.length >> 1;\n\t\tconst item = data[pos];\n\t\twhile (pos < halfLength) {\n\t\t\tlet bestChild = (pos << 1) + 1;\n\t\t\tconst right = bestChild + 1;\n\t\t\tif (right < this.length && compare(data[right], data[bestChild]) < 0) bestChild = right;\n\t\t\tif (compare(data[bestChild], item) >= 0) break;\n\t\t\tdata[pos] = data[bestChild];\n\t\t\tpos = bestChild;\n\t\t}\n\t\tdata[pos] = item;\n\t}\n};\n//#endregion\n//#region node_modules/quickselect/index.js\n/**\n* Rearranges items so that all items in the [left, k] are the smallest.\n* The k-th element will have the (k - left + 1)-th smallest value in [left, right].\n*\n* @template T\n* @param {T[]} arr the array to partially sort (in place)\n* @param {number} k middle index for partial sorting (as defined above)\n* @param {number} [left=0] left index of the range to sort\n* @param {number} [right=arr.length-1] right index\n* @param {(a: T, b: T) => number} [compare = (a, b) => a - b] compare function\n*/\nfunction quickselect(arr, k, left = 0, right = arr.length - 1, compare = defaultCompare) {\n\twhile (right > left) {\n\t\tif (right - left > 600) {\n\t\t\tconst n = right - left + 1;\n\t\t\tconst m = k - left + 1;\n\t\t\tconst z = Math.log(n);\n\t\t\tconst s = .5 * Math.exp(2 * z / 3);\n\t\t\tconst sd = .5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n\t\t\tquickselect(arr, k, Math.max(left, Math.floor(k - m * s / n + sd)), Math.min(right, Math.floor(k + (n - m) * s / n + sd)), compare);\n\t\t}\n\t\tconst t = arr[k];\n\t\tlet i = left;\n\t\t/** @type {number} */\n\t\tlet j = right;\n\t\tswap(arr, left, k);\n\t\tif (compare(arr[right], t) > 0) swap(arr, left, right);\n\t\twhile (i < j) {\n\t\t\tswap(arr, i, j);\n\t\t\ti++;\n\t\t\tj--;\n\t\t\twhile (compare(arr[i], t) < 0) i++;\n\t\t\twhile (compare(arr[j], t) > 0) j--;\n\t\t}\n\t\tif (compare(arr[left], t) === 0) swap(arr, left, j);\n\t\telse {\n\t\t\tj++;\n\t\t\tswap(arr, j, right);\n\t\t}\n\t\tif (j <= k) left = j + 1;\n\t\tif (k <= j) right = j - 1;\n\t}\n}\n/**\n* @template T\n* @param {T[]} arr\n* @param {number} i\n* @param {number} j\n*/\nfunction swap(arr, i, j) {\n\tconst tmp = arr[i];\n\tarr[i] = arr[j];\n\tarr[j] = tmp;\n}\n/**\n* @template T\n* @param {T} a\n* @param {T} b\n* @returns {number}\n*/\nfunction defaultCompare(a, b) {\n\treturn a < b ? -1 : a > b ? 1 : 0;\n}\n//#endregion\n//#region src/util/classify_rings.ts\n/**\n* Classifies an array of rings into polygons with outer rings and holes\n* @param rings - the rings to classify\n* @param maxRings - the maximum number of rings to include in a polygon, use 0 to include all rings\n* @returns an array of polygons with internal rings as holes\n*/\nfunction classifyRings(rings, maxRings) {\n\tif (rings.length <= 1) return [rings];\n\tconst polygons = [];\n\tlet polygon;\n\tlet ccw;\n\tfor (const ring of rings) {\n\t\tconst area = calculateSignedArea(ring);\n\t\tif (area === 0) continue;\n\t\tring.area = Math.abs(area);\n\t\tif (ccw === void 0) ccw = area < 0;\n\t\tif (ccw === area < 0) {\n\t\t\tif (polygon) polygons.push(polygon);\n\t\t\tpolygon = [ring];\n\t\t} else polygon.push(ring);\n\t}\n\tif (polygon) polygons.push(polygon);\n\tif (maxRings > 1) for (let j = 0; j < polygons.length; j++) {\n\t\tif (polygons[j].length <= maxRings) continue;\n\t\tquickselect(polygons[j], maxRings, 1, polygons[j].length - 1, compareAreas);\n\t\tpolygons[j] = polygons[j].slice(0, maxRings);\n\t}\n\treturn polygons;\n}\nfunction compareAreas(a, b) {\n\treturn b.area - a.area;\n}\n/**\n* Returns the signed area for the polygon ring. Positive areas are exterior rings and\n* have a clockwise winding. Negative areas are interior rings and have a counter clockwise\n* ordering.\n*\n* @param ring - Exterior or interior ring\n* @returns Signed area\n*/\nfunction calculateSignedArea(ring) {\n\tlet sum = 0;\n\tfor (let i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {\n\t\tp1 = ring[i];\n\t\tp2 = ring[j];\n\t\tsum += (p2.x - p1.x) * (p1.y + p2.y);\n\t}\n\treturn sum;\n}\n//#endregion\n//#region src/util/cheap_ruler.ts\nconst RE = 6378.137;\nconst E2 = .0066943799901413165;\nconst RAD = Math.PI / 180;\nvar CheapRuler = class {\n\tconstructor(lat) {\n\t\tconst m = RAD * RE * 1e3;\n\t\tconst coslat = Math.cos(lat * RAD);\n\t\tconst w2 = 1 / (1 - E2 * (1 - coslat * coslat));\n\t\tconst w = Math.sqrt(w2);\n\t\tthis.kx = m * w * coslat;\n\t\tthis.ky = m * w * w2 * .9933056200098587;\n\t}\n\t/**\n\t* Given two points of the form [longitude, latitude], returns the distance.\n\t*\n\t* @param a - point [longitude, latitude]\n\t* @param b - point [longitude, latitude]\n\t* @returns distance\n\t* @example\n\t* const distance = ruler.distance([30.5, 50.5], [30.51, 50.49]);\n\t* //=distance\n\t*/\n\tdistance(a, b) {\n\t\tconst dx = this.wrap(a[0] - b[0]) * this.kx;\n\t\tconst dy = (a[1] - b[1]) * this.ky;\n\t\treturn Math.sqrt(dx * dx + dy * dy);\n\t}\n\t/**\n\t* Returns an object of the form {point, index, t}, where point is closest point on the line\n\t* from the given point, index is the start index of the segment with the closest point,\n\t* and t is a parameter from 0 to 1 that indicates where the closest point is on that segment.\n\t*\n\t* @param line - an array of points that form the line\n\t* @param p - point [longitude, latitude]\n\t* @returns the nearest point, its index in the array and the proportion along the line\n\t* @example\n\t* const point = ruler.pointOnLine(line, [-67.04, 50.5]).point;\n\t* //=point\n\t*/\n\tpointOnLine(line, p) {\n\t\tlet minDist = Infinity;\n\t\tlet minX, minY, minI, minT;\n\t\tfor (let i = 0; i < line.length - 1; i++) {\n\t\t\tlet x = line[i][0];\n\t\t\tlet y = line[i][1];\n\t\t\tlet dx = this.wrap(line[i + 1][0] - x) * this.kx;\n\t\t\tlet dy = (line[i + 1][1] - y) * this.ky;\n\t\t\tlet t = 0;\n\t\t\tif (dx !== 0 || dy !== 0) {\n\t\t\t\tt = (this.wrap(p[0] - x) * this.kx * dx + (p[1] - y) * this.ky * dy) / (dx * dx + dy * dy);\n\t\t\t\tif (t > 1) {\n\t\t\t\t\tx = line[i + 1][0];\n\t\t\t\t\ty = line[i + 1][1];\n\t\t\t\t} else if (t > 0) {\n\t\t\t\t\tx += dx / this.kx * t;\n\t\t\t\t\ty += dy / this.ky * t;\n\t\t\t\t}\n\t\t\t}\n\t\t\tdx = this.wrap(p[0] - x) * this.kx;\n\t\t\tdy = (p[1] - y) * this.ky;\n\t\t\tconst sqDist = dx * dx + dy * dy;\n\t\t\tif (sqDist < minDist) {\n\t\t\t\tminDist = sqDist;\n\t\t\t\tminX = x;\n\t\t\t\tminY = y;\n\t\t\t\tminI = i;\n\t\t\t\tminT = t;\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tpoint: [minX, minY],\n\t\t\tindex: minI,\n\t\t\tt: Math.max(0, Math.min(1, minT))\n\t\t};\n\t}\n\twrap(deg) {\n\t\twhile (deg < -180) deg += 360;\n\t\twhile (deg > 180) deg -= 360;\n\t\treturn deg;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/distance.ts\nconst MinPointsSize = 100;\nconst MinLinePointsSize = 50;\nfunction compareDistPair(a, b) {\n\treturn b[0] - a[0];\n}\nfunction getRangeSize(range) {\n\treturn range[1] - range[0] + 1;\n}\nfunction isRangeSafe(range, threshold) {\n\treturn range[1] >= range[0] && range[1] < threshold;\n}\nfunction splitRange(range, isLine) {\n\tif (range[0] > range[1]) return [null, null];\n\tconst size = getRangeSize(range);\n\tif (isLine) {\n\t\tif (size === 2) return [range, null];\n\t\tconst size1 = Math.floor(size / 2);\n\t\treturn [[range[0], range[0] + size1], [range[0] + size1, range[1]]];\n\t}\n\tif (size === 1) return [range, null];\n\tconst size1 = Math.floor(size / 2) - 1;\n\treturn [[range[0], range[0] + size1], [range[0] + size1 + 1, range[1]]];\n}\nfunction getBBox(coords, range) {\n\tif (!isRangeSafe(range, coords.length)) return [\n\t\tInfinity,\n\t\tInfinity,\n\t\t-Infinity,\n\t\t-Infinity\n\t];\n\tconst bbox = [\n\t\tInfinity,\n\t\tInfinity,\n\t\t-Infinity,\n\t\t-Infinity\n\t];\n\tfor (let i = range[0]; i <= range[1]; ++i) updateBBox(bbox, coords[i]);\n\treturn bbox;\n}\nfunction getPolygonBBox(polygon) {\n\tconst bbox = [\n\t\tInfinity,\n\t\tInfinity,\n\t\t-Infinity,\n\t\t-Infinity\n\t];\n\tfor (const ring of polygon) for (const coord of ring) updateBBox(bbox, coord);\n\treturn bbox;\n}\nfunction isValidBBox(bbox) {\n\treturn bbox[0] !== -Infinity && bbox[1] !== -Infinity && bbox[2] !== Infinity && bbox[3] !== Infinity;\n}\nfunction bboxToBBoxDistance(bbox1, bbox2, ruler) {\n\tif (!isValidBBox(bbox1) || !isValidBBox(bbox2)) return NaN;\n\tlet dx = 0;\n\tlet dy = 0;\n\tif (bbox1[2] < bbox2[0]) dx = bbox2[0] - bbox1[2];\n\tif (bbox1[0] > bbox2[2]) dx = bbox1[0] - bbox2[2];\n\tif (bbox1[1] > bbox2[3]) dy = bbox1[1] - bbox2[3];\n\tif (bbox1[3] < bbox2[1]) dy = bbox2[1] - bbox1[3];\n\treturn ruler.distance([0, 0], [dx, dy]);\n}\nfunction pointToLineDistance(point, line, ruler) {\n\tconst nearestPoint = ruler.pointOnLine(line, point);\n\treturn ruler.distance(point, nearestPoint.point);\n}\nfunction segmentToSegmentDistance(p1, p2, q1, q2, ruler) {\n\tconst dist1 = Math.min(pointToLineDistance(p1, [q1, q2], ruler), pointToLineDistance(p2, [q1, q2], ruler));\n\tconst dist2 = Math.min(pointToLineDistance(q1, [p1, p2], ruler), pointToLineDistance(q2, [p1, p2], ruler));\n\treturn Math.min(dist1, dist2);\n}\nfunction lineToLineDistance(line1, range1, line2, range2, ruler) {\n\tif (!(isRangeSafe(range1, line1.length) && isRangeSafe(range2, line2.length))) return Infinity;\n\tlet dist = Infinity;\n\tfor (let i = range1[0]; i < range1[1]; ++i) {\n\t\tconst p1 = line1[i];\n\t\tconst p2 = line1[i + 1];\n\t\tfor (let j = range2[0]; j < range2[1]; ++j) {\n\t\t\tconst q1 = line2[j];\n\t\t\tconst q2 = line2[j + 1];\n\t\t\tif (segmentIntersectSegment(p1, p2, q1, q2)) return 0;\n\t\t\tdist = Math.min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));\n\t\t}\n\t}\n\treturn dist;\n}\nfunction pointsToPointsDistance(points1, range1, points2, range2, ruler) {\n\tif (!(isRangeSafe(range1, points1.length) && isRangeSafe(range2, points2.length))) return NaN;\n\tlet dist = Infinity;\n\tfor (let i = range1[0]; i <= range1[1]; ++i) for (let j = range2[0]; j <= range2[1]; ++j) {\n\t\tdist = Math.min(dist, ruler.distance(points1[i], points2[j]));\n\t\tif (dist === 0) return dist;\n\t}\n\treturn dist;\n}\nfunction pointToPolygonDistance(point, polygon, ruler) {\n\tif (pointWithinPolygon(point, polygon, true)) return 0;\n\tlet dist = Infinity;\n\tfor (const ring of polygon) {\n\t\tconst front = ring[0];\n\t\tconst back = ring[ring.length - 1];\n\t\tif (front !== back) {\n\t\t\tdist = Math.min(dist, pointToLineDistance(point, [back, front], ruler));\n\t\t\tif (dist === 0) return dist;\n\t\t}\n\t\tconst nearestPoint = ruler.pointOnLine(ring, point);\n\t\tdist = Math.min(dist, ruler.distance(point, nearestPoint.point));\n\t\tif (dist === 0) return dist;\n\t}\n\treturn dist;\n}\nfunction lineToPolygonDistance(line, range, polygon, ruler) {\n\tif (!isRangeSafe(range, line.length)) return NaN;\n\tfor (let i = range[0]; i <= range[1]; ++i) if (pointWithinPolygon(line[i], polygon, true)) return 0;\n\tlet dist = Infinity;\n\tfor (let i = range[0]; i < range[1]; ++i) {\n\t\tconst p1 = line[i];\n\t\tconst p2 = line[i + 1];\n\t\tfor (const ring of polygon) for (let j = 0, len = ring.length, k = len - 1; j < len; k = j++) {\n\t\t\tconst q1 = ring[k];\n\t\t\tconst q2 = ring[j];\n\t\t\tif (segmentIntersectSegment(p1, p2, q1, q2)) return 0;\n\t\t\tdist = Math.min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));\n\t\t}\n\t}\n\treturn dist;\n}\nfunction polygonIntersect(poly1, poly2) {\n\tfor (const ring of poly1) for (const point of ring) if (pointWithinPolygon(point, poly2, true)) return true;\n\treturn false;\n}\nfunction polygonToPolygonDistance(polygon1, polygon2, ruler, currentMiniDist = Infinity) {\n\tconst bbox1 = getPolygonBBox(polygon1);\n\tconst bbox2 = getPolygonBBox(polygon2);\n\tif (currentMiniDist !== Infinity && bboxToBBoxDistance(bbox1, bbox2, ruler) >= currentMiniDist) return currentMiniDist;\n\tif (boxWithinBox(bbox1, bbox2)) {\n\t\tif (polygonIntersect(polygon1, polygon2)) return 0;\n\t} else if (polygonIntersect(polygon2, polygon1)) return 0;\n\tlet dist = Infinity;\n\tfor (const ring1 of polygon1) for (let i = 0, len1 = ring1.length, l = len1 - 1; i < len1; l = i++) {\n\t\tconst p1 = ring1[l];\n\t\tconst p2 = ring1[i];\n\t\tfor (const ring2 of polygon2) for (let j = 0, len2 = ring2.length, k = len2 - 1; j < len2; k = j++) {\n\t\t\tconst q1 = ring2[k];\n\t\t\tconst q2 = ring2[j];\n\t\t\tif (segmentIntersectSegment(p1, p2, q1, q2)) return 0;\n\t\t\tdist = Math.min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));\n\t\t}\n\t}\n\treturn dist;\n}\nfunction updateQueue(distQueue, miniDist, ruler, points, polyBBox, rangeA) {\n\tif (!rangeA) return;\n\tconst tempDist = bboxToBBoxDistance(getBBox(points, rangeA), polyBBox, ruler);\n\tif (tempDist < miniDist) distQueue.push([\n\t\ttempDist,\n\t\trangeA,\n\t\t[0, 0]\n\t]);\n}\nfunction updateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, range1, range2) {\n\tif (!range1 || !range2) return;\n\tconst tempDist = bboxToBBoxDistance(getBBox(pointSet1, range1), getBBox(pointSet2, range2), ruler);\n\tif (tempDist < miniDist) distQueue.push([\n\t\ttempDist,\n\t\trange1,\n\t\trange2\n\t]);\n}\nfunction pointsToPolygonDistance(points, isLine, polygon, ruler, currentMiniDist = Infinity) {\n\tlet miniDist = Math.min(ruler.distance(points[0], polygon[0][0]), currentMiniDist);\n\tif (miniDist === 0) return miniDist;\n\tconst distQueue = new TinyQueue([[\n\t\t0,\n\t\t[0, points.length - 1],\n\t\t[0, 0]\n\t]], compareDistPair);\n\tconst polyBBox = getPolygonBBox(polygon);\n\twhile (distQueue.length > 0) {\n\t\tconst distPair = distQueue.pop();\n\t\tif (distPair[0] >= miniDist) continue;\n\t\tconst range = distPair[1];\n\t\tconst threshold = isLine ? MinLinePointsSize : MinPointsSize;\n\t\tif (getRangeSize(range) <= threshold) {\n\t\t\tif (!isRangeSafe(range, points.length)) return NaN;\n\t\t\tif (isLine) {\n\t\t\t\tconst tempDist = lineToPolygonDistance(points, range, polygon, ruler);\n\t\t\t\tif (isNaN(tempDist) || tempDist === 0) return tempDist;\n\t\t\t\tminiDist = Math.min(miniDist, tempDist);\n\t\t\t} else for (let i = range[0]; i <= range[1]; ++i) {\n\t\t\t\tconst tempDist = pointToPolygonDistance(points[i], polygon, ruler);\n\t\t\t\tminiDist = Math.min(miniDist, tempDist);\n\t\t\t\tif (miniDist === 0) return 0;\n\t\t\t}\n\t\t} else {\n\t\t\tconst newRangesA = splitRange(range, isLine);\n\t\t\tupdateQueue(distQueue, miniDist, ruler, points, polyBBox, newRangesA[0]);\n\t\t\tupdateQueue(distQueue, miniDist, ruler, points, polyBBox, newRangesA[1]);\n\t\t}\n\t}\n\treturn miniDist;\n}\nfunction pointSetToPointSetDistance(pointSet1, isLine1, pointSet2, isLine2, ruler, currentMiniDist = Infinity) {\n\tlet miniDist = Math.min(currentMiniDist, ruler.distance(pointSet1[0], pointSet2[0]));\n\tif (miniDist === 0) return miniDist;\n\tconst distQueue = new TinyQueue([[\n\t\t0,\n\t\t[0, pointSet1.length - 1],\n\t\t[0, pointSet2.length - 1]\n\t]], compareDistPair);\n\twhile (distQueue.length > 0) {\n\t\tconst distPair = distQueue.pop();\n\t\tif (distPair[0] >= miniDist) continue;\n\t\tconst rangeA = distPair[1];\n\t\tconst rangeB = distPair[2];\n\t\tconst threshold1 = isLine1 ? MinLinePointsSize : MinPointsSize;\n\t\tconst threshold2 = isLine2 ? MinLinePointsSize : MinPointsSize;\n\t\tif (getRangeSize(rangeA) <= threshold1 && getRangeSize(rangeB) <= threshold2) {\n\t\t\tif (!isRangeSafe(rangeA, pointSet1.length) && isRangeSafe(rangeB, pointSet2.length)) return NaN;\n\t\t\tlet tempDist;\n\t\t\tif (isLine1 && isLine2) {\n\t\t\t\ttempDist = lineToLineDistance(pointSet1, rangeA, pointSet2, rangeB, ruler);\n\t\t\t\tminiDist = Math.min(miniDist, tempDist);\n\t\t\t} else if (isLine1 && !isLine2) {\n\t\t\t\tconst sublibe = pointSet1.slice(rangeA[0], rangeA[1] + 1);\n\t\t\t\tfor (let i = rangeB[0]; i <= rangeB[1]; ++i) {\n\t\t\t\t\ttempDist = pointToLineDistance(pointSet2[i], sublibe, ruler);\n\t\t\t\t\tminiDist = Math.min(miniDist, tempDist);\n\t\t\t\t\tif (miniDist === 0) return miniDist;\n\t\t\t\t}\n\t\t\t} else if (!isLine1 && isLine2) {\n\t\t\t\tconst sublibe = pointSet2.slice(rangeB[0], rangeB[1] + 1);\n\t\t\t\tfor (let i = rangeA[0]; i <= rangeA[1]; ++i) {\n\t\t\t\t\ttempDist = pointToLineDistance(pointSet1[i], sublibe, ruler);\n\t\t\t\t\tminiDist = Math.min(miniDist, tempDist);\n\t\t\t\t\tif (miniDist === 0) return miniDist;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttempDist = pointsToPointsDistance(pointSet1, rangeA, pointSet2, rangeB, ruler);\n\t\t\t\tminiDist = Math.min(miniDist, tempDist);\n\t\t\t}\n\t\t} else {\n\t\t\tconst newRangesA = splitRange(rangeA, isLine1);\n\t\t\tconst newRangesB = splitRange(rangeB, isLine2);\n\t\t\tupdateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[0], newRangesB[0]);\n\t\t\tupdateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[0], newRangesB[1]);\n\t\t\tupdateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[1], newRangesB[0]);\n\t\t\tupdateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[1], newRangesB[1]);\n\t\t}\n\t}\n\treturn miniDist;\n}\nfunction pointToGeometryDistance(ctx, geometries) {\n\tconst tilePoints = ctx.geometry();\n\tconst pointPosition = tilePoints.flat().map((p) => getLngLatFromTileCoord([p.x, p.y], ctx.canonical));\n\tif (tilePoints.length === 0) return NaN;\n\tconst ruler = new CheapRuler(pointPosition[0][1]);\n\tlet dist = Infinity;\n\tfor (const geometry of geometries) {\n\t\tswitch (geometry.type) {\n\t\t\tcase \"Point\":\n\t\t\t\tdist = Math.min(dist, pointSetToPointSetDistance(pointPosition, false, [geometry.coordinates], false, ruler, dist));\n\t\t\t\tbreak;\n\t\t\tcase \"LineString\":\n\t\t\t\tdist = Math.min(dist, pointSetToPointSetDistance(pointPosition, false, geometry.coordinates, true, ruler, dist));\n\t\t\t\tbreak;\n\t\t\tcase \"Polygon\": dist = Math.min(dist, pointsToPolygonDistance(pointPosition, false, geometry.coordinates, ruler, dist));\n\t\t}\n\t\tif (dist === 0) return dist;\n\t}\n\treturn dist;\n}\nfunction lineStringToGeometryDistance(ctx, geometries) {\n\tconst tileLine = ctx.geometry();\n\tconst linePositions = tileLine.flat().map((p) => getLngLatFromTileCoord([p.x, p.y], ctx.canonical));\n\tif (tileLine.length === 0) return NaN;\n\tconst ruler = new CheapRuler(linePositions[0][1]);\n\tlet dist = Infinity;\n\tfor (const geometry of geometries) {\n\t\tswitch (geometry.type) {\n\t\t\tcase \"Point\":\n\t\t\t\tdist = Math.min(dist, pointSetToPointSetDistance(linePositions, true, [geometry.coordinates], false, ruler, dist));\n\t\t\t\tbreak;\n\t\t\tcase \"LineString\":\n\t\t\t\tdist = Math.min(dist, pointSetToPointSetDistance(linePositions, true, geometry.coordinates, true, ruler, dist));\n\t\t\t\tbreak;\n\t\t\tcase \"Polygon\": dist = Math.min(dist, pointsToPolygonDistance(linePositions, true, geometry.coordinates, ruler, dist));\n\t\t}\n\t\tif (dist === 0) return dist;\n\t}\n\treturn dist;\n}\nfunction polygonToGeometryDistance(ctx, geometries) {\n\tconst tilePolygon = ctx.geometry();\n\tif (tilePolygon.length === 0 || tilePolygon[0].length === 0) return NaN;\n\tconst polygons = classifyRings(tilePolygon, 0).map((polygon) => {\n\t\treturn polygon.map((ring) => {\n\t\t\treturn ring.map((p) => getLngLatFromTileCoord([p.x, p.y], ctx.canonical));\n\t\t});\n\t});\n\tconst ruler = new CheapRuler(polygons[0][0][0][1]);\n\tlet dist = Infinity;\n\tfor (const geometry of geometries) for (const polygon of polygons) {\n\t\tswitch (geometry.type) {\n\t\t\tcase \"Point\":\n\t\t\t\tdist = Math.min(dist, pointsToPolygonDistance([geometry.coordinates], false, polygon, ruler, dist));\n\t\t\t\tbreak;\n\t\t\tcase \"LineString\":\n\t\t\t\tdist = Math.min(dist, pointsToPolygonDistance(geometry.coordinates, true, polygon, ruler, dist));\n\t\t\t\tbreak;\n\t\t\tcase \"Polygon\": dist = Math.min(dist, polygonToPolygonDistance(polygon, geometry.coordinates, ruler, dist));\n\t\t}\n\t\tif (dist === 0) return dist;\n\t}\n\treturn dist;\n}\nfunction toSimpleGeometry(geometry) {\n\tif (geometry.type === \"MultiPolygon\") return geometry.coordinates.map((polygon) => {\n\t\treturn {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: polygon\n\t\t};\n\t});\n\tif (geometry.type === \"MultiLineString\") return geometry.coordinates.map((lineString) => {\n\t\treturn {\n\t\t\ttype: \"LineString\",\n\t\t\tcoordinates: lineString\n\t\t};\n\t});\n\tif (geometry.type === \"MultiPoint\") return geometry.coordinates.map((point) => {\n\t\treturn {\n\t\t\ttype: \"Point\",\n\t\t\tcoordinates: point\n\t\t};\n\t});\n\treturn [geometry];\n}\nvar Distance = class Distance {\n\tconstructor(geojson, geometries) {\n\t\tthis.type = NumberType;\n\t\tthis.geojson = geojson;\n\t\tthis.geometries = geometries;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(`'distance' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n\t\tif (isValue(args[1])) {\n\t\t\tconst geojson = args[1];\n\t\t\tif (geojson.type === \"FeatureCollection\") return new Distance(geojson, geojson.features.map((feature) => toSimpleGeometry(feature.geometry)).flat());\n\t\t\telse if (geojson.type === \"Feature\") return new Distance(geojson, toSimpleGeometry(geojson.geometry));\n\t\t\telse if (\"type\" in geojson && \"coordinates\" in geojson) return new Distance(geojson, toSimpleGeometry(geojson));\n\t\t}\n\t\treturn context.error(\"'distance' expression requires valid geojson object that contains polygon geometry type.\");\n\t}\n\tevaluate(ctx) {\n\t\tif (ctx.geometry() != null && ctx.canonicalID() != null) {\n\t\t\tif (ctx.geometryType() === \"Point\") return pointToGeometryDistance(ctx, this.geometries);\n\t\t\telse if (ctx.geometryType() === \"LineString\") return lineStringToGeometryDistance(ctx, this.geometries);\n\t\t\telse if (ctx.geometryType() === \"Polygon\") return polygonToGeometryDistance(ctx, this.geometries);\n\t\t}\n\t\treturn NaN;\n\t}\n\teachChild() {}\n\toutputDefined() {\n\t\treturn true;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/semiliteral.ts\nvar Semiliteral = class Semiliteral {\n\tconstructor(arr) {\n\t\tlet elementType = null;\n\t\tfor (const expr of arr) if (!elementType) elementType = expr.type;\n\t\telse if (elementType === expr.type) continue;\n\t\telse {\n\t\t\telementType = ValueType;\n\t\t\tbreak;\n\t\t}\n\t\tthis.type = array(elementType ?? ValueType, arr.length);\n\t\tthis.arr = arr;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(`'semiliteral' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n\t\tif (!isValue(args[1])) return context.error(`invalid value of type \"${typeof args[1]}\"`);\n\t\tconst value = args[1];\n\t\tconst type = typeOf(value);\n\t\tif (type.kind === \"array\") {\n\t\t\tconst parsed = value.map((item) => context.parse(item, null, ValueType));\n\t\t\treturn new Semiliteral(parsed);\n\t\t} else return new Literal(type, value);\n\t}\n\tevaluate(ctx) {\n\t\treturn this.arr.map((arg) => arg.evaluate(ctx));\n\t}\n\teachChild(fn) {\n\t\tthis.arr.forEach(fn);\n\t}\n\toutputDefined() {\n\t\treturn this.arr.every((arg) => arg.outputDefined());\n\t}\n};\n//#endregion\n//#region src/expression/definitions/global_state.ts\nvar GlobalState = class GlobalState {\n\tconstructor(key) {\n\t\tthis.key = key;\n\t\tthis.type = ValueType;\n\t}\n\tstatic parse(args, context) {\n\t\tif (args.length !== 2) return context.error(`Expected 1 argument, but found ${args.length - 1} instead.`);\n\t\tconst key = args[1];\n\t\tif (key === void 0 || key === null) return context.error(\"Global state property must be defined.\");\n\t\tif (typeof key !== \"string\") return context.error(`Global state property must be string, but found ${typeof args[1]} instead.`);\n\t\treturn new GlobalState(key);\n\t}\n\tevaluate(ctx) {\n\t\tconst globalState = ctx.globals?.globalState;\n\t\tif (!globalState || Object.keys(globalState).length === 0) return null;\n\t\treturn getOwn(globalState, this.key) ?? null;\n\t}\n\teachChild() {}\n\toutputDefined() {\n\t\treturn false;\n\t}\n};\n//#endregion\n//#region src/expression/definitions/index.ts\nconst expressions = {\n\t\"==\": Equals,\n\t\"!=\": NotEquals,\n\t\">\": GreaterThan,\n\t\"<\": LessThan,\n\t\">=\": GreaterThanOrEqual,\n\t\"<=\": LessThanOrEqual,\n\tarray: Assertion,\n\tat: At,\n\tboolean: Assertion,\n\tcase: Case,\n\tcoalesce: Coalesce,\n\tcollator: CollatorExpression,\n\tformat: FormatExpression,\n\timage: ImageExpression,\n\tin: In,\n\t\"index-of\": IndexOf,\n\tinterpolate: Interpolate,\n\t\"interpolate-hcl\": Interpolate,\n\t\"interpolate-lab\": Interpolate,\n\tlength: Length,\n\tlet: Let,\n\tliteral: Literal,\n\tmatch: Match,\n\tnumber: Assertion,\n\t\"number-format\": NumberFormat,\n\tobject: Assertion,\n\tsemiliteral: Semiliteral,\n\tslice: Slice,\n\tstep: Step,\n\tstring: Assertion,\n\t\"to-boolean\": Coercion,\n\t\"to-color\": Coercion,\n\t\"to-number\": Coercion,\n\t\"to-string\": Coercion,\n\tvar: Var,\n\twithin: Within,\n\tdistance: Distance,\n\t\"global-state\": GlobalState\n};\n//#endregion\n//#region src/expression/compound_expression.ts\nvar CompoundExpression = class CompoundExpression {\n\tconstructor(name, type, evaluate, args, key) {\n\t\tthis.name = name;\n\t\tthis.type = type;\n\t\tthis._evaluate = evaluate;\n\t\tthis.args = args;\n\t\tthis.key = key;\n\t}\n\tevaluate(ctx) {\n\t\treturn this._evaluate(ctx, this.args, this.key);\n\t}\n\teachChild(fn) {\n\t\tthis.args.forEach(fn);\n\t}\n\toutputDefined() {\n\t\treturn false;\n\t}\n\tstatic parse(args, context) {\n\t\tconst op = args[0];\n\t\tconst definition = CompoundExpression.definitions[op];\n\t\tif (!definition) return context.error(`Unknown expression \"${op}\". If you wanted a literal array, use [\"literal\", [...]].`, 0);\n\t\tconst type = Array.isArray(definition) ? definition[0] : definition.type;\n\t\tconst availableOverloads = Array.isArray(definition) ? [[definition[1], definition[2]]] : definition.overloads;\n\t\tconst overloads = availableOverloads.filter(([signature]) => !Array.isArray(signature) || signature.length === args.length - 1);\n\t\tlet signatureContext = null;\n\t\tfor (const [params, evaluate] of overloads) {\n\t\t\tsignatureContext = new ParsingContext(context.registry, isExpressionConstant, context.path, null, context.scope);\n\t\t\tconst parsedArgs = [];\n\t\t\tlet argParseFailed = false;\n\t\t\tfor (let i = 1; i < args.length; i++) {\n\t\t\t\tconst arg = args[i];\n\t\t\t\tconst expectedType = Array.isArray(params) ? params[i - 1] : params.type;\n\t\t\t\tconst parsed = signatureContext.parse(arg, 1 + parsedArgs.length, expectedType);\n\t\t\t\tif (!parsed) {\n\t\t\t\t\targParseFailed = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tparsedArgs.push(parsed);\n\t\t\t}\n\t\t\tif (argParseFailed) continue;\n\t\t\tif (Array.isArray(params)) {\n\t\t\t\tif (params.length !== parsedArgs.length) {\n\t\t\t\t\tsignatureContext.error(`Expected ${params.length} arguments, but found ${parsedArgs.length} instead.`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (let i = 0; i < parsedArgs.length; i++) {\n\t\t\t\tconst expected = Array.isArray(params) ? params[i] : params.type;\n\t\t\t\tconst arg = parsedArgs[i];\n\t\t\t\tsignatureContext.concat(i + 1).checkSubtype(expected, arg.type);\n\t\t\t}\n\t\t\tif (signatureContext.errors.length === 0) return new CompoundExpression(op, type, evaluate, parsedArgs, context.key);\n\t\t}\n\t\tif (overloads.length === 1) context.errors.push(...signatureContext.errors);\n\t\telse {\n\t\t\tconst signatures = (overloads.length ? overloads : availableOverloads).map(([params]) => stringifySignature(params)).join(\" | \");\n\t\t\tconst actualTypes = [];\n\t\t\tfor (let i = 1; i < args.length; i++) {\n\t\t\t\tconst parsed = context.parse(args[i], 1 + actualTypes.length);\n\t\t\t\tif (!parsed) return null;\n\t\t\t\tactualTypes.push(typeToString(parsed.type));\n\t\t\t}\n\t\t\tcontext.error(`Expected arguments of type ${signatures}, but found (${actualTypes.join(\", \")}) instead.`);\n\t\t}\n\t\treturn null;\n\t}\n\tstatic register(registry, definitions) {\n\t\tCompoundExpression.definitions = definitions;\n\t\tfor (const name in definitions) registry[name] = CompoundExpression;\n\t}\n};\nfunction rgba(ctx, [r, g, b, a], key) {\n\tr = r.evaluate(ctx);\n\tg = g.evaluate(ctx);\n\tb = b.evaluate(ctx);\n\tconst alpha = a ? a.evaluate(ctx) : 1;\n\tconst error = validateRGBA(r, g, b, alpha);\n\tif (error) throw new RuntimeError(error, key);\n\treturn new Color(r / 255, g / 255, b / 255, alpha, false);\n}\nfunction has(key, obj) {\n\treturn key in obj && obj[key] !== void 0;\n}\nfunction get(key, obj) {\n\tconst v = obj[key];\n\treturn typeof v === \"undefined\" ? null : v;\n}\nfunction binarySearch(v, a, i, j) {\n\twhile (i <= j) {\n\t\tconst m = i + j >> 1;\n\t\tif (a[m] === v) return true;\n\t\tif (a[m] > v) j = m - 1;\n\t\telse i = m + 1;\n\t}\n\treturn false;\n}\nfunction varargs(type) {\n\treturn { type };\n}\nCompoundExpression.register(expressions, {\n\terror: [\n\t\tErrorType,\n\t\t[StringType],\n\t\t(ctx, [v], key) => {\n\t\t\tthrow new RuntimeError(v.evaluate(ctx), key);\n\t\t}\n\t],\n\ttypeof: [\n\t\tStringType,\n\t\t[ValueType],\n\t\t(ctx, [v]) => typeToString(typeOf(v.evaluate(ctx)))\n\t],\n\t\"to-rgba\": [\n\t\tarray(NumberType, 4),\n\t\t[ColorType],\n\t\t(ctx, [v]) => {\n\t\t\tconst [r, g, b, a] = v.evaluate(ctx).rgb;\n\t\t\treturn [\n\t\t\t\tr * 255,\n\t\t\t\tg * 255,\n\t\t\t\tb * 255,\n\t\t\t\ta\n\t\t\t];\n\t\t}\n\t],\n\trgb: [\n\t\tColorType,\n\t\t[\n\t\t\tNumberType,\n\t\t\tNumberType,\n\t\t\tNumberType\n\t\t],\n\t\trgba\n\t],\n\trgba: [\n\t\tColorType,\n\t\t[\n\t\t\tNumberType,\n\t\t\tNumberType,\n\t\t\tNumberType,\n\t\t\tNumberType\n\t\t],\n\t\trgba\n\t],\n\thas: {\n\t\ttype: BooleanType,\n\t\toverloads: [[[StringType], (ctx, [key]) => has(key.evaluate(ctx), ctx.properties())], [[StringType, ObjectType], (ctx, [key, obj]) => has(key.evaluate(ctx), obj.evaluate(ctx))]]\n\t},\n\tget: {\n\t\ttype: ValueType,\n\t\toverloads: [[[StringType], (ctx, [key]) => get(key.evaluate(ctx), ctx.properties())], [[StringType, ObjectType], (ctx, [key, obj]) => get(key.evaluate(ctx), obj.evaluate(ctx))]]\n\t},\n\t\"feature-state\": [\n\t\tValueType,\n\t\t[StringType],\n\t\t(ctx, [key]) => get(key.evaluate(ctx), ctx.featureState || {})\n\t],\n\tproperties: [\n\t\tObjectType,\n\t\t[],\n\t\t(ctx) => ctx.properties()\n\t],\n\t\"geometry-type\": [\n\t\tStringType,\n\t\t[],\n\t\t(ctx) => ctx.geometryType()\n\t],\n\tid: [\n\t\tValueType,\n\t\t[],\n\t\t(ctx) => ctx.id()\n\t],\n\tzoom: [\n\t\tNumberType,\n\t\t[],\n\t\t(ctx) => ctx.globals.zoom\n\t],\n\t\"heatmap-density\": [\n\t\tNumberType,\n\t\t[],\n\t\t(ctx) => ctx.globals.heatmapDensity || 0\n\t],\n\televation: [\n\t\tNumberType,\n\t\t[],\n\t\t(ctx) => ctx.globals.elevation || 0\n\t],\n\t\"line-progress\": [\n\t\tNumberType,\n\t\t[],\n\t\t(ctx) => ctx.globals.lineProgress || 0\n\t],\n\taccumulated: [\n\t\tValueType,\n\t\t[],\n\t\t(ctx) => ctx.globals.accumulated === void 0 ? null : ctx.globals.accumulated\n\t],\n\t\"+\": [\n\t\tNumberType,\n\t\tvarargs(NumberType),\n\t\t(ctx, args) => {\n\t\t\tlet result = 0;\n\t\t\tfor (const arg of args) result += arg.evaluate(ctx);\n\t\t\treturn result;\n\t\t}\n\t],\n\t\"*\": [\n\t\tNumberType,\n\t\tvarargs(NumberType),\n\t\t(ctx, args) => {\n\t\t\tlet result = 1;\n\t\t\tfor (const arg of args) result *= arg.evaluate(ctx);\n\t\t\treturn result;\n\t\t}\n\t],\n\t\"-\": {\n\t\ttype: NumberType,\n\t\toverloads: [[[NumberType, NumberType], (ctx, [a, b]) => a.evaluate(ctx) - b.evaluate(ctx)], [[NumberType], (ctx, [a]) => -a.evaluate(ctx)]]\n\t},\n\t\"/\": [\n\t\tNumberType,\n\t\t[NumberType, NumberType],\n\t\t(ctx, [a, b]) => a.evaluate(ctx) / b.evaluate(ctx)\n\t],\n\t\"%\": [\n\t\tNumberType,\n\t\t[NumberType, NumberType],\n\t\t(ctx, [a, b]) => a.evaluate(ctx) % b.evaluate(ctx)\n\t],\n\tln2: [\n\t\tNumberType,\n\t\t[],\n\t\t() => Math.LN2\n\t],\n\tpi: [\n\t\tNumberType,\n\t\t[],\n\t\t() => Math.PI\n\t],\n\te: [\n\t\tNumberType,\n\t\t[],\n\t\t() => Math.E\n\t],\n\t\"^\": [\n\t\tNumberType,\n\t\t[NumberType, NumberType],\n\t\t(ctx, [b, e]) => Math.pow(b.evaluate(ctx), e.evaluate(ctx))\n\t],\n\tsqrt: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [x]) => Math.sqrt(x.evaluate(ctx))\n\t],\n\tlog10: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN10\n\t],\n\tln: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.log(n.evaluate(ctx))\n\t],\n\tlog2: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN2\n\t],\n\tsin: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.sin(n.evaluate(ctx))\n\t],\n\tcos: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.cos(n.evaluate(ctx))\n\t],\n\ttan: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.tan(n.evaluate(ctx))\n\t],\n\tasin: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.asin(n.evaluate(ctx))\n\t],\n\tacos: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.acos(n.evaluate(ctx))\n\t],\n\tatan: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.atan(n.evaluate(ctx))\n\t],\n\tmin: [\n\t\tNumberType,\n\t\tvarargs(NumberType),\n\t\t(ctx, args) => Math.min(...args.map((arg) => arg.evaluate(ctx)))\n\t],\n\tmax: [\n\t\tNumberType,\n\t\tvarargs(NumberType),\n\t\t(ctx, args) => Math.max(...args.map((arg) => arg.evaluate(ctx)))\n\t],\n\tabs: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.abs(n.evaluate(ctx))\n\t],\n\tround: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => {\n\t\t\tconst v = n.evaluate(ctx);\n\t\t\treturn v < 0 ? -Math.round(-v) : Math.round(v);\n\t\t}\n\t],\n\tfloor: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.floor(n.evaluate(ctx))\n\t],\n\tceil: [\n\t\tNumberType,\n\t\t[NumberType],\n\t\t(ctx, [n]) => Math.ceil(n.evaluate(ctx))\n\t],\n\t\"filter-==\": [\n\t\tBooleanType,\n\t\t[StringType, ValueType],\n\t\t(ctx, [k, v]) => ctx.properties()[k.value] === v.value\n\t],\n\t\"filter-id-==\": [\n\t\tBooleanType,\n\t\t[ValueType],\n\t\t(ctx, [v]) => ctx.id() === v.value\n\t],\n\t\"filter-type-==\": [\n\t\tBooleanType,\n\t\t[StringType],\n\t\t(ctx, [v]) => ctx.geometryType() === v.value\n\t],\n\t\"filter-<\": [\n\t\tBooleanType,\n\t\t[StringType, ValueType],\n\t\t(ctx, [k, v]) => {\n\t\t\tconst a = ctx.properties()[k.value];\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a < b;\n\t\t}\n\t],\n\t\"filter-id-<\": [\n\t\tBooleanType,\n\t\t[ValueType],\n\t\t(ctx, [v]) => {\n\t\t\tconst a = ctx.id();\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a < b;\n\t\t}\n\t],\n\t\"filter->\": [\n\t\tBooleanType,\n\t\t[StringType, ValueType],\n\t\t(ctx, [k, v]) => {\n\t\t\tconst a = ctx.properties()[k.value];\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a > b;\n\t\t}\n\t],\n\t\"filter-id->\": [\n\t\tBooleanType,\n\t\t[ValueType],\n\t\t(ctx, [v]) => {\n\t\t\tconst a = ctx.id();\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a > b;\n\t\t}\n\t],\n\t\"filter-<=\": [\n\t\tBooleanType,\n\t\t[StringType, ValueType],\n\t\t(ctx, [k, v]) => {\n\t\t\tconst a = ctx.properties()[k.value];\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a <= b;\n\t\t}\n\t],\n\t\"filter-id-<=\": [\n\t\tBooleanType,\n\t\t[ValueType],\n\t\t(ctx, [v]) => {\n\t\t\tconst a = ctx.id();\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a <= b;\n\t\t}\n\t],\n\t\"filter->=\": [\n\t\tBooleanType,\n\t\t[StringType, ValueType],\n\t\t(ctx, [k, v]) => {\n\t\t\tconst a = ctx.properties()[k.value];\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a >= b;\n\t\t}\n\t],\n\t\"filter-id->=\": [\n\t\tBooleanType,\n\t\t[ValueType],\n\t\t(ctx, [v]) => {\n\t\t\tconst a = ctx.id();\n\t\t\tconst b = v.value;\n\t\t\treturn typeof a === typeof b && a >= b;\n\t\t}\n\t],\n\t\"filter-has\": [\n\t\tBooleanType,\n\t\t[ValueType],\n\t\t(ctx, [k]) => {\n\t\t\tconst key = k.value;\n\t\t\tconst props = ctx.properties();\n\t\t\treturn key in props && props[key] !== void 0;\n\t\t}\n\t],\n\t\"filter-has-id\": [\n\t\tBooleanType,\n\t\t[],\n\t\t(ctx) => ctx.id() !== null && ctx.id() !== void 0\n\t],\n\t\"filter-type-in\": [\n\t\tBooleanType,\n\t\t[array(StringType)],\n\t\t(ctx, [v]) => v.value.indexOf(ctx.geometryType()) >= 0\n\t],\n\t\"filter-id-in\": [\n\t\tBooleanType,\n\t\t[array(ValueType)],\n\t\t(ctx, [v]) => v.value.indexOf(ctx.id()) >= 0\n\t],\n\t\"filter-in-small\": [\n\t\tBooleanType,\n\t\t[StringType, array(ValueType)],\n\t\t(ctx, [k, v]) => v.value.indexOf(ctx.properties()[k.value]) >= 0\n\t],\n\t\"filter-in-large\": [\n\t\tBooleanType,\n\t\t[StringType, array(ValueType)],\n\t\t(ctx, [k, v]) => binarySearch(ctx.properties()[k.value], v.value, 0, v.value.length - 1)\n\t],\n\tall: {\n\t\ttype: BooleanType,\n\t\toverloads: [[[BooleanType, BooleanType], (ctx, [a, b]) => a.evaluate(ctx) && b.evaluate(ctx)], [varargs(BooleanType), (ctx, args) => {\n\t\t\tfor (const arg of args) if (!arg.evaluate(ctx)) return false;\n\t\t\treturn true;\n\t\t}]]\n\t},\n\tany: {\n\t\ttype: BooleanType,\n\t\toverloads: [[[BooleanType, BooleanType], (ctx, [a, b]) => a.evaluate(ctx) || b.evaluate(ctx)], [varargs(BooleanType), (ctx, args) => {\n\t\t\tfor (const arg of args) if (arg.evaluate(ctx)) return true;\n\t\t\treturn false;\n\t\t}]]\n\t},\n\t\"!\": [\n\t\tBooleanType,\n\t\t[BooleanType],\n\t\t(ctx, [b]) => !b.evaluate(ctx)\n\t],\n\t\"is-supported-script\": [\n\t\tBooleanType,\n\t\t[StringType],\n\t\t(ctx, [s]) => {\n\t\t\tconst isSupportedScript = ctx.globals && ctx.globals.isSupportedScript;\n\t\t\tif (isSupportedScript) return isSupportedScript(s.evaluate(ctx));\n\t\t\treturn true;\n\t\t}\n\t],\n\tupcase: [\n\t\tStringType,\n\t\t[StringType],\n\t\t(ctx, [s]) => s.evaluate(ctx).toUpperCase()\n\t],\n\tdowncase: [\n\t\tStringType,\n\t\t[StringType],\n\t\t(ctx, [s]) => s.evaluate(ctx).toLowerCase()\n\t],\n\tconcat: [\n\t\tStringType,\n\t\tvarargs(ValueType),\n\t\t(ctx, args) => args.map((arg) => valueToString(arg.evaluate(ctx))).join(\"\")\n\t],\n\tsplit: [\n\t\tarray(StringType),\n\t\t[StringType, StringType],\n\t\t(ctx, [s, delim]) => s.evaluate(ctx).split(delim.evaluate(ctx))\n\t],\n\tjoin: [\n\t\tStringType,\n\t\t[array(StringType), StringType],\n\t\t(ctx, [arr, delim]) => arr.evaluate(ctx).join(delim.evaluate(ctx))\n\t],\n\t\"resolved-locale\": [\n\t\tStringType,\n\t\t[CollatorType],\n\t\t(ctx, [collator]) => collator.evaluate(ctx).resolvedLocale()\n\t]\n});\nfunction stringifySignature(signature) {\n\tif (Array.isArray(signature)) return `(${signature.map(typeToString).join(\", \")})`;\n\telse return `(${typeToString(signature.type)}...)`;\n}\nfunction isExpressionConstant(expression) {\n\tif (expression instanceof Var) return isExpressionConstant(expression.boundExpression);\n\telse if (expression instanceof CompoundExpression && expression.name === \"error\") return false;\n\telse if (expression instanceof CollatorExpression) return false;\n\telse if (expression instanceof Within) return false;\n\telse if (expression instanceof Distance) return false;\n\telse if (expression instanceof GlobalState) return false;\n\tconst isTypeAnnotation = expression instanceof Coercion || expression instanceof Assertion;\n\tlet childrenConstant = true;\n\texpression.eachChild((child) => {\n\t\tif (isTypeAnnotation) childrenConstant = childrenConstant && isExpressionConstant(child);\n\t\telse childrenConstant = childrenConstant && child instanceof Literal;\n\t});\n\tif (!childrenConstant) return false;\n\treturn isFeatureConstant(expression) && isGlobalPropertyConstant(expression, [\n\t\t\"zoom\",\n\t\t\"heatmap-density\",\n\t\t\"elevation\",\n\t\t\"line-progress\",\n\t\t\"accumulated\",\n\t\t\"is-supported-script\"\n\t]);\n}\nfunction isFeatureConstant(e) {\n\tif (e instanceof CompoundExpression) {\n\t\tif (e.name === \"get\" && e.args.length === 1) return false;\n\t\telse if (e.name === \"feature-state\") return false;\n\t\telse if (e.name === \"has\" && e.args.length === 1) return false;\n\t\telse if (e.name === \"properties\" || e.name === \"geometry-type\" || e.name === \"id\") return false;\n\t\telse if (/^filter-/.test(e.name)) return false;\n\t}\n\tif (e instanceof Within) return false;\n\tif (e instanceof Distance) return false;\n\tlet result = true;\n\te.eachChild((arg) => {\n\t\tif (result && !isFeatureConstant(arg)) result = false;\n\t});\n\treturn result;\n}\nfunction isStateConstant(e) {\n\tif (e instanceof CompoundExpression) {\n\t\tif (e.name === \"feature-state\") return false;\n\t}\n\tlet result = true;\n\te.eachChild((arg) => {\n\t\tif (result && !isStateConstant(arg)) result = false;\n\t});\n\treturn result;\n}\nfunction isGlobalPropertyConstant(e, properties) {\n\tif (e instanceof CompoundExpression && properties.indexOf(e.name) >= 0) return false;\n\tlet result = true;\n\te.eachChild((arg) => {\n\t\tif (result && !isGlobalPropertyConstant(arg, properties)) result = false;\n\t});\n\treturn result;\n}\n//#endregion\n//#region src/util/result.ts\nfunction success(value) {\n\treturn {\n\t\tresult: \"success\",\n\t\tvalue\n\t};\n}\nfunction error(value) {\n\treturn {\n\t\tresult: \"error\",\n\t\tvalue\n\t};\n}\n//#endregion\n//#region src/util/properties.ts\nfunction supportsPropertyExpression(spec) {\n\treturn spec[\"property-type\"] === \"data-driven\" || spec[\"property-type\"] === \"cross-faded-data-driven\";\n}\nfunction supportsZoomExpression(spec) {\n\treturn !!spec.expression && spec.expression.parameters.indexOf(\"zoom\") > -1;\n}\nfunction supportsInterpolation(spec) {\n\treturn !!spec.expression && spec.expression.interpolated;\n}\n//#endregion\n//#region src/util/extend.ts\nfunction extendBy(output, ...inputs) {\n\tfor (const input of inputs) for (const k in input) output[k] = input[k];\n\treturn output;\n}\n//#endregion\n//#region src/util/get_type.ts\nfunction getType(val) {\n\tif (val instanceof Number) return \"number\";\n\telse if (val instanceof String) return \"string\";\n\telse if (val instanceof Boolean) return \"boolean\";\n\telse if (Array.isArray(val)) return \"array\";\n\telse if (val === null) return \"null\";\n\telse return typeof val;\n}\n//#endregion\n//#region src/function/index.ts\nfunction isFunction(value) {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value) && typeOf(value) === ObjectType;\n}\nfunction identityFunction(x) {\n\treturn x;\n}\nfunction getParseFunction(propertySpec) {\n\tswitch (propertySpec.type) {\n\t\tcase \"color\": return Color.parse;\n\t\tcase \"padding\": return Padding.parse;\n\t\tcase \"numberArray\": return NumberArray.parse;\n\t\tcase \"colorArray\": return ColorArray.parse;\n\t\tdefault: return null;\n\t}\n}\nfunction getInnerFunction(type) {\n\tswitch (type) {\n\t\tcase \"exponential\": return evaluateExponentialFunction;\n\t\tcase \"interval\": return evaluateIntervalFunction;\n\t\tcase \"categorical\": return evaluateCategoricalFunction;\n\t\tcase \"identity\": return evaluateIdentityFunction;\n\t\tdefault: throw new Error(`Unknown function type \"${type}\"`);\n\t}\n}\nfunction createFunction(parameters, propertySpec) {\n\tconst zoomAndFeatureDependent = parameters.stops && typeof parameters.stops[0][0] === \"object\";\n\tconst featureDependent = zoomAndFeatureDependent || parameters.property !== void 0;\n\tconst zoomDependent = zoomAndFeatureDependent || !featureDependent;\n\tconst type = parameters.type || (supportsInterpolation(propertySpec) ? \"exponential\" : \"interval\");\n\tconst parseFn = getParseFunction(propertySpec);\n\tif (parseFn) {\n\t\tparameters = extendBy({}, parameters);\n\t\tif (parameters.stops) parameters.stops = parameters.stops.map((stop) => {\n\t\t\treturn [stop[0], parseFn(stop[1])];\n\t\t});\n\t\tif (parameters.default) parameters.default = parseFn(parameters.default);\n\t\telse parameters.default = parseFn(propertySpec.default);\n\t}\n\tif (parameters.colorSpace && !isSupportedInterpolationColorSpace(parameters.colorSpace)) throw new Error(`Unknown color space: \"${parameters.colorSpace}\"`);\n\tconst innerFun = getInnerFunction(type);\n\tlet hashedStops;\n\tlet categoricalKeyType;\n\tif (type === \"categorical\") {\n\t\thashedStops = Object.create(null);\n\t\tfor (const stop of parameters.stops) hashedStops[stop[0]] = stop[1];\n\t\tcategoricalKeyType = typeof parameters.stops[0][0];\n\t}\n\tif (zoomAndFeatureDependent) {\n\t\tconst featureFunctions = {};\n\t\tconst zoomStops = [];\n\t\tfor (let s = 0; s < parameters.stops.length; s++) {\n\t\t\tconst stop = parameters.stops[s];\n\t\t\tconst zoom = stop[0].zoom;\n\t\t\tif (featureFunctions[zoom] === void 0) {\n\t\t\t\tfeatureFunctions[zoom] = {\n\t\t\t\t\tzoom,\n\t\t\t\t\ttype: parameters.type,\n\t\t\t\t\tproperty: parameters.property,\n\t\t\t\t\tdefault: parameters.default,\n\t\t\t\t\tstops: []\n\t\t\t\t};\n\t\t\t\tzoomStops.push(zoom);\n\t\t\t}\n\t\t\tfeatureFunctions[zoom].stops.push([stop[0].value, stop[1]]);\n\t\t}\n\t\tconst featureFunctionStops = [];\n\t\tfor (const z of zoomStops) featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z], propertySpec)]);\n\t\tconst interpolationType = { name: \"linear\" };\n\t\treturn {\n\t\t\tkind: \"composite\",\n\t\t\tinterpolationType,\n\t\t\tinterpolationFactor: Interpolate.interpolationFactor.bind(void 0, interpolationType),\n\t\t\tzoomStops: featureFunctionStops.map((s) => s[0]),\n\t\t\tevaluate({ zoom }, properties) {\n\t\t\t\treturn evaluateExponentialFunction({\n\t\t\t\t\tstops: featureFunctionStops,\n\t\t\t\t\tbase: parameters.base\n\t\t\t\t}, propertySpec, zoom).evaluate(zoom, properties);\n\t\t\t}\n\t\t};\n\t} else if (zoomDependent) {\n\t\tconst interpolationType = type === \"exponential\" ? {\n\t\t\tname: \"exponential\",\n\t\t\tbase: parameters.base !== void 0 ? parameters.base : 1\n\t\t} : null;\n\t\treturn {\n\t\t\tkind: \"camera\",\n\t\t\tinterpolationType,\n\t\t\tinterpolationFactor: Interpolate.interpolationFactor.bind(void 0, interpolationType),\n\t\t\tzoomStops: parameters.stops.map((s) => s[0]),\n\t\t\tevaluate: ({ zoom }) => innerFun(parameters, propertySpec, zoom, hashedStops, categoricalKeyType)\n\t\t};\n\t} else return {\n\t\tkind: \"source\",\n\t\tevaluate(_, feature) {\n\t\t\tconst value = feature && feature.properties ? feature.properties[parameters.property] : void 0;\n\t\t\tif (value === void 0) return coalesce$1(parameters.default, propertySpec.default);\n\t\t\treturn innerFun(parameters, propertySpec, value, hashedStops, categoricalKeyType);\n\t\t}\n\t};\n}\nfunction coalesce$1(a, b, c) {\n\tif (a !== void 0) return a;\n\tif (b !== void 0) return b;\n\tif (c !== void 0) return c;\n}\nfunction evaluateCategoricalFunction(parameters, propertySpec, input, hashedStops, keyType) {\n\treturn coalesce$1(typeof input === keyType ? hashedStops[input] : void 0, parameters.default, propertySpec.default);\n}\nfunction evaluateIntervalFunction(parameters, propertySpec, input) {\n\tif (getType(input) !== \"number\") return coalesce$1(parameters.default, propertySpec.default);\n\tconst n = parameters.stops.length;\n\tif (n === 1) return parameters.stops[0][1];\n\tif (input <= parameters.stops[0][0]) return parameters.stops[0][1];\n\tif (input >= parameters.stops[n - 1][0]) return parameters.stops[n - 1][1];\n\tconst index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input, \"\");\n\treturn parameters.stops[index][1];\n}\nfunction evaluateExponentialFunction(parameters, propertySpec, input) {\n\tconst base = parameters.base !== void 0 ? parameters.base : 1;\n\tif (getType(input) !== \"number\") return coalesce$1(parameters.default, propertySpec.default);\n\tconst n = parameters.stops.length;\n\tif (n === 1) return parameters.stops[0][1];\n\tif (input <= parameters.stops[0][0]) return parameters.stops[0][1];\n\tif (input >= parameters.stops[n - 1][0]) return parameters.stops[n - 1][1];\n\tconst index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input, \"\");\n\tconst t = interpolationFactor(input, base, parameters.stops[index][0], parameters.stops[index + 1][0]);\n\tconst outputLower = parameters.stops[index][1];\n\tconst outputUpper = parameters.stops[index + 1][1];\n\tconst interp = interpolateFactory[propertySpec.type] || identityFunction;\n\tif (typeof outputLower.evaluate === \"function\") return { evaluate(...args) {\n\t\tconst evaluatedLower = outputLower.evaluate.apply(void 0, args);\n\t\tconst evaluatedUpper = outputUpper.evaluate.apply(void 0, args);\n\t\tif (evaluatedLower === void 0 || evaluatedUpper === void 0) return;\n\t\treturn interp(evaluatedLower, evaluatedUpper, t, parameters.colorSpace);\n\t} };\n\treturn interp(outputLower, outputUpper, t, parameters.colorSpace);\n}\nfunction evaluateIdentityFunction(parameters, propertySpec, input) {\n\tswitch (propertySpec.type) {\n\t\tcase \"color\":\n\t\t\tinput = Color.parse(input);\n\t\t\tbreak;\n\t\tcase \"formatted\":\n\t\t\tinput = Formatted.fromString(input.toString());\n\t\t\tbreak;\n\t\tcase \"resolvedImage\":\n\t\t\tinput = ResolvedImage.fromString(input.toString());\n\t\t\tbreak;\n\t\tcase \"padding\":\n\t\t\tinput = Padding.parse(input);\n\t\t\tbreak;\n\t\tcase \"colorArray\":\n\t\t\tinput = ColorArray.parse(input);\n\t\t\tbreak;\n\t\tcase \"numberArray\":\n\t\t\tinput = NumberArray.parse(input);\n\t\t\tbreak;\n\t\tdefault: if (getType(input) !== propertySpec.type && (propertySpec.type !== \"enum\" || !propertySpec.values[input])) input = void 0;\n\t}\n\treturn coalesce$1(input, parameters.default, propertySpec.default);\n}\n/**\n* Returns a ratio that can be used to interpolate between exponential function\n* stops.\n*\n* How it works:\n* Two consecutive stop values define a (scaled and shifted) exponential\n* function `f(x) = a * base^x + b`, where `base` is the user-specified base,\n* and `a` and `b` are constants affording sufficient degrees of freedom to fit\n* the function to the given stops.\n*\n* Here's a bit of algebra that lets us compute `f(x)` directly from the stop\n* values without explicitly solving for `a` and `b`:\n*\n* First stop value: `f(x0) = y0 = a * base^x0 + b`\n* Second stop value: `f(x1) = y1 = a * base^x1 + b`\n* => `y1 - y0 = a(base^x1 - base^x0)`\n* => `a = (y1 - y0)/(base^x1 - base^x0)`\n*\n* Desired value: `f(x) = y = a * base^x + b`\n* => `f(x) = y0 + a * (base^x - base^x0)`\n*\n* From the above, we can replace the `a` in `a * (base^x - base^x0)` and do a\n* little algebra:\n* ```\n* a * (base^x - base^x0) = (y1 - y0)/(base^x1 - base^x0) * (base^x - base^x0)\n* = (y1 - y0) * (base^x - base^x0) / (base^x1 - base^x0)\n* ```\n*\n* If we let `(base^x - base^x0) / (base^x1 base^x0)`, then we have\n* `f(x) = y0 + (y1 - y0) * ratio`. In other words, `ratio` may be treated as\n* an interpolation factor between the two stops' output values.\n*\n* (Note: a slightly different form for `ratio`,\n* `(base^(x-x0) - 1) / (base^(x1-x0) - 1) `, is equivalent, but requires fewer\n* expensive `Math.pow()` operations.)\n*\n* @private\n*/\nfunction interpolationFactor(input, base, lowerValue, upperValue) {\n\tconst difference = upperValue - lowerValue;\n\tconst progress = input - lowerValue;\n\tif (difference === 0) return 0;\n\telse if (base === 1) return progress / difference;\n\telse return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);\n}\n//#endregion\n//#region src/expression/index.ts\nvar StyleExpression = class {\n\tconstructor(expression, rootKey, propertySpec, globalState) {\n\t\tthis.expression = expression;\n\t\tthis._warningHistory = {};\n\t\tthis._evaluator = new EvaluationContext();\n\t\tthis._defaultValue = propertySpec ? getDefaultValue(propertySpec) : null;\n\t\tthis._enumValues = propertySpec && propertySpec.type === \"enum\" ? propertySpec.values : null;\n\t\tthis._globalState = globalState;\n\t\tthis._rootKey = rootKey;\n\t}\n\tevaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) {\n\t\tif (this._globalState) globals = addGlobalState(globals, this._globalState);\n\t\tthis._evaluator.globals = globals;\n\t\tthis._evaluator.feature = feature;\n\t\tthis._evaluator.featureState = featureState;\n\t\tthis._evaluator.canonical = canonical;\n\t\tthis._evaluator.availableImages = availableImages || null;\n\t\tthis._evaluator.formattedSection = formattedSection;\n\t\treturn this.expression.evaluate(this._evaluator);\n\t}\n\tevaluate(globals, feature, featureState, canonical, availableImages, formattedSection) {\n\t\tif (this._globalState) globals = addGlobalState(globals, this._globalState);\n\t\tthis._evaluator.globals = globals;\n\t\tthis._evaluator.feature = feature || null;\n\t\tthis._evaluator.featureState = featureState || null;\n\t\tthis._evaluator.canonical = canonical;\n\t\tthis._evaluator.availableImages = availableImages || null;\n\t\tthis._evaluator.formattedSection = formattedSection || null;\n\t\ttry {\n\t\t\tconst val = this.expression.evaluate(this._evaluator);\n\t\t\tif (val === null || val === void 0 || typeof val === \"number\" && val !== val) return this._defaultValue;\n\t\t\tif (this._enumValues && !(val in this._enumValues)) throw new RuntimeError(`Expected value to be one of ${Object.keys(this._enumValues).map((v) => JSON.stringify(v)).join(\", \")}, but found ${JSON.stringify(val)} instead.`, \"\");\n\t\t\treturn val;\n\t\t} catch (e) {\n\t\t\tconst path = e instanceof RuntimeError ? e.path : \"\";\n\t\t\tconst dedupKey = `${path}|${e.message}`;\n\t\t\tif (!this._warningHistory[dedupKey]) {\n\t\t\t\tthis._warningHistory[dedupKey] = true;\n\t\t\t\tif (typeof console !== \"undefined\") console.warn(formatRuntimeWarning(this._rootKey, path, e.message, this._defaultValue));\n\t\t\t}\n\t\t\treturn this._defaultValue;\n\t\t}\n\t}\n};\n/**\n* Builds the warning logged when an expression or legacy function fails at\n* evaluation: a `rootKey + index path` location prefix, plus the fallback\n* value being used.\n* @param rootKey Caller-supplied location of the expression in the style JSON\n* @param path Index path of the throwing sub-expression ('' for the root)\n* @param message The error message from the failed evaluation\n* @param defaultValue The value being fallen back to\n* @returns The formatted warning string\n*/\nfunction formatRuntimeWarning(rootKey, path, message, defaultValue) {\n\treturn `${rootKey}${path}: ${message}${defaultValue == null ? \"\" : ` Falling back to ${String(defaultValue)}.`}`;\n}\n/**\n* Rejects a missing or empty root key. The location prefix is what makes\n* runtime warnings actionable, so callers must always supply one; failing\n* here surfaces the programmer error at style load instead of producing\n* unattributable warnings at render time.\n* @param rootKey The root key to check\n*/\nfunction assertRootKey(rootKey) {\n\tif (!rootKey) throw new Error(\"rootKey must identify the location of the expression in the style JSON, e.g. \\\"layers[3].paint.line-width\\\".\");\n}\nfunction isExpression(expression) {\n\treturn Array.isArray(expression) && expression.length > 0 && typeof expression[0] === \"string\" && expression[0] in expressions;\n}\n/**\n* Parse and typecheck the given style spec JSON expression. If\n* options.defaultValue is provided, then the resulting StyleExpression's\n* `evaluate()` method will handle errors by logging a warning (once per\n* message) and returning the default value. Otherwise, it will throw\n* evaluation errors.\n*\n* @private\n*/\nfunction createExpression(expression, rootKey, propertySpec, globalState) {\n\tassertRootKey(rootKey);\n\tconst parser = new ParsingContext(expressions, isExpressionConstant, [], propertySpec ? getExpectedType(propertySpec) : void 0);\n\tconst parsed = parser.parse(expression, void 0, void 0, void 0, propertySpec && propertySpec.type === \"string\" ? { typeAnnotation: \"coerce\" } : void 0);\n\tif (!parsed) return error(parser.errors);\n\treturn success(new StyleExpression(parsed, rootKey, propertySpec, globalState));\n}\nvar ZoomConstantExpression = class {\n\tconstructor(kind, expression, globalState) {\n\t\tthis.kind = kind;\n\t\tthis._styleExpression = expression;\n\t\tthis.isStateDependent = kind !== \"constant\" && !isStateConstant(expression.expression);\n\t\tthis.globalStateRefs = findGlobalStateRefs(expression.expression);\n\t\tthis._globalState = globalState;\n\t}\n\tevaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) {\n\t\tif (this._globalState) globals = addGlobalState(globals, this._globalState);\n\t\treturn this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);\n\t}\n\tevaluate(globals, feature, featureState, canonical, availableImages, formattedSection) {\n\t\tif (this._globalState) globals = addGlobalState(globals, this._globalState);\n\t\treturn this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);\n\t}\n};\nvar ZoomDependentExpression = class {\n\tconstructor(kind, expression, zoomStops, interpolationType, globalState) {\n\t\tthis.kind = kind;\n\t\tthis.zoomStops = zoomStops;\n\t\tthis._styleExpression = expression;\n\t\tthis.isStateDependent = kind !== \"camera\" && !isStateConstant(expression.expression);\n\t\tthis.globalStateRefs = findGlobalStateRefs(expression.expression);\n\t\tthis.interpolationType = interpolationType;\n\t\tthis._globalState = globalState;\n\t}\n\tevaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) {\n\t\tif (this._globalState) globals = addGlobalState(globals, this._globalState);\n\t\treturn this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);\n\t}\n\tevaluate(globals, feature, featureState, canonical, availableImages, formattedSection) {\n\t\tif (this._globalState) globals = addGlobalState(globals, this._globalState);\n\t\treturn this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);\n\t}\n\tinterpolationFactor(input, lower, upper) {\n\t\tif (this.interpolationType) return Interpolate.interpolationFactor(this.interpolationType, input, lower, upper);\n\t\telse return 0;\n\t}\n};\nfunction isZoomExpression(expression) {\n\treturn expression._styleExpression !== void 0;\n}\nfunction createPropertyExpression(expressionInput, rootKey, propertySpec, globalState) {\n\tconst expression = createExpression(expressionInput, rootKey, propertySpec, globalState);\n\tif (expression.result === \"error\") return expression;\n\tconst parsed = expression.value.expression;\n\tconst isFeatureConstantResult = isFeatureConstant(parsed);\n\tif (!isFeatureConstantResult && !supportsPropertyExpression(propertySpec)) return error([new ExpressionParsingError(\"\", \"data expressions not supported\")]);\n\tconst isZoomConstant = isGlobalPropertyConstant(parsed, [\"zoom\"]);\n\tif (!isZoomConstant && !supportsZoomExpression(propertySpec)) return error([new ExpressionParsingError(\"\", \"zoom expressions not supported\")]);\n\tconst zoomCurve = findZoomCurve(parsed);\n\tif (!zoomCurve && !isZoomConstant) return error([new ExpressionParsingError(\"\", \"\\\"zoom\\\" expression may only be used as input to a top-level \\\"step\\\" or \\\"interpolate\\\" expression.\")]);\n\telse if (zoomCurve instanceof ExpressionParsingError) return error([zoomCurve]);\n\telse if (zoomCurve instanceof Interpolate && !supportsInterpolation(propertySpec)) return error([new ExpressionParsingError(\"\", \"\\\"interpolate\\\" expressions cannot be used with this property\")]);\n\tif (!zoomCurve) return success(isFeatureConstantResult ? new ZoomConstantExpression(\"constant\", expression.value, globalState) : new ZoomConstantExpression(\"source\", expression.value, globalState));\n\tconst interpolationType = zoomCurve instanceof Interpolate ? zoomCurve.interpolation : void 0;\n\treturn success(isFeatureConstantResult ? new ZoomDependentExpression(\"camera\", expression.value, zoomCurve.labels, interpolationType, globalState) : new ZoomDependentExpression(\"composite\", expression.value, zoomCurve.labels, interpolationType, globalState));\n}\nvar StylePropertyFunction = class StylePropertyFunction {\n\tconstructor(parameters, rootKey, specification) {\n\t\tthis.isStateDependent = false;\n\t\tthis.globalStateRefs = /* @__PURE__ */ new Set();\n\t\tthis._globalState = null;\n\t\tassertRootKey(rootKey);\n\t\tthis._parameters = parameters;\n\t\tthis._specification = specification;\n\t\tthis._rootKey = rootKey;\n\t\tthis._defaultValue = getDefaultValue(specification);\n\t\tthis._warningHistory = {};\n\t\tconst fn = createFunction(this._parameters, this._specification);\n\t\tthis.kind = fn.kind;\n\t\tthis.interpolationFactor = fn.interpolationFactor;\n\t\tthis.zoomStops = fn.zoomStops;\n\t\tthis.interpolationType = fn.interpolationType;\n\t\tthis._innerEvaluate = fn.evaluate;\n\t}\n\t/**\n\t* Evaluates the legacy function, handling a runtime throw (e.g. interpolating\n\t* mismatched value types) by warning with the property location and falling\n\t* back to the spec default, mirroring {@link StyleExpression.evaluate}.\n\t* @param globals Global evaluation properties (e.g. zoom)\n\t* @param feature The feature being evaluated, if any\n\t* @returns The function result, or the spec default if evaluation throws\n\t*/\n\tevaluate(globals, feature) {\n\t\ttry {\n\t\t\treturn this._innerEvaluate(globals, feature);\n\t\t} catch (e) {\n\t\t\tconst message = e instanceof Error ? e.message : String(e);\n\t\t\tconst dedupKey = `|${message}`;\n\t\t\tif (!this._warningHistory[dedupKey]) {\n\t\t\t\tthis._warningHistory[dedupKey] = true;\n\t\t\t\tif (typeof console !== \"undefined\") console.warn(formatRuntimeWarning(this._rootKey, \"\", message, this._defaultValue));\n\t\t\t}\n\t\t\treturn this._defaultValue;\n\t\t}\n\t}\n\tstatic deserialize(serialized) {\n\t\treturn new StylePropertyFunction(serialized._parameters, serialized._rootKey, serialized._specification);\n\t}\n\tstatic serialize(input) {\n\t\treturn {\n\t\t\t_parameters: input._parameters,\n\t\t\t_specification: input._specification,\n\t\t\t_rootKey: input._rootKey\n\t\t};\n\t}\n};\nfunction normalizePropertyExpression(value, rootKey, specification, globalState) {\n\tif (isFunction(value)) return new StylePropertyFunction(value, rootKey, specification);\n\telse if (isExpression(value)) {\n\t\tconst expression = createPropertyExpression(value, rootKey, specification, globalState);\n\t\tif (expression.result === \"error\") throw new Error(expression.value.map((err) => `${err.key}: ${err.message}`).join(\", \"));\n\t\treturn expression.value;\n\t} else {\n\t\tlet constant = value;\n\t\tif (specification.type === \"color\" && typeof value === \"string\") constant = Color.parse(value);\n\t\telse if (specification.type === \"padding\" && (typeof value === \"number\" || Array.isArray(value))) constant = Padding.parse(value);\n\t\telse if (specification.type === \"numberArray\" && (typeof value === \"number\" || Array.isArray(value))) constant = NumberArray.parse(value);\n\t\telse if (specification.type === \"colorArray\" && (typeof value === \"string\" || Array.isArray(value))) constant = ColorArray.parse(value);\n\t\telse if (specification.type === \"variableAnchorOffsetCollection\" && Array.isArray(value)) constant = VariableAnchorOffsetCollection.parse(value);\n\t\telse if (specification.type === \"projectionDefinition\" && typeof value === \"string\") constant = ProjectionDefinition.parse(value);\n\t\treturn {\n\t\t\tglobalStateRefs: /* @__PURE__ */ new Set(),\n\t\t\t_globalState: null,\n\t\t\tkind: \"constant\",\n\t\t\tevaluate: () => constant\n\t\t};\n\t}\n}\nfunction findZoomCurve(expression) {\n\tlet result = null;\n\tif (expression instanceof Let) result = findZoomCurve(expression.result);\n\telse if (expression instanceof Coalesce) for (const arg of expression.args) {\n\t\tresult = findZoomCurve(arg);\n\t\tif (result) break;\n\t}\n\telse if ((expression instanceof Step || expression instanceof Interpolate) && expression.input instanceof CompoundExpression && expression.input.name === \"zoom\") result = expression;\n\tif (result instanceof ExpressionParsingError) return result;\n\texpression.eachChild((child) => {\n\t\tconst childResult = findZoomCurve(child);\n\t\tif (childResult instanceof ExpressionParsingError) result = childResult;\n\t\telse if (!result && childResult) result = new ExpressionParsingError(\"\", \"\\\"zoom\\\" expression may only be used as input to a top-level \\\"step\\\" or \\\"interpolate\\\" expression.\");\n\t\telse if (result && childResult && result !== childResult) result = new ExpressionParsingError(\"\", \"Only one zoom-based \\\"step\\\" or \\\"interpolate\\\" subexpression may be used in an expression.\");\n\t});\n\treturn result;\n}\nfunction findGlobalStateRefs(expression, results = /* @__PURE__ */ new Set()) {\n\tif (expression instanceof GlobalState) results.add(expression.key);\n\texpression.eachChild((childExpression) => {\n\t\tfindGlobalStateRefs(childExpression, results);\n\t});\n\treturn results;\n}\nfunction getExpectedType(spec) {\n\tconst types = {\n\t\tcolor: ColorType,\n\t\tstring: StringType,\n\t\tnumber: NumberType,\n\t\tenum: StringType,\n\t\tboolean: BooleanType,\n\t\tformatted: FormattedType,\n\t\tpadding: PaddingType,\n\t\tnumberArray: NumberArrayType,\n\t\tcolorArray: ColorArrayType,\n\t\tprojectionDefinition: ProjectionDefinitionType,\n\t\tresolvedImage: ResolvedImageType,\n\t\tvariableAnchorOffsetCollection: VariableAnchorOffsetCollectionType\n\t};\n\tif (spec.type === \"array\") return array(types[spec.value] || ValueType, spec.length);\n\treturn types[spec.type];\n}\nfunction getDefaultValue(spec) {\n\tif (spec.type === \"color\" && isFunction(spec.default)) return new Color(0, 0, 0, 0);\n\tswitch (spec.type) {\n\t\tcase \"color\": return Color.parse(spec.default) || null;\n\t\tcase \"padding\": return Padding.parse(spec.default) || null;\n\t\tcase \"numberArray\": return NumberArray.parse(spec.default) || null;\n\t\tcase \"colorArray\": return ColorArray.parse(spec.default) || null;\n\t\tcase \"variableAnchorOffsetCollection\": return VariableAnchorOffsetCollection.parse(spec.default) || null;\n\t\tcase \"projectionDefinition\": return ProjectionDefinition.parse(spec.default) || null;\n\t\tdefault: return spec.default === void 0 ? null : spec.default;\n\t}\n}\nfunction addGlobalState(globals, globalState) {\n\tconst { zoom, heatmapDensity, elevation, lineProgress, isSupportedScript, accumulated } = globals ?? {};\n\treturn {\n\t\tzoom,\n\t\theatmapDensity,\n\t\televation,\n\t\tlineProgress,\n\t\tisSupportedScript,\n\t\taccumulated,\n\t\tglobalState\n\t};\n}\n//#endregion\n//#region src/feature_filter/index.ts\nfunction classifyChildren(children) {\n\tlet sawLegacy = false;\n\tfor (const child of children) {\n\t\tconst classification = classifyFilter(child);\n\t\tif (classification === \"expression\") return \"expression\";\n\t\tif (classification === \"legacy\") sawLegacy = true;\n\t}\n\treturn sawLegacy ? \"legacy\" : \"neutral\";\n}\nfunction classifyFilter(filter) {\n\tif (typeof filter === \"boolean\") return \"neutral\";\n\tif (!Array.isArray(filter) || filter.length === 0) return \"legacy\";\n\tswitch (filter[0]) {\n\t\tcase \"has\":\n\t\t\tif (filter.length < 2 || filter[1] === \"$id\" || filter[1] === \"$type\") return \"legacy\";\n\t\t\treturn filter.length === 2 ? \"neutral\" : \"expression\";\n\t\tcase \"in\": return filter.length >= 3 && (typeof filter[1] !== \"string\" || Array.isArray(filter[2])) ? \"expression\" : \"legacy\";\n\t\tcase \"!in\":\n\t\tcase \"!has\": return \"legacy\";\n\t\tcase \"==\":\n\t\tcase \"!=\":\n\t\tcase \">\":\n\t\tcase \">=\":\n\t\tcase \"<\":\n\t\tcase \"<=\": return filter.length !== 3 || Array.isArray(filter[1]) || Array.isArray(filter[2]) ? \"expression\" : \"legacy\";\n\t\tcase \"none\": return \"legacy\";\n\t\tcase \"any\":\n\t\tcase \"all\": return classifyChildren(filter.slice(1));\n\t\tdefault: return \"expression\";\n\t}\n}\nfunction isExpressionFilter(filter) {\n\treturn classifyFilter(filter) !== \"legacy\";\n}\nfunction getFilterPropertyExpression(property) {\n\tif (property === \"$type\") return [\"geometry-type\"];\n\tif (property === \"$id\") return [\"id\"];\n\treturn [\"get\", property];\n}\nfunction getLegacyFilterExpressionSuggestion(filter) {\n\tswitch (filter[0]) {\n\t\tcase \"==\":\n\t\tcase \"!=\":\n\t\tcase \"<\":\n\t\tcase \"<=\":\n\t\tcase \">\":\n\t\tcase \">=\":\n\t\t\tif (filter.length !== 3 || typeof filter[1] !== \"string\") return null;\n\t\t\treturn [\n\t\t\t\tfilter[0],\n\t\t\t\tgetFilterPropertyExpression(filter[1]),\n\t\t\t\tfilter[2]\n\t\t\t];\n\t\tcase \"in\":\n\t\tcase \"!in\": {\n\t\t\tif (filter.length < 2 || typeof filter[1] !== \"string\") return null;\n\t\t\tconst expression = [\n\t\t\t\t\"in\",\n\t\t\t\tgetFilterPropertyExpression(filter[1]),\n\t\t\t\t[\"literal\", filter.slice(2)]\n\t\t\t];\n\t\t\treturn filter[0] === \"!in\" ? [\"!\", expression] : expression;\n\t\t}\n\t\tcase \"has\":\n\t\tcase \"!has\": {\n\t\t\tif (filter.length !== 2 || typeof filter[1] !== \"string\") return null;\n\t\t\tif (filter[1] === \"$type\" || filter[1] === \"$id\") return null;\n\t\t\tconst expression = [\"has\", filter[1]];\n\t\t\treturn filter[0] === \"!has\" ? [\"!\", expression] : expression;\n\t\t}\n\t\tdefault: return null;\n\t}\n}\nfunction getMixedFilterMessage(filter) {\n\tif ((filter[0] === \"<\" || filter[0] === \"<=\" || filter[0] === \">\" || filter[0] === \">=\") && filter[1] === \"$type\") return `\"$type\" cannot be use with operator \"${filter[0]}\"`;\n\tconst suggestion = getLegacyFilterExpressionSuggestion(filter);\n\tif (suggestion) return `Mixing deprecated filter syntax with expression syntax is not supported. Replace ${JSON.stringify(filter)} with ${JSON.stringify(suggestion)}.`;\n\treturn `Mixing deprecated filter syntax with expression syntax is not supported. Convert ${JSON.stringify(filter)} to expression syntax.`;\n}\nfunction checkChild(index, path, filter) {\n\tconst child = filter[index];\n\tif (!Array.isArray(child)) return null;\n\tif (!isExpressionFilter(child)) return {\n\t\tpath: path.concat(index),\n\t\tlegacyFilter: child\n\t};\n\treturn findMixedLegacyFilter(child, path.concat(index));\n}\nfunction findMixedLegacyFilter(filter, path = []) {\n\tif (!Array.isArray(filter) || filter.length < 1) return null;\n\tswitch (filter[0]) {\n\t\tcase \"all\":\n\t\tcase \"any\":\n\t\tcase \"none\":\n\t\t\tfor (let i = 1; i < filter.length; i++) {\n\t\t\t\tconst diagnostic = checkChild(i, path, filter);\n\t\t\t\tif (diagnostic) return diagnostic;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"!\": {\n\t\t\tconst diagnostic = checkChild(1, path, filter);\n\t\t\tif (diagnostic) return diagnostic;\n\t\t\tbreak;\n\t\t}\n\t\tcase \"case\": for (let i = 1; i < filter.length - 1; i += 2) {\n\t\t\tconst diagnostic = checkChild(i, path, filter);\n\t\t\tif (diagnostic) return diagnostic;\n\t\t}\n\t}\n\treturn null;\n}\nfunction warnAboutMixedLegacyFilter(filter, rootKey) {\n\tconst diagnostic = findMixedLegacyFilter(filter);\n\tif (!diagnostic || typeof console === \"undefined\") return;\n\tconst path = diagnostic.path.map((index) => `[${index}]`).join(\"\");\n\tconsole.warn(`${rootKey}${path}: ${getMixedFilterMessage(diagnostic.legacyFilter)}`);\n}\nconst filterSpec = {\n\ttype: \"boolean\",\n\tdefault: false,\n\ttransition: false,\n\t\"property-type\": \"data-driven\",\n\texpression: {\n\t\tinterpolated: false,\n\t\tparameters: [\"zoom\", \"feature\"]\n\t}\n};\n/**\n* Given a filter expressed as nested arrays, return a new function\n* that evaluates whether a given feature (with a .properties or .tags property)\n* passes its test.\n*\n* @private\n* @param filter MapLibre filter\n* @param rootKey Location of the filter in the style JSON (e.g. `layers[3].filter`),\n* used to prefix runtime warnings\n* @param [globalState] Global state object to be used for evaluating 'global-state' expressions\n* @returns filter-evaluating function\n*/\nfunction featureFilter(filter, rootKey, globalState) {\n\tif (filter === null || filter === void 0) return {\n\t\tfilter: () => true,\n\t\tneedGeometry: false,\n\t\tgetGlobalStateRefs: () => /* @__PURE__ */ new Set()\n\t};\n\tif (!isExpressionFilter(filter)) filter = convertFilter$1(filter);\n\telse warnAboutMixedLegacyFilter(filter, rootKey);\n\tconst compiled = createExpression(filter, rootKey, filterSpec, globalState);\n\tif (compiled.result === \"error\") throw new Error(compiled.value.map((err) => `${err.key}: ${err.message}`).join(\", \"));\n\telse return {\n\t\tfilter: (globalProperties, feature, canonical) => compiled.value.evaluate(globalProperties, feature, {}, canonical),\n\t\tneedGeometry: geometryNeeded(filter),\n\t\tgetGlobalStateRefs: () => findGlobalStateRefs(compiled.value.expression)\n\t};\n}\nfunction compare(a, b) {\n\treturn a < b ? -1 : a > b ? 1 : 0;\n}\nfunction geometryNeeded(filter) {\n\tif (!Array.isArray(filter)) return false;\n\tif (filter[0] === \"within\" || filter[0] === \"distance\") return true;\n\tfor (let index = 1; index < filter.length; index++) if (geometryNeeded(filter[index])) return true;\n\treturn false;\n}\nfunction convertFilter$1(filter) {\n\tif (!filter) return true;\n\tconst op = filter[0];\n\tif (filter.length <= 1) return op !== \"any\";\n\treturn op === \"==\" ? convertComparisonOp$1(filter[1], filter[2], \"==\") : op === \"!=\" ? convertNegation(convertComparisonOp$1(filter[1], filter[2], \"==\")) : op === \"<\" || op === \">\" || op === \"<=\" || op === \">=\" ? convertComparisonOp$1(filter[1], filter[2], op) : op === \"any\" ? convertDisjunctionOp(filter.slice(1)) : op === \"all\" ? [\"all\"].concat(filter.slice(1).map(convertFilter$1)) : op === \"none\" ? [\"all\"].concat(filter.slice(1).map(convertFilter$1).map(convertNegation)) : op === \"in\" ? convertInOp$1(filter[1], filter.slice(2)) : op === \"!in\" ? convertNegation(convertInOp$1(filter[1], filter.slice(2))) : op === \"has\" ? convertHasOp$1(filter[1]) : op === \"!has\" ? convertNegation(convertHasOp$1(filter[1])) : true;\n}\nfunction convertComparisonOp$1(property, value, op) {\n\tswitch (property) {\n\t\tcase \"$type\": return [`filter-type-${op}`, value];\n\t\tcase \"$id\": return [`filter-id-${op}`, value];\n\t\tdefault: return [\n\t\t\t`filter-${op}`,\n\t\t\tproperty,\n\t\t\tvalue\n\t\t];\n\t}\n}\nfunction convertDisjunctionOp(filters) {\n\treturn [\"any\"].concat(filters.map(convertFilter$1));\n}\nfunction convertInOp$1(property, values) {\n\tif (values.length === 0) return false;\n\tswitch (property) {\n\t\tcase \"$type\": return [\"filter-type-in\", [\"literal\", values]];\n\t\tcase \"$id\": return [\"filter-id-in\", [\"literal\", values]];\n\t\tdefault: if (values.length > 200 && !values.some((v) => typeof v !== typeof values[0])) return [\n\t\t\t\"filter-in-large\",\n\t\t\tproperty,\n\t\t\t[\"literal\", values.sort(compare)]\n\t\t];\n\t\telse return [\n\t\t\t\"filter-in-small\",\n\t\t\tproperty,\n\t\t\t[\"literal\", values]\n\t\t];\n\t}\n}\nfunction convertHasOp$1(property) {\n\tswitch (property) {\n\t\tcase \"$type\": return true;\n\t\tcase \"$id\": return [\"filter-has-id\"];\n\t\tdefault: return [\"filter-has\", property];\n\t}\n}\nfunction convertNegation(filter) {\n\treturn [\"!\", filter];\n}\n//#endregion\n//#region src/feature_filter/convert.ts\nfunction convertFilter(filter, expectedTypes = {}) {\n\tif (isExpressionFilter(filter)) return filter;\n\tif (!filter) return true;\n\tconst legacyFilter = filter;\n\tconst legacyOp = legacyFilter[0];\n\tif (filter.length <= 1) return legacyOp !== \"any\";\n\tswitch (legacyOp) {\n\t\tcase \"==\":\n\t\tcase \"!=\":\n\t\tcase \"<\":\n\t\tcase \">\":\n\t\tcase \"<=\":\n\t\tcase \">=\": {\n\t\t\tconst [, property, value] = filter;\n\t\t\treturn convertComparisonOp(property, value, legacyOp, expectedTypes);\n\t\t}\n\t\tcase \"any\": {\n\t\t\tconst [, ...conditions] = legacyFilter;\n\t\t\treturn [\"any\", ...conditions.map((f) => {\n\t\t\t\tconst types = {};\n\t\t\t\tconst child = convertFilter(f, types);\n\t\t\t\tconst typechecks = runtimeTypeChecks(types);\n\t\t\t\treturn typechecks === true ? child : [\n\t\t\t\t\t\"case\",\n\t\t\t\t\ttypechecks,\n\t\t\t\t\tchild,\n\t\t\t\t\tfalse\n\t\t\t\t];\n\t\t\t})];\n\t\t}\n\t\tcase \"all\": {\n\t\t\tconst [, ...conditions] = legacyFilter;\n\t\t\tconst children = conditions.map((f) => convertFilter(f, expectedTypes));\n\t\t\treturn children.length > 1 ? [\"all\", ...children] : children[0];\n\t\t}\n\t\tcase \"none\": {\n\t\t\tconst [, ...conditions] = legacyFilter;\n\t\t\treturn [\"!\", convertFilter([\"any\", ...conditions], {})];\n\t\t}\n\t\tcase \"in\": {\n\t\t\tconst [, property, ...values] = legacyFilter;\n\t\t\treturn convertInOp(property, values);\n\t\t}\n\t\tcase \"!in\": {\n\t\t\tconst [, property, ...values] = legacyFilter;\n\t\t\treturn convertInOp(property, values, true);\n\t\t}\n\t\tcase \"has\": return convertHasOp(legacyFilter[1]);\n\t\tcase \"!has\": return [\"!\", convertHasOp(legacyFilter[1])];\n\t\tdefault: return true;\n\t}\n}\nfunction runtimeTypeChecks(expectedTypes) {\n\tconst conditions = [];\n\tfor (const property in expectedTypes) {\n\t\tconst get = property === \"$id\" ? [\"id\"] : [\"get\", property];\n\t\tconditions.push([\n\t\t\t\"==\",\n\t\t\t[\"typeof\", get],\n\t\t\texpectedTypes[property]\n\t\t]);\n\t}\n\tif (conditions.length === 0) return true;\n\tif (conditions.length === 1) return conditions[0];\n\treturn [\"all\", ...conditions];\n}\nfunction convertComparisonOp(property, value, op, expectedTypes) {\n\tlet get;\n\tif (property === \"$type\") return [\n\t\top,\n\t\t[\"geometry-type\"],\n\t\tvalue\n\t];\n\telse if (property === \"$id\") get = [\"id\"];\n\telse get = [\"get\", property];\n\tif (expectedTypes && value !== null) expectedTypes[property] = typeof value;\n\tif (op === \"==\" && property !== \"$id\" && value === null) return [\n\t\t\"all\",\n\t\t[\"has\", property],\n\t\t[\n\t\t\t\"==\",\n\t\t\tget,\n\t\t\tnull\n\t\t]\n\t];\n\telse if (op === \"!=\" && property !== \"$id\" && value === null) return [\n\t\t\"any\",\n\t\t[\"!\", [\"has\", property]],\n\t\t[\n\t\t\t\"!=\",\n\t\t\tget,\n\t\t\tnull\n\t\t]\n\t];\n\treturn [\n\t\top,\n\t\tget,\n\t\tvalue\n\t];\n}\nfunction convertInOp(property, values, negate = false) {\n\tif (values.length === 0) return negate;\n\tlet get;\n\tif (property === \"$type\") get = [\"geometry-type\"];\n\telse if (property === \"$id\") get = [\"id\"];\n\telse get = [\"get\", property];\n\tlet uniformTypes = true;\n\tconst type = typeof values[0];\n\tfor (const value of values) if (typeof value !== type) {\n\t\tuniformTypes = false;\n\t\tbreak;\n\t}\n\tif (uniformTypes && (type === \"string\" || type === \"number\")) {\n\t\tconst uniqueValues = values.sort().filter((v, i) => i === 0 || values[i - 1] !== v);\n\t\treturn [\n\t\t\t\"match\",\n\t\t\tget,\n\t\t\tuniqueValues,\n\t\t\t!negate,\n\t\t\tnegate\n\t\t];\n\t}\n\tif (negate) return [\"all\", ...values.map((v) => [\n\t\t\"!=\",\n\t\tget,\n\t\tv\n\t])];\n\telse return [\"any\", ...values.map((v) => [\n\t\t\"==\",\n\t\tget,\n\t\tv\n\t])];\n}\nfunction convertHasOp(property) {\n\tif (property === \"$type\") return true;\n\telse if (property === \"$id\") return [\n\t\t\"!=\",\n\t\t[\"id\"],\n\t\tnull\n\t];\n\telse return [\"has\", property];\n}\n//#endregion\n//#region src/function/convert.ts\nfunction convertLiteral(value) {\n\treturn typeof value === \"object\" ? [\"literal\", value] : value;\n}\nfunction convertFunction(parameters, propertySpec) {\n\tlet stops = parameters.stops;\n\tif (!stops) return convertIdentityFunction(parameters, propertySpec);\n\tconst zoomAndFeatureDependent = stops && typeof stops[0][0] === \"object\";\n\tconst featureDependent = zoomAndFeatureDependent || parameters.property !== void 0;\n\tconst zoomDependent = zoomAndFeatureDependent || !featureDependent;\n\tstops = stops.map((stop) => {\n\t\tif (!featureDependent && propertySpec.tokens && typeof stop[1] === \"string\") return [stop[0], convertTokenString(stop[1])];\n\t\treturn [stop[0], convertLiteral(stop[1])];\n\t});\n\tif (zoomAndFeatureDependent) return convertZoomAndPropertyFunction(parameters, propertySpec, stops);\n\telse if (zoomDependent) return convertZoomFunction(parameters, propertySpec, stops);\n\telse return convertPropertyFunction(parameters, propertySpec, stops);\n}\nfunction convertIdentityFunction(parameters, propertySpec) {\n\tconst get = [\"get\", parameters.property];\n\tif (parameters.default === void 0) return propertySpec.type === \"string\" ? [\"string\", get] : get;\n\telse if (propertySpec.type === \"enum\") return [\n\t\t\"match\",\n\t\tget,\n\t\tObject.keys(propertySpec.values),\n\t\tget,\n\t\tparameters.default\n\t];\n\telse {\n\t\tconst expression = [\n\t\t\tpropertySpec.type === \"color\" ? \"to-color\" : propertySpec.type,\n\t\t\tget,\n\t\t\tconvertLiteral(parameters.default)\n\t\t];\n\t\tif (propertySpec.type === \"array\") expression.splice(1, 0, propertySpec.value, propertySpec.length || null);\n\t\treturn expression;\n\t}\n}\nfunction getInterpolateOperator(parameters) {\n\tswitch (parameters.colorSpace) {\n\t\tcase \"hcl\": return \"interpolate-hcl\";\n\t\tcase \"lab\": return \"interpolate-lab\";\n\t\tdefault: return \"interpolate\";\n\t}\n}\nfunction convertZoomAndPropertyFunction(parameters, propertySpec, stops) {\n\tconst featureFunctionParameters = {};\n\tconst featureFunctionStops = {};\n\tconst zoomStops = [];\n\tfor (let s = 0; s < stops.length; s++) {\n\t\tconst stop = stops[s];\n\t\tconst zoom = stop[0].zoom;\n\t\tif (featureFunctionParameters[zoom] === void 0) {\n\t\t\tfeatureFunctionParameters[zoom] = {\n\t\t\t\tzoom,\n\t\t\t\ttype: parameters.type,\n\t\t\t\tproperty: parameters.property,\n\t\t\t\tdefault: parameters.default\n\t\t\t};\n\t\t\tfeatureFunctionStops[zoom] = [];\n\t\t\tzoomStops.push(zoom);\n\t\t}\n\t\tfeatureFunctionStops[zoom].push([stop[0].value, stop[1]]);\n\t}\n\tif (getFunctionType({}, propertySpec) === \"exponential\") {\n\t\tconst expression = [\n\t\t\tgetInterpolateOperator(parameters),\n\t\t\t[\"linear\"],\n\t\t\t[\"zoom\"]\n\t\t];\n\t\tfor (const z of zoomStops) appendStopPair(expression, z, convertPropertyFunction(featureFunctionParameters[z], propertySpec, featureFunctionStops[z]), false);\n\t\treturn expression;\n\t} else {\n\t\tconst expression = [\"step\", [\"zoom\"]];\n\t\tfor (const z of zoomStops) appendStopPair(expression, z, convertPropertyFunction(featureFunctionParameters[z], propertySpec, featureFunctionStops[z]), true);\n\t\tfixupDegenerateStepCurve(expression);\n\t\treturn expression;\n\t}\n}\nfunction coalesce(a, b) {\n\tif (a !== void 0) return a;\n\tif (b !== void 0) return b;\n}\nfunction getFallback(parameters, propertySpec) {\n\tconst defaultValue = convertLiteral(coalesce(parameters.default, propertySpec.default));\n\tif (defaultValue === void 0 && propertySpec.type === \"resolvedImage\") return \"\";\n\treturn defaultValue;\n}\nfunction convertPropertyFunction(parameters, propertySpec, stops) {\n\tconst type = getFunctionType(parameters, propertySpec);\n\tconst get = [\"get\", parameters.property];\n\tif (type === \"categorical\" && typeof stops[0][0] === \"boolean\") {\n\t\tconst expression = [\"case\"];\n\t\tfor (const stop of stops) expression.push([\n\t\t\t\"==\",\n\t\t\tget,\n\t\t\tstop[0]\n\t\t], stop[1]);\n\t\texpression.push(getFallback(parameters, propertySpec));\n\t\treturn expression;\n\t} else if (type === \"categorical\") {\n\t\tconst expression = [\"match\", get];\n\t\tfor (const stop of stops) appendStopPair(expression, stop[0], stop[1], false);\n\t\texpression.push(getFallback(parameters, propertySpec));\n\t\treturn expression;\n\t} else if (type === \"interval\") {\n\t\tconst expression = [\"step\", [\"number\", get]];\n\t\tfor (const stop of stops) appendStopPair(expression, stop[0], stop[1], true);\n\t\tfixupDegenerateStepCurve(expression);\n\t\treturn parameters.default === void 0 ? expression : [\n\t\t\t\"case\",\n\t\t\t[\n\t\t\t\t\"==\",\n\t\t\t\t[\"typeof\", get],\n\t\t\t\t\"number\"\n\t\t\t],\n\t\t\texpression,\n\t\t\tconvertLiteral(parameters.default)\n\t\t];\n\t} else if (type === \"exponential\") {\n\t\tconst base = parameters.base !== void 0 ? parameters.base : 1;\n\t\tconst expression = [\n\t\t\tgetInterpolateOperator(parameters),\n\t\t\tbase === 1 ? [\"linear\"] : [\"exponential\", base],\n\t\t\t[\"number\", get]\n\t\t];\n\t\tfor (const stop of stops) appendStopPair(expression, stop[0], stop[1], false);\n\t\treturn parameters.default === void 0 ? expression : [\n\t\t\t\"case\",\n\t\t\t[\n\t\t\t\t\"==\",\n\t\t\t\t[\"typeof\", get],\n\t\t\t\t\"number\"\n\t\t\t],\n\t\t\texpression,\n\t\t\tconvertLiteral(parameters.default)\n\t\t];\n\t} else throw new Error(`Unknown property function type ${type}`);\n}\nfunction convertZoomFunction(parameters, propertySpec, stops, input = [\"zoom\"]) {\n\tconst type = getFunctionType(parameters, propertySpec);\n\tlet expression;\n\tlet isStep = false;\n\tif (type === \"interval\") {\n\t\texpression = [\"step\", input];\n\t\tisStep = true;\n\t} else if (type === \"exponential\") {\n\t\tconst base = parameters.base !== void 0 ? parameters.base : 1;\n\t\texpression = [\n\t\t\tgetInterpolateOperator(parameters),\n\t\t\tbase === 1 ? [\"linear\"] : [\"exponential\", base],\n\t\t\tinput\n\t\t];\n\t} else throw new Error(`Unknown zoom function type \"${type}\"`);\n\tfor (const stop of stops) appendStopPair(expression, stop[0], stop[1], isStep);\n\tfixupDegenerateStepCurve(expression);\n\treturn expression;\n}\nfunction fixupDegenerateStepCurve(expression) {\n\tif (expression[0] === \"step\" && expression.length === 3) {\n\t\texpression.push(0);\n\t\texpression.push(expression[3]);\n\t}\n}\nfunction appendStopPair(curve, input, output, isStep) {\n\tif (curve.length > 3 && input === curve[curve.length - 2]) return;\n\tif (!(isStep && curve.length === 2)) curve.push(input);\n\tcurve.push(output);\n}\nfunction getFunctionType(parameters, propertySpec) {\n\tif (parameters.type) return parameters.type;\n\telse return propertySpec.expression.interpolated ? \"exponential\" : \"interval\";\n}\nfunction convertTokenString(s) {\n\tconst result = [\"concat\"];\n\tconst re = /{([^{}]+)}/g;\n\tlet pos = 0;\n\tfor (let match = re.exec(s); match !== null; match = re.exec(s)) {\n\t\tconst literal = s.slice(pos, re.lastIndex - match[0].length);\n\t\tpos = re.lastIndex;\n\t\tif (literal.length > 0) result.push(literal);\n\t\tresult.push([\"get\", match[1]]);\n\t}\n\tif (result.length === 1) return s;\n\tif (pos < s.length) result.push(s.slice(pos));\n\telse if (result.length === 2) return [\"to-string\", result[1]];\n\treturn result;\n}\n//#endregion\n//#region src/visit.ts\nfunction getPropertyReference(propertyName) {\n\tfor (let i = 0; i < v8_default.layout.length; i++) for (const key in v8_default[v8_default.layout[i]]) if (key === propertyName) return v8_default[v8_default.layout[i]][key];\n\tfor (let i = 0; i < v8_default.paint.length; i++) for (const key in v8_default[v8_default.paint[i]]) if (key === propertyName) return v8_default[v8_default.paint[i]][key];\n\treturn null;\n}\nfunction eachSource(style, callback) {\n\tfor (const k in style.sources) callback(style.sources[k]);\n}\nfunction eachLayer(style, callback) {\n\tfor (const layer of style.layers) callback(layer);\n}\nfunction eachProperty(style, options, callback) {\n\tfunction inner(layer, propertyType) {\n\t\tconst properties = layer[propertyType];\n\t\tif (!properties) return;\n\t\tObject.keys(properties).forEach((key) => {\n\t\t\tcallback({\n\t\t\t\tpath: [\n\t\t\t\t\tlayer.id,\n\t\t\t\t\tpropertyType,\n\t\t\t\t\tkey\n\t\t\t\t],\n\t\t\t\tkey,\n\t\t\t\tvalue: properties[key],\n\t\t\t\treference: getPropertyReference(key),\n\t\t\t\tset(x) {\n\t\t\t\t\tproperties[key] = x;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\teachLayer(style, (layer) => {\n\t\tif (options.paint) inner(layer, \"paint\");\n\t\tif (options.layout) inner(layer, \"layout\");\n\t});\n}\n//#endregion\n//#region src/group_by_layout.ts\nfunction stringify$1(obj) {\n\tconst type = typeof obj;\n\tif (type === \"number\" || type === \"boolean\" || type === \"string\" || obj === void 0 || obj === null) return JSON.stringify(obj);\n\tif (Array.isArray(obj)) {\n\t\tlet str = \"[\";\n\t\tfor (const val of obj) str += `${stringify$1(val)},`;\n\t\treturn `${str}]`;\n\t}\n\tconst keys = Object.keys(obj).sort();\n\tlet str = \"{\";\n\tfor (let i = 0; i < keys.length; i++) str += `${JSON.stringify(keys[i])}:${stringify$1(obj[keys[i]])},`;\n\treturn `${str}}`;\n}\nfunction getKey(layer) {\n\tlet key = \"\";\n\tfor (const k of refProperties) key += `/${stringify$1(layer[k])}`;\n\treturn key;\n}\n/**\n* Groups layers by their layout-affecting properties.\n* These are the properties that were formerly used by explicit `ref` mechanism\n* for layers: 'type', 'source', 'source-layer', 'minzoom', 'maxzoom',\n* 'filter', and 'layout'.\n*\n* The input is not modified. The output layers are references to the\n* input layers.\n*\n* @param layers - an array of {@link LayerSpecification}.\n* @param cachedKeys - an object to keep already calculated keys.\n* @returns an array of arrays of {@link LayerSpecification} objects, where each inner array\n* contains layers that share the same layout-affecting properties.\n*/\nfunction groupByLayout(layers, cachedKeys) {\n\tconst groups = {};\n\tfor (let i = 0; i < layers.length; i++) {\n\t\tconst k = cachedKeys && cachedKeys[layers[i].id] || getKey(layers[i]);\n\t\tif (cachedKeys) cachedKeys[layers[i].id] = k;\n\t\tlet group = groups[k];\n\t\tif (!group) group = groups[k] = [];\n\t\tgroup.push(layers[i]);\n\t}\n\tconst result = [];\n\tfor (const k in groups) result.push(groups[k]);\n\treturn result;\n}\n//#endregion\n//#region src/empty.ts\nfunction emptyStyle() {\n\tconst style = {};\n\tconst version = latest[\"$version\"];\n\tfor (const styleKey in latest[\"$root\"]) {\n\t\tconst specification = latest[\"$root\"][styleKey];\n\t\tif (specification.required) {\n\t\t\tlet value = null;\n\t\t\tif (styleKey === \"version\") value = version;\n\t\t\telse if (specification.type === \"array\") value = [];\n\t\t\telse value = {};\n\t\t\tif (value != null) style[styleKey] = value;\n\t\t}\n\t}\n\treturn style;\n}\n//#endregion\n//#region src/validate/validate_constants.ts\nfunction validateConstants(options) {\n\tconst key = options.key;\n\tconst constants = options.value;\n\tif (constants) return [new ValidationError(key, constants, \"constants have been deprecated as of v8\")];\n\telse return [];\n}\n//#endregion\n//#region src/util/unbundle_jsonlint.ts\nfunction unbundle(value) {\n\tif (value instanceof Number || value instanceof String || value instanceof Boolean) return value.valueOf();\n\telse return value;\n}\nfunction deepUnbundle(value) {\n\tif (Array.isArray(value)) return value.map(deepUnbundle);\n\telse if (value instanceof Object && !(value instanceof Number || value instanceof String || value instanceof Boolean)) {\n\t\tconst unbundledValue = {};\n\t\tfor (const key in value) unbundledValue[key] = deepUnbundle(value[key]);\n\t\treturn unbundledValue;\n\t}\n\treturn unbundle(value);\n}\n//#endregion\n//#region src/validate/validate_object.ts\nfunction validateObject(options) {\n\tconst key = options.key;\n\tconst object = options.value;\n\tconst elementSpecs = options.valueSpec || {};\n\tconst elementValidators = options.objectElementValidators || {};\n\tconst style = options.style;\n\tconst styleSpec = options.styleSpec;\n\tconst validateSpec = options.validateSpec;\n\tlet errors = [];\n\tconst type = getType(object);\n\tif (type !== \"object\") return [new ValidationError(key, object, `object expected, ${type} found`)];\n\tfor (const objectKey in object) {\n\t\tconst elementSpecKey = objectKey.split(\".\")[0];\n\t\tconst elementSpec = getOwn(elementSpecs, elementSpecKey) || elementSpecs[\"*\"];\n\t\tlet validateElement;\n\t\tif (getOwn(elementValidators, elementSpecKey)) validateElement = elementValidators[elementSpecKey];\n\t\telse if (getOwn(elementSpecs, elementSpecKey)) {\n\t\t\tif (object[objectKey] === void 0) continue;\n\t\t\tvalidateElement = validateSpec;\n\t\t} else if (elementValidators[\"*\"]) validateElement = elementValidators[\"*\"];\n\t\telse if (elementSpecs[\"*\"]) validateElement = validateSpec;\n\t\telse {\n\t\t\terrors.push(new ValidationError(key, object[objectKey], `unknown property \"${objectKey}\"`));\n\t\t\tcontinue;\n\t\t}\n\t\terrors = errors.concat(validateElement({\n\t\t\tkey: (key ? `${key}.` : key) + objectKey,\n\t\t\tvalue: object[objectKey],\n\t\t\tvalueSpec: elementSpec,\n\t\t\tstyle,\n\t\t\tstyleSpec,\n\t\t\tobject,\n\t\t\tobjectKey,\n\t\t\tvalidateSpec\n\t\t}, object));\n\t}\n\tfor (const elementSpecKey in elementSpecs) {\n\t\tif (elementValidators[elementSpecKey]) continue;\n\t\tif (elementSpecs[elementSpecKey].required && elementSpecs[elementSpecKey][\"default\"] === void 0 && object[elementSpecKey] === void 0) errors.push(new ValidationError(key, object, `missing required property \"${elementSpecKey}\"`));\n\t}\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_array.ts\nfunction validateArray(options) {\n\tconst array = options.value;\n\tconst arraySpec = options.valueSpec;\n\tconst validateSpec = options.validateSpec;\n\tconst style = options.style;\n\tconst styleSpec = options.styleSpec;\n\tconst key = options.key;\n\tconst validateArrayElement = options.arrayElementValidator || validateSpec;\n\tif (getType(array) !== \"array\") return [new ValidationError(key, array, `array expected, ${getType(array)} found`)];\n\tif (arraySpec.length && array.length !== arraySpec.length) return [new ValidationError(key, array, `array length ${arraySpec.length} expected, length ${array.length} found`)];\n\tlet arrayElementSpec = {\n\t\ttype: arraySpec.value,\n\t\tvalues: arraySpec.values\n\t};\n\tif (styleSpec.$version < 7) arrayElementSpec[\"function\"] = arraySpec.function;\n\tif (getType(arraySpec.value) === \"object\") arrayElementSpec = arraySpec.value;\n\tlet errors = [];\n\tfor (let i = 0; i < array.length; i++) errors = errors.concat(validateArrayElement({\n\t\tarray,\n\t\tarrayIndex: i,\n\t\tvalue: array[i],\n\t\tvalueSpec: arrayElementSpec,\n\t\tvalidateSpec: options.validateSpec,\n\t\tstyle,\n\t\tstyleSpec,\n\t\tkey: `${key}[${i}]`\n\t}));\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_number.ts\nfunction validateNumber(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tconst valueSpec = options.valueSpec;\n\tlet type = getType(value);\n\tif (type === \"number\" && value !== value) type = \"NaN\";\n\tif (type !== \"number\") return [new ValidationError(key, value, `number expected, ${type} found`)];\n\tif (\"minimum\" in valueSpec && value < valueSpec.minimum) return [new ValidationError(key, value, `${value} is less than the minimum value ${valueSpec.minimum}`)];\n\tif (\"maximum\" in valueSpec && value > valueSpec.maximum) return [new ValidationError(key, value, `${value} is greater than the maximum value ${valueSpec.maximum}`)];\n\treturn [];\n}\n//#endregion\n//#region src/validate/validate_function.ts\nfunction validateFunction(options) {\n\tconst functionValueSpec = options.valueSpec;\n\tconst functionType = unbundle(options.value.type);\n\tlet stopKeyType;\n\tlet stopDomainValues = {};\n\tlet previousStopDomainValue;\n\tlet previousStopDomainZoom;\n\tconst isZoomFunction = functionType !== \"categorical\" && options.value.property === void 0;\n\tconst isPropertyFunction = !isZoomFunction;\n\tconst isZoomAndPropertyFunction = getType(options.value.stops) === \"array\" && getType(options.value.stops[0]) === \"array\" && getType(options.value.stops[0][0]) === \"object\";\n\tconst errors = validateObject({\n\t\tkey: options.key,\n\t\tvalue: options.value,\n\t\tvalueSpec: options.styleSpec.function,\n\t\tvalidateSpec: options.validateSpec,\n\t\tstyle: options.style,\n\t\tstyleSpec: options.styleSpec,\n\t\tobjectElementValidators: {\n\t\t\tstops: validateFunctionStops,\n\t\t\tdefault: validateFunctionDefault\n\t\t}\n\t});\n\tif (functionType === \"identity\" && isZoomFunction) errors.push(new ValidationError(options.key, options.value, \"missing required property \\\"property\\\"\"));\n\tif (functionType !== \"identity\" && !options.value.stops) errors.push(new ValidationError(options.key, options.value, \"missing required property \\\"stops\\\"\"));\n\tif (functionType === \"exponential\" && options.valueSpec.expression && !supportsInterpolation(options.valueSpec)) errors.push(new ValidationError(options.key, options.value, \"exponential functions not supported\"));\n\tif (options.styleSpec.$version >= 8) {\n\t\tif (isPropertyFunction && !supportsPropertyExpression(options.valueSpec)) errors.push(new ValidationError(options.key, options.value, \"property functions not supported\"));\n\t\telse if (isZoomFunction && !supportsZoomExpression(options.valueSpec)) errors.push(new ValidationError(options.key, options.value, \"zoom functions not supported\"));\n\t}\n\tif ((functionType === \"categorical\" || isZoomAndPropertyFunction) && options.value.property === void 0) errors.push(new ValidationError(options.key, options.value, \"\\\"property\\\" property is required\"));\n\treturn errors;\n\tfunction validateFunctionStops(options) {\n\t\tif (functionType === \"identity\") return [new ValidationError(options.key, options.value, \"identity function may not have a \\\"stops\\\" property\")];\n\t\tlet errors = [];\n\t\tconst value = options.value;\n\t\terrors = errors.concat(validateArray({\n\t\t\tkey: options.key,\n\t\t\tvalue,\n\t\t\tvalueSpec: options.valueSpec,\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tstyle: options.style,\n\t\t\tstyleSpec: options.styleSpec,\n\t\t\tarrayElementValidator: validateFunctionStop\n\t\t}));\n\t\tif (getType(value) === \"array\" && value.length === 0) errors.push(new ValidationError(options.key, value, \"array must have at least one stop\"));\n\t\treturn errors;\n\t}\n\tfunction validateFunctionStop(options) {\n\t\tlet errors = [];\n\t\tconst value = options.value;\n\t\tconst key = options.key;\n\t\tif (getType(value) !== \"array\") return [new ValidationError(key, value, `array expected, ${getType(value)} found`)];\n\t\tif (value.length !== 2) return [new ValidationError(key, value, `array length 2 expected, length ${value.length} found`)];\n\t\tif (isZoomAndPropertyFunction) {\n\t\t\tif (getType(value[0]) !== \"object\") return [new ValidationError(key, value, `object expected, ${getType(value[0])} found`)];\n\t\t\tif (value[0].zoom === void 0) return [new ValidationError(key, value, \"object stop key must have zoom\")];\n\t\t\tif (value[0].value === void 0) return [new ValidationError(key, value, \"object stop key must have value\")];\n\t\t\tif (previousStopDomainZoom && previousStopDomainZoom > unbundle(value[0].zoom)) return [new ValidationError(key, value[0].zoom, \"stop zoom values must appear in ascending order\")];\n\t\t\tif (unbundle(value[0].zoom) !== previousStopDomainZoom) {\n\t\t\t\tpreviousStopDomainZoom = unbundle(value[0].zoom);\n\t\t\t\tpreviousStopDomainValue = void 0;\n\t\t\t\tstopDomainValues = {};\n\t\t\t}\n\t\t\terrors = errors.concat(validateObject({\n\t\t\t\tkey: `${key}[0]`,\n\t\t\t\tvalue: value[0],\n\t\t\t\tvalueSpec: { zoom: {} },\n\t\t\t\tvalidateSpec: options.validateSpec,\n\t\t\t\tstyle: options.style,\n\t\t\t\tstyleSpec: options.styleSpec,\n\t\t\t\tobjectElementValidators: {\n\t\t\t\t\tzoom: validateNumber,\n\t\t\t\t\tvalue: validateStopDomainValue\n\t\t\t\t}\n\t\t\t}));\n\t\t} else errors = errors.concat(validateStopDomainValue({\n\t\t\tkey: `${key}[0]`,\n\t\t\tvalue: value[0],\n\t\t\tvalueSpec: {},\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tstyle: options.style,\n\t\t\tstyleSpec: options.styleSpec\n\t\t}, value));\n\t\tif (isExpression(deepUnbundle(value[1]))) return errors.concat([new ValidationError(`${key}[1]`, value[1], \"expressions are not allowed in function stops.\")]);\n\t\treturn errors.concat(options.validateSpec({\n\t\t\tkey: `${key}[1]`,\n\t\t\tvalue: value[1],\n\t\t\tvalueSpec: functionValueSpec,\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tstyle: options.style,\n\t\t\tstyleSpec: options.styleSpec\n\t\t}));\n\t}\n\tfunction validateStopDomainValue(options, stop) {\n\t\tconst type = getType(options.value);\n\t\tconst value = unbundle(options.value);\n\t\tconst reportValue = options.value !== null ? options.value : stop;\n\t\tif (!stopKeyType) stopKeyType = type;\n\t\telse if (type !== stopKeyType) return [new ValidationError(options.key, reportValue, `${type} stop domain type must match previous stop domain type ${stopKeyType}`)];\n\t\tif (type !== \"number\" && type !== \"string\" && type !== \"boolean\") return [new ValidationError(options.key, reportValue, \"stop domain value must be a number, string, or boolean\")];\n\t\tif (type !== \"number\" && functionType !== \"categorical\") {\n\t\t\tlet message = `number expected, ${type} found`;\n\t\t\tif (supportsPropertyExpression(functionValueSpec) && functionType === void 0) message += \"\\nIf you intended to use a categorical function, specify `\\\"type\\\": \\\"categorical\\\"`.\";\n\t\t\treturn [new ValidationError(options.key, reportValue, message)];\n\t\t}\n\t\tif (functionType === \"categorical\" && type === \"number\" && (!isFinite(value) || Math.floor(value) !== value)) return [new ValidationError(options.key, reportValue, `integer expected, found ${value}`)];\n\t\tif (functionType !== \"categorical\" && type === \"number\" && previousStopDomainValue !== void 0 && value < previousStopDomainValue) return [new ValidationError(options.key, reportValue, \"stop domain values must appear in ascending order\")];\n\t\telse previousStopDomainValue = value;\n\t\tif (functionType === \"categorical\" && value in stopDomainValues) return [new ValidationError(options.key, reportValue, \"stop domain values must be unique\")];\n\t\telse stopDomainValues[value] = true;\n\t\treturn [];\n\t}\n\tfunction validateFunctionDefault(options) {\n\t\treturn options.validateSpec({\n\t\t\tkey: options.key,\n\t\t\tvalue: options.value,\n\t\t\tvalueSpec: functionValueSpec,\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tstyle: options.style,\n\t\t\tstyleSpec: options.styleSpec\n\t\t});\n\t}\n}\n//#endregion\n//#region src/validate/validate_expression.ts\nfunction validateExpression(options) {\n\tconst expression = (options.expressionContext === \"property\" ? createPropertyExpression : createExpression)(deepUnbundle(options.value), options.key, options.valueSpec);\n\tif (expression.result === \"error\") return expression.value.map((error) => {\n\t\treturn new ValidationError(`${options.key}${error.key}`, options.value, error.message);\n\t});\n\tconst expressionObj = expression.value.expression || expression.value._styleExpression.expression;\n\tif (options.expressionContext === \"property\" && options.propertyKey === \"text-font\" && !expressionObj.outputDefined()) return [new ValidationError(options.key, options.value, `Invalid data expression for \"${options.propertyKey}\". Output values must be contained as literals within the expression.`)];\n\tif (options.expressionContext === \"property\" && options.propertyType === \"layout\" && !isStateConstant(expressionObj)) return [new ValidationError(options.key, options.value, \"\\\"feature-state\\\" data expressions are not supported with layout properties.\")];\n\tif (options.expressionContext === \"filter\" && !isStateConstant(expressionObj)) return [new ValidationError(options.key, options.value, \"\\\"feature-state\\\" data expressions are not supported with filters.\")];\n\tif (options.expressionContext && options.expressionContext.indexOf(\"cluster\") === 0) {\n\t\tif (!isGlobalPropertyConstant(expressionObj, [\"zoom\", \"feature-state\"])) return [new ValidationError(options.key, options.value, \"\\\"zoom\\\" and \\\"feature-state\\\" expressions are not supported with cluster properties.\")];\n\t\tif (options.expressionContext === \"cluster-initial\" && !isFeatureConstant(expressionObj)) return [new ValidationError(options.key, options.value, \"Feature data expressions are not supported with initial expression part of cluster properties.\")];\n\t}\n\treturn [];\n}\n//#endregion\n//#region src/validate/validate_boolean.ts\nfunction validateBoolean(options) {\n\tconst value = options.value;\n\tconst key = options.key;\n\tconst type = getType(value);\n\tif (type !== \"boolean\") return [new ValidationError(key, value, `boolean expected, ${type} found`)];\n\treturn [];\n}\n//#endregion\n//#region src/validate/validate_color.ts\nfunction validateColor(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tconst type = getType(value);\n\tif (type !== \"string\") return [new ValidationError(key, value, `color expected, ${type} found`)];\n\tif (!Color.parse(String(value))) return [new ValidationError(key, value, `color expected, \"${value}\" found`)];\n\treturn [];\n}\n//#endregion\n//#region src/validate/validate_enum.ts\nfunction validateEnum(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tconst valueSpec = options.valueSpec;\n\tconst errors = [];\n\tif (Array.isArray(valueSpec.values)) {\n\t\tif (valueSpec.values.indexOf(unbundle(value)) === -1) errors.push(new ValidationError(key, value, `expected one of [${valueSpec.values.join(\", \")}], ${JSON.stringify(value)} found`));\n\t} else if (Object.keys(valueSpec.values).indexOf(unbundle(value)) === -1) errors.push(new ValidationError(key, value, `expected one of [${Object.keys(valueSpec.values).join(\", \")}], ${JSON.stringify(value)} found`));\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_filter.ts\nfunction getValueAtPath(value, path) {\n\tlet current = value;\n\tfor (const index of path) current = current[index];\n\treturn current;\n}\n/**\n* Reports a filter that mixes deprecated syntax into an expression tree as a *warning*.\n* @param options The validation options, used for the key and the un-unbundled value\n* @param value The unbundled filter to inspect\n* @returns A single warning, or an empty array when nothing is mixed\n*/\nfunction validateNoMixedLegacyFilter(options, value) {\n\tconst diagnostic = findMixedLegacyFilter(value);\n\tif (!diagnostic) return [];\n\treturn [new ValidationError(`${options.key}${diagnostic.path.map((index) => `[${index}]`).join(\"\")}`, getValueAtPath(options.value, diagnostic.path), getMixedFilterMessage(diagnostic.legacyFilter), null, \"warning\")];\n}\nfunction validateFilter(options) {\n\tconst value = deepUnbundle(options.value);\n\tif (!isExpressionFilter(value)) return validateNonExpressionFilter(options);\n\treturn [...validateNoMixedLegacyFilter(options, value), ...validateExpression(extendBy({}, options, {\n\t\texpressionContext: \"filter\",\n\t\tvalueSpec: { value: \"boolean\" }\n\t}))];\n}\nfunction validateNonExpressionFilter(options) {\n\tconst value = options.value;\n\tconst key = options.key;\n\tif (getType(value) !== \"array\") return [new ValidationError(key, value, `array expected, ${getType(value)} found`)];\n\tconst styleSpec = options.styleSpec;\n\tlet type;\n\tlet errors = [];\n\tif (value.length < 1) return [new ValidationError(key, value, \"filter array must have at least 1 element\")];\n\terrors = errors.concat(validateEnum({\n\t\tkey: `${key}[0]`,\n\t\tvalue: value[0],\n\t\tvalueSpec: styleSpec.filter_operator,\n\t\tstyle: options.style,\n\t\tstyleSpec: options.styleSpec\n\t}));\n\tswitch (unbundle(value[0])) {\n\t\tcase \"<\":\n\t\tcase \"<=\":\n\t\tcase \">\":\n\t\tcase \">=\": if (value.length >= 2 && unbundle(value[1]) === \"$type\") errors.push(new ValidationError(key, value, `\"$type\" cannot be use with operator \"${value[0]}\"`));\n\t\tcase \"==\":\n\t\tcase \"!=\": if (value.length !== 3) errors.push(new ValidationError(key, value, `filter array for operator \"${value[0]}\" must have 3 elements`));\n\t\tcase \"in\":\n\t\tcase \"!in\":\n\t\t\tif (value.length >= 2) {\n\t\t\t\ttype = getType(value[1]);\n\t\t\t\tif (type !== \"string\") errors.push(new ValidationError(`${key}[1]`, value[1], `string expected, ${type} found`));\n\t\t\t}\n\t\t\tfor (let i = 2; i < value.length; i++) {\n\t\t\t\ttype = getType(value[i]);\n\t\t\t\tif (unbundle(value[1]) === \"$type\") errors = errors.concat(validateEnum({\n\t\t\t\t\tkey: `${key}[${i}]`,\n\t\t\t\t\tvalue: value[i],\n\t\t\t\t\tvalueSpec: styleSpec.geometry_type,\n\t\t\t\t\tstyle: options.style,\n\t\t\t\t\tstyleSpec: options.styleSpec\n\t\t\t\t}));\n\t\t\t\telse if (type !== \"string\" && type !== \"number\" && type !== \"boolean\") errors.push(new ValidationError(`${key}[${i}]`, value[i], `string, number, or boolean expected, ${type} found`));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"any\":\n\t\tcase \"all\":\n\t\tcase \"none\":\n\t\t\tfor (let i = 1; i < value.length; i++) errors = errors.concat(validateNonExpressionFilter({\n\t\t\t\tkey: `${key}[${i}]`,\n\t\t\t\tvalue: value[i],\n\t\t\t\tstyle: options.style,\n\t\t\t\tstyleSpec: options.styleSpec\n\t\t\t}));\n\t\t\tbreak;\n\t\tcase \"has\":\n\t\tcase \"!has\":\n\t\t\ttype = getType(value[1]);\n\t\t\tif (value.length !== 2) errors.push(new ValidationError(key, value, `filter array for \"${value[0]}\" operator must have 2 elements`));\n\t\t\telse if (type !== \"string\") errors.push(new ValidationError(`${key}[1]`, value[1], `string expected, ${type} found`));\n\t}\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_property.ts\nfunction validateProperty(options, propertyType) {\n\tconst key = options.key;\n\tconst validateSpec = options.validateSpec;\n\tconst style = options.style;\n\tconst styleSpec = options.styleSpec;\n\tconst value = options.value;\n\tconst propertyKey = options.objectKey;\n\tconst layerSpec = styleSpec[`${propertyType}_${options.layerType}`];\n\tif (!layerSpec) return [];\n\tconst transitionMatch = propertyKey.match(/^(.*)-transition$/);\n\tif (propertyType === \"paint\" && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) return validateSpec({\n\t\tkey,\n\t\tvalue,\n\t\tvalueSpec: styleSpec.transition,\n\t\tstyle,\n\t\tstyleSpec\n\t});\n\tconst valueSpec = options.valueSpec || layerSpec[propertyKey];\n\tif (!valueSpec) return [new ValidationError(key, value, `unknown property \"${propertyKey}\"`)];\n\tlet tokenMatch;\n\tif (getType(value) === \"string\" && supportsPropertyExpression(valueSpec) && !valueSpec.tokens && (tokenMatch = /^{([^}]+)}$/.exec(value))) return [new ValidationError(key, value, `\"${propertyKey}\" does not support interpolation syntax\\nUse an identity property function instead: \\`{ \"type\": \"identity\", \"property\": ${JSON.stringify(tokenMatch[1])} }\\`.`)];\n\tconst errors = [];\n\tif (options.layerType === \"symbol\") {\n\t\tif (propertyKey === \"text-font\" && isFunction(deepUnbundle(value)) && unbundle(value.type) === \"identity\") errors.push(new ValidationError(key, value, \"\\\"text-font\\\" does not support identity functions\"));\n\t}\n\treturn errors.concat(validateSpec({\n\t\tkey: options.key,\n\t\tvalue,\n\t\tvalueSpec,\n\t\tstyle,\n\t\tstyleSpec,\n\t\texpressionContext: \"property\",\n\t\tpropertyType,\n\t\tpropertyKey\n\t}));\n}\n//#endregion\n//#region src/validate/validate_paint_property.ts\nfunction validatePaintProperty(options) {\n\treturn validateProperty(options, \"paint\");\n}\n//#endregion\n//#region src/validate/validate_layout_property.ts\nfunction validateLayoutProperty(options) {\n\treturn validateProperty(options, \"layout\");\n}\n//#endregion\n//#region src/validate/validate_layer.ts\nfunction validateLayer(options) {\n\tlet errors = [];\n\tconst layer = options.value;\n\tconst key = options.key;\n\tconst style = options.style;\n\tconst styleSpec = options.styleSpec;\n\tif (getType(layer) !== \"object\") return [new ValidationError(key, layer, `object expected, ${getType(layer)} found`)];\n\tif (!layer.type && !layer.ref) errors.push(new ValidationError(key, layer, \"either \\\"type\\\" or \\\"ref\\\" is required\"));\n\tlet type = unbundle(layer.type);\n\tconst ref = unbundle(layer.ref);\n\tif (layer.id) {\n\t\tconst layerId = unbundle(layer.id);\n\t\tfor (let i = 0; i < options.arrayIndex; i++) {\n\t\t\tconst otherLayer = style.layers[i];\n\t\t\tif (unbundle(otherLayer.id) === layerId) errors.push(new ValidationError(key, layer.id, `duplicate layer id \"${layer.id}\", previously used at line ${otherLayer.id.__line__}`));\n\t\t}\n\t}\n\tif (\"ref\" in layer) {\n\t\t[\n\t\t\t\"type\",\n\t\t\t\"source\",\n\t\t\t\"source-layer\",\n\t\t\t\"filter\",\n\t\t\t\"layout\"\n\t\t].forEach((p) => {\n\t\t\tif (p in layer) errors.push(new ValidationError(key, layer[p], `\"${p}\" is prohibited for ref layers`));\n\t\t});\n\t\tlet parent;\n\t\tstyle.layers.forEach((layer) => {\n\t\t\tif (unbundle(layer.id) === ref) parent = layer;\n\t\t});\n\t\tif (!parent) errors.push(new ValidationError(key, layer.ref, `ref layer \"${ref}\" not found`));\n\t\telse if (parent.ref) errors.push(new ValidationError(key, layer.ref, \"ref cannot reference another ref layer\"));\n\t\telse type = unbundle(parent.type);\n\t} else if (type !== \"background\") {\n\t\tif (!layer.source) errors.push(new ValidationError(key, layer, \"missing required property \\\"source\\\"\"));\n\t\telse {\n\t\t\tconst source = style.sources && style.sources[layer.source];\n\t\t\tconst sourceType = source && unbundle(source.type);\n\t\t\tif (!source) errors.push(new ValidationError(key, layer.source, `source \"${layer.source}\" not found`));\n\t\t\telse if (sourceType === \"vector\" && type === \"raster\") errors.push(new ValidationError(key, layer.source, `layer \"${layer.id}\" requires a raster source`));\n\t\t\telse if (sourceType !== \"raster-dem\" && type === \"hillshade\") errors.push(new ValidationError(key, layer.source, `layer \"${layer.id}\" requires a raster-dem source`));\n\t\t\telse if (sourceType !== \"raster-dem\" && type === \"color-relief\") errors.push(new ValidationError(key, layer.source, `layer \"${layer.id}\" requires a raster-dem source`));\n\t\t\telse if (sourceType === \"raster\" && type !== \"raster\") errors.push(new ValidationError(key, layer.source, `layer \"${layer.id}\" requires a vector source`));\n\t\t\telse if (sourceType === \"vector\" && !layer[\"source-layer\"]) errors.push(new ValidationError(key, layer, `layer \"${layer.id}\" must specify a \"source-layer\"`));\n\t\t\telse if (sourceType === \"raster-dem\" && type !== \"hillshade\" && type !== \"color-relief\") errors.push(new ValidationError(key, layer.source, \"raster-dem source can only be used with layer type 'hillshade' or 'color-relief'.\"));\n\t\t\telse if (type === \"line\" && layer.paint && layer.paint[\"line-gradient\"] && (sourceType !== \"geojson\" || !source.lineMetrics)) errors.push(new ValidationError(key, layer, `layer \"${layer.id}\" specifies a line-gradient, which requires a GeoJSON source with \\`lineMetrics\\` enabled.`));\n\t\t}\n\t}\n\tif (type === \"raster\" && layer.paint?.resampling && layer.paint?.[\"raster-resampling\"]) errors.push(new ValidationError(key, layer.paint, `layer \"${layer.id}\" redundantly specifies \"resampling\" and \"raster-resampling\" paint properties, but only one is allowed. It is advised to use \"resampling\".`));\n\terrors = errors.concat(validateObject({\n\t\tkey,\n\t\tvalue: layer,\n\t\tvalueSpec: styleSpec.layer,\n\t\tstyle: options.style,\n\t\tstyleSpec: options.styleSpec,\n\t\tvalidateSpec: options.validateSpec,\n\t\tobjectElementValidators: {\n\t\t\t\"*\"() {\n\t\t\t\treturn [];\n\t\t\t},\n\t\t\ttype() {\n\t\t\t\treturn options.validateSpec({\n\t\t\t\t\tkey: `${key}.type`,\n\t\t\t\t\tvalue: layer.type,\n\t\t\t\t\tvalueSpec: styleSpec.layer.type,\n\t\t\t\t\tstyle: options.style,\n\t\t\t\t\tstyleSpec: options.styleSpec,\n\t\t\t\t\tvalidateSpec: options.validateSpec,\n\t\t\t\t\tobject: layer,\n\t\t\t\t\tobjectKey: \"type\"\n\t\t\t\t});\n\t\t\t},\n\t\t\tfilter: validateFilter,\n\t\t\tlayout(options) {\n\t\t\t\treturn validateObject({\n\t\t\t\t\tlayer,\n\t\t\t\t\tkey: options.key,\n\t\t\t\t\tvalue: options.value,\n\t\t\t\t\tstyle: options.style,\n\t\t\t\t\tstyleSpec: options.styleSpec,\n\t\t\t\t\tvalidateSpec: options.validateSpec,\n\t\t\t\t\tobjectElementValidators: { \"*\"(options) {\n\t\t\t\t\t\treturn validateLayoutProperty(extendBy({ layerType: type }, options));\n\t\t\t\t\t} }\n\t\t\t\t});\n\t\t\t},\n\t\t\tpaint(options) {\n\t\t\t\treturn validateObject({\n\t\t\t\t\tlayer,\n\t\t\t\t\tkey: options.key,\n\t\t\t\t\tvalue: options.value,\n\t\t\t\t\tstyle: options.style,\n\t\t\t\t\tstyleSpec: options.styleSpec,\n\t\t\t\t\tvalidateSpec: options.validateSpec,\n\t\t\t\t\tobjectElementValidators: { \"*\"(options) {\n\t\t\t\t\t\treturn validatePaintProperty(extendBy({ layerType: type }, options));\n\t\t\t\t\t} }\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}));\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_string.ts\nfunction validateString(options) {\n\tconst value = options.value;\n\tconst key = options.key;\n\tconst type = getType(value);\n\tif (type !== \"string\") return [new ValidationError(key, value, `string expected, ${type} found`)];\n\treturn [];\n}\n//#endregion\n//#region src/validate/validate_raster_dem_source.ts\nfunction validateRasterDEMSource(options) {\n\tconst sourceName = options.sourceName ?? \"\";\n\tconst rasterDEM = options.value;\n\tconst styleSpec = options.styleSpec;\n\tconst rasterDEMSpec = styleSpec.source_raster_dem;\n\tconst style = options.style;\n\tlet errors = [];\n\tconst rootType = getType(rasterDEM);\n\tif (rasterDEM === void 0) return errors;\n\telse if (rootType !== \"object\") {\n\t\terrors.push(new ValidationError(\"source_raster_dem\", rasterDEM, `object expected, ${rootType} found`));\n\t\treturn errors;\n\t}\n\tconst isCustomEncoding = unbundle(rasterDEM.encoding) === \"custom\";\n\tconst customEncodingKeys = [\n\t\t\"redFactor\",\n\t\t\"greenFactor\",\n\t\t\"blueFactor\",\n\t\t\"baseShift\"\n\t];\n\tconst encodingName = options.value.encoding ? `\"${options.value.encoding}\"` : \"Default\";\n\tfor (const key in rasterDEM) if (!isCustomEncoding && customEncodingKeys.includes(key)) errors.push(new ValidationError(key, rasterDEM[key], `In \"${sourceName}\": \"${key}\" is only valid when \"encoding\" is set to \"custom\". ${encodingName} encoding found`));\n\telse if (rasterDEMSpec[key]) errors = errors.concat(options.validateSpec({\n\t\tkey,\n\t\tvalue: rasterDEM[key],\n\t\tvalueSpec: rasterDEMSpec[key],\n\t\tvalidateSpec: options.validateSpec,\n\t\tstyle,\n\t\tstyleSpec\n\t}));\n\telse errors.push(new ValidationError(key, rasterDEM[key], `unknown property \"${key}\"`));\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_source.ts\nconst objectElementValidators = { promoteId: validatePromoteId };\nfunction validateSource(options) {\n\tconst value = options.value;\n\tconst key = options.key;\n\tconst styleSpec = options.styleSpec;\n\tconst style = options.style;\n\tconst validateSpec = options.validateSpec;\n\tif (!value.type) return [new ValidationError(key, value, \"\\\"type\\\" is required\")];\n\tconst type = unbundle(value.type);\n\tlet errors;\n\tswitch (type) {\n\t\tcase \"vector\":\n\t\tcase \"raster\":\n\t\t\terrors = validateObject({\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\tvalueSpec: styleSpec[`source_${type.replace(\"-\", \"_\")}`],\n\t\t\t\tstyle: options.style,\n\t\t\t\tstyleSpec,\n\t\t\t\tobjectElementValidators,\n\t\t\t\tvalidateSpec\n\t\t\t});\n\t\t\treturn errors;\n\t\tcase \"raster-dem\":\n\t\t\terrors = validateRasterDEMSource({\n\t\t\t\tsourceName: key,\n\t\t\t\tvalue,\n\t\t\t\tstyle: options.style,\n\t\t\t\tstyleSpec,\n\t\t\t\tvalidateSpec\n\t\t\t});\n\t\t\treturn errors;\n\t\tcase \"geojson\":\n\t\t\terrors = validateObject({\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\tvalueSpec: styleSpec.source_geojson,\n\t\t\t\tstyle,\n\t\t\t\tstyleSpec,\n\t\t\t\tvalidateSpec,\n\t\t\t\tobjectElementValidators\n\t\t\t});\n\t\t\tif (value.cluster) for (const prop in value.clusterProperties) {\n\t\t\t\tconst [operator, mapExpr] = value.clusterProperties[prop];\n\t\t\t\tconst reduceExpr = typeof operator === \"string\" ? [\n\t\t\t\t\toperator,\n\t\t\t\t\t[\"accumulated\"],\n\t\t\t\t\t[\"get\", prop]\n\t\t\t\t] : operator;\n\t\t\t\terrors.push(...validateExpression({\n\t\t\t\t\tkey: `${key}.${prop}.map`,\n\t\t\t\t\tvalue: mapExpr,\n\t\t\t\t\tvalidateSpec,\n\t\t\t\t\texpressionContext: \"cluster-map\"\n\t\t\t\t}));\n\t\t\t\terrors.push(...validateExpression({\n\t\t\t\t\tkey: `${key}.${prop}.reduce`,\n\t\t\t\t\tvalue: reduceExpr,\n\t\t\t\t\tvalidateSpec,\n\t\t\t\t\texpressionContext: \"cluster-reduce\"\n\t\t\t\t}));\n\t\t\t}\n\t\t\treturn errors;\n\t\tcase \"video\": return validateObject({\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\tvalueSpec: styleSpec.source_video,\n\t\t\tstyle,\n\t\t\tvalidateSpec,\n\t\t\tstyleSpec\n\t\t});\n\t\tcase \"image\": return validateObject({\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\tvalueSpec: styleSpec.source_image,\n\t\t\tstyle,\n\t\t\tvalidateSpec,\n\t\t\tstyleSpec\n\t\t});\n\t\tcase \"canvas\": return [new ValidationError(key, null, \"Please use runtime APIs to add canvas sources, rather than including them in stylesheets.\", \"source.canvas\")];\n\t\tdefault: return validateEnum({\n\t\t\tkey: `${key}.type`,\n\t\t\tvalue: value.type,\n\t\t\tvalueSpec: { values: [\n\t\t\t\t\"vector\",\n\t\t\t\t\"raster\",\n\t\t\t\t\"raster-dem\",\n\t\t\t\t\"geojson\",\n\t\t\t\t\"video\",\n\t\t\t\t\"image\"\n\t\t\t] },\n\t\t\tstyle,\n\t\t\tvalidateSpec,\n\t\t\tstyleSpec\n\t\t});\n\t}\n}\nfunction validatePromoteId({ key, value }) {\n\tif (getType(value) === \"string\") return validateString({\n\t\tkey,\n\t\tvalue\n\t});\n\telse {\n\t\tconst errors = [];\n\t\tfor (const prop in value) errors.push(...validateString({\n\t\t\tkey: `${key}.${prop}`,\n\t\t\tvalue: value[prop]\n\t\t}));\n\t\treturn errors;\n\t}\n}\n//#endregion\n//#region src/validate/validate_light.ts\nfunction validateLight(options) {\n\tconst light = options.value;\n\tconst styleSpec = options.styleSpec;\n\tconst lightSpec = styleSpec.light;\n\tconst style = options.style;\n\tlet errors = [];\n\tconst rootType = getType(light);\n\tif (light === void 0) return errors;\n\telse if (rootType !== \"object\") {\n\t\terrors = errors.concat([new ValidationError(\"light\", light, `object expected, ${rootType} found`)]);\n\t\treturn errors;\n\t}\n\tfor (const key in light) {\n\t\tconst transitionMatch = key.match(/^(.*)-transition$/);\n\t\tif (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) errors = errors.concat(options.validateSpec({\n\t\t\tkey,\n\t\t\tvalue: light[key],\n\t\t\tvalueSpec: styleSpec.transition,\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tstyle,\n\t\t\tstyleSpec\n\t\t}));\n\t\telse if (lightSpec[key]) errors = errors.concat(options.validateSpec({\n\t\t\tkey,\n\t\t\tvalue: light[key],\n\t\t\tvalueSpec: lightSpec[key],\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tstyle,\n\t\t\tstyleSpec\n\t\t}));\n\t\telse errors = errors.concat([new ValidationError(key, light[key], `unknown property \"${key}\"`)]);\n\t}\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_sky.ts\nfunction validateSky(options) {\n\tconst sky = options.value;\n\tconst styleSpec = options.styleSpec;\n\tconst skySpec = styleSpec.sky;\n\tconst style = options.style;\n\tconst rootType = getType(sky);\n\tif (sky === void 0) return [];\n\telse if (rootType !== \"object\") return [new ValidationError(\"sky\", sky, `object expected, ${rootType} found`)];\n\tlet errors = [];\n\tfor (const key in sky) if (skySpec[key]) errors = errors.concat(options.validateSpec({\n\t\tkey,\n\t\tvalue: sky[key],\n\t\tvalueSpec: skySpec[key],\n\t\tstyle,\n\t\tstyleSpec\n\t}));\n\telse errors = errors.concat([new ValidationError(key, sky[key], `unknown property \"${key}\"`)]);\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_terrain.ts\nfunction validateTerrain(options) {\n\tconst terrain = options.value;\n\tconst styleSpec = options.styleSpec;\n\tconst terrainSpec = styleSpec.terrain;\n\tconst style = options.style;\n\tlet errors = [];\n\tconst rootType = getType(terrain);\n\tif (terrain === void 0) return errors;\n\telse if (rootType !== \"object\") {\n\t\terrors = errors.concat([new ValidationError(\"terrain\", terrain, `object expected, ${rootType} found`)]);\n\t\treturn errors;\n\t}\n\tfor (const key in terrain) if (terrainSpec[key]) errors = errors.concat(options.validateSpec({\n\t\tkey,\n\t\tvalue: terrain[key],\n\t\tvalueSpec: terrainSpec[key],\n\t\tvalidateSpec: options.validateSpec,\n\t\tstyle,\n\t\tstyleSpec\n\t}));\n\telse errors = errors.concat([new ValidationError(key, terrain[key], `unknown property \"${key}\"`)]);\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_formatted.ts\nfunction validateFormatted(options) {\n\tif (validateString(options).length === 0) return [];\n\treturn validateExpression(options);\n}\n//#endregion\n//#region src/validate/validate_image.ts\nfunction validateImage(options) {\n\tif (validateString(options).length === 0) return [];\n\treturn validateExpression(options);\n}\n//#endregion\n//#region src/validate/validate_padding.ts\nfunction validatePadding(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tif (getType(value) === \"array\") {\n\t\tif (value.length < 1 || value.length > 4) return [new ValidationError(key, value, `padding requires 1 to 4 values; ${value.length} values found`)];\n\t\tconst arrayElementSpec = { type: \"number\" };\n\t\tlet errors = [];\n\t\tfor (let i = 0; i < value.length; i++) errors = errors.concat(options.validateSpec({\n\t\t\tkey: `${key}[${i}]`,\n\t\t\tvalue: value[i],\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tvalueSpec: arrayElementSpec\n\t\t}));\n\t\treturn errors;\n\t} else return validateNumber({\n\t\tkey,\n\t\tvalue,\n\t\tvalueSpec: {}\n\t});\n}\n//#endregion\n//#region src/validate/validate_number_array.ts\nfunction validateNumberArray(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tif (getType(value) === \"array\") {\n\t\tconst arrayElementSpec = { type: \"number\" };\n\t\tif (value.length < 1) return [new ValidationError(key, value, \"array length at least 1 expected, length 0 found\")];\n\t\tlet errors = [];\n\t\tfor (let i = 0; i < value.length; i++) errors = errors.concat(options.validateSpec({\n\t\t\tkey: `${key}[${i}]`,\n\t\t\tvalue: value[i],\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tvalueSpec: arrayElementSpec\n\t\t}));\n\t\treturn errors;\n\t} else return validateNumber({\n\t\tkey,\n\t\tvalue,\n\t\tvalueSpec: {}\n\t});\n}\n//#endregion\n//#region src/validate/validate_color_array.ts\nfunction validateColorArray(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tif (getType(value) === \"array\") {\n\t\tif (value.length < 1) return [new ValidationError(key, value, \"array length at least 1 expected, length 0 found\")];\n\t\tlet errors = [];\n\t\tfor (let i = 0; i < value.length; i++) errors = errors.concat(validateColor({\n\t\t\tkey: `${key}[${i}]`,\n\t\t\tvalue: value[i],\n\t\t\tvalueSpec: {}\n\t\t}));\n\t\treturn errors;\n\t} else return validateColor({\n\t\tkey,\n\t\tvalue,\n\t\tvalueSpec: {}\n\t});\n}\n//#endregion\n//#region src/validate/validate_variable_anchor_offset_collection.ts\nfunction validateVariableAnchorOffsetCollection(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tconst type = getType(value);\n\tconst styleSpec = options.styleSpec;\n\tif (type !== \"array\" || value.length < 1 || value.length % 2 !== 0) return [new ValidationError(key, value, \"variableAnchorOffsetCollection requires a non-empty array of even length\")];\n\tlet errors = [];\n\tfor (let i = 0; i < value.length; i += 2) {\n\t\terrors = errors.concat(validateEnum({\n\t\t\tkey: `${key}[${i}]`,\n\t\t\tvalue: value[i],\n\t\t\tvalueSpec: styleSpec[\"layout_symbol\"][\"text-anchor\"]\n\t\t}));\n\t\terrors = errors.concat(validateArray({\n\t\t\tkey: `${key}[${i + 1}]`,\n\t\t\tvalue: value[i + 1],\n\t\t\tvalueSpec: {\n\t\t\t\tlength: 2,\n\t\t\t\tvalue: \"number\"\n\t\t\t},\n\t\t\tvalidateSpec: options.validateSpec,\n\t\t\tstyle: options.style,\n\t\t\tstyleSpec\n\t\t}));\n\t}\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_sprite.ts\nfunction validateSprite(options) {\n\tlet errors = [];\n\tconst sprite = options.value;\n\tconst key = options.key;\n\tif (!Array.isArray(sprite)) return validateString({\n\t\tkey,\n\t\tvalue: sprite\n\t});\n\telse {\n\t\tconst allSpriteIds = [];\n\t\tconst allSpriteURLs = [];\n\t\tfor (const i in sprite) {\n\t\t\tif (sprite[i].id && allSpriteIds.includes(sprite[i].id)) errors.push(new ValidationError(key, sprite, `all the sprites' ids must be unique, but ${sprite[i].id} is duplicated`));\n\t\t\tallSpriteIds.push(sprite[i].id);\n\t\t\tif (sprite[i].url && allSpriteURLs.includes(sprite[i].url)) errors.push(new ValidationError(key, sprite, `all the sprites' URLs must be unique, but ${sprite[i].url} is duplicated`));\n\t\t\tallSpriteURLs.push(sprite[i].url);\n\t\t\terrors = errors.concat(validateObject({\n\t\t\t\tkey: `${key}[${i}]`,\n\t\t\t\tvalue: sprite[i],\n\t\t\t\tvalueSpec: {\n\t\t\t\t\tid: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true\n\t\t\t\t\t},\n\t\t\t\t\turl: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\trequired: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tvalidateSpec: options.validateSpec\n\t\t\t}));\n\t\t}\n\t\treturn errors;\n\t}\n}\n//#endregion\n//#region src/validate/validate_projection.ts\nfunction validateProjection(options) {\n\tconst projection = options.value;\n\tconst styleSpec = options.styleSpec;\n\tconst projectionSpec = styleSpec.projection;\n\tconst style = options.style;\n\tconst rootType = getType(projection);\n\tif (projection === void 0) return [];\n\telse if (rootType !== \"object\") return [new ValidationError(\"projection\", projection, `object expected, ${rootType} found`)];\n\tlet errors = [];\n\tfor (const key in projection) if (projectionSpec[key]) errors = errors.concat(options.validateSpec({\n\t\tkey,\n\t\tvalue: projection[key],\n\t\tvalueSpec: projectionSpec[key],\n\t\tstyle,\n\t\tstyleSpec\n\t}));\n\telse errors = errors.concat([new ValidationError(key, projection[key], `unknown property \"${key}\"`)]);\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate_projectiondefinition.ts\nfunction validateProjectionDefinition(options) {\n\tconst key = options.key;\n\tlet value = options.value;\n\tvalue = value instanceof String ? value.valueOf() : value;\n\tconst type = getType(value);\n\tif (type === \"array\" && !isProjectionDefinitionValue(value) && !isPropertyValueSpecification(value)) return [new ValidationError(key, value, `projection expected, invalid array ${JSON.stringify(value)} found`)];\n\telse if (![\"array\", \"string\"].includes(type)) return [new ValidationError(key, value, `projection expected, invalid type \"${type}\" found`)];\n\treturn [];\n}\nfunction isPropertyValueSpecification(value) {\n\tif ([\n\t\t\"interpolate\",\n\t\t\"step\",\n\t\t\"literal\"\n\t].includes(value[0])) return true;\n\treturn false;\n}\nfunction isProjectionDefinitionValue(value) {\n\treturn Array.isArray(value) && value.length === 3 && typeof value[0] === \"string\" && typeof value[1] === \"string\" && typeof value[2] === \"number\";\n}\n//#endregion\n//#region src/util/is_object_literal.ts\nfunction isObjectLiteral(anything) {\n\treturn Boolean(anything) && anything.constructor === Object;\n}\n//#endregion\n//#region src/validate/validate_state.ts\nfunction validateState(options) {\n\tif (!isObjectLiteral(options.value)) return [new ValidationError(options.key, options.value, `object expected, ${getType(options.value)} found`)];\n\treturn [];\n}\n//#endregion\n//#region src/validate/validate_font_faces.ts\nfunction validateFontFaces(options) {\n\tconst key = options.key;\n\tconst value = options.value;\n\tconst validateSpec = options.validateSpec;\n\tconst styleSpec = options.styleSpec;\n\tconst style = options.style;\n\tif (!isObjectLiteral(value)) return [new ValidationError(key, value, `object expected, ${getType(value)} found`)];\n\tconst errors = [];\n\tfor (const fontName in value) {\n\t\tconst fontValue = value[fontName];\n\t\tconst fontValueType = getType(fontValue);\n\t\tif (fontValueType === \"string\") errors.push(...validateString({\n\t\t\tkey: `${key}.${fontName}`,\n\t\t\tvalue: fontValue\n\t\t}));\n\t\telse if (fontValueType === \"array\") {\n\t\t\tconst fontFaceSpec = {\n\t\t\t\turl: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true\n\t\t\t\t},\n\t\t\t\t\"unicode-range\": {\n\t\t\t\t\ttype: \"array\",\n\t\t\t\t\tvalue: \"string\"\n\t\t\t\t}\n\t\t\t};\n\t\t\tfor (const [i, fontFace] of fontValue.entries()) errors.push(...validateObject({\n\t\t\t\tkey: `${key}.${fontName}[${i}]`,\n\t\t\t\tvalue: fontFace,\n\t\t\t\tvalueSpec: fontFaceSpec,\n\t\t\t\tstyleSpec,\n\t\t\t\tstyle,\n\t\t\t\tvalidateSpec\n\t\t\t}));\n\t\t} else errors.push(new ValidationError(`${key}.${fontName}`, fontValue, `string or array expected, ${fontValueType} found`));\n\t}\n\treturn errors;\n}\n//#endregion\n//#region src/validate/validate.ts\nconst VALIDATORS = {\n\t\"*\"() {\n\t\treturn [];\n\t},\n\tarray: validateArray,\n\tboolean: validateBoolean,\n\tnumber: validateNumber,\n\tcolor: validateColor,\n\tconstants: validateConstants,\n\tenum: validateEnum,\n\tfilter: validateFilter,\n\tfunction: validateFunction,\n\tlayer: validateLayer,\n\tobject: validateObject,\n\tsource: validateSource,\n\tlight: validateLight,\n\tsky: validateSky,\n\tterrain: validateTerrain,\n\tprojection: validateProjection,\n\tprojectionDefinition: validateProjectionDefinition,\n\tstring: validateString,\n\tformatted: validateFormatted,\n\tresolvedImage: validateImage,\n\tpadding: validatePadding,\n\tnumberArray: validateNumberArray,\n\tcolorArray: validateColorArray,\n\tvariableAnchorOffsetCollection: validateVariableAnchorOffsetCollection,\n\tsprite: validateSprite,\n\tstate: validateState,\n\tfontFaces: validateFontFaces\n};\n/**\n* Main recursive validation function used internally.\n* You should use `validateStyleMin` in the browser or `validateStyle` in node env.\n* @param options - the options object\n* @param options.key - string representing location of validation in style tree. Used only\n* for more informative error reporting.\n* @param options.value - current value from style being evaluated. May be anything from a\n* high level object that needs to be descended into deeper or a simple\n* scalar value.\n* @param options.valueSpec - current spec being evaluated. Tracks value.\n* @param options.styleSpec - current full spec being evaluated.\n* @param options.validateSpec - the validate function itself\n* @param options.style - the style object\n* @param options.objectElementValidators - optional object of functions that will be called\n* @returns an array of errors, or an empty array if no errors are found.\n*/\nfunction validate(options) {\n\tconst value = options.value;\n\tconst valueSpec = options.valueSpec;\n\tconst styleSpec = options.styleSpec;\n\toptions.validateSpec = validate;\n\tif (valueSpec.expression && isFunction(unbundle(value))) return validateFunction(options);\n\telse if (valueSpec.expression && isExpression(deepUnbundle(value))) return validateExpression(options);\n\telse if (valueSpec.type && VALIDATORS[valueSpec.type]) return VALIDATORS[valueSpec.type](options);\n\telse return validateObject(extendBy({}, options, { valueSpec: valueSpec.type ? styleSpec[valueSpec.type] : valueSpec }));\n}\n//#endregion\n//#region src/validate/validate_glyphs_url.ts\nfunction validateGlyphsUrl(options) {\n\tconst value = options.value;\n\tconst key = options.key;\n\tconst errors = validateString(options);\n\tif (errors.length) return errors;\n\tif (value.indexOf(\"{fontstack}\") === -1) errors.push(new ValidationError(key, value, \"\\\"glyphs\\\" url must include a \\\"{fontstack}\\\" token\"));\n\tif (value.indexOf(\"{range}\") === -1) errors.push(new ValidationError(key, value, \"\\\"glyphs\\\" url must include a \\\"{range}\\\" token\"));\n\treturn errors;\n}\n//#endregion\n//#region src/validate_style.min.ts\n/**\n* Validate a MapLibre style against the style specification.\n* Use this when running in the browser.\n*\n* @param style - The style to be validated.\n* @param styleSpec - The style specification to validate against.\n* If omitted, the latest style spec is used.\n* @returns an array of errors, or an empty array if no errors are found.\n* @example\n* const validate = require('@maplibre/maplibre-gl-style-spec/').validateStyleMin;\n* const errors = validate(style);\n*/\nfunction validateStyleMin(style, styleSpec = latest) {\n\tlet errors = [];\n\terrors = errors.concat(validate({\n\t\tkey: \"\",\n\t\tvalue: style,\n\t\tvalueSpec: styleSpec.$root,\n\t\tstyleSpec,\n\t\tstyle,\n\t\tvalidateSpec: validate,\n\t\tobjectElementValidators: {\n\t\t\tglyphs: validateGlyphsUrl,\n\t\t\t\"*\"() {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\t}));\n\tif (style[\"constants\"]) errors = errors.concat(validateConstants({\n\t\tkey: \"constants\",\n\t\tvalue: style[\"constants\"],\n\t\tstyle,\n\t\tstyleSpec,\n\t\tvalidateSpec: validate\n\t}));\n\treturn sortErrors(errors);\n}\nvalidateStyleMin.source = wrapCleanErrors(injectValidateSpec(validateSource));\nvalidateStyleMin.sprite = wrapCleanErrors(injectValidateSpec(validateSprite));\nvalidateStyleMin.glyphs = wrapCleanErrors(injectValidateSpec(validateGlyphsUrl));\nvalidateStyleMin.light = wrapCleanErrors(injectValidateSpec(validateLight));\nvalidateStyleMin.sky = wrapCleanErrors(injectValidateSpec(validateSky));\nvalidateStyleMin.terrain = wrapCleanErrors(injectValidateSpec(validateTerrain));\nvalidateStyleMin.state = wrapCleanErrors(injectValidateSpec(validateState));\nvalidateStyleMin.layer = wrapCleanErrors(injectValidateSpec(validateLayer));\nvalidateStyleMin.filter = wrapCleanErrors(injectValidateSpec(validateFilter));\nvalidateStyleMin.paintProperty = wrapCleanErrors(injectValidateSpec(validatePaintProperty));\nvalidateStyleMin.layoutProperty = wrapCleanErrors(injectValidateSpec(validateLayoutProperty));\nfunction injectValidateSpec(validator) {\n\treturn function(options) {\n\t\treturn validator(Object.assign({}, options, { validateSpec: validate }));\n\t};\n}\nfunction sortErrors(errors) {\n\treturn [].concat(errors).sort((a, b) => {\n\t\treturn a.line - b.line;\n\t});\n}\nfunction wrapCleanErrors(inner) {\n\treturn function(...args) {\n\t\treturn sortErrors(inner.apply(this, args));\n\t};\n}\n//#endregion\n//#region node_modules/json-stringify-pretty-compact/index.js\nconst stringOrChar = /(\"(?:[^\\\\\"]|\\\\.)*\")|[:,]/g;\nfunction stringify(passedObj, options = {}) {\n\tconst indent = JSON.stringify([1], void 0, options.indent === void 0 ? 2 : options.indent).slice(2, -3);\n\tconst maxLength = indent === \"\" ? Infinity : options.maxLength === void 0 ? 80 : options.maxLength;\n\tlet { replacer } = options;\n\treturn (function _stringify(obj, currentIndent, reserved) {\n\t\tif (obj && typeof obj.toJSON === \"function\") obj = obj.toJSON();\n\t\tconst string = JSON.stringify(obj, replacer);\n\t\tif (string === void 0) return string;\n\t\tconst length = maxLength - currentIndent.length - reserved;\n\t\tif (string.length <= length) {\n\t\t\tconst prettified = string.replace(stringOrChar, (match, stringLiteral) => {\n\t\t\t\treturn stringLiteral || `${match} `;\n\t\t\t});\n\t\t\tif (prettified.length <= length) return prettified;\n\t\t}\n\t\tif (replacer != null) {\n\t\t\tobj = JSON.parse(string);\n\t\t\treplacer = void 0;\n\t\t}\n\t\tif (typeof obj === \"object\" && obj !== null) {\n\t\t\tconst nextIndent = currentIndent + indent;\n\t\t\tconst items = [];\n\t\t\tlet index = 0;\n\t\t\tlet start;\n\t\t\tlet end;\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\tstart = \"[\";\n\t\t\t\tend = \"]\";\n\t\t\t\tconst { length } = obj;\n\t\t\t\tfor (; index < length; index++) items.push(_stringify(obj[index], nextIndent, index === length - 1 ? 0 : 1) || \"null\");\n\t\t\t} else {\n\t\t\t\tstart = \"{\";\n\t\t\t\tend = \"}\";\n\t\t\t\tconst keys = Object.keys(obj);\n\t\t\t\tconst { length } = keys;\n\t\t\t\tfor (; index < length; index++) {\n\t\t\t\t\tconst key = keys[index];\n\t\t\t\t\tconst keyPart = `${JSON.stringify(key)}: `;\n\t\t\t\t\tconst value = _stringify(obj[key], nextIndent, keyPart.length + (index === length - 1 ? 0 : 1));\n\t\t\t\t\tif (value !== void 0) items.push(keyPart + value);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (items.length > 0) return [\n\t\t\t\tstart,\n\t\t\t\tindent + items.join(`,\\n${nextIndent}`),\n\t\t\t\tend\n\t\t\t].join(`\\n${currentIndent}`);\n\t\t}\n\t\treturn string;\n\t})(passedObj, \"\", 0);\n}\n//#endregion\n//#region src/format.ts\nfunction sortKeysBy(obj, reference) {\n\tconst result = {};\n\tfor (const key in reference) if (obj[key] !== void 0) result[key] = obj[key];\n\tfor (const key in obj) if (result[key] === void 0) result[key] = obj[key];\n\treturn result;\n}\n/**\n* Format a MapLibre Style. Returns a stringified style with its keys\n* sorted in the same order as the reference style.\n*\n* The optional `space` argument is passed to\n* [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)\n* to generate formatted output.\n*\n* If `space` is unspecified, a default of `2` spaces will be used.\n*\n* @private\n* @param {Object} style a MapLibre Style\n* @param {number} [space] space argument to pass to `JSON.stringify`\n* @returns {string} stringified formatted JSON\n* @example\n* var fs = require('fs');\n* var format = require('maplibre-gl-style-spec').format;\n* var style = fs.readFileSync('./source.json', 'utf8');\n* fs.writeFileSync('./dest.json', format(style));\n* fs.writeFileSync('./dest.min.json', format(style, 0));\n*/\nfunction format(style, space = 2) {\n\tstyle = sortKeysBy(style, latest.$root);\n\tif (style.layers) style.layers = style.layers.map((layer) => sortKeysBy(layer, latest.layer));\n\treturn stringify(style, { indent: space });\n}\n//#endregion\n//#region src/migrate/v8.ts\nfunction eachLayout(layer, callback) {\n\tfor (const k in layer) if (k.indexOf(\"layout\") === 0) callback(layer[k], k);\n}\nfunction eachPaint(layer, callback) {\n\tfor (const k in layer) if (k.indexOf(\"paint\") === 0) callback(layer[k], k);\n}\nfunction resolveConstant(style, value) {\n\tif (typeof value === \"string\" && value[0] === \"@\") return resolveConstant(style, style.constants[value]);\n\telse return value;\n}\nfunction isFunction$1(value) {\n\treturn Array.isArray(value.stops);\n}\nfunction renameProperty(obj, from, to) {\n\tobj[to] = obj[from];\n\tdelete obj[from];\n}\nfunction migrateV8(style) {\n\tstyle.version = 8;\n\teachSource(style, (source) => {\n\t\tif (source.type === \"video\" && source[\"url\"] !== void 0) renameProperty(source, \"url\", \"urls\");\n\t\tif (source.type === \"video\") source.coordinates.forEach((coord) => {\n\t\t\treturn coord.reverse();\n\t\t});\n\t});\n\teachLayer(style, (layer) => {\n\t\teachLayout(layer, (layout) => {\n\t\t\tif (layout[\"symbol-min-distance\"] !== void 0) renameProperty(layout, \"symbol-min-distance\", \"symbol-spacing\");\n\t\t});\n\t\teachPaint(layer, (paint) => {\n\t\t\tif (paint[\"background-image\"] !== void 0) renameProperty(paint, \"background-image\", \"background-pattern\");\n\t\t\tif (paint[\"line-image\"] !== void 0) renameProperty(paint, \"line-image\", \"line-pattern\");\n\t\t\tif (paint[\"fill-image\"] !== void 0) renameProperty(paint, \"fill-image\", \"fill-pattern\");\n\t\t});\n\t});\n\teachProperty(style, {\n\t\tpaint: true,\n\t\tlayout: true\n\t}, (property) => {\n\t\tconst value = resolveConstant(style, property.value);\n\t\tif (isFunction$1(value)) value.stops.forEach((stop) => {\n\t\t\tstop[1] = resolveConstant(style, stop[1]);\n\t\t});\n\t\tproperty.set(value);\n\t});\n\tdelete style[\"constants\"];\n\teachLayer(style, (layer) => {\n\t\teachLayout(layer, (layout) => {\n\t\t\tdelete layout[\"text-max-size\"];\n\t\t\tdelete layout[\"icon-max-size\"];\n\t\t});\n\t\teachPaint(layer, (paint) => {\n\t\t\tif (paint[\"text-size\"]) {\n\t\t\t\tif (!layer.layout) layer.layout = {};\n\t\t\t\tlayer.layout[\"text-size\"] = paint[\"text-size\"];\n\t\t\t\tdelete paint[\"text-size\"];\n\t\t\t}\n\t\t\tif (paint[\"icon-size\"]) {\n\t\t\t\tif (!layer.layout) layer.layout = {};\n\t\t\t\tlayer.layout[\"icon-size\"] = paint[\"icon-size\"];\n\t\t\t\tdelete paint[\"icon-size\"];\n\t\t\t}\n\t\t});\n\t});\n\tfunction migrateFontStack(font) {\n\t\tfunction splitAndTrim(string) {\n\t\t\treturn string.split(\",\").map((s) => {\n\t\t\t\treturn s.trim();\n\t\t\t});\n\t\t}\n\t\tif (Array.isArray(font)) return font;\n\t\telse if (typeof font === \"string\") return splitAndTrim(font);\n\t\telse if (typeof font === \"object\") {\n\t\t\tfont.stops.forEach((stop) => {\n\t\t\t\tstop[1] = splitAndTrim(stop[1]);\n\t\t\t});\n\t\t\treturn font;\n\t\t} else throw new Error(\"unexpected font value\");\n\t}\n\teachLayer(style, (layer) => {\n\t\teachLayout(layer, (layout) => {\n\t\t\tif (layout[\"text-font\"]) layout[\"text-font\"] = migrateFontStack(layout[\"text-font\"]);\n\t\t});\n\t});\n\tlet firstSymbolLayer = 0;\n\tfor (let i = style.layers.length - 1; i >= 0; i--) if (style.layers[i].type !== \"symbol\") {\n\t\tfirstSymbolLayer = i + 1;\n\t\tbreak;\n\t}\n\tconst symbolLayers = style.layers.splice(firstSymbolLayer);\n\tsymbolLayers.reverse();\n\tstyle.layers = style.layers.concat(symbolLayers);\n\treturn style;\n}\n//#endregion\n//#region src/migrate/expressions.ts\n/**\n* Migrate the given style object in place to use expressions. Specifically,\n* this will convert (a) \"stop\" functions, and (b) legacy filters to their\n* expression equivalents.\n* @param style The style object to migrate.\n* @returns The migrated style object.\n*/\nfunction expressions$1(style) {\n\tconst converted = [];\n\teachLayer(style, (layer) => {\n\t\tif (layer.filter) layer.filter = convertFilter(layer.filter);\n\t});\n\teachProperty(style, {\n\t\tpaint: true,\n\t\tlayout: true\n\t}, ({ path, key, value, reference, set }) => {\n\t\tif (isExpression(value) || key.endsWith(\"-transition\") || reference === null) return;\n\t\tif (typeof value === \"object\" && !Array.isArray(value)) {\n\t\t\tset(convertFunction(value, reference));\n\t\t\tconverted.push(path.join(\".\"));\n\t\t} else if (reference.tokens && typeof value === \"string\") set(convertTokenString(value));\n\t});\n\treturn style;\n}\n//#endregion\n//#region src/migrate/migrate_colors.ts\n/**\n* Migrate color style values to supported format.\n*\n* @param colorToMigrate Color value to migrate, could be a string or an expression.\n* @returns Color style value in supported format.\n*/\nfunction migrateColors(colorToMigrate) {\n\treturn JSON.parse(migrateHslColors(JSON.stringify(colorToMigrate)));\n}\n/**\n* Created to migrate from colors supported by the former CSS color parsing\n* library `csscolorparser` but not compliant with the CSS Color specification,\n* like `hsl(900, 0.15, 90%)`.\n*\n* @param colorToMigrate Serialized color style value.\n* @returns A serialized color style value in which all non-standard hsl color values\n* have been converted to a format that complies with the CSS Color specification.\n*\n* @example\n* migrateHslColors('\"hsl(900, 0.15, 90%)\"'); // returns '\"hsl(900, 15%, 90%)\"'\n* migrateHslColors('\"hsla(900, .15, .9)\"'); // returns '\"hsl(900, 15%, 90%)\"'\n* migrateHslColors('\"hsl(900, 15%, 90%)\"'); // returns '\"hsl(900, 15%, 90%)\"' - no changes\n*/\nfunction migrateHslColors(colorToMigrate) {\n\treturn colorToMigrate.replace(/\"hsla?\\((.+?)\\)\"/gi, (match, hslArgs) => {\n\t\tconst argsMatch = hslArgs.match(/^(.+?)\\s*,\\s*(.+?)\\s*,\\s*(.+?)(?:\\s*,\\s*(.+))?$/i);\n\t\tif (argsMatch) {\n\t\t\tlet [h, s, l, a] = argsMatch.slice(1);\n\t\t\t[s, l] = [s, l].map((v) => v.endsWith(\"%\") ? v : `${parseFloat(v) * 100}%`);\n\t\t\treturn `\"hsl${typeof a === \"string\" ? \"a\" : \"\"}(${[\n\t\t\t\th,\n\t\t\t\ts,\n\t\t\t\tl,\n\t\t\t\ta\n\t\t\t].filter(Boolean).join(\",\")})\"`;\n\t\t}\n\t\treturn match;\n\t});\n}\n//#endregion\n//#region src/migrate.ts\n/**\n* Migrate a Mapbox/MapLibre GL Style to the latest version.\n*\n* @param style - a MapLibre Style\n* @returns a migrated style\n* @example\n* const fs = require('fs');\n* const migrate = require('@maplibre/maplibre-gl-style-spec').migrate;\n* const style = fs.readFileSync('./style.json', 'utf8');\n* fs.writeFileSync('./style.json', JSON.stringify(migrate(style)));\n*/\nfunction migrate(style) {\n\tlet migrated = false;\n\tif (style.version === 7) {\n\t\tstyle = migrateV8(style);\n\t\tmigrated = true;\n\t}\n\tif (style.version === 8) {\n\t\tmigrated = !!expressions$1(style);\n\t\tmigrated = true;\n\t}\n\teachProperty(style, {\n\t\tpaint: true,\n\t\tlayout: true\n\t}, ({ value, reference, set }) => {\n\t\tif (reference?.type === \"color\") set(migrateColors(value));\n\t});\n\tif (!migrated) throw new Error(`Cannot migrate from ${style.version}`);\n\treturn style;\n}\n//#endregion\n//#region src/expression/visibility.ts\nconst visibilitySpec = {\n\ttype: \"enum\",\n\t\"property-type\": \"data-constant\",\n\texpression: {\n\t\tinterpolated: false,\n\t\tparameters: [\"global-state\"]\n\t},\n\tvalues: {\n\t\tvisible: {},\n\t\tnone: {}\n\t},\n\ttransition: false,\n\tdefault: \"visible\"\n};\nvar VisibilityExpressionClass = class {\n\tconstructor(visibility, rootKey, globalState) {\n\t\tthis._rootKey = rootKey;\n\t\tthis._globalState = globalState;\n\t\tthis.setValue(visibility);\n\t}\n\tevaluate() {\n\t\treturn this._literalValue ?? this._compiledValue.evaluate({});\n\t}\n\tsetValue(visibility) {\n\t\tif (visibility === null || visibility === void 0 || visibility === \"visible\" || visibility === \"none\") {\n\t\t\tthis._literalValue = visibility === \"none\" ? \"none\" : \"visible\";\n\t\t\tthis._compiledValue = void 0;\n\t\t\tthis._globalStateRefs = /* @__PURE__ */ new Set();\n\t\t\treturn;\n\t\t}\n\t\tconst compiled = createExpression(visibility, this._rootKey, visibilitySpec, this._globalState);\n\t\tif (compiled.result === \"error\") {\n\t\t\tthis._literalValue = \"visible\";\n\t\t\tthis._compiledValue = void 0;\n\t\t\tthrow new Error(compiled.value.map((err) => `${err.key}: ${err.message}`).join(\", \"));\n\t\t}\n\t\tthis._literalValue = void 0;\n\t\tthis._compiledValue = compiled.value;\n\t\tthis._globalStateRefs = findGlobalStateRefs(compiled.value.expression);\n\t}\n\tgetGlobalStateRefs() {\n\t\treturn this._globalStateRefs;\n\t}\n};\n/**\n* Creates a visibility expression from a visibility specification.\n* @param visibility - the visibility specification, literal or expression\n* @param rootKey - location of the visibility value in the style JSON\n* (e.g. `layers[3].layout.visibility`), used to prefix runtime warnings\n* @param globalState - the global state object\n* @returns visibility expression object\n*/\nfunction createVisibility(visibility, rootKey, globalState) {\n\treturn new VisibilityExpressionClass(visibility, rootKey, globalState);\n}\n//#endregion\n//#region src/index.ts\nconst expression = {\n\tStyleExpression,\n\tStylePropertyFunction,\n\tZoomConstantExpression,\n\tZoomDependentExpression,\n\tcreateExpression,\n\tcreatePropertyExpression,\n\tisExpression,\n\tisExpressionFilter,\n\tisZoomExpression,\n\tnormalizePropertyExpression\n};\nconst styleFunction = {\n\tconvertFunction,\n\tcreateFunction,\n\tisFunction\n};\nconst visit = {\n\teachLayer,\n\teachProperty,\n\teachSource\n};\n//#endregion\nexport { Color, ColorArray, ColorType, CompoundExpression, EvaluationContext, FormatExpression, Formatted, FormattedSection, FormattedType, Interpolate, Literal, NullType, NumberArray, Padding, ParsingError, ProjectionDefinition, ProjectionDefinitionType, ResolvedImage, Step, StyleExpression, StylePropertyFunction, ValidationError, VariableAnchorOffsetCollection, ZoomConstantExpression, ZoomDependentExpression, classifyRings, convertFilter, convertFunction, createExpression, createFunction, createPropertyExpression, createVisibility as createVisibilityExpression, derefLayers, diff, emptyStyle, expression, expressions, featureFilter, format, styleFunction as function, groupByLayout, interpolateFactory as interpolates, isExpression, isFunction, isZoomExpression, latest, latest as v8, migrate, normalizePropertyExpression, supportsPropertyExpression, typeToString as toString, typeOf, validate, validateStyleMin, visit };\n\n//# sourceMappingURL=index.mjs.map","import {latest as styleSpec, validateStyleMin} from '@maplibre/maplibre-gl-style-spec';\nimport {ErrorEvent} from '../util/evented.ts';\nimport {warnOnce} from '../util/util.ts';\n\nimport type {StyleSpecification, ValidationError} from '@maplibre/maplibre-gl-style-spec';\nimport type {Evented} from '../util/evented.ts';\nimport type {StyleSetterOptions} from './style.ts';\n\n/**\n * Validates a single part of a style, e.g. a source, a filter or a paint property.\n * The options it takes are the ones assembled by {@link validateAndEmit}.\n */\nexport type Validator = (options: any) => readonly ValidationError[];\n\ntype ValidateStyle = {\n source: Validator;\n sprite: Validator;\n glyphs: Validator;\n layer: Validator;\n light: Validator;\n sky: Validator;\n terrain: Validator;\n filter: Validator;\n paintProperty: Validator;\n layoutProperty: Validator;\n (b: any, a?: any | null): readonly ValidationError[];\n};\n\nexport const validateStyle = (validateStyleMin as unknown as ValidateStyle);\n\n/**\n * The source types the spec has a schema for, and therefore the only ones it can judge. Taken from\n * the spec itself so the two cannot drift apart.\n */\nexport const SPEC_SOURCE_TYPES: ReadonlySet = new Set(\n Object.keys(styleSpec)\n .filter(key => key.startsWith('source_'))\n .map(key => key.slice('source_'.length).replaceAll('_', '-'))\n);\n\n/**\n * The sources whose type the spec has no schema for, so it rejects them outright even though we\n * render them: `canvas`, and anything registered with {@link addSourceType}. They are the renderer's\n * business rather than the spec's, so the spec's complaints about them are dropped -- otherwise\n * `map.setStyle(map.getStyle())` would fail on a source the user added correctly.\n *\n * Each such source produces a single error keyed by `sources.`, which is what is matched here.\n * @param style - the style about to be validated\n * @returns the `sources.` key prefixes whose errors should be ignored\n */\nfunction unjudgeableSourceKeys(style: StyleSpecification): string[] {\n return Object.entries(style.sources ?? {})\n .filter(([, source]) => !SPEC_SOURCE_TYPES.has(source.type))\n .map(([id]) => `sources.${id}`);\n}\n\n/**\n * Validates a whole style and emits what it finds, ignoring the sources the spec cannot judge.\n *\n * @param emitter - the object to fire {@link ErrorEvent}s on\n * @param style - the style to validate\n * @returns whether validation failed, i.e. whether the caller should give up on the style\n */\nexport function validateStyleAndEmit(emitter: Evented, style: StyleSpecification): boolean {\n const ignored = unjudgeableSourceKeys(style);\n const errors = validateStyle(style).filter(({message}) =>\n !ignored.some(key => message.startsWith(`${key}:`) || message.startsWith(`${key}.`))\n );\n return emitValidationErrors(emitter, errors);\n}\n\n/**\n * Emits everything a validator found, and reports whether any of it was severe enough to abort.\n *\n * Warnings are logged rather than emitted as errors: the style still renders, just not necessarily\n * as its author intended (e.g. a filter mixing deprecated syntax into an expression tree). Treating\n * them as errors would abort the whole style load and leave a blank map.\n * See https://github.com/maplibre/maplibre-style-spec/issues/1751\n *\n * @param emitter - the object to fire {@link ErrorEvent}s on\n * @param errors - what validation turned up, if anything\n * @returns whether validation failed, i.e. whether the caller should give up on the value\n */\nexport function emitValidationErrors(emitter: Evented, errors: readonly ValidationError[]): boolean {\n let hasErrors = false;\n for (const error of errors) {\n if (error.severity === 'warning') {\n warnOnce(error.message);\n continue;\n }\n emitter.fire(new ErrorEvent(new Error(error.message)));\n hasErrors = true;\n }\n return hasErrors;\n}\n\n/**\n * Runs a validator over a value and emits whatever it finds.\n *\n * @param emitter - the object to fire {@link ErrorEvent}s on\n * @param validator - the validator to run, e.g. {@link validateFilter}\n * @param params - what to validate: the `value`, plus whatever context the validator needs, such as\n * the `key` locating it in the style, or the surrounding `style` that {@link validateStyle.layer} looks at\n * @param options - setter options; validation is skipped entirely when `validate` is `false`\n * @returns whether validation failed, i.e. whether the caller should give up on the value\n */\nexport function validateAndEmit(\n emitter: Evented,\n validator: Validator,\n params: {value: unknown} & Record,\n options?: StyleSetterOptions\n): boolean {\n if (options?.validate === false) {\n return false;\n }\n return emitValidationErrors(emitter, validator({\n styleSpec,\n ...params\n }));\n}\n","/*\nThis file was copied from https://github.com/mapbox/grid-index and was\nmigrated from JavaScript to TypeScript.\n\nCopyright (c) 2016, Mapbox\n\nPermission to use, copy, modify, and/or distribute this software for any purpose\nwith or without fee is hereby granted, provided that the above copyright notice\nand this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\nOF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\nTORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\nTHIS SOFTWARE.\n*/\n\nconst NUM_PARAMS = 3;\n\nexport type SerializedGrid = {\n buffer: ArrayBuffer;\n};\n\nexport class TransferableGridIndex {\n cells: number[][];\n arrayBuffer: ArrayBuffer;\n d: number;\n keys: number[];\n bboxes: number[];\n n: number;\n extent: number;\n padding: number;\n scale: any;\n uid: number;\n min: number;\n max: number;\n\n constructor(extent: number | ArrayBuffer, n?: number, padding?: number) {\n const cells = this.cells = [];\n\n if (extent instanceof ArrayBuffer) {\n this.arrayBuffer = extent;\n const array = new Int32Array(this.arrayBuffer);\n extent = array[0];\n n = array[1];\n padding = array[2];\n\n this.d = n + 2 * padding;\n for (let k = 0; k < this.d * this.d; k++) {\n const start = array[NUM_PARAMS + k];\n const end = array[NUM_PARAMS + k + 1];\n cells.push(start === end ? null : array.subarray(start, end));\n }\n const keysOffset = array[NUM_PARAMS + cells.length];\n const bboxesOffset = array[NUM_PARAMS + cells.length + 1];\n this.keys = array.subarray(keysOffset, bboxesOffset) as any as number[];\n this.bboxes = array.subarray(bboxesOffset) as any as number[];\n\n this.insert = this._insertReadonly;\n\n } else {\n this.d = n + 2 * padding;\n for (let i = 0; i < this.d * this.d; i++) {\n cells.push([]);\n }\n this.keys = [];\n this.bboxes = [];\n }\n\n this.n = n;\n this.extent = extent;\n this.padding = padding;\n this.scale = n / extent;\n this.uid = 0;\n\n const p = (padding / n) * extent;\n this.min = -p;\n this.max = extent + p;\n }\n\n insert(key: number, x1: number, y1: number, x2: number, y2: number): void {\n this._forEachCell(x1, y1, x2, y2, this._insertCell, this.uid++, undefined, undefined);\n this.keys.push(key);\n this.bboxes.push(x1);\n this.bboxes.push(y1);\n this.bboxes.push(x2);\n this.bboxes.push(y2);\n }\n\n _insertReadonly(): void {\n throw new Error('Cannot insert into a GridIndex created from an ArrayBuffer.');\n }\n\n _insertCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, uid: number): void {\n this.cells[cellIndex].push(uid);\n }\n\n query(x1: number, y1: number, x2: number, y2: number, intersectionTest?: (x1: number, y1: number, x2: number, y2: number) => boolean): number[] {\n const min = this.min;\n const max = this.max;\n if (x1 <= min && y1 <= min && max <= x2 && max <= y2 && !intersectionTest) {\n return [...this.keys];\n\n } else {\n const result = [];\n const seenUids = {};\n this._forEachCell(x1, y1, x2, y2, this._queryCell, result, seenUids, intersectionTest);\n return result;\n }\n }\n\n _queryCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, result: number[], seenUids: Record, intersectionTest: (x1: number, y1: number, x2: number, y2: number) => boolean): void {\n const cell = this.cells[cellIndex];\n if (cell !== null) {\n const keys = this.keys;\n const bboxes = this.bboxes;\n for (const uid of cell) {\n if (seenUids[uid] === undefined) {\n const offset = uid * 4;\n if (intersectionTest ?\n intersectionTest(bboxes[offset + 0], bboxes[offset + 1], bboxes[offset + 2], bboxes[offset + 3]) :\n ((x1 <= bboxes[offset + 2]) &&\n (y1 <= bboxes[offset + 3]) &&\n (x2 >= bboxes[offset + 0]) &&\n (y2 >= bboxes[offset + 1]))) {\n seenUids[uid] = true;\n result.push(keys[uid]);\n } else {\n seenUids[uid] = false;\n }\n }\n }\n }\n }\n\n _forEachCell(x1: number, y1: number, x2: number, y2: number, fn: Function, arg1: unknown, arg2: unknown, intersectionTest?: (x1: number, y1: number, x2: number, y2: number) => boolean): void {\n const cx1 = this._convertToCellCoord(x1);\n const cy1 = this._convertToCellCoord(y1);\n const cx2 = this._convertToCellCoord(x2);\n const cy2 = this._convertToCellCoord(y2);\n for (let x = cx1; x <= cx2; x++) {\n for (let y = cy1; y <= cy2; y++) {\n const cellIndex = this.d * y + x;\n if (intersectionTest && !intersectionTest(\n this._convertFromCellCoord(x),\n this._convertFromCellCoord(y),\n this._convertFromCellCoord(x + 1),\n this._convertFromCellCoord(y + 1))) continue;\n if (fn.call(this, x1, y1, x2, y2, cellIndex, arg1, arg2, intersectionTest)) return;\n }\n }\n }\n\n _convertFromCellCoord(x: number): number {\n return (x - this.padding) / this.scale;\n }\n\n _convertToCellCoord(x: number): number {\n return Math.max(0, Math.min(this.d - 1, Math.floor(x * this.scale) + this.padding));\n }\n\n toArrayBuffer(): ArrayBuffer {\n if (this.arrayBuffer) return this.arrayBuffer;\n\n const cells = this.cells;\n\n const metadataLength = NUM_PARAMS + this.cells.length + 1 + 1;\n let totalCellLength = 0;\n for (const cell of this.cells) {\n totalCellLength += cell.length;\n }\n\n const array = new Int32Array(metadataLength + totalCellLength + this.keys.length + this.bboxes.length);\n array[0] = this.extent;\n array[1] = this.n;\n array[2] = this.padding;\n\n let offset = metadataLength;\n for (let k = 0; k < cells.length; k++) {\n const cell = cells[k];\n array[NUM_PARAMS + k] = offset;\n array.set(cell, offset);\n offset += cell.length;\n }\n\n array[NUM_PARAMS + cells.length] = offset;\n array.set(this.keys, offset);\n offset += this.keys.length;\n\n array[NUM_PARAMS + cells.length + 1] = offset;\n array.set(this.bboxes, offset);\n offset += this.bboxes.length;\n\n return array.buffer;\n }\n\n public static serialize(grid: TransferableGridIndex, transferables?: Transferable[]): SerializedGrid {\n const buffer = grid.toArrayBuffer();\n if (transferables) {\n transferables.push(buffer);\n }\n return {buffer};\n }\n\n public static deserialize(serialized: SerializedGrid): TransferableGridIndex {\n return new TransferableGridIndex(serialized.buffer);\n }\n}\n","import {TransferableGridIndex} from './transferable_grid_index.ts';\nimport {Color, CompoundExpression, expressions, ResolvedImage, StylePropertyFunction,\n StyleExpression, ZoomDependentExpression, ZoomConstantExpression} from '@maplibre/maplibre-gl-style-spec';\nimport {AJAXError} from './ajax.ts';\nimport {isImageBitmap} from './util.ts';\n\n/**\n * A class that is serialized to and json, that can be constructed back to the original class in the worker or in the main thread\n */\ntype SerializedObject = {\n [_: string]: S;\n};\n\n/**\n * All the possible values that can be serialized and sent to and from the worker\n */\nexport type Serialized = null | void | boolean | number | string | Boolean | Number | String | Date | RegExp | ArrayBuffer | ArrayBufferView | ImageData | ImageBitmap | Blob | Serialized[] | SerializedObject;\n\ntype Registry = {\n [_: string]: {\n klass: {\n new (...args: any): any;\n deserialize?: (input: Serialized) => unknown;\n serialize?: (input: any, transferables: Transferable[]) => SerializedObject;\n };\n omit: readonly string[];\n shallow: readonly string[];\n };\n};\n\n/**\n * Register options\n */\ntype RegisterOptions = {\n /**\n * List of properties to omit from serialization (e.g., cached/computed properties)\n */\n omit?: ReadonlyArray;\n /**\n * List of properties that should be serialized by a simple shallow copy, rather than by a recursive call to serialize().\n */\n shallow?: ReadonlyArray;\n};\n\nconst registry: Registry = {};\n\n/**\n * Register the given class as serializable.\n *\n * @param options - the registration options\n */\nexport function register(\n name: string,\n klass: {\n new (...args: any): T;\n },\n options: RegisterOptions = {}\n): void {\n if (registry[name]) throw new Error(`${name} is already registered.`);\n ((Object.defineProperty as any))(klass, '_classRegistryKey', {\n value: name,\n writeable: false\n });\n registry[name] = {\n klass,\n omit: options.omit as readonly string[] || [],\n shallow: options.shallow as readonly string[] || []\n };\n}\n\nregister('Object', Object);\nregister('Set', Set);\nregister('TransferableGridIndex', TransferableGridIndex);\n\nregister('Color', Color);\nregister('Error', Error);\nregister('AJAXError', AJAXError);\nregister('ResolvedImage', ResolvedImage);\n\nregister('StylePropertyFunction', StylePropertyFunction);\nregister('StyleExpression', StyleExpression, {omit: ['_evaluator']});\n\nregister('ZoomDependentExpression', ZoomDependentExpression);\nregister('ZoomConstantExpression', ZoomConstantExpression);\nregister('CompoundExpression', CompoundExpression, {omit: ['_evaluate']});\nfor (const name in expressions) {\n if ((expressions[name] as any)._classRegistryKey) continue;\n register(`Expression_${name}`, expressions[name]);\n}\n\nfunction isArrayBuffer(value: any): value is ArrayBuffer {\n return value && typeof ArrayBuffer !== 'undefined' &&\n (value instanceof ArrayBuffer || (value.constructor?.name === 'ArrayBuffer'));\n}\n\nfunction getClassRegistryKey(input: Object|SerializedObject): string {\n const klass = (input.constructor as any);\n return (input as SerializedObject).$name || klass._classRegistryKey;\n}\n\nfunction isRegistered(input: unknown): boolean {\n if (input === null || typeof input !== 'object') {\n return false;\n }\n const classRegistryKey = getClassRegistryKey(input);\n return classRegistryKey && classRegistryKey !== 'Object';\n}\n\nfunction isSerializeHandledByBuiltin(input: unknown) {\n return (!isRegistered(input) && (\n input === null ||\n input === undefined ||\n typeof input === 'boolean' ||\n typeof input === 'number' ||\n typeof input === 'string' ||\n input instanceof Boolean ||\n input instanceof Number ||\n input instanceof String ||\n input instanceof Date ||\n input instanceof RegExp ||\n input instanceof Blob ||\n input instanceof Error ||\n isArrayBuffer(input) ||\n isImageBitmap(input) ||\n ArrayBuffer.isView(input) ||\n input instanceof ImageData)\n );\n}\n\n/**\n * Serialize the given object for transfer to or from a web worker.\n *\n * For non-builtin types, recursively serialize each property (possibly\n * omitting certain properties - see register()), and package the result along\n * with the constructor's `name` so that the appropriate constructor can be\n * looked up in `deserialize()`.\n *\n * If a `transferables` array is provided, add any transferable objects (i.e.,\n * any ArrayBuffers or ArrayBuffer views) to the list. (If a copy is needed,\n * this should happen in the client code, before using serialize().)\n */\nexport function serialize(input: unknown, transferables?: Transferable[] | null): Serialized {\n if (isSerializeHandledByBuiltin(input)) {\n if (isArrayBuffer(input) || isImageBitmap(input)) {\n if (transferables) {\n transferables.push(input);\n }\n }\n if (ArrayBuffer.isView(input)) {\n if (transferables) {\n transferables.push(input.buffer);\n }\n }\n if (input instanceof ImageData) {\n if (transferables) {\n transferables.push(input.data.buffer);\n }\n }\n return input;\n }\n\n if (Array.isArray(input)) {\n const serialized: Serialized[] = [];\n for (const item of input) {\n serialized.push(serialize(item, transferables));\n }\n return serialized;\n }\n\n if (typeof input !== 'object') {\n throw new Error(`can't serialize object of type ${typeof input}`);\n }\n const classRegistryKey = getClassRegistryKey(input);\n if (!classRegistryKey) {\n throw new Error(`can't serialize object of unregistered class ${input.constructor.name}`);\n }\n if (!registry[classRegistryKey]) throw new Error(`${classRegistryKey} is not registered.`);\n const {klass} = registry[classRegistryKey];\n const properties: SerializedObject = klass.serialize ?\n // (Temporary workaround) allow a class to provide static\n // `serialize()` and `deserialize()` methods to bypass the generic\n // approach.\n // This temporary workaround lets us use the generic serialization\n // approach for objects whose members include instances of dynamic\n // StructArray types. Once we refactor StructArray to be static,\n // we can remove this complexity.\n klass.serialize(input, transferables) : {};\n\n if (!klass.serialize) {\n for (const key in input) {\n if (!input.hasOwnProperty(key)) continue;\n if (registry[classRegistryKey].omit.includes(key)) continue;\n const property = input[key];\n if (property === undefined) continue;\n properties[key] = registry[classRegistryKey].shallow.includes(key) ?\n property :\n serialize(property, transferables);\n }\n if (input instanceof Error) {\n properties.message = input.message;\n }\n } else {\n if (properties === transferables?.[transferables.length - 1]) {\n throw new Error('statically serialized object won\\'t survive transfer of $name property');\n }\n }\n\n if (properties.$name) {\n throw new Error('$name property is reserved for worker serialization logic.');\n }\n if (classRegistryKey !== 'Object') {\n properties.$name = classRegistryKey;\n }\n\n return properties;\n}\n\nexport function deserialize(input: Serialized): unknown {\n if (isSerializeHandledByBuiltin(input)) {\n return input;\n }\n\n if (Array.isArray(input)) {\n return input.map(deserialize);\n }\n\n if (typeof input !== 'object') {\n throw new Error(`can't deserialize object of type ${typeof input}`);\n }\n const classRegistryKey = getClassRegistryKey(input) || 'Object';\n if (!registry[classRegistryKey]) {\n throw new Error(`can't deserialize unregistered class ${classRegistryKey}`);\n }\n const {klass} = registry[classRegistryKey];\n if (!klass) {\n throw new Error(`can't deserialize unregistered class ${classRegistryKey}`);\n }\n\n if (klass.deserialize) {\n return klass.deserialize(input);\n }\n\n const result = Object.create(klass.prototype);\n\n for (const key of Object.keys(input)) {\n if (key === '$name') continue;\n const value = (input as SerializedObject)[key];\n result[key] = registry[classRegistryKey].shallow.includes(key) ? value : deserialize(value);\n }\n\n return result;\n}\n","export class ZoomHistory {\n lastZoom: number;\n lastFloorZoom: number;\n lastIntegerZoom: number;\n lastIntegerZoomTime: number;\n first: boolean;\n\n constructor() {\n this.first = true;\n }\n\n update(z: number, now: number): boolean {\n const floorZ = Math.floor(z);\n\n if (this.first) {\n this.first = false;\n this.lastIntegerZoom = floorZ;\n this.lastIntegerZoomTime = 0;\n this.lastZoom = z;\n this.lastFloorZoom = floorZ;\n return true;\n }\n\n if (this.lastFloorZoom > floorZ) {\n this.lastIntegerZoom = floorZ + 1;\n this.lastIntegerZoomTime = now;\n } else if (this.lastFloorZoom < floorZ) {\n this.lastIntegerZoom = floorZ;\n this.lastIntegerZoomTime = now;\n }\n\n if (z !== this.lastZoom) {\n this.lastZoom = z;\n this.lastFloorZoom = floorZ;\n return true;\n }\n\n return false;\n }\n}\n","// This file is generated. Edit build/generate-unicode-data.ts, then run `npm run generate-unicode-data`.\n\n/**\n * Returns whether the fallback fonts specified by the\n * `localIdeographFontFamily` map option apply to the given codepoint. \n */\nexport function codePointUsesLocalIdeographFontFamily(codePoint: number): boolean {\n return /[\\u02EA\\u02EB\\u1100-\\u11FF\\u2E80-\\u2FDF\\u3000-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFE10-\\uFE1F\\uFE30-\\uFE4F\\uFF00-\\uFFEF]|\\uD81B[\\uDFE0-\\uDFFF]|[\\uD81C-\\uD822\\uD840-\\uD868\\uD86A-\\uD86D\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883\\uD885-\\uD88C][\\uDC00-\\uDFFF]|\\uD823[\\uDC00-\\uDCD5\\uDCFF-\\uDD1E\\uDD80-\\uDDF2]|\\uD82B[\\uDFF0-\\uDFFF]|\\uD82C[\\uDC00-\\uDEFB]|\\uD83C[\\uDE00-\\uDEFF]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEAD\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0\\uDFF0-\\uDFFF]|\\uD87B[\\uDC00-\\uDE5D]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A\\uDF50-\\uDFFF]|\\uD88D[\\uDC00-\\uDC79]/gim.test(String.fromCodePoint(codePoint));\n}\n\n/**\n * Returns whether the given codepoint participates in ideographic line\n * breaking.\n */\nexport function codePointAllowsIdeographicBreaking(codePoint: number): boolean {\n return /[\\u02EA\\u02EB\\u2E80-\\u2FDF\\u2FF0-\\u303F\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FD-\\u30FF\\u3105-\\u312F\\u31A0-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFE10-\\uFE1F\\uFE30-\\uFE4F\\uFF00-\\uFFEF]|\\uD81B[\\uDFE0-\\uDFFF]|[\\uD81C-\\uD822\\uD840-\\uD868\\uD86A-\\uD86D\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883\\uD885-\\uD88C][\\uDC00-\\uDFFF]|\\uD823[\\uDC00-\\uDCD5\\uDCFF-\\uDD1E\\uDD80-\\uDDF2]|\\uD82B[\\uDFF0-\\uDFFF]|\\uD82C[\\uDC00-\\uDEFB]|\\uD83C[\\uDE00-\\uDEFF]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEAD\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0\\uDFF0-\\uDFFF]|\\uD87B[\\uDC00-\\uDE5D]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A\\uDF50-\\uDFFF]|\\uD88D[\\uDC00-\\uDC79]/gim.test(String.fromCodePoint(codePoint));\n}\n\n/**\n * Returns true if the given Unicode codepoint identifies a character with\n * upright orientation.\n *\n * A character has upright orientation if it is drawn upright (unrotated)\n * whether the line is oriented horizontally or vertically, even if both\n * adjacent characters can be rotated. For example, a Chinese character is\n * always drawn upright. An uprightly oriented character causes an adjacent\n * “neutral” character to be drawn upright as well.\n */\nexport function codePointHasUprightVerticalOrientation(codePoint: number): boolean {\n return /[\\u02EA\\u02EB\\u1100-\\u11FF\\u1400-\\u167F\\u18B0-\\u18F5\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u3007\\u3012\\u3013\\u3020-\\u302F\\u3031-\\u303F\\u3041-\\u3096\\u309D-\\u30FB\\u30FD-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u3190-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFE10-\\uFE1F\\uFE30-\\uFE48\\uFE50-\\uFE57\\uFE5F-\\uFE62\\uFE67-\\uFE6F\\uFF00-\\uFF07\\uFF0A-\\uFF0C\\uFF0E-\\uFF19\\uFF1F-\\uFF3A\\uFF3C\\uFF3E\\uFF40-\\uFF5A\\uFFE0-\\uFFE2\\uFFE4-\\uFFE7]|\\uD802[\\uDD80-\\uDD9F]|\\uD805[\\uDD80-\\uDDFF]|\\uD806[\\uDE00-\\uDEBF]|\\uD811[\\uDC00-\\uDE7F]|\\uD81B[\\uDFE0-\\uDFE4\\uDFF0-\\uDFF6]|[\\uD81C-\\uD822\\uD83D\\uD840-\\uD868\\uD86A-\\uD86D\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883\\uD885-\\uD88C][\\uDC00-\\uDFFF]|\\uD823[\\uDC00-\\uDCD5\\uDCFF-\\uDD1E\\uDD80-\\uDDF2]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD30-\\uDEFB]|\\uD833[\\uDEC0-\\uDFCF]|\\uD834[\\uDC00-\\uDDFF\\uDEE0-\\uDF7F]|\\uD836[\\uDC00-\\uDEAF]|\\uD83C[\\uDC00-\\uDE00\\uDF00-\\uDFFF]|\\uD83E[\\uDD00-\\uDEFF]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEAD\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0\\uDFF0-\\uDFFF]|\\uD87B[\\uDC00-\\uDE5D]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A\\uDF50-\\uDFFF]|\\uD88D[\\uDC00-\\uDC79]/gim.test(String.fromCodePoint(codePoint));\n}\n\n/**\n * Returns true if the given Unicode codepoint identifies a character with\n * neutral orientation.\n *\n * A character has neutral orientation if it may be drawn rotated or unrotated\n * when the line is oriented vertically, depending on the orientation of the\n * adjacent characters. For example, along a vertically oriented line, the\n * vulgar fraction ½ is drawn upright among Chinese characters but rotated among\n * Latin letters. A neutrally oriented character does not influence whether an\n * adjacent character is drawn upright or rotated.\n */\nexport function codePointHasNeutralVerticalOrientation(codePoint: number): boolean {\n return /[\\xA7\\xA9\\xAE\\xB1\\xBC-\\xBE\\xD7\\xF7\\u2016\\u2020\\u2021\\u2030\\u2031\\u203B\\u203C\\u2042\\u2047-\\u2049\\u2051\\u2100-\\u218F\\u221E\\u2234\\u2235\\u2300-\\u2307\\u230C-\\u231F\\u2324-\\u2328\\u232B\\u237D-\\u239A\\u23BE-\\u23CD\\u23CF\\u23D1-\\u23DB\\u23E2-\\u2422\\u2424-\\u24FF\\u25A0-\\u2619\\u2620-\\u2767\\u2776-\\u2793\\u2B12-\\u2B2F\\u2B50-\\u2B59\\u2BB8-\\u2BEB\\u3000-\\u303F\\u30A0-\\u30FF\\uE000-\\uF8FF\\uFE30-\\uFE6F\\uFF00-\\uFFEF\\uFFFC\\uFFFD]|[\\uDB80-\\uDBFF][\\uDC00-\\uDFFF]/gim.test(String.fromCodePoint(codePoint));\n}\n\n/**\n * Returns whether the give codepoint is likely to require complex text shaping.\n */\nexport function codePointRequiresComplexTextShaping(codePoint: number): boolean {\n return /[\\u0900-\\u0DFF\\u0F00-\\u109F\\u1780-\\u17FF]/gim.test(String.fromCodePoint(codePoint));\n}\n","import {\n codePointAllowsIdeographicBreaking,\n codePointHasUprightVerticalOrientation,\n codePointHasNeutralVerticalOrientation,\n codePointRequiresComplexTextShaping\n} from '../util/unicode_properties.g.ts';\n\nexport function charIsWhitespace(char: number): boolean {\n return /\\s/u.test(String.fromCodePoint(char));\n}\n\nexport function allowsIdeographicBreaking(chars: string): boolean {\n for (const char of chars) {\n if (!codePointAllowsIdeographicBreaking(char.codePointAt(0))) return false;\n }\n return true;\n}\n\nexport function allowsVerticalWritingMode(chars: string): boolean {\n for (const char of chars) {\n if (codePointHasUprightVerticalOrientation(char.codePointAt(0))) return true;\n }\n return false;\n}\n\nexport function allowsLetterSpacing(chars: string): boolean {\n for (const char of chars) {\n if (!charAllowsLetterSpacing(char.codePointAt(0))) return false;\n }\n return true;\n}\n\n/**\n * Returns a regular expression matching the given script codes, excluding any\n * code that the execution environment lacks support for in regular expressions.\n */\nfunction sanitizedRegExpFromScriptCodes(scriptCodes: string[]): RegExp {\n const supportedPropertyEscapes = scriptCodes.map(code => {\n try {\n return new RegExp(`\\\\p{sc=${code}}`, 'u').source;\n } catch {\n return null;\n }\n }).filter(pe => pe);\n return new RegExp(supportedPropertyEscapes.join('|'), 'u');\n}\n\n/**\n * ISO 15924 script codes of scripts that disallow letter spacing as of Unicode\n * 16.0.0.\n *\n * In general, cursive scripts are incompatible with letter spacing.\n */\nconst cursiveScriptCodes = [\n 'Arab', // Arabic\n 'Dupl', // Duployan\n 'Mong', // Mongolian\n 'Ougr', // Old Uyghur\n 'Syrc', // Syriac\n];\n\nconst cursiveScriptRegExp = sanitizedRegExpFromScriptCodes(cursiveScriptCodes);\n\nexport function charAllowsLetterSpacing(char: number): boolean {\n return !cursiveScriptRegExp.test(String.fromCodePoint(char));\n}\n\n/**\n * Returns true if the given Unicode codepoint identifies a character with\n * rotated orientation.\n *\n * A character has rotated orientation if it is drawn rotated when the line is\n * oriented vertically, even if both adjacent characters are upright. For\n * example, a Latin letter is drawn rotated along a vertical line. A rotated\n * character causes an adjacent “neutral” character to be drawn rotated as well.\n */\nexport function charHasRotatedVerticalOrientation(char: number): boolean {\n return !(codePointHasUprightVerticalOrientation(char) ||\n codePointHasNeutralVerticalOrientation(char));\n}\n\nexport function charInComplexShapingScript(char: number): boolean {\n return /\\p{sc=Arab}/u.test(String.fromCodePoint(char));\n}\n\n/**\n * ISO 15924 script codes of scripts that are primarily written horizontally\n * right-to-left according to Unicode 16.0.0.\n */\nconst rtlScriptCodes = [\n 'Adlm', // Adlam\n 'Arab', // Arabic\n 'Armi', // Imperial Aramaic\n 'Avst', // Avestan\n 'Chrs', // Chorasmian\n 'Cprt', // Cypriot\n 'Egyp', // Egyptian Hieroglyphs\n 'Elym', // Elymaic\n 'Gara', // Garay\n 'Hatr', // Hatran\n 'Hebr', // Hebrew\n 'Hung', // Old Hungarian\n 'Khar', // Kharoshthi\n 'Lydi', // Lydian\n 'Mand', // Mandaic\n 'Mani', // Manichaean\n 'Mend', // Mende Kikakui\n 'Merc', // Meroitic Cursive\n 'Mero', // Meroitic Hieroglyphs\n 'Narb', // Old North Arabian\n 'Nbat', // Nabataean\n 'Nkoo', // NKo\n 'Orkh', // Old Turkic\n 'Palm', // Palmyrene\n 'Phli', // Inscriptional Pahlavi\n 'Phlp', // Psalter Pahlavi\n 'Phnx', // Phoenician\n 'Prti', // Inscriptional Parthian\n 'Rohg', // Hanifi Rohingya\n 'Samr', // Samaritan\n 'Sarb', // Old South Arabian\n 'Sogo', // Old Sogdian\n 'Syrc', // Syriac\n 'Thaa', // Thaana\n 'Todr', // Todhri\n 'Yezi', // Yezidi\n];\n\nconst rtlScriptRegExp = sanitizedRegExpFromScriptCodes(rtlScriptCodes);\n\nexport function charInRTLScript(char: number): boolean {\n return rtlScriptRegExp.test(String.fromCodePoint(char));\n}\n\nexport function charInSupportedScript(char: number, canRenderRTL: boolean): boolean {\n // This is a rough heuristic: whether we \"can render\" a script\n // actually depends on the properties of the font being used\n // and whether differences from the ideal rendering are considered\n // semantically significant.\n\n // Even in Latin script, we \"can't render\" combinations such as the fi\n // ligature, but we don't consider that semantically significant.\n if (!canRenderRTL && charInRTLScript(char)) {\n return false;\n }\n return !codePointRequiresComplexTextShaping(char);\n\n}\n\nexport function stringContainsRTLText(chars: string): boolean {\n for (const char of chars) {\n if (charInRTLScript(char.codePointAt(0))) {\n return true;\n }\n }\n return false;\n}\n\nexport function isStringInSupportedScript(chars: string, canRenderRTL: boolean): boolean {\n for (const char of chars) {\n if (!charInSupportedScript(char.codePointAt(0), canRenderRTL)) {\n return false;\n }\n }\n return true;\n}\n","import {type PluginState, type RTLPluginStatus} from './rtl_text_plugin_status.ts';\n\nexport interface RTLTextPlugin {\n applyArabicShaping: (a: string) => string;\n processBidirectionalText: ((b: string, a: number[]) => string[]);\n processStyledBidirectionalText: ((c: string, b: number[], a: number[]) => Array<[string, number[]]>);\n}\n\nclass RTLWorkerPlugin implements RTLTextPlugin {\n readonly TIMEOUT = 5000;\n\n applyArabicShaping: (a: string) => string = null;\n processBidirectionalText: ((b: string, a: number[]) => string[]) = null;\n processStyledBidirectionalText: ((c: string, b: number[], a: number[]) => Array<[string, number[]]>) = null;\n pluginStatus: RTLPluginStatus = 'unavailable';\n pluginURL: string = null;\n loadScriptResolve: () => void = () => {};\n\n private setState(state: PluginState): void {\n this.pluginStatus = state.pluginStatus;\n this.pluginURL = state.pluginURL;\n }\n\n private getState(): PluginState {\n return {\n pluginStatus: this.pluginStatus,\n pluginURL: this.pluginURL\n };\n }\n\n public setMethods(rtlTextPlugin: RTLTextPlugin): void {\n if (rtlWorkerPlugin.isParsed()) {\n throw new Error('RTL text plugin already registered.');\n }\n this.applyArabicShaping = rtlTextPlugin.applyArabicShaping;\n this.processBidirectionalText = rtlTextPlugin.processBidirectionalText;\n this.processStyledBidirectionalText = rtlTextPlugin.processStyledBidirectionalText;\n this.loadScriptResolve();\n }\n\n public isParsed(): boolean {\n return this.applyArabicShaping != null &&\n this.processBidirectionalText != null &&\n this.processStyledBidirectionalText != null;\n }\n\n public getRTLTextPluginStatus(): RTLPluginStatus {\n return this.pluginStatus;\n }\n\n public async syncState(incomingState: PluginState, loadScript: (url: string) => Promise): Promise {\n // Parsed plugin cannot be changed, so just return its current state.\n if (this.isParsed()) {\n return this.getState();\n }\n\n if (incomingState.pluginStatus !== 'loading') {\n // simply sync and done\n this.setState(incomingState);\n return incomingState;\n }\n const urlToLoad = incomingState.pluginURL;\n const loadScriptPromise = new Promise((resolve) => {\n this.loadScriptResolve = resolve;\n });\n const dontWaitForeverTimeoutPromise = new Promise((resolve) => setTimeout(() => resolve(), this.TIMEOUT));\n await loadScript(urlToLoad);\n await Promise.race([loadScriptPromise, dontWaitForeverTimeoutPromise]);\n const complete = this.isParsed();\n if (complete) {\n const loadedState: PluginState = {\n pluginStatus: 'loaded',\n pluginURL: urlToLoad\n };\n this.setState(loadedState);\n return loadedState;\n }\n\n // error case\n this.setState({\n pluginStatus: 'error',\n pluginURL: ''\n });\n throw new Error(`RTL Text Plugin failed to import scripts from ${urlToLoad}`);\n }\n}\n\nexport const rtlWorkerPlugin: RTLWorkerPlugin = new RTLWorkerPlugin();\n","import {ZoomHistory} from './zoom_history.ts';\nimport {isStringInSupportedScript} from '../util/script_detection.ts';\nimport {rtlWorkerPlugin} from '../source/rtl_text_plugin_worker.ts';\n\nimport type {GlobalProperties, TransitionSpecification} from '@maplibre/maplibre-gl-style-spec';\n\nexport type CrossfadeParameters = {\n fromScale: number;\n toScale: number;\n t: number;\n};\n\n/**\n * @internal\n * A parameter that can be evaluated to a value.\n * It's main purpose is a parameter to expression `evaluate` methods.\n */\nexport class EvaluationParameters implements GlobalProperties {\n zoom: number;\n now: number;\n fadeDuration: number;\n zoomHistory: ZoomHistory;\n transition: TransitionSpecification;\n // has to be an own property of an object to be used in expressions\n // if defined as class method, it'll hidden from operations\n // that iterate over own enumerable properties\n // (i..e spread operator (...), Object.keys(), for...in statement, etc.)\n isSupportedScript: (_: string) => boolean = isSupportedScript;\n\n // \"options\" may also be another EvaluationParameters to copy, see CrossFadedProperty.possiblyEvaluate\n constructor(zoom: number, options?: any) {\n this.zoom = zoom;\n\n if (options) {\n this.now = options.now || 0;\n this.fadeDuration = options.fadeDuration || 0;\n this.zoomHistory = options.zoomHistory || new ZoomHistory();\n this.transition = options.transition || {};\n } else {\n this.now = 0;\n this.fadeDuration = 0;\n this.zoomHistory = new ZoomHistory();\n this.transition = {};\n }\n }\n\n crossFadingFactor(): number {\n if (this.fadeDuration === 0) {\n return 1;\n } else {\n return Math.min((this.now - this.zoomHistory.lastIntegerZoomTime) / this.fadeDuration, 1);\n }\n }\n\n getCrossfadeParameters(): CrossfadeParameters {\n const z = this.zoom;\n const fraction = z - Math.floor(z);\n const t = this.crossFadingFactor();\n\n return z > this.zoomHistory.lastIntegerZoom ?\n {fromScale: 2, toScale: 1, t: fraction + (1 - fraction) * t} :\n {fromScale: 0.5, toScale: 1, t: 1 - (1 - t) * fraction};\n }\n}\n\nfunction isSupportedScript(str: string): boolean {\n return isStringInSupportedScript(str, rtlWorkerPlugin.getRTLTextPluginStatus() === 'loaded');\n}\n","import {clone, extend, easeCubicInOut, warnOnce} from '../util/util.ts';\nimport {interpolates, type Color, type StylePropertySpecification, normalizePropertyExpression,\n type Feature,\n type FeatureState,\n type StylePropertyExpression,\n type SourceExpression,\n type CompositeExpression, type TransitionSpecification,\n type PropertyValueSpecification} from '@maplibre/maplibre-gl-style-spec';\nimport {register} from '../util/web_worker_transfer.ts';\nimport {EvaluationParameters} from './evaluation_parameters.ts';\n\nimport {type CanonicalTileID} from '../tile/tile_id.ts';\n\ntype TimePoint = number;\n\nexport const TRANSITION_SUFFIX = '-transition';\n\n/**\n * A from-to type\n */\nexport type CrossFaded = {\n to: T;\n from: T;\n};\n\n/**\n * @internal\n * Implementations of the `Property` interface:\n *\n * * Hold metadata about a property that's independent of any specific value: stuff like the type of the value,\n * the default value, etc. This comes from the style specification JSON.\n * * Define behavior that needs to be polymorphic across different properties: \"possibly evaluating\"\n * an input value (see below), and interpolating between two possibly-evaluted values.\n *\n * The type `T` is the fully-evaluated value type (e.g. `number`, `string`, `Color`).\n * The type `R` is the intermediate \"possibly evaluated\" value type. See below.\n *\n * There are two main implementations of the interface -- one for properties that allow data-driven values,\n * and one for properties that don't. There are a few \"special case\" implementations as well: one for properties\n * which cross-fade between two values rather than interpolating, one for `heatmap-color` and `line-gradient`,\n * and one for `light-position`.\n */\nexport interface Property {\n specification: StylePropertySpecification;\n name: string;\n possiblyEvaluate(\n value: PropertyValue,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): R;\n interpolate(a: R, b: R, t: number): R;\n}\n\n/**\n * @internal\n * `PropertyValue` represents the value part of a property key-value unit. It's used to represent both\n * paint and layout property values, and regardless of whether or not their property supports data-driven\n * expressions.\n *\n * `PropertyValue` stores the raw input value as seen in a style or a runtime styling API call, i.e. one of the\n * following:\n *\n * * A constant value of the type appropriate for the property\n * * A function which produces a value of that type (but functions are quasi-deprecated in favor of expressions)\n * * An expression which produces a value of that type\n * * \"undefined\"/\"not present\", in which case the property is assumed to take on its default value.\n *\n * In addition to storing the original input value, `PropertyValue` also stores a normalized representation,\n * effectively treating functions as if they are expressions, and constant or default values as if they are\n * (constant) expressions.\n */\nexport class PropertyValue {\n property: Property;\n value: PropertyValueSpecification | void;\n expression: StylePropertyExpression;\n\n constructor(property: Property, value: PropertyValueSpecification | void, rootKey: string, globalState: Record) {\n this.property = property;\n this.value = value;\n this.expression = normalizePropertyExpression(value === undefined ? property.specification.default : value, rootKey, property.specification, globalState);\n }\n\n isDataDriven(): boolean {\n return this.expression.kind === 'source' || this.expression.kind === 'composite';\n }\n\n getGlobalStateRefs(): Set {\n return this.expression.globalStateRefs || new Set();\n }\n\n possiblyEvaluate(\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): R {\n return this.property.possiblyEvaluate(this, parameters, canonical, availableImages);\n }\n}\n\nexport type TransitionParameters = {\n now: TimePoint;\n transition: TransitionSpecification;\n};\n\n/**\n * @internal\n * Paint properties are _transitionable_: they can change in a fluid manner, interpolating or cross-fading between\n * old and new value. The duration of the transition, and the delay before it begins, is configurable.\n *\n * `TransitionablePropertyValue` is a compositional class that stores both the property value and that transition\n * configuration.\n *\n * A `TransitionablePropertyValue` can calculate the next step in the evaluation chain for paint property values:\n * `TransitioningPropertyValue`.\n */\nclass TransitionablePropertyValue {\n property: Property;\n value: PropertyValue;\n transition: TransitionSpecification | void;\n\n constructor(property: Property, rootKey: string, globalState: Record) {\n this.property = property;\n this.value = new PropertyValue(property, undefined, rootKey, globalState);\n }\n\n transitioned(parameters: TransitionParameters, prior: TransitioningPropertyValue): TransitioningPropertyValue {\n return new TransitioningPropertyValue(this.property, this.value, prior,\n extend({}, parameters.transition, this.transition), parameters.now);\n }\n\n untransitioned(): TransitioningPropertyValue {\n return new TransitioningPropertyValue(this.property, this.value, null, {}, 0);\n }\n}\n\n/**\n * @internal\n * `Transitionable` stores a map of all (property name, `TransitionablePropertyValue`) pairs for paint properties of a\n * given layer type. It can calculate the `TransitioningPropertyValue`s for all of them at once, producing a\n * `Transitioning` instance for the same set of properties.\n */\nexport class Transitionable {\n _properties: Properties;\n _values: {[K in keyof Props]: TransitionablePropertyValue};\n private _globalState: Record;\n private _rootKey: string;\n\n constructor(properties: Properties, rootKey: string, globalState: Record) {\n this._properties = properties;\n this._values = (Object.create(properties.defaultTransitionablePropertyValues));\n this._globalState = globalState;\n this._rootKey = rootKey;\n }\n\n /** rootKey of a property, e.g. `layers[3].paint.line-color`. */\n private _propertyRootKey(name: keyof Props): string {\n return `${this._rootKey}.${String(name)}`;\n }\n\n hasProperty(name: string): boolean {\n return name in this._properties.defaultTransitionablePropertyValues;\n }\n\n getValue(name: S): PropertyValueSpecification | void {\n return clone(this._values[name].value.value);\n }\n\n setValue(name: S, value: PropertyValueSpecification | void): void {\n if (!Object.hasOwn(this._values, name)) {\n this._values[name] = new TransitionablePropertyValue(this._values[name].property, this._propertyRootKey(name), this._globalState);\n }\n // Note that we do not _remove_ an own property in the case where a value is being reset\n // to the default: the transition might still be non-default.\n this._values[name].value = new PropertyValue(this._values[name].property, value === null ? undefined : clone(value), this._propertyRootKey(name), this._globalState);\n }\n\n getTransition(name: S): TransitionSpecification | void {\n return clone(this._values[name].transition);\n }\n\n setTransition(name: S, value: TransitionSpecification | void): void {\n if (!Object.hasOwn(this._values, name)) {\n this._values[name] = new TransitionablePropertyValue(this._values[name].property, this._propertyRootKey(name), this._globalState);\n }\n this._values[name].transition = clone(value) || undefined;\n }\n\n serialize(): any {\n const result: any = {};\n for (const property of Object.keys(this._values)) {\n const value = this.getValue(property as keyof Props);\n if (value !== undefined) {\n result[property] = value;\n }\n\n const transition = this.getTransition(property as keyof Props);\n if (transition !== undefined) {\n result[`${property}${TRANSITION_SUFFIX}`] = transition;\n }\n }\n return result;\n }\n\n transitioned(parameters: TransitionParameters, prior: Transitioning): Transitioning {\n const result = new Transitioning(this._properties);\n for (const property of Object.keys(this._values)) {\n result._values[property] = this._values[property].transitioned(parameters, prior._values[property]);\n }\n return result;\n }\n\n untransitioned(): Transitioning {\n const result = new Transitioning(this._properties);\n for (const property of Object.keys(this._values)) {\n result._values[property] = this._values[property].untransitioned();\n }\n return result;\n }\n}\n\n/**\n * @internal\n * `TransitioningPropertyValue` implements the first of two intermediate steps in the evaluation chain of a paint\n * property value. In this step, transitions between old and new values are handled: as long as the transition is in\n * progress, `TransitioningPropertyValue` maintains a reference to the prior value, and interpolates between it and\n * the new value based on the current time and the configured transition duration and delay. The product is the next\n * step in the evaluation chain: the \"possibly evaluated\" result type `R`. See below for more on this concept.\n */\nclass TransitioningPropertyValue {\n property: Property;\n value: PropertyValue;\n prior: TransitioningPropertyValue;\n begin: TimePoint;\n end: TimePoint;\n\n constructor(property: Property,\n value: PropertyValue,\n prior: TransitioningPropertyValue,\n transition: TransitionSpecification,\n now: TimePoint) {\n this.property = property;\n this.value = value;\n this.begin = now + transition.delay || 0;\n this.end = this.begin + transition.duration || 0;\n if (property.specification.transition && (transition.delay || transition.duration)) {\n this.prior = prior;\n }\n }\n\n possiblyEvaluate(\n parameters: EvaluationParameters,\n canonical: CanonicalTileID,\n availableImages: string[]\n ): R {\n const now = parameters.now || 0;\n const finalValue = this.value.possiblyEvaluate(parameters, canonical, availableImages);\n const prior = this.prior;\n if (!prior) {\n // No prior value.\n return finalValue;\n } else if (now > this.end) {\n // Transition from prior value is now complete.\n this.prior = null;\n return finalValue;\n } else if (this.value.isDataDriven()) {\n // Transitions to data-driven properties are not supported.\n // We snap immediately to the data-driven value so that, when we perform layout,\n // we see the data-driven function and can use it to populate vertex buffers.\n this.prior = null;\n return finalValue;\n } else if (now < this.begin) {\n // Transition hasn't started yet.\n return prior.possiblyEvaluate(parameters, canonical, availableImages);\n } else {\n // Interpolate between recursively-calculated prior value and final.\n const t = (now - this.begin) / (this.end - this.begin);\n return this.property.interpolate(prior.possiblyEvaluate(parameters, canonical, availableImages), finalValue, easeCubicInOut(t));\n }\n }\n}\n\n/**\n * @internal\n * `Transitioning` stores a map of all (property name, `TransitioningPropertyValue`) pairs for paint properties of a\n * given layer type. It can calculate the possibly-evaluated values for all of them at once, producing a\n * `PossiblyEvaluated` instance for the same set of properties.\n */\nexport class Transitioning {\n _properties: Properties;\n _values: {[K in keyof Props]: PossiblyEvaluatedPropertyValue};\n\n constructor(properties: Properties) {\n this._properties = properties;\n this._values = (Object.create(properties.defaultTransitioningPropertyValues));\n }\n\n possiblyEvaluate(\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): PossiblyEvaluated {\n const result = new PossiblyEvaluated(this._properties);\n for (const property of Object.keys(this._values)) {\n result._values[property] = this._values[property].possiblyEvaluate(parameters, canonical, availableImages);\n }\n return result;\n }\n\n hasTransition(): boolean {\n for (const property of Object.keys(this._values)) {\n if (this._values[property].prior) {\n return true;\n }\n }\n return false;\n }\n}\n\n// ------- Layout -------\n\n/**\n * Because layout properties are not transitionable, they have a simpler representation and evaluation chain than\n * paint properties: `PropertyValue`s are possibly evaluated, producing possibly evaluated values, which are then\n * fully evaluated.\n *\n * `Layout` stores a map of all (property name, `PropertyValue`) pairs for layout properties of a\n * given layer type. It can calculate the possibly-evaluated values for all of them at once, producing a\n * `PossiblyEvaluated` instance for the same set of properties.\n */\nexport class Layout {\n _properties: Properties;\n _values: {[K in keyof Props]: PropertyValue>};\n private _globalState: Record; // reference to global state\n private _rootKey: string;\n\n constructor(properties: Properties, rootKey: string, globalState: Record) {\n this._properties = properties;\n this._values = (Object.create(properties.defaultPropertyValues));\n this._globalState = globalState;\n this._rootKey = rootKey;\n }\n\n /** rootKey of a property, e.g. `layers[3].layout.line-cap`. */\n private _propertyRootKey(name: keyof Props): string {\n return `${this._rootKey}.${String(name)}`;\n }\n\n hasValue(name: S): boolean {\n return this._values[name].value !== undefined;\n }\n\n hasProperty(name: string): boolean {\n return name in this._properties.defaultPropertyValues;\n }\n\n getValue(name: S): any {\n return clone(this._values[name].value);\n }\n\n setValue(name: S, value: any): void {\n this._values[name] = new PropertyValue(this._values[name].property, value === null ? undefined : clone(value), this._propertyRootKey(name), this._globalState) as any;\n }\n\n serialize(): any {\n const result: any = {};\n for (const property of Object.keys(this._values)) {\n const value = this.getValue(property as keyof Props);\n if (value !== undefined) {\n result[property] = value;\n }\n }\n return result;\n }\n\n possiblyEvaluate(\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): PossiblyEvaluated {\n const result = new PossiblyEvaluated(this._properties);\n for (const property of Object.keys(this._values)) {\n result._values[property] = this._values[property].possiblyEvaluate(parameters, canonical, availableImages);\n }\n return result;\n }\n}\n\n// ------- PossiblyEvaluated -------\n\n/**\n * \"Possibly evaluated value\" is an intermediate stage in the evaluation chain for both paint and layout property\n * values. The purpose of this stage is to optimize away unnecessary recalculations for data-driven properties. Code\n * which uses data-driven property values must assume that the value is dependent on feature data, and request that it\n * be evaluated for each feature. But when that property value is in fact a constant or camera function, the calculation\n * will not actually depend on the feature, and we can benefit from returning the prior result of having done the\n * evaluation once, ahead of time, in an intermediate step whose inputs are just the value and \"global\" parameters\n * such as current zoom level.\n *\n * `PossiblyEvaluatedValue` represents the three possible outcomes of this step: if the input value was a constant or\n * camera expression, then the \"possibly evaluated\" result is a constant value. Otherwise, the input value was either\n * a source or composite expression, and we must defer final evaluation until supplied a feature. We separate\n * the source and composite cases because they are handled differently when generating GL attributes, buffers, and\n * uniforms.\n *\n * Note that `PossiblyEvaluatedValue` (and `PossiblyEvaluatedPropertyValue`, below) are _not_ used for properties that\n * do not allow data-driven values. For such properties, we know that the \"possibly evaluated\" result is always a constant\n * scalar value. See below.\n */\ntype PossiblyEvaluatedValue = {\n kind: 'constant';\n value: T;\n} | SourceExpression | CompositeExpression;\n\n/**\n * @internal\n * `PossiblyEvaluatedPropertyValue` is used for data-driven paint and layout property values. It holds a\n * `PossiblyEvaluatedValue` and the `GlobalProperties` that were used to generate it. You're not allowed to supply\n * a different set of `GlobalProperties` when performing the final evaluation because they would be ignored in the\n * case where the input value was a constant or camera function.\n */\nexport class PossiblyEvaluatedPropertyValue {\n property: DataDrivenProperty;\n value: PossiblyEvaluatedValue;\n parameters: EvaluationParameters;\n\n constructor(property: DataDrivenProperty, value: PossiblyEvaluatedValue, parameters: EvaluationParameters) {\n this.property = property;\n this.value = value;\n this.parameters = parameters;\n }\n\n isConstant(): boolean {\n return this.value.kind === 'constant';\n }\n\n constantOr(value: T): T {\n if (this.value.kind === 'constant') {\n return this.value.value;\n } else {\n return value;\n }\n }\n\n evaluate(\n feature: Feature,\n featureState: FeatureState,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): T {\n return this.property.evaluate(this.value, this.parameters, feature, featureState, canonical, availableImages);\n }\n}\n\n/**\n * @internal\n * `PossiblyEvaluated` stores a map of all (property name, `R`) pairs for paint or layout properties of a\n * given layer type.\n */\nexport class PossiblyEvaluated {\n _properties: Properties;\n _values: PossibleEvaluatedProps;\n\n constructor(properties: Properties) {\n this._properties = properties;\n this._values = Object.create(properties.defaultPossiblyEvaluatedValues);\n }\n\n get(name: S): PossibleEvaluatedProps[S] {\n return this._values[name];\n }\n}\n\n/**\n * Returns the length of the array value, or undefined if the value is not an array or a style spec array wrapper.\n */\nfunction getArrayValueLength(value: unknown): number | undefined {\n if (Array.isArray(value)) {\n return value.length;\n }\n const values = (value as {values?: unknown})?.values;\n return Array.isArray(values) ? values.length : undefined;\n}\n\n/**\n * Returns true if the two values are arrays of different length, either bare arrays or style spec array wrappers.\n */\nfunction isNonInterpolableArrayChange(a: unknown, b: unknown): boolean {\n const lengthA = getArrayValueLength(a);\n const lengthB = getArrayValueLength(b);\n return lengthA !== undefined && lengthB !== undefined && lengthA !== lengthB;\n}\n\n/**\n * @internal\n * An implementation of `Property` for properties that do not permit data-driven (source or composite) expressions.\n * This restriction allows us to declare statically that the result of possibly evaluating this kind of property\n * is in fact always the scalar type `T`, and can be used without further evaluating the value on a per-feature basis.\n */\nexport class DataConstantProperty implements Property {\n specification: StylePropertySpecification;\n name: string;\n\n constructor(specification: StylePropertySpecification, name: string) {\n this.specification = specification;\n this.name = name;\n }\n\n possiblyEvaluate(value: PropertyValue, parameters: EvaluationParameters): T {\n if (value.isDataDriven()) throw new Error('Value should not be data driven');\n return value.expression.evaluate(parameters);\n }\n\n interpolate(a: T, b: T, t: number): T {\n if (isNonInterpolableArrayChange(a, b)) {\n warnOnce(`Property \"${this.name}\" is trying to interpolate arrays of different lengths. Rendering may 'jump'.`);\n return b;\n }\n const interpolationType = this.specification.type as keyof typeof interpolates;\n const interpolationFn = interpolates[interpolationType] as ((from: T, to: T, t: number) => T) | undefined;\n if (interpolationFn) {\n return interpolationFn(a, b, t);\n } else {\n return a;\n }\n }\n}\n\n/**\n * @internal\n * An implementation of `Property` for properties that permit data-driven (source or composite) expressions.\n * The result of possibly evaluating this kind of property is `PossiblyEvaluatedPropertyValue`; obtaining\n * a scalar value `T` requires further evaluation on a per-feature basis.\n */\nexport class DataDrivenProperty implements Property> {\n specification: StylePropertySpecification;\n name: string;\n overrides: any;\n\n constructor(specification: StylePropertySpecification, name: string, overrides?: any) {\n this.specification = specification;\n this.name = name;\n this.overrides = overrides;\n }\n\n possiblyEvaluate(\n value: PropertyValue>,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): PossiblyEvaluatedPropertyValue {\n if (value.expression.kind === 'constant' || value.expression.kind === 'camera') {\n return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: value.expression.evaluate(parameters, null, {}, canonical, availableImages)}, parameters);\n } else {\n return new PossiblyEvaluatedPropertyValue(this, value.expression, parameters);\n }\n }\n\n interpolate(\n a: PossiblyEvaluatedPropertyValue,\n b: PossiblyEvaluatedPropertyValue,\n t: number\n ): PossiblyEvaluatedPropertyValue {\n // If either possibly-evaluated value is non-constant, give up: we aren't able to interpolate data-driven values.\n if (a.value.kind !== 'constant' || b.value.kind !== 'constant') {\n return a;\n }\n\n // Special case hack solely for fill-outline-color. The undefined value is subsequently handled in\n // FillStyleLayer.recalculate, which sets fill-outline-color to the fill-color value if the former\n // is a PossiblyEvaluatedPropertyValue containing a constant undefined value. In addition to the\n // return value here, the other source of a PossiblyEvaluatedPropertyValue containing a constant\n // undefined value is the \"default value\" for fill-outline-color held in\n // `Properties.defaultPossiblyEvaluatedValues`, which serves as the prototype of\n // `PossiblyEvaluated._values`.\n if (a.value.value === undefined || b.value.value === undefined) {\n return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: undefined}, a.parameters);\n }\n\n if (isNonInterpolableArrayChange(a.value.value, b.value.value)) {\n warnOnce(`Property \"${this.name}\" is trying to interpolate arrays of different lengths. Rendering may 'jump'.`);\n return b;\n }\n\n const interpolationType = this.specification.type as keyof typeof interpolates;\n const interpolationFn = interpolates[interpolationType] as ((from: T, to: T, t: number) => T) | undefined;\n if (interpolationFn) {\n const interpolatedValue = interpolationFn(a.value.value, b.value.value, t);\n return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: interpolatedValue}, a.parameters);\n } else {\n return a;\n }\n }\n\n evaluate(\n value: PossiblyEvaluatedValue,\n parameters: EvaluationParameters,\n feature: Feature,\n featureState: FeatureState,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): T {\n if (value.kind === 'constant') {\n return value.value;\n } else {\n return value.evaluate(parameters, feature, featureState, canonical, availableImages);\n }\n }\n}\n\n/**\n * @internal\n * An implementation of `Property` for data driven `line-pattern` which are transitioned by cross-fading\n * rather than interpolation.\n */\n\nexport class CrossFadedDataDrivenProperty extends DataDrivenProperty> {\n\n possiblyEvaluate(\n value: PropertyValue, PossiblyEvaluatedPropertyValue>>,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): PossiblyEvaluatedPropertyValue> {\n if (value.value === undefined) {\n return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: undefined}, parameters);\n } else if (value.expression.kind === 'constant') {\n const evaluatedValue = value.expression.evaluate(parameters, null, {}, canonical, availableImages);\n const isImageExpression = value.property.specification.type as any === 'resolvedImage';\n const constantValue = isImageExpression && typeof evaluatedValue !== 'string' ? evaluatedValue.name : evaluatedValue;\n const constant = this._calculate(constantValue, constantValue, constantValue, parameters);\n return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: constant}, parameters);\n } else if (value.expression.kind === 'camera') {\n const cameraVal = this._calculate(\n value.expression.evaluate({zoom: parameters.zoom - 1.0}),\n value.expression.evaluate({zoom: parameters.zoom}),\n value.expression.evaluate({zoom: parameters.zoom + 1.0}),\n parameters);\n return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: cameraVal}, parameters);\n } else {\n // source or composite expression\n return new PossiblyEvaluatedPropertyValue(this, value.expression, parameters);\n }\n }\n\n evaluate(\n value: PossiblyEvaluatedValue>,\n globals: EvaluationParameters,\n feature: Feature,\n featureState: FeatureState,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): CrossFaded {\n if (value.kind === 'source') {\n const constant = value.evaluate(globals, feature, featureState, canonical, availableImages);\n return this._calculate(constant, constant, constant, globals);\n } else if (value.kind === 'composite') {\n return this._calculate(\n value.evaluate({zoom: Math.floor(globals.zoom) - 1.0}, feature, featureState),\n value.evaluate({zoom: Math.floor(globals.zoom)}, feature, featureState),\n value.evaluate({zoom: Math.floor(globals.zoom) + 1.0}, feature, featureState),\n globals);\n } else {\n return value.value;\n }\n }\n\n _calculate(min: T, mid: T, max: T, parameters: EvaluationParameters): CrossFaded {\n const z = parameters.zoom;\n return z > parameters.zoomHistory.lastIntegerZoom ? {from: min, to: mid} : {from: max, to: mid};\n }\n\n interpolate(a: PossiblyEvaluatedPropertyValue>): PossiblyEvaluatedPropertyValue> {\n return a;\n }\n}\n/**\n * @internal\n * An implementation of `Property` for `*-pattern` and `line-dasharray`, which are transitioned by cross-fading\n * rather than interpolation.\n */\nexport class CrossFadedProperty implements Property> {\n specification: StylePropertySpecification;\n name: string;\n\n constructor(specification: StylePropertySpecification, name: string) {\n this.specification = specification;\n this.name = name;\n }\n\n possiblyEvaluate(\n value: PropertyValue>,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): CrossFaded {\n if (value.value === undefined) {\n return undefined;\n } else if (value.expression.kind === 'constant') {\n const constant = value.expression.evaluate(parameters, null, {}, canonical, availableImages);\n return this._calculate(constant, constant, constant, parameters);\n } else {\n return this._calculate(\n value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom - 1.0), parameters)),\n value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom), parameters)),\n value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom + 1.0), parameters)),\n parameters);\n }\n }\n\n _calculate(min: T, mid: T, max: T, parameters: EvaluationParameters): CrossFaded {\n const z = parameters.zoom;\n return z > parameters.zoomHistory.lastIntegerZoom ? {from: min, to: mid} : {from: max, to: mid};\n }\n\n interpolate(a?: CrossFaded | null): CrossFaded {\n return a;\n }\n}\n\n/**\n * @internal\n * An implementation of `Property` for `heatmap-color` and `line-gradient`. Interpolation is a no-op, and\n * evaluation returns a boolean value in order to indicate its presence, but the real\n * evaluation happens in StyleLayer classes.\n */\n\nexport class ColorRampProperty implements Property {\n specification: StylePropertySpecification;\n name: string;\n\n constructor(specification: StylePropertySpecification, name: string) {\n this.specification = specification;\n this.name = name;\n }\n\n possiblyEvaluate(\n value: PropertyValue,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: string[]\n ): boolean {\n return !!value.expression.evaluate(parameters, null, {}, canonical, availableImages);\n }\n\n interpolate(): boolean { return false; }\n}\n\n/**\n * @internal\n * `Properties` holds objects containing default values for the layout or paint property set of a given\n * layer type. These objects are immutable, and they are used as the prototypes for the `_values` members of\n * `Transitionable`, `Transitioning`, `Layout`, and `PossiblyEvaluated`. This allows these classes to avoid\n * doing work in the common case where a property has no explicit value set and should be considered to take\n * on the default value: using `for (const property of Object.keys(this._values))`, they can iterate over\n * only the _own_ properties of `_values`, skipping repeated calculation of transitions and possible/final\n * evaluations for defaults, the result of which will always be the same.\n */\nexport class Properties {\n properties: Props;\n defaultPropertyValues: {[K in keyof Props]: PropertyValue};\n defaultTransitionablePropertyValues: {[K in keyof Props]: TransitionablePropertyValue};\n defaultTransitioningPropertyValues: {[K in keyof Props]: TransitioningPropertyValue};\n defaultPossiblyEvaluatedValues: {[K in keyof Props]: PossiblyEvaluatedPropertyValue};\n overridableProperties: string[];\n\n constructor(properties: Props) {\n this.properties = properties;\n this.defaultPropertyValues = ({} as any);\n this.defaultTransitionablePropertyValues = ({} as any);\n this.defaultTransitioningPropertyValues = ({} as any);\n this.defaultPossiblyEvaluatedValues = ({} as any);\n this.overridableProperties = ([]);\n\n for (const property in properties) {\n const prop = properties[property] as any;\n if (prop.specification.overridable) {\n this.overridableProperties.push(property);\n }\n // These defaults are shared across all layers, so we only have the property name as a location\n // here. The full location (e.g. `layers[3].paint.line-color`) is filled in later when an actual\n // value is set through Transitionable/Layout.\n const defaultPropertyValue = this.defaultPropertyValues[property] =\n new PropertyValue(prop, undefined, prop.name, undefined);\n const defaultTransitionablePropertyValue = this.defaultTransitionablePropertyValues[property] =\n new TransitionablePropertyValue(prop, prop.name, undefined);\n this.defaultTransitioningPropertyValues[property] =\n defaultTransitionablePropertyValue.untransitioned();\n this.defaultPossiblyEvaluatedValues[property] =\n defaultPropertyValue.possiblyEvaluate({} as any);\n }\n }\n}\n\nregister('DataDrivenProperty', DataDrivenProperty);\nregister('DataConstantProperty', DataConstantProperty);\nregister('CrossFadedDataDrivenProperty', CrossFadedDataDrivenProperty);\nregister('CrossFadedProperty', CrossFadedProperty);\nregister('ColorRampProperty', ColorRampProperty);\n","import {filterObject} from '../util/util.ts';\nimport {createVisibilityExpression, featureFilter, supportsPropertyExpression} from '@maplibre/maplibre-gl-style-spec';\nimport {validateStyle, validateAndEmit, type Validator} from './validate_style.ts';\nimport {Evented, ErrorEvent, type ErrorEventType} from '../util/evented.ts';\nimport {Layout, Transitionable, type Transitioning, type Properties, PossiblyEvaluated, PossiblyEvaluatedPropertyValue, TRANSITION_SUFFIX} from './properties.ts';\n\nimport type {mat4} from 'gl-matrix';\nimport type {Bucket, BucketParameters} from '../data/bucket.ts';\nimport type Point from '@mapbox/point-geometry';\nimport type {\n FeatureFilter,\n FeatureState,\n LayerSpecification,\n FilterSpecification,\n VisibilitySpecification,\n VisibilityExpression,\n AllPaintProperties,\n AllLayoutProperties,\n} from '@maplibre/maplibre-gl-style-spec';\nimport type {TransitionParameters, PropertyValue} from './properties.ts';\nimport type {EvaluationParameters} from './evaluation_parameters.ts';\nimport type {CrossfadeParameters} from './evaluation_parameters.ts';\nimport type {IReadonlyTransform, GetElevation} from '../geo/transform_interface.ts';\nimport type {CustomLayerInterface} from './style_layer/custom_style_layer.ts';\nimport type {Map} from '../ui/map.ts';\nimport type {StyleSetterOptions} from './style.ts';\nimport type {UnwrappedTileID} from '../tile/tile_id.ts';\nimport type {VectorTileFeatureLike} from '@maplibre/vt-pbf';\n\nexport type PaintPropertyEntry = { [K in keyof AllPaintProperties]: {name: K; value: AllPaintProperties[K]} }[keyof AllPaintProperties];\n\nexport type QueryIntersectsFeatureParams = {\n /**\n * The geometry to check intersection with.\n * This geometry is in tile coordinates.\n */\n queryGeometry: Point[];\n /**\n * The feature to allow expression evaluation.\n */\n feature: VectorTileFeatureLike;\n /**\n * The feature state to allow expression evaluation.\n */\n featureState: FeatureState;\n /**\n * The geometry of the feature.\n * This geometry is in tile coordinates.\n */\n geometry: Point[][];\n /**\n * The current zoom level.\n */\n zoom: number;\n /**\n * The transform to convert from tile coordinates to pixels.\n */\n transform: IReadonlyTransform;\n /**\n * The number of pixels per tile unit.\n */\n pixelsToTileUnits: number;\n /**\n * The matrix to convert from tile coordinates to pixel coordinates.\n * The pixel coordinates are relative to the center of the screen.\n */\n pixelPosMatrix: mat4;\n /**\n * The unwrapped tile ID for the tile being queried.\n */\n unwrappedTileID: UnwrappedTileID;\n /**\n * A function to get the elevation of a point in tile coordinates.\n */\n getElevation: GetElevation | undefined;\n};\n\nconst ERROR_PAINT_NOT_LAYOUT = ' is a PAINT property not a LAYOUT property. Use get/setPaintProperty instead?';\nconst ERROR_LAYOUT_NOT_PAINT = ' is a LAYOUT property not a PAINT property. Use get/setLayoutProperty instead?';\n\n/**\n * A base class for style layers\n */\nexport abstract class StyleLayer extends Evented {\n id: string;\n metadata: unknown;\n type: LayerSpecification['type'] | CustomLayerInterface['type'];\n source: string;\n sourceLayer: string;\n minzoom: number;\n maxzoom: number;\n filter: FilterSpecification | void;\n visibility: VisibilitySpecification;\n private _evaluatedVisibility: 'visible' | 'none' | void;\n\n _crossfadeParameters: CrossfadeParameters;\n\n _unevaluatedLayout: Layout;\n readonly layout: unknown;\n\n _transitionablePaint: Transitionable;\n _transitioningPaint: Transitioning;\n readonly paint: unknown;\n\n _featureFilter: FeatureFilter;\n\n _visibilityExpression: VisibilityExpression;\n\n readonly onAdd: ((map: Map) => void);\n readonly onRemove: ((map: Map) => void);\n\n queryRadius?(bucket: Bucket): number;\n queryIntersectsFeature?(params: QueryIntersectsFeatureParams): boolean | number;\n createBucket?(parameters: BucketParameters): Bucket;\n\n private _globalState: Record; // reference to global state\n\n constructor(layer: LayerSpecification | CustomLayerInterface, properties: Readonly<{\n layout?: Properties;\n paint?: Properties;\n }>, globalState: Record) {\n super();\n\n this.id = layer.id;\n this.type = layer.type;\n this._globalState = globalState;\n this._featureFilter = {filter: () => true, needGeometry: false, getGlobalStateRefs: () => new Set()};\n this._visibilityExpression = createVisibilityExpression(this.visibility, `layers[${this.id}].layout.visibility`, globalState);\n\n if (layer.type === 'custom') return;\n\n this.metadata = layer.metadata;\n this.minzoom = layer.minzoom;\n this.maxzoom = layer.maxzoom;\n\n if (layer.type !== 'background') {\n this.source = layer.source;\n this.sourceLayer = layer['source-layer'];\n this.filter = layer.filter;\n this._featureFilter = featureFilter(layer.filter, `layers[${this.id}].filter`, globalState);\n }\n\n if (properties.layout) {\n this._unevaluatedLayout = new Layout(properties.layout, `layers[${this.id}].layout`, globalState);\n }\n\n if (properties.paint) {\n this._transitionablePaint = new Transitionable(properties.paint, `layers[${this.id}].paint`, globalState);\n\n for (const property in layer.paint) {\n this.setPaintProperty(property as keyof AllPaintProperties, layer.paint[property as keyof typeof layer.paint], {validate: false});\n }\n for (const property in layer.layout) {\n this.setLayoutProperty(property as keyof AllLayoutProperties, layer.layout[property as keyof typeof layer.layout], {validate: false});\n }\n\n this._transitioningPaint = this._transitionablePaint.untransitioned();\n this.paint = new PossiblyEvaluated(properties.paint);\n }\n }\n\n setFilter(filter: FilterSpecification | void): void {\n this.filter = filter;\n this._featureFilter = featureFilter(filter, `layers[${this.id}].filter`, this._globalState);\n }\n\n getCrossfadeParameters(): CrossfadeParameters {\n return this._crossfadeParameters;\n }\n\n getLayoutProperty(name: K): AllLayoutProperties[K] {\n if (name === 'visibility') {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- otherwise typescript fails with error TS2590: Expression produces a union type that is too complex to represent\n return this.visibility as AllLayoutProperties[K];\n }\n if (this._transitionablePaint?.hasProperty(name)) {\n throw new Error(name + ERROR_PAINT_NOT_LAYOUT);\n }\n if (!this._unevaluatedLayout) {\n throw new Error(`Cannot get layout property \"${name}\" on layer type \"${this.type}\" which has no layout properties.`);\n }\n return this._unevaluatedLayout.getValue(name);\n }\n\n /**\n * Get list of global state references that are used within layout or filter properties.\n * This is used to determine if layer source need to be reloaded when global state property changes.\n *\n */\n getLayoutAffectingGlobalStateRefs(): Set {\n const globalStateRefs = new Set();\n\n for (const globalStateRef of this._visibilityExpression.getGlobalStateRefs()) {\n globalStateRefs.add(globalStateRef);\n }\n\n if (this._unevaluatedLayout) {\n for (const propertyName in this._unevaluatedLayout._values) {\n const value = this._unevaluatedLayout._values[propertyName];\n\n for (const globalStateRef of value.getGlobalStateRefs()) {\n globalStateRefs.add(globalStateRef);\n }\n }\n }\n\n for (const globalStateRef of this._featureFilter.getGlobalStateRefs()) {\n globalStateRefs.add(globalStateRef);\n }\n\n return globalStateRefs;\n }\n\n /**\n * Get list of global state references that are used within paint properties.\n * This is used to determine if layer needs to be repainted when global state property changes.\n *\n */\n getPaintAffectingGlobalStateRefs(): globalThis.Map {\n const globalStateRefs = new globalThis.Map();\n\n if (this._transitionablePaint) {\n for (const propertyName in this._transitionablePaint._values) {\n const value = this._transitionablePaint._values[propertyName].value;\n\n for (const globalStateRef of value.getGlobalStateRefs()) {\n const properties = globalStateRefs.get(globalStateRef) ?? [];\n properties.push({name: propertyName as keyof AllPaintProperties, value: value.value} as PaintPropertyEntry);\n globalStateRefs.set(globalStateRef, properties);\n }\n }\n }\n\n return globalStateRefs;\n }\n\n /**\n * Get list of global state references that are used within visibility expression.\n * This is used to determine if layer visibility needs to be updated when global state property changes.\n */\n getVisibilityAffectingGlobalStateRefs(): Set {\n return this._visibilityExpression.getGlobalStateRefs();\n }\n\n setLayoutProperty(name: K, value: AllLayoutProperties[K], options: StyleSetterOptions = {}): void {\n if (name === 'visibility') {\n this.visibility = value as VisibilitySpecification;\n this._visibilityExpression.setValue(value as VisibilitySpecification);\n this.recalculateVisibility();\n return;\n }\n\n if (this._transitionablePaint?.hasProperty(name)) {\n this.fire(new ErrorEvent(new Error(name + ERROR_PAINT_NOT_LAYOUT)));\n return;\n }\n\n if (value !== null && value !== undefined && this._validate(validateStyle.layoutProperty, `layers.${this.id}.layout.${name}`, name, value, options)) return;\n\n this._unevaluatedLayout.setValue(name, value);\n }\n\n getPaintProperty(name: K): AllPaintProperties[K] {\n if (name.endsWith(TRANSITION_SUFFIX)) {\n const baseName = name.slice(0, -TRANSITION_SUFFIX.length);\n if (baseName === 'visibility' || this._unevaluatedLayout?.hasProperty(baseName)) {\n throw new Error(name + ERROR_LAYOUT_NOT_PAINT);\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- otherwise typescript fails with error TS2590: Expression produces a union type that is too complex to represent\n return this._transitionablePaint.getTransition(baseName) as AllPaintProperties[K];\n } else {\n if (name as any === 'visibility' || this._unevaluatedLayout?.hasProperty(name)) {\n throw new Error(name + ERROR_LAYOUT_NOT_PAINT);\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- otherwise typescript fails with error TS2590: Expression produces a union type that is too complex to represent\n return this._transitionablePaint.getValue(name) as AllPaintProperties[K];\n }\n }\n\n setPaintProperty(name: K, value: AllPaintProperties[K], options: StyleSetterOptions = {}): boolean {\n if (name as any === 'visibility' || this._unevaluatedLayout?.hasProperty(name)) {\n this.fire(new ErrorEvent(new Error(name + ERROR_LAYOUT_NOT_PAINT)));\n return false;\n }\n\n if (value !== null && value !== undefined && this._validate(validateStyle.paintProperty, `layers.${this.id}.paint.${name}`, name, value, options)) return false;\n\n if (name.endsWith(TRANSITION_SUFFIX)) {\n this._transitionablePaint.setTransition(name.slice(0, -TRANSITION_SUFFIX.length), (value as any) || undefined);\n return false;\n } else {\n const transitionable = this._transitionablePaint._values[name];\n const isCrossFadedProperty = transitionable.property.specification['property-type'] === 'cross-faded-data-driven';\n const wasDataDriven = transitionable.value.isDataDriven();\n const oldValue = transitionable.value;\n\n // Transitionable.setValue uses a free-floating T that can't unify with the AllPaintProperties union -> better types downstream of this code needed\n this._transitionablePaint.setValue(name, value as any);\n this._handleSpecialPaintPropertyUpdate(name);\n\n const newValue = this._transitionablePaint._values[name].value;\n const isDataDriven = newValue.isDataDriven();\n\n // if a cross-faded value is changed, we need to make sure the new icons get added to each tile's iconAtlas\n // so a call to _updateLayer is necessary, and we return true from this function so it gets called in\n // Style.setPaintProperty\n return isDataDriven || wasDataDriven || isCrossFadedProperty || this._handleOverridablePaintPropertyUpdate(name, oldValue, newValue);\n }\n }\n\n _handleSpecialPaintPropertyUpdate(_: string): void {\n // No-op; can be overridden by derived classes.\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _handleOverridablePaintPropertyUpdate(name: string, oldValue: PropertyValue, newValue: PropertyValue): boolean {\n // No-op; can be overridden by derived classes.\n return false;\n }\n\n isHidden(zoom: number = this.minzoom, roundMinZoom: boolean = false): boolean {\n if (this.minzoom && zoom < (roundMinZoom ? Math.floor(this.minzoom) : this.minzoom)) return true;\n if (this.maxzoom && zoom >= this.maxzoom) return true;\n return this._evaluatedVisibility === 'none';\n }\n\n updateTransitions(parameters: TransitionParameters): void {\n this._transitioningPaint = this._transitionablePaint.transitioned(parameters, this._transitioningPaint);\n }\n\n hasTransition(): boolean {\n return this._transitioningPaint.hasTransition();\n }\n\n recalculateVisibility(): void {\n this._evaluatedVisibility = this._visibilityExpression.evaluate();\n }\n\n recalculate(parameters: EvaluationParameters, availableImages: string[]): void {\n if (parameters.getCrossfadeParameters) {\n this._crossfadeParameters = parameters.getCrossfadeParameters();\n }\n\n if (this._unevaluatedLayout) {\n (this as any).layout = this._unevaluatedLayout.possiblyEvaluate(parameters, undefined, availableImages);\n }\n\n (this as any).paint = this._transitioningPaint.possiblyEvaluate(parameters, undefined, availableImages);\n }\n\n serialize(): LayerSpecification {\n const output: LayerSpecification = {\n 'id': this.id,\n 'type': this.type as LayerSpecification['type'],\n 'source': this.source,\n 'source-layer': this.sourceLayer,\n 'metadata': this.metadata,\n 'minzoom': this.minzoom,\n 'maxzoom': this.maxzoom,\n 'filter': this.filter as FilterSpecification,\n 'layout': this._unevaluatedLayout?.serialize(),\n 'paint': this._transitionablePaint?.serialize()\n };\n\n if (this.visibility) {\n output.layout ||= {};\n output.layout.visibility = this.visibility;\n }\n\n return filterObject(output, (value, key) => {\n return value !== undefined &&\n !(key === 'layout' && !Object.keys(value).length) &&\n !(key === 'paint' && !Object.keys(value).length);\n });\n }\n\n _validate(validate: Validator, key: string, name: string, value: unknown, options: StyleSetterOptions = {}): boolean {\n return validateAndEmit(this, validate, {\n key,\n layerType: this.type,\n objectKey: name,\n value\n }, options);\n }\n\n is3D(): boolean {\n return false;\n }\n\n isTileClipped(): boolean {\n return false;\n }\n\n hasOffscreenPass(): boolean {\n return false;\n }\n\n resize(): void {\n // noop\n }\n\n isStateDependent(): boolean {\n for (const property in (this as any).paint._values) {\n const value = (this as any).paint.get(property);\n if (!(value instanceof PossiblyEvaluatedPropertyValue) || !supportsPropertyExpression(value.property.specification)) {\n continue;\n }\n\n if ((value.value.kind === 'source' || value.value.kind === 'composite') &&\n value.value.isStateDependent) {\n return true;\n }\n }\n return false;\n }\n}\n","// This file is generated. Edit build/generate-style-code.ts, then run 'npm run codegen'.\n/* eslint-disable */\n\nimport {latest as styleSpec} from '@maplibre/maplibre-gl-style-spec';\n\nimport {\n Properties,\n DataConstantProperty,\n DataDrivenProperty,\n CrossFadedDataDrivenProperty,\n CrossFadedProperty,\n ColorRampProperty,\n PossiblyEvaluatedPropertyValue,\n CrossFaded\n} from '../properties.ts';\n\nimport type {Color, Formatted, Padding, NumberArray, ColorArray, ResolvedImage, VariableAnchorOffsetCollection, ProjectionDefinitionSpecification} from '@maplibre/maplibre-gl-style-spec';\nimport {StylePropertySpecification} from '@maplibre/maplibre-gl-style-spec';\n\n\nexport type RasterPaintProps = {\n \"raster-opacity\": DataConstantProperty,\n \"raster-hue-rotate\": DataConstantProperty,\n \"raster-brightness-min\": DataConstantProperty,\n \"raster-brightness-max\": DataConstantProperty,\n \"raster-saturation\": DataConstantProperty,\n \"raster-contrast\": DataConstantProperty,\n \"resampling\": DataConstantProperty<\"linear\" | \"nearest\">,\n \"raster-resampling\": DataConstantProperty<\"linear\" | \"nearest\">,\n \"raster-fade-duration\": DataConstantProperty,\n};\n\nexport type RasterPaintPropsPossiblyEvaluated = {\n \"raster-opacity\": number,\n \"raster-hue-rotate\": number,\n \"raster-brightness-min\": number,\n \"raster-brightness-max\": number,\n \"raster-saturation\": number,\n \"raster-contrast\": number,\n \"resampling\": \"linear\" | \"nearest\",\n \"raster-resampling\": \"linear\" | \"nearest\",\n \"raster-fade-duration\": number,\n};\n\nlet paint: Properties;\nconst getPaint = (): Properties => paint = paint || new Properties({\n \"raster-opacity\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-opacity\"] as any as StylePropertySpecification, \"raster-opacity\"),\n \"raster-hue-rotate\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-hue-rotate\"] as any as StylePropertySpecification, \"raster-hue-rotate\"),\n \"raster-brightness-min\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-brightness-min\"] as any as StylePropertySpecification, \"raster-brightness-min\"),\n \"raster-brightness-max\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-brightness-max\"] as any as StylePropertySpecification, \"raster-brightness-max\"),\n \"raster-saturation\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-saturation\"] as any as StylePropertySpecification, \"raster-saturation\"),\n \"raster-contrast\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-contrast\"] as any as StylePropertySpecification, \"raster-contrast\"),\n \"resampling\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"resampling\"] as any as StylePropertySpecification, \"resampling\"),\n \"raster-resampling\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-resampling\"] as any as StylePropertySpecification, \"raster-resampling\"),\n \"raster-fade-duration\": new DataConstantProperty(styleSpec[\"paint_raster\"][\"raster-fade-duration\"] as any as StylePropertySpecification, \"raster-fade-duration\"),\n});\n\nexport default ({ get paint(): Properties { return getPaint() } });","import {StyleLayer} from '../style_layer.ts';\n\nimport properties, {type RasterPaintPropsPossiblyEvaluated} from './raster_style_layer_properties.g.ts';\nimport {type Transitionable, type Transitioning, type PossiblyEvaluated} from '../properties.ts';\n\nimport type {RasterPaintProps} from './raster_style_layer_properties.g.ts';\nimport type {LayerSpecification} from '@maplibre/maplibre-gl-style-spec';\n\nexport const isRasterStyleLayer = (layer: StyleLayer): layer is RasterStyleLayer => layer.type === 'raster';\n\nexport class RasterStyleLayer extends StyleLayer {\n _transitionablePaint: Transitionable;\n _transitioningPaint: Transitioning;\n paint: PossiblyEvaluated;\n\n constructor(layer: LayerSpecification, globalState: Record) {\n super(layer, properties, globalState);\n }\n}\n","// Note: all \"sizes\" are measured in bytes\n\n/**\n * @internal\n * A view type size\n */\nconst viewTypes: {\n Int8: Int8ArrayConstructor;\n Uint8: Uint8ArrayConstructor;\n Int16: Int16ArrayConstructor;\n Uint16: Uint16ArrayConstructor;\n Int32: Int32ArrayConstructor;\n Uint32: Uint32ArrayConstructor;\n Float32: Float32ArrayConstructor;\n} = {\n 'Int8': Int8Array,\n 'Uint8': Uint8Array,\n 'Int16': Int16Array,\n 'Uint16': Uint16Array,\n 'Int32': Int32Array,\n 'Uint32': Uint32Array,\n 'Float32': Float32Array\n};\n\n/**\n * @internal\n * A view type size\n */\nexport type ViewType = keyof typeof viewTypes;\n\n/** @internal */\nclass Struct {\n _pos1: number;\n _pos2: number;\n _pos4: number;\n _pos8: number;\n readonly _structArray: StructArray;\n\n // The following properties are defined on the prototype of sub classes.\n size: number;\n\n /**\n * @param structArray - The StructArray the struct is stored in\n * @param index - The index of the struct in the StructArray.\n */\n constructor(structArray: StructArray, index: number) {\n (this as any)._structArray = structArray;\n this._pos1 = index * this.size;\n this._pos2 = this._pos1 / 2;\n this._pos4 = this._pos1 / 4;\n this._pos8 = this._pos1 / 8;\n }\n}\n\nconst DEFAULT_CAPACITY = 128;\nconst RESIZE_MULTIPLIER = 5;\n\n/**\n * @internal\n * A struct array member\n */\nexport type StructArrayMember = {\n name: string;\n type: ViewType;\n components: number;\n offset: number;\n};\n\nexport type StructArrayLayout = {\n members: StructArrayMember[];\n size: number;\n alignment: number;\n};\n\n/**\n * An array that can be deserialized\n */\nexport type SerializedStructArray = {\n length: number;\n arrayBuffer: ArrayBuffer;\n};\n\n/**\n * @internal\n * `StructArray` provides an abstraction over `ArrayBuffer` and `TypedArray`\n * making it behave like an array of typed structs.\n *\n * Conceptually, a StructArray is comprised of elements, i.e., instances of its\n * associated struct type. Each particular struct type, together with an\n * alignment size, determines the memory layout of a StructArray whose elements\n * are of that type. Thus, for each such layout that we need, we have\n * a corresponding StructArrayLayout class, inheriting from StructArray and\n * implementing `emplaceBack()` and `_refreshViews()`.\n *\n * In some cases, where we need to access particular elements of a StructArray,\n * we implement a more specific subclass that inherits from one of the\n * StructArrayLayouts and adds a `get(i): T` accessor that returns a structured\n * object whose properties are proxies into the underlying memory space for the\n * i-th element. This affords the convenience of working with (seemingly) plain\n * Javascript objects without the overhead of serializing/deserializing them\n * into ArrayBuffers for efficient web worker transfer.\n */\nabstract class StructArray {\n capacity: number;\n length: number;\n isTransferred: boolean;\n arrayBuffer: ArrayBuffer;\n uint8: Uint8Array;\n\n // The following properties are defined on the prototype.\n members: StructArrayMember[];\n bytesPerElement: number;\n abstract emplaceBack(...v: number[]): number;\n abstract emplace(i: number, ...v: number[]): number;\n\n constructor() {\n this.isTransferred = false;\n this.capacity = -1;\n this.resize(0);\n }\n\n /**\n * Serialize a StructArray instance. Serializes both the raw data and the\n * metadata needed to reconstruct the StructArray base class during\n * deserialization.\n */\n static serialize(array: StructArray, transferables?: Transferable[]): SerializedStructArray {\n\n array._trim();\n\n if (transferables) {\n array.isTransferred = true;\n transferables.push(array.arrayBuffer);\n }\n\n return {\n length: array.length,\n arrayBuffer: array.arrayBuffer,\n };\n }\n\n static deserialize(this: {prototype: T} & (new () => T), input: SerializedStructArray): T {\n const structArray: T = Object.create(this.prototype);\n structArray.arrayBuffer = input.arrayBuffer;\n structArray.length = input.length;\n structArray.capacity = input.arrayBuffer.byteLength / structArray.bytesPerElement;\n structArray._refreshViews();\n return structArray;\n }\n\n /**\n * Resize the array to discard unused capacity.\n */\n _trim(): void {\n if (this.length !== this.capacity) {\n this.capacity = this.length;\n this.arrayBuffer = this.arrayBuffer.slice(0, this.length * this.bytesPerElement);\n this._refreshViews();\n }\n }\n\n /**\n * Resets the length of the array to 0 without de-allocating capacity.\n */\n clear(): void {\n this.length = 0;\n }\n\n /**\n * Resize the array.\n * If `n` is greater than the current length then additional elements with undefined values are added.\n * If `n` is less than the current length then the array will be reduced to the first `n` elements.\n * @param n - The new size of the array.\n */\n resize(n: number): void {\n this.reserve(n);\n this.length = n;\n }\n\n /**\n * Indicate a planned increase in size, so that any necessary allocation may\n * be done once, ahead of time.\n * @param n - The expected size of the array.\n */\n reserve(n: number): void {\n if (n > this.capacity) {\n this.capacity = Math.max(n, Math.floor(this.capacity * RESIZE_MULTIPLIER), DEFAULT_CAPACITY);\n this.arrayBuffer = new ArrayBuffer(this.capacity * this.bytesPerElement);\n\n const oldUint8Array = this.uint8;\n this._refreshViews();\n if (oldUint8Array) this.uint8.set(oldUint8Array);\n }\n }\n\n /**\n * Create TypedArray views for the current ArrayBuffer.\n */\n _refreshViews(): void {\n throw new Error('_refreshViews() must be implemented by each concrete StructArray layout');\n }\n\n /**\n * Replace the buffer with an empty one so typed views release the original ArrayBuffer for GC.\n */\n freeBufferAfterUpload(): void {\n this.arrayBuffer = new ArrayBuffer(0);\n this._refreshViews();\n }\n}\n\n/**\n * Given a list of member fields, create a full StructArrayLayout, in\n * particular calculating the correct byte offset for each field. This data\n * is used at build time to generate StructArrayLayout_*.emplaceBack() and\n * other accessors, and at runtime for binding vertex buffer attributes.\n */\nfunction createLayout(\n members: Array<{\n name: string;\n type: ViewType;\n readonly components?: number;\n }>,\n alignment: number = 1\n): StructArrayLayout {\n\n let offset = 0;\n let maxSize = 0;\n const layoutMembers = members.map((member) => {\n const typeSize = sizeOf(member.type);\n const memberOffset = offset = align(offset, Math.max(alignment, typeSize));\n const components = member.components || 1;\n\n maxSize = Math.max(maxSize, typeSize);\n offset += typeSize * components;\n\n return {\n name: member.name,\n type: member.type,\n components,\n offset: memberOffset,\n };\n });\n\n const size = align(offset, Math.max(maxSize, alignment));\n\n return {\n members: layoutMembers,\n size,\n alignment\n };\n}\n\nfunction sizeOf(type: ViewType): number {\n return viewTypes[type].BYTES_PER_ELEMENT;\n}\n\nfunction align(offset: number, size: number): number {\n return Math.ceil(offset / size) * size;\n}\n\nexport {StructArray, Struct, viewTypes, createLayout};\n","// This file is generated. Edit build/generate-struct-arrays.ts, then run `npm run codegen`.\n\nimport {Struct, StructArray} from '../util/struct_array.ts';\nimport {register} from '../util/web_worker_transfer.ts';\nimport Point from '@mapbox/point-geometry';\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[2]\n *\n */\nclass StructArrayLayout2i4 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1);\n }\n\n public emplace(i: number, v0: number, v1: number): number {\n const o2 = i * 2;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n return i;\n }\n}\n\nStructArrayLayout2i4.prototype.bytesPerElement = 4;\nregister('StructArrayLayout2i4', StructArrayLayout2i4);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[3]\n *\n */\nclass StructArrayLayout3i6 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number): number {\n const o2 = i * 3;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.int16[o2 + 2] = v2;\n return i;\n }\n}\n\nStructArrayLayout3i6.prototype.bytesPerElement = 6;\nregister('StructArrayLayout3i6', StructArrayLayout3i6);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[4]\n *\n */\nclass StructArrayLayout4i8 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number): number {\n const o2 = i * 4;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.int16[o2 + 2] = v2;\n this.int16[o2 + 3] = v3;\n return i;\n }\n}\n\nStructArrayLayout4i8.prototype.bytesPerElement = 8;\nregister('StructArrayLayout4i8', StructArrayLayout4i8);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[2]\n * [4] - Int16[4]\n *\n */\nclass StructArrayLayout2i4i12 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const o2 = i * 6;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.int16[o2 + 2] = v2;\n this.int16[o2 + 3] = v3;\n this.int16[o2 + 4] = v4;\n this.int16[o2 + 5] = v5;\n return i;\n }\n}\n\nStructArrayLayout2i4i12.prototype.bytesPerElement = 12;\nregister('StructArrayLayout2i4i12', StructArrayLayout2i4i12);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[2]\n * [4] - Uint8[4]\n *\n */\nclass StructArrayLayout2i4ub8 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const o2 = i * 4;\n const o1 = i * 8;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.uint8[o1 + 4] = v2;\n this.uint8[o1 + 5] = v3;\n this.uint8[o1 + 6] = v4;\n this.uint8[o1 + 7] = v5;\n return i;\n }\n}\n\nStructArrayLayout2i4ub8.prototype.bytesPerElement = 8;\nregister('StructArrayLayout2i4ub8', StructArrayLayout2i4ub8);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Float32[2]\n *\n */\nclass StructArrayLayout2f8 extends StructArray {\n uint8: Uint8Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1);\n }\n\n public emplace(i: number, v0: number, v1: number): number {\n const o4 = i * 2;\n this.float32[o4 + 0] = v0;\n this.float32[o4 + 1] = v1;\n return i;\n }\n}\n\nStructArrayLayout2f8.prototype.bytesPerElement = 8;\nregister('StructArrayLayout2f8', StructArrayLayout2f8);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint16[10]\n *\n */\nclass StructArrayLayout10ui20 extends StructArray {\n uint8: Uint8Array;\n uint16: Uint16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number): number {\n const o2 = i * 10;\n this.uint16[o2 + 0] = v0;\n this.uint16[o2 + 1] = v1;\n this.uint16[o2 + 2] = v2;\n this.uint16[o2 + 3] = v3;\n this.uint16[o2 + 4] = v4;\n this.uint16[o2 + 5] = v5;\n this.uint16[o2 + 6] = v6;\n this.uint16[o2 + 7] = v7;\n this.uint16[o2 + 8] = v8;\n this.uint16[o2 + 9] = v9;\n return i;\n }\n}\n\nStructArrayLayout10ui20.prototype.bytesPerElement = 20;\nregister('StructArrayLayout10ui20', StructArrayLayout10ui20);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint16[8]\n *\n */\nclass StructArrayLayout8ui16 extends StructArray {\n uint8: Uint8Array;\n uint16: Uint16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number): number {\n const o2 = i * 8;\n this.uint16[o2 + 0] = v0;\n this.uint16[o2 + 1] = v1;\n this.uint16[o2 + 2] = v2;\n this.uint16[o2 + 3] = v3;\n this.uint16[o2 + 4] = v4;\n this.uint16[o2 + 5] = v5;\n this.uint16[o2 + 6] = v6;\n this.uint16[o2 + 7] = v7;\n return i;\n }\n}\n\nStructArrayLayout8ui16.prototype.bytesPerElement = 16;\nregister('StructArrayLayout8ui16', StructArrayLayout8ui16);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[4]\n * [8] - Uint16[4]\n * [16] - Int16[4]\n * [24] - Float32[1]\n *\n */\nclass StructArrayLayout4i4ui4i1f28 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n uint16: Uint16Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number): number {\n const o2 = i * 14;\n const o4 = i * 7;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.int16[o2 + 2] = v2;\n this.int16[o2 + 3] = v3;\n this.uint16[o2 + 4] = v4;\n this.uint16[o2 + 5] = v5;\n this.uint16[o2 + 6] = v6;\n this.uint16[o2 + 7] = v7;\n this.int16[o2 + 8] = v8;\n this.int16[o2 + 9] = v9;\n this.int16[o2 + 10] = v10;\n this.int16[o2 + 11] = v11;\n this.float32[o4 + 6] = v12;\n return i;\n }\n}\n\nStructArrayLayout4i4ui4i1f28.prototype.bytesPerElement = 28;\nregister('StructArrayLayout4i4ui4i1f28', StructArrayLayout4i4ui4i1f28);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Float32[3]\n *\n */\nclass StructArrayLayout3f12 extends StructArray {\n uint8: Uint8Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number): number {\n const o4 = i * 3;\n this.float32[o4 + 0] = v0;\n this.float32[o4 + 1] = v1;\n this.float32[o4 + 2] = v2;\n return i;\n }\n}\n\nStructArrayLayout3f12.prototype.bytesPerElement = 12;\nregister('StructArrayLayout3f12', StructArrayLayout3f12);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint32[1]\n *\n */\nclass StructArrayLayout1ul4 extends StructArray {\n uint8: Uint8Array;\n uint32: Uint32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint32 = new Uint32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0);\n }\n\n public emplace(i: number, v0: number): number {\n const o4 = i * 1;\n this.uint32[o4 + 0] = v0;\n return i;\n }\n}\n\nStructArrayLayout1ul4.prototype.bytesPerElement = 4;\nregister('StructArrayLayout1ul4', StructArrayLayout1ul4);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[6]\n * [12] - Uint32[1]\n * [16] - Uint16[2]\n *\n */\nclass StructArrayLayout6i1ul2ui20 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n uint32: Uint32Array;\n uint16: Uint16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n this.uint32 = new Uint32Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number): number {\n const o2 = i * 10;\n const o4 = i * 5;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.int16[o2 + 2] = v2;\n this.int16[o2 + 3] = v3;\n this.int16[o2 + 4] = v4;\n this.int16[o2 + 5] = v5;\n this.uint32[o4 + 3] = v6;\n this.uint16[o2 + 8] = v7;\n this.uint16[o2 + 9] = v8;\n return i;\n }\n}\n\nStructArrayLayout6i1ul2ui20.prototype.bytesPerElement = 20;\nregister('StructArrayLayout6i1ul2ui20', StructArrayLayout6i1ul2ui20);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[2]\n * [4] - Int16[2]\n * [8] - Int16[2]\n *\n */\nclass StructArrayLayout2i2i2i12 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const o2 = i * 6;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.int16[o2 + 2] = v2;\n this.int16[o2 + 3] = v3;\n this.int16[o2 + 4] = v4;\n this.int16[o2 + 5] = v5;\n return i;\n }\n}\n\nStructArrayLayout2i2i2i12.prototype.bytesPerElement = 12;\nregister('StructArrayLayout2i2i2i12', StructArrayLayout2i2i2i12);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Float32[2]\n * [8] - Float32[1]\n * [12] - Int16[2]\n *\n */\nclass StructArrayLayout2f1f2i16 extends StructArray {\n uint8: Uint8Array;\n float32: Float32Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number): number {\n const o4 = i * 4;\n const o2 = i * 8;\n this.float32[o4 + 0] = v0;\n this.float32[o4 + 1] = v1;\n this.float32[o4 + 2] = v2;\n this.int16[o2 + 6] = v3;\n this.int16[o2 + 7] = v4;\n return i;\n }\n}\n\nStructArrayLayout2f1f2i16.prototype.bytesPerElement = 16;\nregister('StructArrayLayout2f1f2i16', StructArrayLayout2f1f2i16);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint8[2]\n * [4] - Float32[2]\n * [12] - Int16[2]\n *\n */\nclass StructArrayLayout2ub2f2i16 extends StructArray {\n uint8: Uint8Array;\n float32: Float32Array;\n int16: Int16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number): number {\n const o1 = i * 16;\n const o4 = i * 4;\n const o2 = i * 8;\n this.uint8[o1 + 0] = v0;\n this.uint8[o1 + 1] = v1;\n this.float32[o4 + 1] = v2;\n this.float32[o4 + 2] = v3;\n this.int16[o2 + 6] = v4;\n this.int16[o2 + 7] = v5;\n return i;\n }\n}\n\nStructArrayLayout2ub2f2i16.prototype.bytesPerElement = 16;\nregister('StructArrayLayout2ub2f2i16', StructArrayLayout2ub2f2i16);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint16[3]\n *\n */\nclass StructArrayLayout3ui6 extends StructArray {\n uint8: Uint8Array;\n uint16: Uint16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number): number {\n const o2 = i * 3;\n this.uint16[o2 + 0] = v0;\n this.uint16[o2 + 1] = v1;\n this.uint16[o2 + 2] = v2;\n return i;\n }\n}\n\nStructArrayLayout3ui6.prototype.bytesPerElement = 6;\nregister('StructArrayLayout3ui6', StructArrayLayout3ui6);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[2]\n * [4] - Uint16[2]\n * [8] - Uint32[3]\n * [20] - Uint16[3]\n * [28] - Float32[2]\n * [36] - Uint8[3]\n * [40] - Uint32[1]\n * [44] - Int16[1]\n * [48] - Float32[1]\n *\n */\nclass StructArrayLayout2i2ui3ul3ui2f3ub1ul1i1f52 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n uint16: Uint16Array;\n uint32: Uint32Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n this.uint32 = new Uint32Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number): number {\n const o2 = i * 26;\n const o4 = i * 13;\n const o1 = i * 52;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.uint16[o2 + 2] = v2;\n this.uint16[o2 + 3] = v3;\n this.uint32[o4 + 2] = v4;\n this.uint32[o4 + 3] = v5;\n this.uint32[o4 + 4] = v6;\n this.uint16[o2 + 10] = v7;\n this.uint16[o2 + 11] = v8;\n this.uint16[o2 + 12] = v9;\n this.float32[o4 + 7] = v10;\n this.float32[o4 + 8] = v11;\n this.uint8[o1 + 36] = v12;\n this.uint8[o1 + 37] = v13;\n this.uint8[o1 + 38] = v14;\n this.uint32[o4 + 10] = v15;\n this.int16[o2 + 22] = v16;\n this.float32[o4 + 12] = v17;\n return i;\n }\n}\n\nStructArrayLayout2i2ui3ul3ui2f3ub1ul1i1f52.prototype.bytesPerElement = 52;\nregister('StructArrayLayout2i2ui3ul3ui2f3ub1ul1i1f52', StructArrayLayout2i2ui3ul3ui2f3ub1ul1i1f52);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Int16[8]\n * [16] - Uint16[15]\n * [48] - Uint32[1]\n * [52] - Float32[2]\n * [60] - Uint16[2]\n * [64] - Float32[1]\n *\n */\nclass StructArrayLayout8i15ui1ul2f2ui1f68 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n uint16: Uint16Array;\n uint32: Uint32Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n this.uint32 = new Uint32Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number, v18: number, v19: number, v20: number, v21: number, v22: number, v23: number, v24: number, v25: number, v26: number, v27: number, v28: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number, v18: number, v19: number, v20: number, v21: number, v22: number, v23: number, v24: number, v25: number, v26: number, v27: number, v28: number): number {\n const o2 = i * 34;\n const o4 = i * 17;\n this.int16[o2 + 0] = v0;\n this.int16[o2 + 1] = v1;\n this.int16[o2 + 2] = v2;\n this.int16[o2 + 3] = v3;\n this.int16[o2 + 4] = v4;\n this.int16[o2 + 5] = v5;\n this.int16[o2 + 6] = v6;\n this.int16[o2 + 7] = v7;\n this.uint16[o2 + 8] = v8;\n this.uint16[o2 + 9] = v9;\n this.uint16[o2 + 10] = v10;\n this.uint16[o2 + 11] = v11;\n this.uint16[o2 + 12] = v12;\n this.uint16[o2 + 13] = v13;\n this.uint16[o2 + 14] = v14;\n this.uint16[o2 + 15] = v15;\n this.uint16[o2 + 16] = v16;\n this.uint16[o2 + 17] = v17;\n this.uint16[o2 + 18] = v18;\n this.uint16[o2 + 19] = v19;\n this.uint16[o2 + 20] = v20;\n this.uint16[o2 + 21] = v21;\n this.uint16[o2 + 22] = v22;\n this.uint32[o4 + 12] = v23;\n this.float32[o4 + 13] = v24;\n this.float32[o4 + 14] = v25;\n this.uint16[o2 + 30] = v26;\n this.uint16[o2 + 31] = v27;\n this.float32[o4 + 16] = v28;\n return i;\n }\n}\n\nStructArrayLayout8i15ui1ul2f2ui1f68.prototype.bytesPerElement = 68;\nregister('StructArrayLayout8i15ui1ul2f2ui1f68', StructArrayLayout8i15ui1ul2f2ui1f68);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Float32[1]\n *\n */\nclass StructArrayLayout1f4 extends StructArray {\n uint8: Uint8Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0);\n }\n\n public emplace(i: number, v0: number): number {\n const o4 = i * 1;\n this.float32[o4 + 0] = v0;\n return i;\n }\n}\n\nStructArrayLayout1f4.prototype.bytesPerElement = 4;\nregister('StructArrayLayout1f4', StructArrayLayout1f4);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint16[1]\n * [4] - Float32[2]\n *\n */\nclass StructArrayLayout1ui2f12 extends StructArray {\n uint8: Uint8Array;\n uint16: Uint16Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number): number {\n const o2 = i * 6;\n const o4 = i * 3;\n this.uint16[o2 + 0] = v0;\n this.float32[o4 + 1] = v1;\n this.float32[o4 + 2] = v2;\n return i;\n }\n}\n\nStructArrayLayout1ui2f12.prototype.bytesPerElement = 12;\nregister('StructArrayLayout1ui2f12', StructArrayLayout1ui2f12);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint32[1]\n * [4] - Uint16[2]\n *\n */\nclass StructArrayLayout1ul2ui8 extends StructArray {\n uint8: Uint8Array;\n uint32: Uint32Array;\n uint16: Uint16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint32 = new Uint32Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number): number {\n const o4 = i * 2;\n const o2 = i * 4;\n this.uint32[o4 + 0] = v0;\n this.uint16[o2 + 2] = v1;\n this.uint16[o2 + 3] = v2;\n return i;\n }\n}\n\nStructArrayLayout1ul2ui8.prototype.bytesPerElement = 8;\nregister('StructArrayLayout1ul2ui8', StructArrayLayout1ul2ui8);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint16[2]\n *\n */\nclass StructArrayLayout2ui4 extends StructArray {\n uint8: Uint8Array;\n uint16: Uint16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1);\n }\n\n public emplace(i: number, v0: number, v1: number): number {\n const o2 = i * 2;\n this.uint16[o2 + 0] = v0;\n this.uint16[o2 + 1] = v1;\n return i;\n }\n}\n\nStructArrayLayout2ui4.prototype.bytesPerElement = 4;\nregister('StructArrayLayout2ui4', StructArrayLayout2ui4);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Uint16[1]\n *\n */\nclass StructArrayLayout1ui2 extends StructArray {\n uint8: Uint8Array;\n uint16: Uint16Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0);\n }\n\n public emplace(i: number, v0: number): number {\n const o2 = i * 1;\n this.uint16[o2 + 0] = v0;\n return i;\n }\n}\n\nStructArrayLayout1ui2.prototype.bytesPerElement = 2;\nregister('StructArrayLayout1ui2', StructArrayLayout1ui2);\n\n/**\n * @internal\n * Implementation of the StructArray layout:\n * [0] - Float32[4]\n *\n */\nclass StructArrayLayout4f16 extends StructArray {\n uint8: Uint8Array;\n float32: Float32Array;\n\n _refreshViews(): void {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: number, v2: number, v3: number): number {\n const i = this.length;\n this.resize(i + 1);\n return this.emplace(i, v0, v1, v2, v3);\n }\n\n public emplace(i: number, v0: number, v1: number, v2: number, v3: number): number {\n const o4 = i * 4;\n this.float32[o4 + 0] = v0;\n this.float32[o4 + 1] = v1;\n this.float32[o4 + 2] = v2;\n this.float32[o4 + 3] = v3;\n return i;\n }\n}\n\nStructArrayLayout4f16.prototype.bytesPerElement = 16;\nregister('StructArrayLayout4f16', StructArrayLayout4f16);\n\n/** @internal */\nclass CollisionBoxStruct extends Struct {\n _structArray: CollisionBoxArray;\n get anchorPointX(): number { return this._structArray.int16[this._pos2 + 0]; }\n get anchorPointY(): number { return this._structArray.int16[this._pos2 + 1]; }\n get x1(): number { return this._structArray.int16[this._pos2 + 2]; }\n get y1(): number { return this._structArray.int16[this._pos2 + 3]; }\n get x2(): number { return this._structArray.int16[this._pos2 + 4]; }\n get y2(): number { return this._structArray.int16[this._pos2 + 5]; }\n get featureIndex(): number { return this._structArray.uint32[this._pos4 + 3]; }\n get sourceLayerIndex(): number { return this._structArray.uint16[this._pos2 + 8]; }\n get bucketIndex(): number { return this._structArray.uint16[this._pos2 + 9]; }\n get anchorPoint(): Point { return new Point(this.anchorPointX, this.anchorPointY); }\n}\n\nCollisionBoxStruct.prototype.size = 20;\n\nexport type CollisionBox = CollisionBoxStruct;\n\n/** @internal */\nexport class CollisionBoxArray extends StructArrayLayout6i1ul2ui20 {\n /**\n * Return the CollisionBoxStruct at the given location in the array.\n * @param index - The index of the element.\n */\n get(index: number): CollisionBoxStruct {\n return new CollisionBoxStruct(this, index);\n }\n}\n\nregister('CollisionBoxArray', CollisionBoxArray);\n\n/** @internal */\nclass PlacedSymbolStruct extends Struct {\n _structArray: PlacedSymbolArray;\n get anchorX(): number { return this._structArray.int16[this._pos2 + 0]; }\n get anchorY(): number { return this._structArray.int16[this._pos2 + 1]; }\n get glyphStartIndex(): number { return this._structArray.uint16[this._pos2 + 2]; }\n get numGlyphs(): number { return this._structArray.uint16[this._pos2 + 3]; }\n get vertexStartIndex(): number { return this._structArray.uint32[this._pos4 + 2]; }\n get lineStartIndex(): number { return this._structArray.uint32[this._pos4 + 3]; }\n get lineLength(): number { return this._structArray.uint32[this._pos4 + 4]; }\n get segment(): number { return this._structArray.uint16[this._pos2 + 10]; }\n get lowerSize(): number { return this._structArray.uint16[this._pos2 + 11]; }\n get upperSize(): number { return this._structArray.uint16[this._pos2 + 12]; }\n get lineOffsetX(): number { return this._structArray.float32[this._pos4 + 7]; }\n get lineOffsetY(): number { return this._structArray.float32[this._pos4 + 8]; }\n get writingMode(): number { return this._structArray.uint8[this._pos1 + 36]; }\n get placedOrientation(): number { return this._structArray.uint8[this._pos1 + 37]; }\n set placedOrientation(x: number) { this._structArray.uint8[this._pos1 + 37] = x; }\n get hidden(): number { return this._structArray.uint8[this._pos1 + 38]; }\n set hidden(x: number) { this._structArray.uint8[this._pos1 + 38] = x; }\n get crossTileID(): number { return this._structArray.uint32[this._pos4 + 10]; }\n set crossTileID(x: number) { this._structArray.uint32[this._pos4 + 10] = x; }\n get associatedIconIndex(): number { return this._structArray.int16[this._pos2 + 22]; }\n get heightOffset(): number { return this._structArray.float32[this._pos4 + 12]; }\n}\n\nPlacedSymbolStruct.prototype.size = 52;\n\nexport type PlacedSymbol = PlacedSymbolStruct;\n\n/** @internal */\nexport class PlacedSymbolArray extends StructArrayLayout2i2ui3ul3ui2f3ub1ul1i1f52 {\n /**\n * Return the PlacedSymbolStruct at the given location in the array.\n * @param index - The index of the element.\n */\n get(index: number): PlacedSymbolStruct {\n return new PlacedSymbolStruct(this, index);\n }\n}\n\nregister('PlacedSymbolArray', PlacedSymbolArray);\n\n/** @internal */\nclass SymbolInstanceStruct extends Struct {\n _structArray: SymbolInstanceArray;\n get anchorX(): number { return this._structArray.int16[this._pos2 + 0]; }\n get anchorY(): number { return this._structArray.int16[this._pos2 + 1]; }\n get rightJustifiedTextSymbolIndex(): number { return this._structArray.int16[this._pos2 + 2]; }\n get centerJustifiedTextSymbolIndex(): number { return this._structArray.int16[this._pos2 + 3]; }\n get leftJustifiedTextSymbolIndex(): number { return this._structArray.int16[this._pos2 + 4]; }\n get verticalPlacedTextSymbolIndex(): number { return this._structArray.int16[this._pos2 + 5]; }\n get placedIconSymbolIndex(): number { return this._structArray.int16[this._pos2 + 6]; }\n get verticalPlacedIconSymbolIndex(): number { return this._structArray.int16[this._pos2 + 7]; }\n get key(): number { return this._structArray.uint16[this._pos2 + 8]; }\n get textBoxStartIndex(): number { return this._structArray.uint16[this._pos2 + 9]; }\n get textBoxEndIndex(): number { return this._structArray.uint16[this._pos2 + 10]; }\n get verticalTextBoxStartIndex(): number { return this._structArray.uint16[this._pos2 + 11]; }\n get verticalTextBoxEndIndex(): number { return this._structArray.uint16[this._pos2 + 12]; }\n get iconBoxStartIndex(): number { return this._structArray.uint16[this._pos2 + 13]; }\n get iconBoxEndIndex(): number { return this._structArray.uint16[this._pos2 + 14]; }\n get verticalIconBoxStartIndex(): number { return this._structArray.uint16[this._pos2 + 15]; }\n get verticalIconBoxEndIndex(): number { return this._structArray.uint16[this._pos2 + 16]; }\n get featureIndex(): number { return this._structArray.uint16[this._pos2 + 17]; }\n get numHorizontalGlyphVertices(): number { return this._structArray.uint16[this._pos2 + 18]; }\n get numVerticalGlyphVertices(): number { return this._structArray.uint16[this._pos2 + 19]; }\n get numIconVertices(): number { return this._structArray.uint16[this._pos2 + 20]; }\n get numVerticalIconVertices(): number { return this._structArray.uint16[this._pos2 + 21]; }\n get useRuntimeCollisionCircles(): number { return this._structArray.uint16[this._pos2 + 22]; }\n get crossTileID(): number { return this._structArray.uint32[this._pos4 + 12]; }\n set crossTileID(x: number) { this._structArray.uint32[this._pos4 + 12] = x; }\n get textBoxScale(): number { return this._structArray.float32[this._pos4 + 13]; }\n get collisionCircleDiameter(): number { return this._structArray.float32[this._pos4 + 14]; }\n get textAnchorOffsetStartIndex(): number { return this._structArray.uint16[this._pos2 + 30]; }\n get textAnchorOffsetEndIndex(): number { return this._structArray.uint16[this._pos2 + 31]; }\n get heightOffset(): number { return this._structArray.float32[this._pos4 + 16]; }\n}\n\nSymbolInstanceStruct.prototype.size = 68;\n\nexport type SymbolInstance = SymbolInstanceStruct;\n\n/** @internal */\nexport class SymbolInstanceArray extends StructArrayLayout8i15ui1ul2f2ui1f68 {\n /**\n * Return the SymbolInstanceStruct at the given location in the array.\n * @param index - The index of the element.\n */\n get(index: number): SymbolInstanceStruct {\n return new SymbolInstanceStruct(this, index);\n }\n}\n\nregister('SymbolInstanceArray', SymbolInstanceArray);\n\n/** @internal */\nexport class GlyphOffsetArray extends StructArrayLayout1f4 {\n getoffsetX(index: number): number { return this.float32[index * 1 + 0]; }\n}\n\nregister('GlyphOffsetArray', GlyphOffsetArray);\n\n/** @internal */\nexport class SymbolLineVertexArray extends StructArrayLayout3i6 {\n getx(index: number): number { return this.int16[index * 3 + 0]; }\n gety(index: number): number { return this.int16[index * 3 + 1]; }\n gettileUnitDistanceFromAnchor(index: number): number { return this.int16[index * 3 + 2]; }\n}\n\nregister('SymbolLineVertexArray', SymbolLineVertexArray);\n\n/** @internal */\nclass TextAnchorOffsetStruct extends Struct {\n _structArray: TextAnchorOffsetArray;\n get textAnchor(): number { return this._structArray.uint16[this._pos2 + 0]; }\n get textOffset0(): number { return this._structArray.float32[this._pos4 + 1]; }\n get textOffset1(): number { return this._structArray.float32[this._pos4 + 2]; }\n}\n\nTextAnchorOffsetStruct.prototype.size = 12;\n\nexport type TextAnchorOffset = TextAnchorOffsetStruct;\n\n/** @internal */\nexport class TextAnchorOffsetArray extends StructArrayLayout1ui2f12 {\n /**\n * Return the TextAnchorOffsetStruct at the given location in the array.\n * @param index - The index of the element.\n */\n get(index: number): TextAnchorOffsetStruct {\n return new TextAnchorOffsetStruct(this, index);\n }\n}\n\nregister('TextAnchorOffsetArray', TextAnchorOffsetArray);\n\n/** @internal */\nclass FeatureIndexStruct extends Struct {\n _structArray: FeatureIndexArray;\n get featureIndex(): number { return this._structArray.uint32[this._pos4 + 0]; }\n get sourceLayerIndex(): number { return this._structArray.uint16[this._pos2 + 2]; }\n get bucketIndex(): number { return this._structArray.uint16[this._pos2 + 3]; }\n}\n\nFeatureIndexStruct.prototype.size = 8;\n\nexport type FeatureIndex = FeatureIndexStruct;\n\n/** @internal */\nexport class FeatureIndexArray extends StructArrayLayout1ul2ui8 {\n /**\n * Return the FeatureIndexStruct at the given location in the array.\n * @param index - The index of the element.\n */\n get(index: number): FeatureIndexStruct {\n return new FeatureIndexStruct(this, index);\n }\n}\n\nregister('FeatureIndexArray', FeatureIndexArray);\n\nexport class PosArray extends StructArrayLayout2i4 {}\nexport class Pos3dArray extends StructArrayLayout3i6 {}\nexport class RasterBoundsArray extends StructArrayLayout4i8 {}\nexport class CircleLayoutArray extends StructArrayLayout2i4 {}\nexport class FillLayoutArray extends StructArrayLayout2i4 {}\nexport class FillExtrusionLayoutArray extends StructArrayLayout2i4i12 {}\nexport class HeatmapLayoutArray extends StructArrayLayout2i4 {}\nexport class LineLayoutArray extends StructArrayLayout2i4ub8 {}\nexport class LineExtLayoutArray extends StructArrayLayout2f8 {}\nexport class PatternLayoutArray extends StructArrayLayout10ui20 {}\nexport class DashLayoutArray extends StructArrayLayout8ui16 {}\nexport class SymbolLayoutArray extends StructArrayLayout4i4ui4i1f28 {}\nexport class SymbolDynamicLayoutArray extends StructArrayLayout3f12 {}\nexport class SymbolOpacityArray extends StructArrayLayout1ul4 {}\nexport class CollisionBoxLayoutArray extends StructArrayLayout2i2i2i12 {}\nexport class CollisionCircleLayoutArray extends StructArrayLayout2f1f2i16 {}\nexport class CollisionVertexArray extends StructArrayLayout2ub2f2i16 {}\nexport class QuadTriangleArray extends StructArrayLayout3ui6 {}\nexport class TriangleIndexArray extends StructArrayLayout3ui6 {}\nexport class LineIndexArray extends StructArrayLayout2ui4 {}\nexport class LineStripIndexArray extends StructArrayLayout1ui2 {}\nexport {\n StructArrayLayout2i4,\n StructArrayLayout3i6,\n StructArrayLayout4i8,\n StructArrayLayout2i4i12,\n StructArrayLayout2i4ub8,\n StructArrayLayout2f8,\n StructArrayLayout10ui20,\n StructArrayLayout8ui16,\n StructArrayLayout4i4ui4i1f28,\n StructArrayLayout3f12,\n StructArrayLayout1ul4,\n StructArrayLayout6i1ul2ui20,\n StructArrayLayout2i2i2i12,\n StructArrayLayout2f1f2i16,\n StructArrayLayout2ub2f2i16,\n StructArrayLayout3ui6,\n StructArrayLayout2i2ui3ul3ui2f3ub1ul1i1f52,\n StructArrayLayout8i15ui1ul2f2ui1f68,\n StructArrayLayout1f4,\n StructArrayLayout1ui2f12,\n StructArrayLayout1ul2ui8,\n StructArrayLayout2ui4,\n StructArrayLayout1ui2,\n StructArrayLayout4f16\n};\n","import {createLayout, type StructArrayLayout, type StructArrayMember} from '../../util/struct_array.ts';\n\nconst layout: StructArrayLayout = createLayout([\n {name: 'a_pos', components: 2, type: 'Int16'}\n], 4);\n\nexport default layout;\nexport const members: StructArrayMember[] = layout.members;\nexport const size: number = layout.size;\nexport const alignment: number = layout.alignment;\n","import {warnOnce} from '../util/util.ts';\n\nimport {register} from '../util/web_worker_transfer.ts';\n\nimport type {VertexArrayObject} from '../webgl/vertex_array_object.ts';\nimport type {StructArray} from '../util/struct_array.ts';\n\n/**\n * @internal\n * A single segment of a vector\n */\nexport type Segment = {\n sortKey?: number;\n vertexOffset: number;\n primitiveOffset: number;\n vertexLength: number;\n primitiveLength: number;\n vaos: {[_: string]: VertexArrayObject};\n};\n\n/**\n * @internal\n * Used for calculations on vector segments\n */\nexport class SegmentVector {\n static MAX_VERTEX_ARRAY_LENGTH: number;\n segments: Segment[];\n private _forceNewSegmentOnNextPrepare: boolean = false;\n\n constructor(segments: Segment[] = []) {\n this.segments = segments;\n }\n\n /**\n * Returns the last segment if `numVertices` fits into it.\n * If there are no segments yet or `numVertices` doesn't fit into the last one, creates a new empty segment and returns it.\n */\n prepareSegment(\n numVertices: number,\n layoutVertexArray: StructArray,\n indexArray: StructArray,\n sortKey?: number\n ): Segment {\n const lastSegment: Segment = this.segments[this.segments.length - 1];\n\n if (numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) {\n warnOnce(`Max vertices per segment is ${SegmentVector.MAX_VERTEX_ARRAY_LENGTH}: bucket requested ${numVertices}. Consider using the \\`fillLargeMeshArrays\\` function if you require meshes with more than ${SegmentVector.MAX_VERTEX_ARRAY_LENGTH} vertices.`);\n }\n\n if (this._forceNewSegmentOnNextPrepare || !lastSegment || lastSegment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH || lastSegment.sortKey !== sortKey) {\n return this.createNewSegment(layoutVertexArray, indexArray, sortKey);\n } else {\n return lastSegment;\n }\n }\n\n /**\n * Creates a new empty segment and returns it.\n */\n createNewSegment(\n layoutVertexArray: StructArray,\n indexArray: StructArray,\n sortKey?: number\n ): Segment {\n const segment: Segment = {\n vertexOffset: layoutVertexArray.length,\n primitiveOffset: indexArray.length,\n vertexLength: 0,\n primitiveLength: 0,\n vaos: {}\n };\n\n if (sortKey !== undefined) {\n segment.sortKey = sortKey;\n }\n\n // If this was set, we have no need to create a new segment on next prepareSegment call,\n // since this function already created a new, empty segment.\n this._forceNewSegmentOnNextPrepare = false;\n this.segments.push(segment);\n return segment;\n }\n\n /**\n * Returns the last segment, or creates a new segments if there are no segments yet.\n */\n getOrCreateLatestSegment(\n layoutVertexArray: StructArray,\n indexArray: StructArray,\n sortKey?: number\n ): Segment {\n return this.prepareSegment(0, layoutVertexArray, indexArray, sortKey);\n }\n\n /**\n * Causes the next call to {@link prepareSegment} to always return a new segment,\n * not reusing the current segment even if the new geometry would fit it.\n */\n forceNewSegmentOnNextPrepare(): void {\n this._forceNewSegmentOnNextPrepare = true;\n }\n\n get(): Segment[] {\n return this.segments;\n }\n\n destroy(): void {\n for (const segment of this.segments) {\n for (const k in segment.vaos) {\n segment.vaos[k].destroy();\n }\n }\n }\n\n static simpleSegment(\n vertexOffset: number,\n primitiveOffset: number,\n vertexLength: number,\n primitiveLength: number\n ): SegmentVector {\n return new SegmentVector([{\n vertexOffset,\n primitiveOffset,\n vertexLength,\n primitiveLength,\n vaos: {},\n sortKey: 0\n }]);\n }\n}\n\n/**\n * The maximum size of a vertex array. This limit is imposed by WebGL's 16 bit\n * addressing of vertex buffers.\n */\nSegmentVector.MAX_VERTEX_ARRAY_LENGTH = Math.pow(2, 16) - 1;\n\nregister('SegmentVector', SegmentVector);\n","import {clamp} from '../util/util.ts';\n\n/**\n * Packs two numbers, interpreted as 8-bit unsigned integers, into a single\n * float. Unpack them in the shader using the `unpack_float()` function,\n * defined in _prelude.vertex.glsl\n */\nexport function packUint8ToFloat(a: number, b: number): number {\n // coerce a and b to 8-bit ints\n a = clamp(Math.floor(a), 0, 255);\n b = clamp(Math.floor(b), 0, 255);\n return 256 * a + b;\n}\n","import {createLayout, type StructArrayLayout} from '../../util/struct_array.ts';\n\nexport const patternAttributes: StructArrayLayout = createLayout([\n // [tl.x, tl.y, br.x, br.y]\n {name: 'a_pattern_from', components: 4, type: 'Uint16'},\n {name: 'a_pattern_to', components: 4, type: 'Uint16'},\n {name: 'a_pixel_ratio_from', components: 1, type: 'Uint16'},\n {name: 'a_pixel_ratio_to', components: 1, type: 'Uint16'},\n]);\n","import {createLayout, type StructArrayLayout} from '../../util/struct_array.ts';\n\nexport const dashAttributes: StructArrayLayout = createLayout([\n // [0, y, height, width]\n {name: 'a_dasharray_from', components: 4, type: 'Uint16'},\n {name: 'a_dasharray_to', components: 4, type: 'Uint16'},\n]);\n","/**\n * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)\n * \n * @author Gary Court\n * @see http://github.com/garycourt/murmurhash-js\n * @author Austin Appleby\n * @see http://sites.google.com/site/murmurhash/\n * \n * @param {string} key ASCII only\n * @param {number} seed Positive integer only\n * @return {number} 32-bit positive integer hash \n */\n\nfunction murmurhash3_32_gc(key, seed) {\n\tvar remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i;\n\t\n\tremainder = key.length & 3; // key.length % 4\n\tbytes = key.length - remainder;\n\th1 = seed;\n\tc1 = 0xcc9e2d51;\n\tc2 = 0x1b873593;\n\ti = 0;\n\t\n\twhile (i < bytes) {\n\t \tk1 = \n\t \t ((key.charCodeAt(i) & 0xff)) |\n\t \t ((key.charCodeAt(++i) & 0xff) << 8) |\n\t \t ((key.charCodeAt(++i) & 0xff) << 16) |\n\t \t ((key.charCodeAt(++i) & 0xff) << 24);\n\t\t++i;\n\t\t\n\t\tk1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;\n\t\tk1 = (k1 << 15) | (k1 >>> 17);\n\t\tk1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;\n\n\t\th1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n\t\th1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;\n\t\th1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));\n\t}\n\t\n\tk1 = 0;\n\t\n\tswitch (remainder) {\n\t\tcase 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;\n\t\tcase 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;\n\t\tcase 1: k1 ^= (key.charCodeAt(i) & 0xff);\n\t\t\n\t\tk1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n\t\tk1 = (k1 << 15) | (k1 >>> 17);\n\t\tk1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n\t\th1 ^= k1;\n\t}\n\t\n\th1 ^= key.length;\n\n\th1 ^= h1 >>> 16;\n\th1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\n\th1 ^= h1 >>> 13;\n\th1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;\n\th1 ^= h1 >>> 16;\n\n\treturn h1 >>> 0;\n}\n\nif(typeof module !== \"undefined\") {\n module.exports = murmurhash3_32_gc\n}","/**\n * JS Implementation of MurmurHash2\n * \n * @author Gary Court\n * @see http://github.com/garycourt/murmurhash-js\n * @author Austin Appleby\n * @see http://sites.google.com/site/murmurhash/\n * \n * @param {string} str ASCII only\n * @param {number} seed Positive integer only\n * @return {number} 32-bit positive integer hash\n */\n\nfunction murmurhash2_32_gc(str, seed) {\n var\n l = str.length,\n h = seed ^ l,\n i = 0,\n k;\n \n while (l >= 4) {\n \tk = \n \t ((str.charCodeAt(i) & 0xff)) |\n \t ((str.charCodeAt(++i) & 0xff) << 8) |\n \t ((str.charCodeAt(++i) & 0xff) << 16) |\n \t ((str.charCodeAt(++i) & 0xff) << 24);\n \n k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n k ^= k >>> 24;\n k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n\n\th = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;\n\n l -= 4;\n ++i;\n }\n \n switch (l) {\n case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16;\n case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8;\n case 1: h ^= (str.charCodeAt(i) & 0xff);\n h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n }\n\n h ^= h >>> 13;\n h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n h ^= h >>> 15;\n\n return h >>> 0;\n}\n\nif(typeof module !== undefined) {\n module.exports = murmurhash2_32_gc\n}\n","var murmur3 = require(\"./murmurhash3_gc.js\")\nvar murmur2 = require(\"./murmurhash2_gc.js\")\n\nmodule.exports = murmur3\nmodule.exports.murmur3 = murmur3\nmodule.exports.murmur2 = murmur2\n","import murmur3 from 'murmurhash-js';\nimport {register} from '../util/web_worker_transfer.ts';\n\ntype SerializedFeaturePositionMap = {\n ids: Float64Array;\n positions: Uint32Array;\n};\n\ntype FeaturePosition = {\n index: number;\n start: number;\n end: number;\n};\n\n// A transferable data structure that maps feature ids to their indices and buffer offsets\nexport class FeaturePositionMap {\n ids: number[];\n positions: number[];\n indexed: boolean;\n\n constructor() {\n this.ids = [];\n this.positions = [];\n this.indexed = false;\n }\n\n add(id: unknown, index: number, start: number, end: number): void {\n this.ids.push(getNumericId(id));\n this.positions.push(index, start, end);\n }\n\n getPositions(id: unknown): FeaturePosition[] {\n if (!this.indexed) throw new Error('Trying to get index, but feature positions are not indexed');\n\n const intId = getNumericId(id);\n\n // binary search for the first occurrence of id in this.ids;\n // relies on ids/positions being sorted by id, which happens in serialization\n let i = 0;\n let j = this.ids.length - 1;\n while (i < j) {\n const m = (i + j) >> 1;\n if (this.ids[m] >= intId) {\n j = m;\n } else {\n i = m + 1;\n }\n }\n const positions = [];\n while (this.ids[i] === intId) {\n const index = this.positions[3 * i];\n const start = this.positions[3 * i + 1];\n const end = this.positions[3 * i + 2];\n positions.push({index, start, end});\n i++;\n }\n return positions;\n }\n\n static serialize(map: FeaturePositionMap, transferables: ArrayBuffer[]): SerializedFeaturePositionMap {\n const ids = new Float64Array(map.ids);\n const positions = new Uint32Array(map.positions);\n\n sort(ids, positions, 0, ids.length - 1);\n\n if (transferables) {\n transferables.push(ids.buffer, positions.buffer);\n }\n\n return {ids, positions};\n }\n\n static deserialize(obj: SerializedFeaturePositionMap): FeaturePositionMap {\n const map = new FeaturePositionMap();\n // after transferring, we only use these arrays statically (no pushes),\n // so TypedArray vs Array distinction that flow points out doesn't matter\n map.ids = (obj.ids as any);\n map.positions = (obj.positions as any);\n map.indexed = true;\n return map;\n }\n}\n\nfunction getNumericId(value: unknown) {\n const numValue = +value;\n if (!isNaN(numValue) && numValue <= Number.MAX_SAFE_INTEGER) {\n return numValue;\n }\n return murmur3(String(value));\n}\n\n// custom quicksort that sorts ids, indices and offsets together (by ids)\n// uses Hoare partitioning & manual tail call optimization to avoid worst case scenarios\nfunction sort(ids, positions, left, right) {\n while (left < right) {\n const pivot = ids[(left + right) >> 1];\n let i = left - 1;\n let j = right + 1;\n\n while (true) {\n do i++; while (ids[i] < pivot);\n do j--; while (ids[j] > pivot);\n if (i >= j) break;\n swap(ids, i, j);\n swap(positions, 3 * i, 3 * j);\n swap(positions, 3 * i + 1, 3 * j + 1);\n swap(positions, 3 * i + 2, 3 * j + 2);\n }\n\n if (j - left < right - j) {\n sort(ids, positions, left, j);\n left = j + 1;\n } else {\n sort(ids, positions, j + 1, right);\n right = j;\n }\n }\n}\n\nfunction swap(arr, i, j) {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\nregister('FeaturePositionMap', FeaturePositionMap);\n","import {Color} from '@maplibre/maplibre-gl-style-spec';\n\nimport type {Context} from './context.ts';\nimport {type mat4, type vec2, type vec3, type vec4} from 'gl-matrix';\n\ntype $ObjMap any> = {\n [K in keyof T]: F extends (v: T[K]) => infer R ? R : never;\n};\n\nexport type UniformValues = $ObjMap(u: Uniform) => V>;\nexport type UniformLocations = {[_: string]: WebGLUniformLocation};\n\n/**\n * @internal\n * A base uniform abstract class\n */\nabstract class Uniform {\n gl: WebGL2RenderingContext;\n location: WebGLUniformLocation;\n current: T;\n\n constructor(context: Context, location: WebGLUniformLocation) {\n this.gl = context.gl;\n this.location = location;\n }\n\n abstract set(v: T): void;\n}\n\nclass Uniform1i extends Uniform {\n constructor(context: Context, location: WebGLUniformLocation) {\n super(context, location);\n this.current = 0;\n }\n\n set(v: number): void {\n if (this.current !== v) {\n this.current = v;\n this.gl.uniform1i(this.location, v);\n }\n }\n}\n\nclass Uniform1f extends Uniform {\n constructor(context: Context, location: WebGLUniformLocation) {\n super(context, location);\n this.current = 0;\n }\n\n set(v: number): void {\n if (this.current !== v) {\n this.current = v;\n this.gl.uniform1f(this.location, v);\n }\n }\n}\n\nclass Uniform2f extends Uniform