{
"version": 3,
"sources": ["../src/configs/config.maptiler.js", "../local.config.js", "../node_modules/events/events.js", "../node_modules/maplibre-gl/node_modules/tslib/tslib.es6.js", "../node_modules/maplibre-gl/node_modules/@mapbox/point-geometry/index.js", "../node_modules/maplibre-gl/node_modules/@mapbox/unitbezier/index.js", "../node_modules/maplibre-gl/src/util/offscreen_canvas_supported.ts", "../node_modules/maplibre-gl/src/util/offscreen_canvas_distorted.ts", "../node_modules/maplibre-gl/src/util/util.ts", "../node_modules/maplibre-gl/src/util/abort_error.ts", "../node_modules/maplibre-gl/src/util/config.ts", "../node_modules/maplibre-gl/src/source/protocol_crud.ts", "../node_modules/maplibre-gl/src/util/ajax.ts", "../node_modules/maplibre-gl/src/util/evented.ts", "../node_modules/maplibre-gl/node_modules/@maplibre/maplibre-gl-style-spec/dist/index.mjs", "../node_modules/maplibre-gl/src/style/validate_style.ts", "../node_modules/maplibre-gl/src/util/transferable_grid_index.ts", "../node_modules/maplibre-gl/src/util/web_worker_transfer.ts", "../node_modules/maplibre-gl/src/style/zoom_history.ts", "../node_modules/maplibre-gl/src/util/is_char_in_unicode_block.ts", "../node_modules/maplibre-gl/src/util/script_detection.ts", "../node_modules/maplibre-gl/src/source/rtl_text_plugin_worker.ts", "../node_modules/maplibre-gl/src/style/evaluation_parameters.ts", "../node_modules/maplibre-gl/src/style/properties.ts", "../node_modules/maplibre-gl/src/style/style_layer.ts", "../node_modules/maplibre-gl/src/util/struct_array.ts", "../node_modules/maplibre-gl/src/data/array_types.g.ts", "../node_modules/maplibre-gl/src/data/bucket/circle_attributes.ts", "../node_modules/maplibre-gl/src/data/segment.ts", "../node_modules/maplibre-gl/src/shaders/encode_attribute.ts", "../node_modules/maplibre-gl/src/data/bucket/pattern_attributes.ts", "../node_modules/maplibre-gl/node_modules/murmurhash-js/murmurhash3_gc.js", "../node_modules/maplibre-gl/node_modules/murmurhash-js/murmurhash2_gc.js", "../node_modules/maplibre-gl/node_modules/murmurhash-js/index.js", "../node_modules/maplibre-gl/src/data/feature_position_map.ts", "../node_modules/maplibre-gl/src/render/uniform_binding.ts", "../node_modules/maplibre-gl/src/data/program_configuration.ts", "../node_modules/maplibre-gl/src/data/extent.ts", "../node_modules/maplibre-gl/src/data/load_geometry.ts", "../node_modules/maplibre-gl/src/data/evaluation_feature.ts", "../node_modules/maplibre-gl/src/data/bucket/circle_bucket.ts", "../node_modules/maplibre-gl/src/util/intersection_tests.ts", "../node_modules/maplibre-gl/src/style/query_utils.ts", "../node_modules/maplibre-gl/src/style/style_layer/circle_style_layer_properties.g.ts", "../node_modules/maplibre-gl/node_modules/gl-matrix/esm/common.js", "../node_modules/maplibre-gl/node_modules/gl-matrix/esm/mat4.js", "../node_modules/maplibre-gl/node_modules/gl-matrix/esm/vec4.js", "../node_modules/maplibre-gl/src/style/style_layer/circle_style_layer.ts", "../node_modules/maplibre-gl/src/data/bucket/heatmap_bucket.ts", "../node_modules/maplibre-gl/src/style/style_layer/heatmap_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/util/image.ts", "../node_modules/maplibre-gl/src/util/color_ramp.ts", "../node_modules/maplibre-gl/src/style/style_layer/heatmap_style_layer.ts", "../node_modules/maplibre-gl/src/style/style_layer/hillshade_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/style/style_layer/hillshade_style_layer.ts", "../node_modules/maplibre-gl/src/data/bucket/fill_attributes.ts", "../node_modules/maplibre-gl/node_modules/earcut/src/earcut.js", "../node_modules/maplibre-gl/src/data/bucket/pattern_bucket_features.ts", "../node_modules/maplibre-gl/src/data/bucket/fill_bucket.ts", "../node_modules/maplibre-gl/src/style/style_layer/fill_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/style/style_layer/fill_style_layer.ts", "../node_modules/maplibre-gl/src/data/bucket/fill_extrusion_attributes.ts", "../node_modules/maplibre-gl/node_modules/@mapbox/vector-tile/lib/vectortilefeature.js", "../node_modules/maplibre-gl/node_modules/@mapbox/vector-tile/lib/vectortilelayer.js", "../node_modules/maplibre-gl/node_modules/@mapbox/vector-tile/lib/vectortile.js", "../node_modules/maplibre-gl/node_modules/@mapbox/vector-tile/index.js", "../node_modules/maplibre-gl/src/data/bucket/fill_extrusion_bucket.ts", "../node_modules/maplibre-gl/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/style/style_layer/fill_extrusion_style_layer.ts", "../node_modules/maplibre-gl/src/data/bucket/line_attributes.ts", "../node_modules/maplibre-gl/src/data/bucket/line_attributes_ext.ts", "../node_modules/maplibre-gl/src/data/bucket/line_bucket.ts", "../node_modules/maplibre-gl/src/style/style_layer/line_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/style/style_layer/line_style_layer.ts", "../node_modules/maplibre-gl/src/data/bucket/symbol_attributes.ts", "../node_modules/maplibre-gl/src/symbol/transform_text.ts", "../node_modules/maplibre-gl/src/util/verticalize_punctuation.ts", "../node_modules/maplibre-gl/src/symbol/one_em.ts", "../node_modules/maplibre-gl/node_modules/pbf/index.js", "../node_modules/maplibre-gl/node_modules/ieee754/index.js", "../node_modules/maplibre-gl/src/style/parse_glyph_pbf.ts", "../node_modules/maplibre-gl/node_modules/potpack/index.js", "../node_modules/maplibre-gl/src/render/image_atlas.ts", "../node_modules/maplibre-gl/src/symbol/shaping.ts", "../node_modules/maplibre-gl/src/symbol/symbol_size.ts", "../node_modules/maplibre-gl/src/style/style_layer/overlap_mode.ts", "../node_modules/maplibre-gl/src/data/bucket/symbol_bucket.ts", "../node_modules/maplibre-gl/src/symbol/merge_lines.ts", "../node_modules/maplibre-gl/src/style/style_layer/symbol_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/style/format_section_override.ts", "../node_modules/maplibre-gl/src/style/style_layer/symbol_style_layer.ts", "../node_modules/maplibre-gl/src/util/resolve_tokens.ts", "../node_modules/maplibre-gl/src/style/style_layer/background_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/style/style_layer/background_style_layer.ts", "../node_modules/maplibre-gl/src/style/style_layer/raster_style_layer_properties.g.ts", "../node_modules/maplibre-gl/src/style/style_layer/raster_style_layer.ts", "../node_modules/maplibre-gl/src/style/style_layer/custom_style_layer.ts", "../node_modules/maplibre-gl/src/util/throttled_invoker.ts", "../node_modules/maplibre-gl/src/geo/lng_lat.ts", "../node_modules/maplibre-gl/src/geo/mercator_coordinate.ts", "../node_modules/maplibre-gl/node_modules/@mapbox/whoots-js/index.mjs", "../node_modules/maplibre-gl/src/source/tile_id.ts", "../node_modules/maplibre-gl/src/util/world_bounds.ts", "../node_modules/maplibre-gl/src/data/dem_data.ts", "../node_modules/maplibre-gl/src/util/dictionary_coder.ts", "../node_modules/maplibre-gl/src/util/vectortile_to_geojson.ts", "../node_modules/maplibre-gl/src/data/feature_index.ts", "../node_modules/maplibre-gl/src/symbol/clip_line.ts", "../node_modules/maplibre-gl/src/symbol/anchor.ts", "../node_modules/maplibre-gl/src/symbol/check_max_angle.ts", "../node_modules/maplibre-gl/src/symbol/get_anchors.ts", "../node_modules/maplibre-gl/src/symbol/quads.ts", "../node_modules/maplibre-gl/src/symbol/collision_feature.ts", "../node_modules/maplibre-gl/node_modules/tinyqueue/index.js", "../node_modules/maplibre-gl/src/util/find_pole_of_inaccessibility.ts", "../node_modules/maplibre-gl/src/style/style_layer/variable_text_anchor.ts", "../node_modules/maplibre-gl/src/symbol/symbol_layout.ts", "../node_modules/maplibre-gl/node_modules/kdbush/index.js", "../node_modules/maplibre-gl/src/util/performance.ts", "../node_modules/maplibre-gl/src/util/actor.ts", "../node_modules/maplibre-gl/src/style/create_style_layer.ts", "../node_modules/maplibre-gl/src/style/style_layer_index.ts", "../node_modules/maplibre-gl/src/render/glyph_atlas.ts", "../node_modules/maplibre-gl/src/source/worker_tile.ts", "../node_modules/maplibre-gl/src/source/vector_tile_worker_source.ts", "../node_modules/maplibre-gl/src/source/raster_dem_tile_worker_source.ts", "../node_modules/maplibre-gl/node_modules/@mapbox/geojson-rewind/index.js", "../node_modules/maplibre-gl/src/source/geojson_wrapper.ts", "../node_modules/maplibre-gl/node_modules/vt-pbf/lib/geojson_wrapper.js", "../node_modules/maplibre-gl/node_modules/vt-pbf/index.js", "../node_modules/maplibre-gl/node_modules/supercluster/index.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/simplify.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/feature.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/convert.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/clip.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/wrap.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/transform.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/tile.js", "../node_modules/maplibre-gl/node_modules/geojson-vt/src/index.js", "../node_modules/maplibre-gl/src/source/geojson_source_diff.ts", "../node_modules/maplibre-gl/src/source/geojson_worker_source.ts", "../node_modules/maplibre-gl/src/source/worker.ts", "../node_modules/maplibre-gl/src/util/browser.ts", "../node_modules/maplibre-gl/src/util/dom.ts", "../node_modules/maplibre-gl/src/util/webp_supported.ts", "../node_modules/maplibre-gl/src/util/image_request.ts", "../node_modules/maplibre-gl/src/util/request_manager.ts", "../node_modules/maplibre-gl/node_modules/gl-matrix/esm/vec3.js", "../node_modules/maplibre-gl/node_modules/gl-matrix/esm/vec2.js", "../node_modules/maplibre-gl/src/util/style.ts", "../node_modules/maplibre-gl/src/style/load_sprite.ts", "../node_modules/maplibre-gl/src/render/texture.ts", "../node_modules/maplibre-gl/src/style/style_image.ts", "../node_modules/maplibre-gl/src/render/image_manager.ts", "../node_modules/maplibre-gl/node_modules/@mapbox/tiny-sdf/index.js", "../node_modules/maplibre-gl/src/render/glyph_manager.ts", "../node_modules/maplibre-gl/src/style/load_glyph_range.ts", "../node_modules/maplibre-gl/src/style/light.ts", "../node_modules/maplibre-gl/src/style/sky.ts", "../node_modules/maplibre-gl/src/render/line_atlas.ts", "../node_modules/maplibre-gl/src/util/worker_pool.ts", "../node_modules/maplibre-gl/src/util/web_worker.ts", "../node_modules/maplibre-gl/src/util/global_worker_pool.ts", "../node_modules/maplibre-gl/src/util/dispatcher.ts", "../node_modules/maplibre-gl/src/source/query_features.ts", "../node_modules/maplibre-gl/src/source/load_tilejson.ts", "../node_modules/maplibre-gl/src/geo/lng_lat_bounds.ts", "../node_modules/maplibre-gl/src/source/tile_bounds.ts", "../node_modules/maplibre-gl/src/source/vector_tile_source.ts", "../node_modules/maplibre-gl/src/source/raster_tile_source.ts", "../node_modules/maplibre-gl/src/source/raster_dem_tile_source.ts", "../node_modules/maplibre-gl/src/source/geojson_source.ts", "../node_modules/maplibre-gl/src/data/raster_bounds_attributes.ts", "../node_modules/maplibre-gl/src/source/image_source.ts", "../node_modules/maplibre-gl/src/source/video_source.ts", "../node_modules/maplibre-gl/src/source/canvas_source.ts", "../node_modules/maplibre-gl/src/source/source.ts", "../node_modules/maplibre-gl/src/source/rtl_text_plugin_status.ts", "../node_modules/maplibre-gl/src/source/rtl_text_plugin_main_thread.ts", "../node_modules/maplibre-gl/src/source/tile.ts", "../node_modules/maplibre-gl/src/data/bucket.ts", "../node_modules/maplibre-gl/src/source/tile_cache.ts", "../node_modules/maplibre-gl/src/source/source_state.ts", "../node_modules/maplibre-gl/src/source/source_cache.ts", "../node_modules/maplibre-gl/src/symbol/path_interpolator.ts", "../node_modules/maplibre-gl/src/symbol/grid_index.ts", "../node_modules/maplibre-gl/src/symbol/projection.ts", "../node_modules/maplibre-gl/src/symbol/collision_index.ts", "../node_modules/maplibre-gl/src/source/pixels_to_tile_units.ts", "../node_modules/maplibre-gl/src/symbol/placement.ts", "../node_modules/maplibre-gl/src/geo/projection/projection.ts", "../node_modules/maplibre-gl/src/style/pauseable_placement.ts", "../node_modules/maplibre-gl/src/symbol/cross_tile_symbol_index.ts", "../node_modules/maplibre-gl/src/style/style.ts", "../node_modules/maplibre-gl/src/data/pos_attributes.ts", "../node_modules/maplibre-gl/src/shaders/shaders.ts", "../node_modules/maplibre-gl/src/shaders/_prelude.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/_prelude.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/background.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/background.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/background_pattern.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/background_pattern.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/circle.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/circle.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/clipping_mask.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/clipping_mask.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/heatmap.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/heatmap.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/heatmap_texture.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/heatmap_texture.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/collision_box.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/collision_box.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/collision_circle.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/collision_circle.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/debug.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/debug.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_outline.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_outline.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_outline_pattern.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_outline_pattern.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_pattern.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_pattern.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_extrusion.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_extrusion.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_extrusion_pattern.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/fill_extrusion_pattern.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/hillshade_prepare.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/hillshade_prepare.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/hillshade.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/hillshade.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line_gradient.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line_gradient.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line_pattern.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line_pattern.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line_sdf.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/line_sdf.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/raster.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/raster.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/symbol_icon.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/symbol_icon.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/symbol_sdf.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/symbol_sdf.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/symbol_text_and_icon.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/symbol_text_and_icon.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/terrain.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/terrain.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/terrain_depth.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/terrain_depth.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/terrain_coords.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/terrain_coords.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/sky.fragment.glsl.g.ts", "../node_modules/maplibre-gl/src/shaders/sky.vertex.glsl.g.ts", "../node_modules/maplibre-gl/src/render/vertex_array_object.ts", "../node_modules/maplibre-gl/src/render/program/terrain_program.ts", "../node_modules/maplibre-gl/src/render/program.ts", "../node_modules/maplibre-gl/src/render/program/pattern.ts", "../node_modules/maplibre-gl/src/render/program/fill_extrusion_program.ts", "../node_modules/maplibre-gl/node_modules/gl-matrix/esm/mat3.js", "../node_modules/maplibre-gl/src/render/program/fill_program.ts", "../node_modules/maplibre-gl/src/render/program/circle_program.ts", "../node_modules/maplibre-gl/src/render/program/collision_program.ts", "../node_modules/maplibre-gl/src/render/program/debug_program.ts", "../node_modules/maplibre-gl/src/render/program/clipping_mask_program.ts", "../node_modules/maplibre-gl/src/render/program/heatmap_program.ts", "../node_modules/maplibre-gl/src/render/program/hillshade_program.ts", "../node_modules/maplibre-gl/src/render/program/line_program.ts", "../node_modules/maplibre-gl/src/render/program/raster_program.ts", "../node_modules/maplibre-gl/src/render/program/symbol_program.ts", "../node_modules/maplibre-gl/src/render/program/background_program.ts", "../node_modules/maplibre-gl/src/render/program/program_uniforms.ts", "../node_modules/maplibre-gl/src/render/program/sky_program.ts", "../node_modules/maplibre-gl/src/gl/index_buffer.ts", "../node_modules/maplibre-gl/src/gl/vertex_buffer.ts", "../node_modules/maplibre-gl/src/gl/webgl2.ts", "../node_modules/maplibre-gl/src/gl/value.ts", "../node_modules/maplibre-gl/src/gl/framebuffer.ts", "../node_modules/maplibre-gl/src/gl/color_mode.ts", "../node_modules/maplibre-gl/src/gl/context.ts", "../node_modules/maplibre-gl/src/gl/depth_mode.ts", "../node_modules/maplibre-gl/src/gl/stencil_mode.ts", "../node_modules/maplibre-gl/src/gl/cull_face_mode.ts", "../node_modules/maplibre-gl/src/render/draw_collision_debug.ts", "../node_modules/maplibre-gl/src/render/draw_symbol.ts", "../node_modules/maplibre-gl/src/render/draw_heatmap.ts", "../node_modules/maplibre-gl/src/render/update_pattern_positions_in_program.ts", "../node_modules/maplibre-gl/src/render/draw_fill.ts", "../node_modules/maplibre-gl/src/render/draw_fill_extrusion.ts", "../node_modules/maplibre-gl/src/render/draw_hillshade.ts", "../node_modules/maplibre-gl/src/render/draw_raster.ts", "../node_modules/maplibre-gl/src/render/draw_debug.ts", "../node_modules/maplibre-gl/src/render/draw_terrain.ts", "../node_modules/maplibre-gl/src/render/mesh.ts", "../node_modules/maplibre-gl/src/render/painter.ts", "../node_modules/maplibre-gl/src/render/draw_sky.ts", "../node_modules/maplibre-gl/src/render/draw_circle.ts", "../node_modules/maplibre-gl/src/render/draw_line.ts", "../node_modules/maplibre-gl/src/render/draw_background.ts", "../node_modules/maplibre-gl/src/render/draw_custom.ts", "../node_modules/maplibre-gl/src/util/primitives.ts", "../node_modules/maplibre-gl/src/geo/edge_insets.ts", "../node_modules/maplibre-gl/src/geo/transform.ts", "../node_modules/maplibre-gl/node_modules/gl-matrix/esm/mat2.js", "../node_modules/maplibre-gl/src/util/throttle.ts", "../node_modules/maplibre-gl/src/ui/hash.ts", "../node_modules/maplibre-gl/src/ui/handler_inertia.ts", "../node_modules/maplibre-gl/src/ui/events.ts", "../node_modules/maplibre-gl/src/ui/handler/map_event.ts", "../node_modules/maplibre-gl/src/ui/handler/transform-provider.ts", "../node_modules/maplibre-gl/src/ui/handler/box_zoom.ts", "../node_modules/maplibre-gl/src/ui/handler/handler_util.ts", "../node_modules/maplibre-gl/src/ui/handler/tap_recognizer.ts", "../node_modules/maplibre-gl/src/ui/handler/tap_zoom.ts", "../node_modules/maplibre-gl/src/ui/handler/drag_handler.ts", "../node_modules/maplibre-gl/src/ui/handler/drag_move_state_manager.ts", "../node_modules/maplibre-gl/src/ui/handler/mouse.ts", "../node_modules/maplibre-gl/src/ui/handler/touch_pan.ts", "../node_modules/maplibre-gl/src/ui/handler/two_fingers_touch.ts", "../node_modules/maplibre-gl/src/ui/handler/keyboard.ts", "../node_modules/maplibre-gl/src/ui/handler/scroll_zoom.ts", "../node_modules/maplibre-gl/src/ui/handler/shim/dblclick_zoom.ts", "../node_modules/maplibre-gl/src/ui/handler/click_zoom.ts", "../node_modules/maplibre-gl/src/ui/handler/tap_drag_zoom.ts", "../node_modules/maplibre-gl/src/ui/handler/shim/drag_pan.ts", "../node_modules/maplibre-gl/src/ui/handler/shim/drag_rotate.ts", "../node_modules/maplibre-gl/src/ui/handler/shim/two_fingers_touch.ts", "../node_modules/maplibre-gl/src/ui/handler/cooperative_gestures.ts", "../node_modules/maplibre-gl/src/ui/handler_manager.ts", "../node_modules/maplibre-gl/src/ui/camera.ts", "../node_modules/maplibre-gl/src/ui/control/attribution_control.ts", "../node_modules/maplibre-gl/src/ui/control/logo_control.ts", "../node_modules/maplibre-gl/src/util/task_queue.ts", "../node_modules/maplibre-gl/src/data/pos3d_attributes.ts", "../node_modules/maplibre-gl/src/source/terrain_source_cache.ts", "../node_modules/maplibre-gl/src/render/terrain.ts", "../node_modules/maplibre-gl/src/gl/render_pool.ts", "../node_modules/maplibre-gl/src/render/render_to_texture.ts", "../node_modules/maplibre-gl/src/ui/default_locale.ts", "../node_modules/maplibre-gl/src/ui/map.ts", "../node_modules/maplibre-gl/src/ui/handler/one_finger_touch_drag.ts", "../node_modules/maplibre-gl/src/ui/control/navigation_control.ts", "../node_modules/maplibre-gl/src/util/geolocation_support.ts", "../node_modules/maplibre-gl/src/util/smart_wrap.ts", "../node_modules/maplibre-gl/src/ui/anchor.ts", "../node_modules/maplibre-gl/src/ui/marker.ts", "../node_modules/maplibre-gl/src/ui/control/geolocate_control.ts", "../node_modules/maplibre-gl/src/ui/control/scale_control.ts", "../node_modules/maplibre-gl/src/ui/popup.ts", "../node_modules/maplibre-gl/src/index.ts", "../node_modules/maplibre-gl/src/ui/control/fullscreen_control.ts", "../node_modules/maplibre-gl/src/ui/control/terrain_control.ts", "../node_modules/maplibre-gl/build/rollup/maplibregl.js", "../node_modules/openmapsamples-maplibre/node_modules/maplibre-gl/rollup/maplibregl.js", "../src/config.js", "../src/constants/label.js", "../node_modules/tokenfield/lib/tokenfield.js", "../node_modules/tokenfield/lib/ajax.js", "../src/js/language_label.js", "../src/americana.js", "../src/search.js", "../node_modules/color-name/index.js", "../node_modules/color-parse/index.mjs", "../node_modules/color-space/rgb.js", "../node_modules/color-space/hsl.js", "../node_modules/color-rgba/index.mjs", "../shieldlib/src/screen_gfx.ts", "../shieldlib/src/shield_text.ts", "../shieldlib/src/custom_shields.ts", "../shieldlib/src/shield_canvas_draw.ts", "../shieldlib/src/shield_banner.ts", "../shieldlib/src/shield.ts", "../shieldlib/src/document_graphics.ts", "../shieldlib/src/shield_renderer.ts", "../shieldlib/src/shield_helper.ts", "../src/layer/highway_shield.js", "../src/js/legend_control.js", "../src/js/icon_control.js", "../src/constants/color.js", "../src/layer/place.js", "../src/layer/landuse.js", "../src/layer/boundary.js", "../src/js/util.js", "../src/layer/road.js", "../src/layer/construction.js", "../src/layer/highway_exit.js", "../src/layer/rail.js", "../src/layer/aeroway.js", "../src/layer/poi.js", "../src/layer/park.js", "../src/layer/building.js", "../src/layer/water.js", "../src/layer/ferry.js", "../src/layer/aerialway.js", "../src/js/legend_config.js", "../node_modules/openmapsamples-maplibre/OpenMapSamplesControl.js", "../node_modules/openmapsamples/lib/Layer.js", "../node_modules/openmapsamples/lib/Sample.js", "../node_modules/openmapsamples/lib/SampleData/Grid.js", "../node_modules/openmapsamples/lib/SampleData/WayRowsSampleData.js", "../node_modules/openmapsamples/lib/Transformation/CopyPropertiesTransformation.js", "../node_modules/openmapsamples/lib/Transformation/RemovePropertiesTransformation.js", "../node_modules/openmapsamples/samples/OpenMapTiles/HighwayAttributes.js", "../node_modules/openmapsamples/samples/OpenMapTiles/HighwayConstructionAttributes.js", "../node_modules/openmapsamples/samples/OpenMapTiles/HighwayLinkAttributes.js", "../node_modules/openmapsamples/samples/OpenMapTiles/HighwayTollAttributes.js", "../node_modules/openmapsamples/lib/SampleData/WayColumnsSampleData.js", "../node_modules/openmapsamples/samples/OpenMapTiles/HighwayIntersections.js", "../node_modules/openmapsamples/samples/OpenMapTiles/HighwayLinkIntersections.js", "../node_modules/openmapsamples/samples/OpenMapTiles/HighwayBridgeAndTunnel.js", "../node_modules/openmapsamples/lib/SampleData/PointRowsSampleData.js", "../node_modules/openmapsamples/samples/OpenMapTiles/Places.js", "../node_modules/openmapsamples/samples/OpenMapTiles/index.js", "../src/js/shield_format.ts", "../src/js/poi.ts", "../src/layer/background.js", "../src/layer/hillshade.js", "../src/layer/oneway.js", "../src/layer/transportation_label.js", "../src/layer/index.js", "../src/js/style.js", "../src/js/map_builder.ts", "../src/debug_config.ts", "../node_modules/pmtiles/dist/index.js"],
"sourcesContent": ["\"use strict\";\n\n/*\nThis style requires a vector tile server to run.\nThis configuration is for running with MapTiler Cloud.\n\nVisit MapTiler Cloud and create an account/log in:\nhttps://cloud.maptiler.com/maps/\n\nGo to Account->Keys and create a key to paste here:\n*/\nconst MAPTILER_KEY = \"hcV0tjbpbwfSyPIlbTmH\";\n\nconst OPENMAPTILES_URL = `https://api.maptiler.com/tiles/v3-openmaptiles/tiles.json?key=${MAPTILER_KEY}`;\nconst ATTRIBUTION_LOGO = `\n\n
\n`;\nconst ATTRIBUTION_TEXT =\n '© MapTiler';\n\n/*\nThe following two variables override the color of the bounding box and halo of\nshield text, respectively. Useful while testing shield design changes.\nBoth accept an HTML color name, hex code, or other CSS color value.\n*/\nconst SHIELD_TEXT_BBOX_COLOR = null;\nconst SHIELD_TEXT_HALO_COLOR_OVERRIDE = null;\n\nexport default {\n OPENMAPTILES_URL,\n ATTRIBUTION_LOGO,\n ATTRIBUTION_TEXT,\n SHIELD_TEXT_BBOX_COLOR,\n SHIELD_TEXT_HALO_COLOR_OVERRIDE,\n};\n", "export {default} from \"./src/configs/config.maptiler.js\";\n", "// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\nmodule.exports.once = once;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nfunction checkListener(listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n}\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction _getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return _getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the `throw` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n checkListener(listener);\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = _getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n if (arguments.length === 0)\n return this.listener.call(this.target);\n return this.listener.apply(this.target, arguments);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n checkListener(listener);\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n checkListener(listener);\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n checkListener(listener);\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n\nfunction once(emitter, name) {\n return new Promise(function (resolve, reject) {\n function errorListener(err) {\n emitter.removeListener(name, resolver);\n reject(err);\n }\n\n function resolver() {\n if (typeof emitter.removeListener === 'function') {\n emitter.removeListener('error', errorListener);\n }\n resolve([].slice.call(arguments));\n };\n\n eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });\n if (name !== 'error') {\n addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });\n }\n });\n}\n\nfunction addErrorHandlerIfEventEmitter(emitter, handler, flags) {\n if (typeof emitter.on === 'function') {\n eventTargetAgnosticAddListener(emitter, 'error', handler, flags);\n }\n}\n\nfunction eventTargetAgnosticAddListener(emitter, name, listener, flags) {\n if (typeof emitter.on === 'function') {\n if (flags.once) {\n emitter.once(name, listener);\n } else {\n emitter.on(name, listener);\n }\n } else if (typeof emitter.addEventListener === 'function') {\n // EventTarget does not have `error` event semantics like Node\n // EventEmitters, we do not listen for `error` events here.\n emitter.addEventListener(name, function wrapListener(arg) {\n // IE does not have builtin `{ once: true }` support so we\n // have to do it manually.\n if (flags.once) {\n emitter.removeEventListener(name, wrapListener);\n }\n listener(arg);\n });\n } else {\n throw new TypeError('The \"emitter\" argument must be of type EventEmitter. Received type ' + typeof emitter);\n }\n}\n", "/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose, inner;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n if (async) inner = dispose;\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n var r, s = 0;\r\n function next() {\r\n while (r = env.stack.pop()) {\r\n try {\r\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n if (r.dispose) {\r\n var result = r.dispose.call(r.value);\r\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n else s |= 1;\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n};\r\n", "'use strict';\n\nmodule.exports = Point;\n\n/**\n * A standalone point geometry with useful accessor, comparison, and\n * modification methods.\n *\n * @class Point\n * @param {Number} x the x-coordinate. this could be longitude or screen\n * pixels, or any other sort of unit.\n * @param {Number} y the y-coordinate. this could be latitude or screen\n * pixels, or any other sort of unit.\n * @example\n * var point = new Point(-77, 38);\n */\nfunction Point(x, y) {\n this.x = x;\n this.y = y;\n}\n\nPoint.prototype = {\n\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: function() { 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: function(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: function(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: function(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: function(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 {Point} k factor\n * @return {Point} output point\n */\n mult: function(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 {Point} k factor\n * @return {Point} output point\n */\n div: function(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: function(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: function(a,p) { return this.clone()._rotateAround(a,p); },\n\n /**\n * Multiply this point by a 4x1 transformation matrix\n * @param {Array} m transformation matrix\n * @return {Point} output point\n */\n matMult: function(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: function() { 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: function() { 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: function() { return this.clone()._round(); },\n\n /**\n * Return the magitude 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: function() {\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: function(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: function(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: function(p) {\n var 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: function() {\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: function(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: function(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: function(x, y) {\n return Math.atan2(\n this.x * y - this.y * x,\n this.x * x + this.y * y);\n },\n\n _matMult: function(m) {\n var 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 _add: function(p) {\n this.x += p.x;\n this.y += p.y;\n return this;\n },\n\n _sub: function(p) {\n this.x -= p.x;\n this.y -= p.y;\n return this;\n },\n\n _mult: function(k) {\n this.x *= k;\n this.y *= k;\n return this;\n },\n\n _div: function(k) {\n this.x /= k;\n this.y /= k;\n return this;\n },\n\n _multByPoint: function(p) {\n this.x *= p.x;\n this.y *= p.y;\n return this;\n },\n\n _divByPoint: function(p) {\n this.x /= p.x;\n this.y /= p.y;\n return this;\n },\n\n _unit: function() {\n this._div(this.mag());\n return this;\n },\n\n _perp: function() {\n var y = this.y;\n this.y = this.x;\n this.x = -y;\n return this;\n },\n\n _rotate: function(angle) {\n var 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 _rotateAround: function(angle, p) {\n var 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: function() {\n this.x = Math.round(this.x);\n this.y = Math.round(this.y);\n return this;\n }\n};\n\n/**\n * Construct a point from an array if necessary, otherwise if the input\n * is already a Point, or an unknown type, return it unchanged\n * @param {Array|Point|*} a any kind of input value\n * @return {Point} constructed point, or passed-through value.\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 (a) {\n if (a instanceof Point) {\n return a;\n }\n if (Array.isArray(a)) {\n return new Point(a[0], a[1]);\n }\n return a;\n};\n", "'use strict';\n\nmodule.exports = UnitBezier;\n\nfunction UnitBezier(p1x, p1y, p2x, p2y) {\n // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).\n this.cx = 3.0 * p1x;\n this.bx = 3.0 * (p2x - p1x) - this.cx;\n this.ax = 1.0 - this.cx - this.bx;\n\n this.cy = 3.0 * p1y;\n this.by = 3.0 * (p2y - p1y) - this.cy;\n this.ay = 1.0 - this.cy - this.by;\n\n this.p1x = p1x;\n this.p1y = p1y;\n this.p2x = p2x;\n this.p2y = p2y;\n}\n\nUnitBezier.prototype = {\n sampleCurveX: function (t) {\n // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.\n return ((this.ax * t + this.bx) * t + this.cx) * t;\n },\n\n sampleCurveY: function (t) {\n return ((this.ay * t + this.by) * t + this.cy) * t;\n },\n\n sampleCurveDerivativeX: function (t) {\n return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;\n },\n\n solveCurveX: function (x, epsilon) {\n if (epsilon === undefined) epsilon = 1e-6;\n\n if (x < 0.0) return 0.0;\n if (x > 1.0) return 1.0;\n\n var t = x;\n\n // First try a few iterations of Newton's method - normally very fast.\n for (var i = 0; i < 8; i++) {\n var x2 = this.sampleCurveX(t) - x;\n if (Math.abs(x2) < epsilon) return t;\n\n var d2 = this.sampleCurveDerivativeX(t);\n if (Math.abs(d2) < 1e-6) break;\n\n t = t - x2 / d2;\n }\n\n // Fall back to the bisection method for reliability.\n var t0 = 0.0;\n var t1 = 1.0;\n t = x;\n\n for (i = 0; i < 20; i++) {\n x2 = this.sampleCurveX(t);\n if (Math.abs(x2 - x) < epsilon) break;\n\n if (x > x2) {\n t0 = t;\n } else {\n t1 = t;\n }\n\n t = (t1 - t0) * 0.5 + t0;\n }\n\n return t;\n },\n\n solve: function (x, epsilon) {\n return this.sampleCurveY(this.solveCurveX(x, epsilon));\n }\n};\n", "let supportsOffscreenCanvas: boolean;\n\nexport function offscreenCanvasSupported(): boolean {\n if (supportsOffscreenCanvas == null) {\n supportsOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' &&\n new OffscreenCanvas(1, 1).getContext('2d') &&\n typeof createImageBitmap === 'function';\n }\n\n return supportsOffscreenCanvas;\n}\n", "import {offscreenCanvasSupported} from './offscreen_canvas_supported';\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", "import Point from '@mapbox/point-geometry';\nimport UnitBezier from '@mapbox/unitbezier';\nimport {isOffscreenCanvasDistorted} from './offscreen_canvas_distorted';\nimport type {Size} from './image';\nimport type {WorkerGlobalScopeInterface} from './web_worker';\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: Array): [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 * 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 const bezier = new UnitBezier(p1x, p1y, p2x, p2y);\n return (t: number) => {\n return bezier.solve(t);\n };\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 = 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): Array {\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: Array): any;\nexport function extend(dest: object, ...sources: Array): 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 (let i = 0; i < properties.length; i++) {\n const k = properties[i];\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 * 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 any 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: Array, b: Array): boolean {\n for (let l = 0; l < a.length; l++) {\n if (b.indexOf(a[l]) >= 0) 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 */\n\nexport function sphericalToCartesian([r, azimuthal, polar]: [number, number, number]): {\n x: number;\n y: number;\n z: number;\n} {\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 x: r * Math.cos(azimuthal) * Math.sin(polar),\n y: r * Math.sin(azimuthal) * Math.sin(polar),\n z: 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\nexport function storageAvailable(type: string): boolean {\n try {\n const storage = window[type];\n storage.setItem('_mapbox_test_', 1);\n storage.removeItem('_mapbox_test_');\n return true;\n } catch (e) {\n return false;\n }\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) {\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) {\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): Promise => {\n if (data.byteLength === 0) {\n return createImageBitmap(new ImageData(1, 1));\n }\n const blob: Blob = new Blob([new Uint8Array(data)], {type: 'image/png'});\n try {\n return createImageBitmap(blob);\n } catch (e) {\n throw new Error(`Could not load image because of ${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 (e) {\n // fall back to OffscreenCanvas\n }\n }\n return readImageDataUsingOffscreenCanvas(image, x, y, width, height);\n}\n\nexport interface Subscription {\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 * 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\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: Array;\n grids?: Array;\n data?: Array;\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", "/**\n * An error message to use when an operation is aborted\n */\nexport const ABORT_ERROR = 'AbortError';\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: Error): boolean {\n return error.message === ABORT_ERROR;\n}\n\n/**\n * Use this when you need to create an abort error.\n * @returns An error object with the message \"AbortError\"\n */\nexport function createAbortError(): Error {\n return new Error(ABORT_ERROR);\n}\n", "import type {RequestParameters, GetResourceResponse} from './ajax';\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 {AddProtocolAction, config} from '../util/config';\n\nexport function getProtocol(url: string) {\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 */\nexport function addProtocol(customProtocol: string, loadFn: AddProtocolAction) {\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) {\n delete config.REGISTERED_PROTOCOLS[customProtocol];\n}\n", "import {extend, isWorker} from './util';\nimport {createAbortError} from './abort_error';\nimport {getProtocol} from '../source/protocol_crud';\nimport {MessageType} from './actor_messages';\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};\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\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 */\nexport const getReferrer = () => isWorker(self) ?\n self.worker && self.worker.referrer :\n (window.location.protocol === 'blob:' ? window.parent : window).location.href;\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 => /^file:/.test(url) || (/^file:/.test(getReferrer()) && !/^\\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 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 const response = await fetch(request);\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 if (abortController.signal.aborted) {\n throw createAbortError();\n }\n return {data: result, cacheControl: response.headers.get('Cache-Control'), expires: response.headers.get('Expires')};\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')});\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(createAbortError());\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 = function(requestParameters: RequestParameters, abortController: AbortController): Promise> {\n if (/:\\/\\//.test(requestParameters.url) && !(/^https?:|^file:/.test(requestParameters.url))) {\n const protocolLoadFn = getProtocol(requestParameters.url);\n if (protocolLoadFn) {\n return protocolLoadFn(requestParameters, abortController);\n }\n if (isWorker(self) && self.worker && 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.prototype.hasOwnProperty.call(Request.prototype, 'signal')) {\n return makeFetchRequest(requestParameters, abortController);\n }\n if (isWorker(self) && self.worker && 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\nexport function sameOrigin(inComingUrl: string) {\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 // also check data URL\n if (!inComingUrl ||\n inComingUrl.indexOf('://') <= 0 || // relative URL\n inComingUrl.indexOf('data:image/') === 0 || // data image URL\n inComingUrl.indexOf('blob:') === 0) { // blob\n return true;\n }\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: Array): 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} from './util';\n\n/**\n * A listener method used as a callback to events\n */\nexport type Listener = (a: any) => any;\n\ntype Listeners = {[_: string]: Array};\n\nfunction _addEventListener(type: string, listener: Listener, listenerList: Listeners) {\n const listenerExists = listenerList[type] && listenerList[type].indexOf(listener) !== -1;\n if (!listenerExists) {\n listenerList[type] = listenerList[type] || [];\n listenerList[type].push(listener);\n }\n}\n\nfunction _removeEventListener(type: string, listener: Listener, listenerList: Listeners) {\n if (listenerList && 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: string;\n\n constructor(type: string, data: any = {}) {\n extend(this, data);\n this.type = type;\n }\n}\n\ninterface ErrorLike {\n message: string;\n}\n\n/**\n * An error event\n */\nexport class ErrorEvent extends Event {\n error: ErrorLike;\n\n constructor(error: ErrorLike, data: any = {}) {\n super('error', extend({error}, data));\n }\n}\n\n/**\n * Methods mixed in to other classes for event capabilities.\n *\n * @group Event Related\n */\nexport class Evented {\n _listeners: Listeners;\n _oneTimeListeners: Listeners;\n _eventedParent: Evented;\n _eventedParentData: any | (() => any);\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: string, listener: Listener): this {\n this._listeners = this._listeners || {};\n _addEventListener(type, listener, this._listeners);\n\n return this;\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: string, listener: Listener) {\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 * @param listener - The function to be called when the event is fired the first time.\n * @returns `this` or a promise if a listener is not provided\n */\n once(type: string, listener?: Listener): this | Promise {\n if (!listener) {\n return new Promise((resolve) => this.once(type, resolve));\n }\n this._oneTimeListeners = this._oneTimeListeners || {};\n _addEventListener(type, listener, this._oneTimeListeners);\n\n return this;\n }\n\n fire(event: Event | string, properties?: any) {\n // Compatibility with (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 if (typeof event === 'string') {\n event = new Event(event, properties || {});\n }\n\n const type = event.type;\n\n if (this.listens(type)) {\n (event as any).target = this;\n\n // make sure adding or removing listeners inside other listeners won't cause an infinite loop\n const listeners = this._listeners && this._listeners[type] ? this._listeners[type].slice() : [];\n for (const listener of listeners) {\n listener.call(this, event);\n }\n\n const oneTimeListeners = this._oneTimeListeners && this._oneTimeListeners[type] ? this._oneTimeListeners[type].slice() : [];\n for (const listener of oneTimeListeners) {\n _removeEventListener(type, listener, this._oneTimeListeners);\n listener.call(this, event);\n }\n\n const parent = this._eventedParent;\n if (parent) {\n extend(\n event,\n typeof this._eventedParentData === 'function' ? this._eventedParentData() : this._eventedParentData\n );\n parent.fire(event);\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 (event instanceof ErrorEvent) {\n console.error(event.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: string): boolean {\n return (\n (this._listeners && this._listeners[type] && this._listeners[type].length > 0) ||\n (this._oneTimeListeners && this._oneTimeListeners[type] && this._oneTimeListeners[type].length > 0) ||\n (this._eventedParent && 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?: any | (() => any)) {\n this._eventedParent = parent;\n this._eventedParentData = data;\n\n return this;\n }\n}\n", "var $version = 8;\nvar $root = {\n\tversion: {\n\t\trequired: true,\n\t\ttype: \"enum\",\n\t\tvalues: [\n\t\t\t8\n\t\t]\n\t},\n\tname: {\n\t\ttype: \"string\"\n\t},\n\tmetadata: {\n\t\ttype: \"*\"\n\t},\n\tcenter: {\n\t\ttype: \"array\",\n\t\tvalue: \"number\"\n\t},\n\tzoom: {\n\t\ttype: \"number\"\n\t},\n\tbearing: {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tperiod: 360,\n\t\tunits: \"degrees\"\n\t},\n\tpitch: {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tunits: \"degrees\"\n\t},\n\tlight: {\n\t\ttype: \"light\"\n\t},\n\tsky: {\n\t\ttype: \"sky\"\n\t},\n\tprojection: {\n\t\ttype: \"projection\"\n\t},\n\tterrain: {\n\t\ttype: \"terrain\"\n\t},\n\tsources: {\n\t\trequired: true,\n\t\ttype: \"sources\"\n\t},\n\tsprite: {\n\t\ttype: \"sprite\"\n\t},\n\tglyphs: {\n\t\ttype: \"string\"\n\t},\n\ttransition: {\n\t\ttype: \"transition\"\n\t},\n\tlayers: {\n\t\trequired: true,\n\t\ttype: \"array\",\n\t\tvalue: \"layer\"\n\t}\n};\nvar sources = {\n\t\"*\": {\n\t\ttype: \"source\"\n\t}\n};\nvar source = [\n\t\"source_vector\",\n\t\"source_raster\",\n\t\"source_raster_dem\",\n\t\"source_geojson\",\n\t\"source_video\",\n\t\"source_image\"\n];\nvar source_vector = {\n\ttype: {\n\t\trequired: true,\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvector: {\n\t\t\t}\n\t\t}\n\t},\n\turl: {\n\t\ttype: \"string\"\n\t},\n\ttiles: {\n\t\ttype: \"array\",\n\t\tvalue: \"string\"\n\t},\n\tbounds: {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 4,\n\t\t\"default\": [\n\t\t\t-180,\n\t\t\t-85.051129,\n\t\t\t180,\n\t\t\t85.051129\n\t\t]\n\t},\n\tscheme: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\txyz: {\n\t\t\t},\n\t\t\ttms: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"xyz\"\n\t},\n\tminzoom: {\n\t\ttype: \"number\",\n\t\t\"default\": 0\n\t},\n\tmaxzoom: {\n\t\ttype: \"number\",\n\t\t\"default\": 22\n\t},\n\tattribution: {\n\t\ttype: \"string\"\n\t},\n\tpromoteId: {\n\t\ttype: \"promoteId\"\n\t},\n\tvolatile: {\n\t\ttype: \"boolean\",\n\t\t\"default\": false\n\t},\n\t\"*\": {\n\t\ttype: \"*\"\n\t}\n};\nvar source_raster = {\n\ttype: {\n\t\trequired: true,\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\traster: {\n\t\t\t}\n\t\t}\n\t},\n\turl: {\n\t\ttype: \"string\"\n\t},\n\ttiles: {\n\t\ttype: \"array\",\n\t\tvalue: \"string\"\n\t},\n\tbounds: {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 4,\n\t\t\"default\": [\n\t\t\t-180,\n\t\t\t-85.051129,\n\t\t\t180,\n\t\t\t85.051129\n\t\t]\n\t},\n\tminzoom: {\n\t\ttype: \"number\",\n\t\t\"default\": 0\n\t},\n\tmaxzoom: {\n\t\ttype: \"number\",\n\t\t\"default\": 22\n\t},\n\ttileSize: {\n\t\ttype: \"number\",\n\t\t\"default\": 512,\n\t\tunits: \"pixels\"\n\t},\n\tscheme: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\txyz: {\n\t\t\t},\n\t\t\ttms: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"xyz\"\n\t},\n\tattribution: {\n\t\ttype: \"string\"\n\t},\n\tvolatile: {\n\t\ttype: \"boolean\",\n\t\t\"default\": false\n\t},\n\t\"*\": {\n\t\ttype: \"*\"\n\t}\n};\nvar source_raster_dem = {\n\ttype: {\n\t\trequired: true,\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\t\"raster-dem\": {\n\t\t\t}\n\t\t}\n\t},\n\turl: {\n\t\ttype: \"string\"\n\t},\n\ttiles: {\n\t\ttype: \"array\",\n\t\tvalue: \"string\"\n\t},\n\tbounds: {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 4,\n\t\t\"default\": [\n\t\t\t-180,\n\t\t\t-85.051129,\n\t\t\t180,\n\t\t\t85.051129\n\t\t]\n\t},\n\tminzoom: {\n\t\ttype: \"number\",\n\t\t\"default\": 0\n\t},\n\tmaxzoom: {\n\t\ttype: \"number\",\n\t\t\"default\": 22\n\t},\n\ttileSize: {\n\t\ttype: \"number\",\n\t\t\"default\": 512,\n\t\tunits: \"pixels\"\n\t},\n\tattribution: {\n\t\ttype: \"string\"\n\t},\n\tencoding: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tterrarium: {\n\t\t\t},\n\t\t\tmapbox: {\n\t\t\t},\n\t\t\tcustom: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"mapbox\"\n\t},\n\tredFactor: {\n\t\ttype: \"number\",\n\t\t\"default\": 1\n\t},\n\tblueFactor: {\n\t\ttype: \"number\",\n\t\t\"default\": 1\n\t},\n\tgreenFactor: {\n\t\ttype: \"number\",\n\t\t\"default\": 1\n\t},\n\tbaseShift: {\n\t\ttype: \"number\",\n\t\t\"default\": 0\n\t},\n\tvolatile: {\n\t\ttype: \"boolean\",\n\t\t\"default\": false\n\t},\n\t\"*\": {\n\t\ttype: \"*\"\n\t}\n};\nvar source_geojson = {\n\ttype: {\n\t\trequired: true,\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tgeojson: {\n\t\t\t}\n\t\t}\n\t},\n\tdata: {\n\t\trequired: true,\n\t\ttype: \"*\"\n\t},\n\tmaxzoom: {\n\t\ttype: \"number\",\n\t\t\"default\": 18\n\t},\n\tattribution: {\n\t\ttype: \"string\"\n\t},\n\tbuffer: {\n\t\ttype: \"number\",\n\t\t\"default\": 128,\n\t\tmaximum: 512,\n\t\tminimum: 0\n\t},\n\tfilter: {\n\t\ttype: \"*\"\n\t},\n\ttolerance: {\n\t\ttype: \"number\",\n\t\t\"default\": 0.375\n\t},\n\tcluster: {\n\t\ttype: \"boolean\",\n\t\t\"default\": false\n\t},\n\tclusterRadius: {\n\t\ttype: \"number\",\n\t\t\"default\": 50,\n\t\tminimum: 0\n\t},\n\tclusterMaxZoom: {\n\t\ttype: \"number\"\n\t},\n\tclusterMinPoints: {\n\t\ttype: \"number\"\n\t},\n\tclusterProperties: {\n\t\ttype: \"*\"\n\t},\n\tlineMetrics: {\n\t\ttype: \"boolean\",\n\t\t\"default\": false\n\t},\n\tgenerateId: {\n\t\ttype: \"boolean\",\n\t\t\"default\": false\n\t},\n\tpromoteId: {\n\t\ttype: \"promoteId\"\n\t}\n};\nvar source_video = {\n\ttype: {\n\t\trequired: true,\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvideo: {\n\t\t\t}\n\t\t}\n\t},\n\turls: {\n\t\trequired: true,\n\t\ttype: \"array\",\n\t\tvalue: \"string\"\n\t},\n\tcoordinates: {\n\t\trequired: true,\n\t\ttype: \"array\",\n\t\tlength: 4,\n\t\tvalue: {\n\t\t\ttype: \"array\",\n\t\t\tlength: 2,\n\t\t\tvalue: \"number\"\n\t\t}\n\t}\n};\nvar source_image = {\n\ttype: {\n\t\trequired: true,\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\timage: {\n\t\t\t}\n\t\t}\n\t},\n\turl: {\n\t\trequired: true,\n\t\ttype: \"string\"\n\t},\n\tcoordinates: {\n\t\trequired: true,\n\t\ttype: \"array\",\n\t\tlength: 4,\n\t\tvalue: {\n\t\t\ttype: \"array\",\n\t\t\tlength: 2,\n\t\t\tvalue: \"number\"\n\t\t}\n\t}\n};\nvar layer = {\n\tid: {\n\t\ttype: \"string\",\n\t\trequired: true\n\t},\n\ttype: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tfill: {\n\t\t\t},\n\t\t\tline: {\n\t\t\t},\n\t\t\tsymbol: {\n\t\t\t},\n\t\t\tcircle: {\n\t\t\t},\n\t\t\theatmap: {\n\t\t\t},\n\t\t\t\"fill-extrusion\": {\n\t\t\t},\n\t\t\traster: {\n\t\t\t},\n\t\t\thillshade: {\n\t\t\t},\n\t\t\tbackground: {\n\t\t\t}\n\t\t},\n\t\trequired: true\n\t},\n\tmetadata: {\n\t\ttype: \"*\"\n\t},\n\tsource: {\n\t\ttype: \"string\"\n\t},\n\t\"source-layer\": {\n\t\ttype: \"string\"\n\t},\n\tminzoom: {\n\t\ttype: \"number\",\n\t\tminimum: 0,\n\t\tmaximum: 24\n\t},\n\tmaxzoom: {\n\t\ttype: \"number\",\n\t\tminimum: 0,\n\t\tmaximum: 24\n\t},\n\tfilter: {\n\t\ttype: \"filter\"\n\t},\n\tlayout: {\n\t\ttype: \"layout\"\n\t},\n\tpaint: {\n\t\ttype: \"paint\"\n\t}\n};\nvar layout = [\n\t\"layout_fill\",\n\t\"layout_line\",\n\t\"layout_circle\",\n\t\"layout_heatmap\",\n\t\"layout_fill-extrusion\",\n\t\"layout_symbol\",\n\t\"layout_raster\",\n\t\"layout_hillshade\",\n\t\"layout_background\"\n];\nvar layout_background = {\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar layout_fill = {\n\t\"fill-sort-key\": {\n\t\ttype: \"number\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar layout_circle = {\n\t\"circle-sort-key\": {\n\t\ttype: \"number\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar layout_heatmap = {\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar layout_line = {\n\t\"line-cap\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tbutt: {\n\t\t\t},\n\t\t\tround: {\n\t\t\t},\n\t\t\tsquare: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"butt\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"line-join\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tbevel: {\n\t\t\t},\n\t\t\tround: {\n\t\t\t},\n\t\t\tmiter: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"miter\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"line-miter-limit\": {\n\t\ttype: \"number\",\n\t\t\"default\": 2,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"line-join\": \"miter\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"line-round-limit\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1.05,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"line-join\": \"round\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"line-sort-key\": {\n\t\ttype: \"number\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar layout_symbol = {\n\t\"symbol-placement\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tpoint: {\n\t\t\t},\n\t\t\tline: {\n\t\t\t},\n\t\t\t\"line-center\": {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"point\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"symbol-spacing\": {\n\t\ttype: \"number\",\n\t\t\"default\": 250,\n\t\tminimum: 1,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"symbol-placement\": \"line\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"symbol-avoid-edges\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"symbol-sort-key\": {\n\t\ttype: \"number\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"symbol-z-order\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tauto: {\n\t\t\t},\n\t\t\t\"viewport-y\": {\n\t\t\t},\n\t\t\tsource: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"auto\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-allow-overlap\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\trequires: [\n\t\t\t\"icon-image\",\n\t\t\t{\n\t\t\t\t\"!\": \"icon-overlap\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-overlap\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tnever: {\n\t\t\t},\n\t\t\talways: {\n\t\t\t},\n\t\t\tcooperative: {\n\t\t\t}\n\t\t},\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-ignore-placement\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-optional\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\trequires: [\n\t\t\t\"icon-image\",\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-rotation-alignment\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t},\n\t\t\tauto: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"auto\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-size\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tunits: \"factor of the original icon size\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-text-fit\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tnone: {\n\t\t\t},\n\t\t\twidth: {\n\t\t\t},\n\t\t\theight: {\n\t\t\t},\n\t\t\tboth: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"none\",\n\t\trequires: [\n\t\t\t\"icon-image\",\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-text-fit-padding\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 4,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"icon-image\",\n\t\t\t\"text-field\",\n\t\t\t{\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],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-image\": {\n\t\ttype: \"resolvedImage\",\n\t\ttokens: true,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-rotate\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tperiod: 360,\n\t\tunits: \"degrees\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-padding\": {\n\t\ttype: \"padding\",\n\t\t\"default\": [\n\t\t\t2\n\t\t],\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-keep-upright\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\trequires: [\n\t\t\t\"icon-image\",\n\t\t\t{\n\t\t\t\t\"icon-rotation-alignment\": \"map\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"symbol-placement\": [\n\t\t\t\t\t\"line\",\n\t\t\t\t\t\"line-center\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-offset\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tcenter: {\n\t\t\t},\n\t\t\tleft: {\n\t\t\t},\n\t\t\tright: {\n\t\t\t},\n\t\t\ttop: {\n\t\t\t},\n\t\t\tbottom: {\n\t\t\t},\n\t\t\t\"top-left\": {\n\t\t\t},\n\t\t\t\"top-right\": {\n\t\t\t},\n\t\t\t\"bottom-left\": {\n\t\t\t},\n\t\t\t\"bottom-right\": {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"center\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-pitch-alignment\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t},\n\t\t\tauto: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"auto\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-pitch-alignment\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t},\n\t\t\tauto: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"auto\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-rotation-alignment\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t},\n\t\t\t\"viewport-glyph\": {\n\t\t\t},\n\t\t\tauto: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"auto\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-field\": {\n\t\ttype: \"formatted\",\n\t\t\"default\": \"\",\n\t\ttokens: true,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-font\": {\n\t\ttype: \"array\",\n\t\tvalue: \"string\",\n\t\t\"default\": [\n\t\t\t\"Open Sans Regular\",\n\t\t\t\"Arial Unicode MS Regular\"\n\t\t],\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-size\": {\n\t\ttype: \"number\",\n\t\t\"default\": 16,\n\t\tminimum: 0,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-max-width\": {\n\t\ttype: \"number\",\n\t\t\"default\": 10,\n\t\tminimum: 0,\n\t\tunits: \"ems\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-line-height\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1.2,\n\t\tunits: \"ems\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-letter-spacing\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tunits: \"ems\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-justify\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tauto: {\n\t\t\t},\n\t\t\tleft: {\n\t\t\t},\n\t\t\tcenter: {\n\t\t\t},\n\t\t\tright: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"center\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-radial-offset\": {\n\t\ttype: \"number\",\n\t\tunits: \"ems\",\n\t\t\"default\": 0,\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\t\"property-type\": \"data-driven\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t}\n\t},\n\t\"text-variable-anchor\": {\n\t\ttype: \"array\",\n\t\tvalue: \"enum\",\n\t\tvalues: {\n\t\t\tcenter: {\n\t\t\t},\n\t\t\tleft: {\n\t\t\t},\n\t\t\tright: {\n\t\t\t},\n\t\t\ttop: {\n\t\t\t},\n\t\t\tbottom: {\n\t\t\t},\n\t\t\t\"top-left\": {\n\t\t\t},\n\t\t\t\"top-right\": {\n\t\t\t},\n\t\t\t\"bottom-left\": {\n\t\t\t},\n\t\t\t\"bottom-right\": {\n\t\t\t}\n\t\t},\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"symbol-placement\": [\n\t\t\t\t\t\"point\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-variable-anchor-offset\": {\n\t\ttype: \"variableAnchorOffsetCollection\",\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"symbol-placement\": [\n\t\t\t\t\t\"point\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tcenter: {\n\t\t\t},\n\t\t\tleft: {\n\t\t\t},\n\t\t\tright: {\n\t\t\t},\n\t\t\ttop: {\n\t\t\t},\n\t\t\tbottom: {\n\t\t\t},\n\t\t\t\"top-left\": {\n\t\t\t},\n\t\t\t\"top-right\": {\n\t\t\t},\n\t\t\t\"bottom-left\": {\n\t\t\t},\n\t\t\t\"bottom-right\": {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"center\",\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"!\": \"text-variable-anchor\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-max-angle\": {\n\t\ttype: \"number\",\n\t\t\"default\": 45,\n\t\tunits: \"degrees\",\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"symbol-placement\": [\n\t\t\t\t\t\"line\",\n\t\t\t\t\t\"line-center\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-writing-mode\": {\n\t\ttype: \"array\",\n\t\tvalue: \"enum\",\n\t\tvalues: {\n\t\t\thorizontal: {\n\t\t\t},\n\t\t\tvertical: {\n\t\t\t}\n\t\t},\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"symbol-placement\": [\n\t\t\t\t\t\"point\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-rotate\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tperiod: 360,\n\t\tunits: \"degrees\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-padding\": {\n\t\ttype: \"number\",\n\t\t\"default\": 2,\n\t\tminimum: 0,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-keep-upright\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": true,\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"text-rotation-alignment\": \"map\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"symbol-placement\": [\n\t\t\t\t\t\"line\",\n\t\t\t\t\t\"line-center\"\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-transform\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tnone: {\n\t\t\t},\n\t\t\tuppercase: {\n\t\t\t},\n\t\t\tlowercase: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"none\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-offset\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tunits: \"ems\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"!\": \"text-radial-offset\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-allow-overlap\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t{\n\t\t\t\t\"!\": \"text-overlap\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-overlap\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tnever: {\n\t\t\t},\n\t\t\talways: {\n\t\t\t},\n\t\t\tcooperative: {\n\t\t\t}\n\t\t},\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-ignore-placement\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-optional\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": false,\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar layout_raster = {\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar layout_hillshade = {\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n};\nvar filter = {\n\ttype: \"array\",\n\tvalue: \"*\"\n};\nvar filter_operator = {\n\ttype: \"enum\",\n\tvalues: {\n\t\t\"==\": {\n\t\t},\n\t\t\"!=\": {\n\t\t},\n\t\t\">\": {\n\t\t},\n\t\t\">=\": {\n\t\t},\n\t\t\"<\": {\n\t\t},\n\t\t\"<=\": {\n\t\t},\n\t\t\"in\": {\n\t\t},\n\t\t\"!in\": {\n\t\t},\n\t\tall: {\n\t\t},\n\t\tany: {\n\t\t},\n\t\tnone: {\n\t\t},\n\t\thas: {\n\t\t},\n\t\t\"!has\": {\n\t\t}\n\t}\n};\nvar geometry_type = {\n\ttype: \"enum\",\n\tvalues: {\n\t\tPoint: {\n\t\t},\n\t\tLineString: {\n\t\t},\n\t\tPolygon: {\n\t\t}\n\t}\n};\nvar function_stop = {\n\ttype: \"array\",\n\tminimum: 0,\n\tmaximum: 24,\n\tvalue: [\n\t\t\"number\",\n\t\t\"color\"\n\t],\n\tlength: 2\n};\nvar expression$1 = {\n\ttype: \"array\",\n\tvalue: \"*\",\n\tminimum: 1\n};\nvar light = {\n\tanchor: {\n\t\ttype: \"enum\",\n\t\t\"default\": \"viewport\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"property-type\": \"data-constant\",\n\t\ttransition: false,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t}\n\t},\n\tposition: {\n\t\ttype: \"array\",\n\t\t\"default\": [\n\t\t\t1.15,\n\t\t\t210,\n\t\t\t30\n\t\t],\n\t\tlength: 3,\n\t\tvalue: \"number\",\n\t\t\"property-type\": \"data-constant\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t}\n\t},\n\tcolor: {\n\t\ttype: \"color\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": \"#ffffff\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t},\n\tintensity: {\n\t\ttype: \"number\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": 0.5,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t}\n};\nvar sky = {\n\t\"sky-color\": {\n\t\ttype: \"color\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": \"#88C6FC\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t},\n\t\"horizon-color\": {\n\t\ttype: \"color\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": \"#ffffff\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t},\n\t\"fog-color\": {\n\t\ttype: \"color\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": \"#ffffff\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t},\n\t\"fog-ground-blend\": {\n\t\ttype: \"number\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": 0.5,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t},\n\t\"horizon-fog-blend\": {\n\t\ttype: \"number\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": 0.8,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t},\n\t\"sky-horizon-blend\": {\n\t\ttype: \"number\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": 0.8,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t},\n\t\"atmosphere-blend\": {\n\t\ttype: \"number\",\n\t\t\"property-type\": \"data-constant\",\n\t\t\"default\": 0.8,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\ttransition: true\n\t}\n};\nvar terrain = {\n\tsource: {\n\t\ttype: \"string\",\n\t\trequired: true\n\t},\n\texaggeration: {\n\t\ttype: \"number\",\n\t\tminimum: 0,\n\t\t\"default\": 1\n\t}\n};\nvar projection = {\n\ttype: {\n\t\ttype: \"enum\",\n\t\t\"default\": \"mercator\",\n\t\tvalues: {\n\t\t\tmercator: {\n\t\t\t},\n\t\t\tglobe: {\n\t\t\t}\n\t\t}\n\t}\n};\nvar paint = [\n\t\"paint_fill\",\n\t\"paint_line\",\n\t\"paint_circle\",\n\t\"paint_heatmap\",\n\t\"paint_fill-extrusion\",\n\t\"paint_symbol\",\n\t\"paint_raster\",\n\t\"paint_hillshade\",\n\t\"paint_background\"\n];\nvar paint_fill = {\n\t\"fill-antialias\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": true,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"fill-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"fill-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"!\": \"fill-pattern\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"fill-outline-color\": {\n\t\ttype: \"color\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"!\": \"fill-pattern\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"fill-antialias\": true\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"fill-translate\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"fill-translate-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"map\",\n\t\trequires: [\n\t\t\t\"fill-translate\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"fill-pattern\": {\n\t\ttype: \"resolvedImage\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"cross-faded-data-driven\"\n\t}\n};\nvar paint_line = {\n\t\"line-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"line-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"!\": \"line-pattern\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"line-translate\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"line-translate-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"map\",\n\t\trequires: [\n\t\t\t\"line-translate\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"line-width\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"line-gap-width\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"line-offset\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"line-blur\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"line-dasharray\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"line widths\",\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"!\": \"line-pattern\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"cross-faded\"\n\t},\n\t\"line-pattern\": {\n\t\ttype: \"resolvedImage\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"cross-faded-data-driven\"\n\t},\n\t\"line-gradient\": {\n\t\ttype: \"color\",\n\t\ttransition: false,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"!\": \"line-dasharray\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"!\": \"line-pattern\"\n\t\t\t},\n\t\t\t{\n\t\t\t\tsource: \"geojson\",\n\t\t\t\thas: {\n\t\t\t\t\tlineMetrics: true\n\t\t\t\t}\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"line-progress\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"color-ramp\"\n\t}\n};\nvar paint_circle = {\n\t\"circle-radius\": {\n\t\ttype: \"number\",\n\t\t\"default\": 5,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"circle-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"circle-blur\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"circle-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"circle-translate\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"circle-translate-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"map\",\n\t\trequires: [\n\t\t\t\"circle-translate\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"circle-pitch-scale\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"map\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"circle-pitch-alignment\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"viewport\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"circle-stroke-width\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"circle-stroke-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"circle-stroke-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t}\n};\nvar paint_heatmap = {\n\t\"heatmap-radius\": {\n\t\ttype: \"number\",\n\t\t\"default\": 30,\n\t\tminimum: 1,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"heatmap-weight\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\ttransition: false,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"heatmap-intensity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"heatmap-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": [\n\t\t\t\"interpolate\",\n\t\t\t[\n\t\t\t\t\"linear\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"heatmap-density\"\n\t\t\t],\n\t\t\t0,\n\t\t\t\"rgba(0, 0, 255, 0)\",\n\t\t\t0.1,\n\t\t\t\"royalblue\",\n\t\t\t0.3,\n\t\t\t\"cyan\",\n\t\t\t0.5,\n\t\t\t\"lime\",\n\t\t\t0.7,\n\t\t\t\"yellow\",\n\t\t\t1,\n\t\t\t\"red\"\n\t\t],\n\t\ttransition: false,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"heatmap-density\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"color-ramp\"\n\t},\n\t\"heatmap-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t}\n};\nvar paint_symbol = {\n\t\"icon-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-halo-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"rgba(0, 0, 0, 0)\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-halo-width\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-halo-blur\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"icon-translate\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"icon-image\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"icon-translate-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"map\",\n\t\trequires: [\n\t\t\t\"icon-image\",\n\t\t\t\"icon-translate\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\toverridable: true,\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-halo-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"rgba(0, 0, 0, 0)\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-halo-width\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-halo-blur\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"text-translate\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\trequires: [\n\t\t\t\"text-field\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"text-translate-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"map\",\n\t\trequires: [\n\t\t\t\"text-field\",\n\t\t\t\"text-translate\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t}\n};\nvar paint_raster = {\n\t\"raster-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"raster-hue-rotate\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tperiod: 360,\n\t\ttransition: true,\n\t\tunits: \"degrees\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"raster-brightness-min\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"raster-brightness-max\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"raster-saturation\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: -1,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"raster-contrast\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: -1,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"raster-resampling\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tlinear: {\n\t\t\t},\n\t\t\tnearest: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"linear\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"raster-fade-duration\": {\n\t\ttype: \"number\",\n\t\t\"default\": 300,\n\t\tminimum: 0,\n\t\ttransition: false,\n\t\tunits: \"milliseconds\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t}\n};\nvar paint_hillshade = {\n\t\"hillshade-illumination-direction\": {\n\t\ttype: \"number\",\n\t\t\"default\": 335,\n\t\tminimum: 0,\n\t\tmaximum: 359,\n\t\ttransition: false,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"hillshade-illumination-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"viewport\",\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"hillshade-exaggeration\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0.5,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"hillshade-shadow-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"hillshade-highlight-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#FFFFFF\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"hillshade-accent-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t}\n};\nvar paint_background = {\n\t\"background-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"!\": \"background-pattern\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"background-pattern\": {\n\t\ttype: \"resolvedImage\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"cross-faded\"\n\t},\n\t\"background-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t}\n};\nvar transition = {\n\tduration: {\n\t\ttype: \"number\",\n\t\t\"default\": 300,\n\t\tminimum: 0,\n\t\tunits: \"milliseconds\"\n\t},\n\tdelay: {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\tunits: \"milliseconds\"\n\t}\n};\nvar promoteId = {\n\t\"*\": {\n\t\ttype: \"string\"\n\t}\n};\nvar v8Spec = {\n\t$version: $version,\n\t$root: $root,\n\tsources: sources,\n\tsource: source,\n\tsource_vector: source_vector,\n\tsource_raster: source_raster,\n\tsource_raster_dem: source_raster_dem,\n\tsource_geojson: source_geojson,\n\tsource_video: source_video,\n\tsource_image: source_image,\n\tlayer: layer,\n\tlayout: layout,\n\tlayout_background: layout_background,\n\tlayout_fill: layout_fill,\n\tlayout_circle: layout_circle,\n\tlayout_heatmap: layout_heatmap,\n\t\"layout_fill-extrusion\": {\n\tvisibility: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tvisible: {\n\t\t\t},\n\t\t\tnone: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"visible\",\n\t\t\"property-type\": \"constant\"\n\t}\n},\n\tlayout_line: layout_line,\n\tlayout_symbol: layout_symbol,\n\tlayout_raster: layout_raster,\n\tlayout_hillshade: layout_hillshade,\n\tfilter: filter,\n\tfilter_operator: filter_operator,\n\tgeometry_type: geometry_type,\n\t\"function\": {\n\texpression: {\n\t\ttype: \"expression\"\n\t},\n\tstops: {\n\t\ttype: \"array\",\n\t\tvalue: \"function_stop\"\n\t},\n\tbase: {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0\n\t},\n\tproperty: {\n\t\ttype: \"string\",\n\t\t\"default\": \"$zoom\"\n\t},\n\ttype: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tidentity: {\n\t\t\t},\n\t\t\texponential: {\n\t\t\t},\n\t\t\tinterval: {\n\t\t\t},\n\t\t\tcategorical: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"exponential\"\n\t},\n\tcolorSpace: {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\trgb: {\n\t\t\t},\n\t\t\tlab: {\n\t\t\t},\n\t\t\thcl: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"rgb\"\n\t},\n\t\"default\": {\n\t\ttype: \"*\",\n\t\trequired: false\n\t}\n},\n\tfunction_stop: function_stop,\n\texpression: expression$1,\n\tlight: light,\n\tsky: sky,\n\tterrain: terrain,\n\tprojection: projection,\n\tpaint: paint,\n\tpaint_fill: paint_fill,\n\t\"paint_fill-extrusion\": {\n\t\"fill-extrusion-opacity\": {\n\t\ttype: \"number\",\n\t\t\"default\": 1,\n\t\tminimum: 0,\n\t\tmaximum: 1,\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"fill-extrusion-color\": {\n\t\ttype: \"color\",\n\t\t\"default\": \"#000000\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t{\n\t\t\t\t\"!\": \"fill-extrusion-pattern\"\n\t\t\t}\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"fill-extrusion-translate\": {\n\t\ttype: \"array\",\n\t\tvalue: \"number\",\n\t\tlength: 2,\n\t\t\"default\": [\n\t\t\t0,\n\t\t\t0\n\t\t],\n\t\ttransition: true,\n\t\tunits: \"pixels\",\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"fill-extrusion-translate-anchor\": {\n\t\ttype: \"enum\",\n\t\tvalues: {\n\t\t\tmap: {\n\t\t\t},\n\t\t\tviewport: {\n\t\t\t}\n\t\t},\n\t\t\"default\": \"map\",\n\t\trequires: [\n\t\t\t\"fill-extrusion-translate\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t},\n\t\"fill-extrusion-pattern\": {\n\t\ttype: \"resolvedImage\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"cross-faded-data-driven\"\n\t},\n\t\"fill-extrusion-height\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\tunits: \"meters\",\n\t\ttransition: true,\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"fill-extrusion-base\": {\n\t\ttype: \"number\",\n\t\t\"default\": 0,\n\t\tminimum: 0,\n\t\tunits: \"meters\",\n\t\ttransition: true,\n\t\trequires: [\n\t\t\t\"fill-extrusion-height\"\n\t\t],\n\t\texpression: {\n\t\t\tinterpolated: true,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\",\n\t\t\t\t\"feature\",\n\t\t\t\t\"feature-state\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-driven\"\n\t},\n\t\"fill-extrusion-vertical-gradient\": {\n\t\ttype: \"boolean\",\n\t\t\"default\": true,\n\t\ttransition: false,\n\t\texpression: {\n\t\t\tinterpolated: false,\n\t\t\tparameters: [\n\t\t\t\t\"zoom\"\n\t\t\t]\n\t\t},\n\t\t\"property-type\": \"data-constant\"\n\t}\n},\n\tpaint_line: paint_line,\n\tpaint_circle: paint_circle,\n\tpaint_heatmap: paint_heatmap,\n\tpaint_symbol: paint_symbol,\n\tpaint_raster: paint_raster,\n\tpaint_hillshade: paint_hillshade,\n\tpaint_background: paint_background,\n\ttransition: transition,\n\t\"property-type\": {\n\t\"data-driven\": {\n\t\ttype: \"property-type\"\n\t},\n\t\"cross-faded\": {\n\t\ttype: \"property-type\"\n\t},\n\t\"cross-faded-data-driven\": {\n\t\ttype: \"property-type\"\n\t},\n\t\"color-ramp\": {\n\t\ttype: \"property-type\"\n\t},\n\t\"data-constant\": {\n\t\ttype: \"property-type\"\n\t},\n\tconstant: {\n\t\ttype: \"property-type\"\n\t}\n},\n\tpromoteId: promoteId\n};\n\nconst refProperties = ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'];\n\nfunction deref(layer, parent) {\n const result = {};\n for (const k in layer) {\n if (k !== 'ref') {\n result[k] = layer[k];\n }\n }\n refProperties.forEach((k) => {\n if (k in parent) {\n result[k] = parent[k];\n }\n });\n return result;\n}\n/**\n * Given an array of layers, some of which may contain `ref` properties\n * whose value is the `id` of another property, return a new array where\n * such layers have been augmented with the 'type', 'source', etc. properties\n * from the parent layer, and the `ref` property has been removed.\n *\n * The input is not modified. The output may contain references to portions\n * of the input.\n *\n * @private\n * @param {Array} layers\n * @returns {Array}\n */\nfunction derefLayers(layers) {\n layers = layers.slice();\n const map = Object.create(null);\n for (let i = 0; i < layers.length; i++) {\n map[layers[i].id] = layers[i];\n }\n for (let i = 0; i < layers.length; i++) {\n if ('ref' in layers[i]) {\n layers[i] = deref(layers[i], map[layers[i].ref]);\n }\n }\n return layers;\n}\n\n/**\n * Deeply compares two object literals.\n *\n * @private\n */\nfunction deepEqual(a, b) {\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length)\n return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i]))\n return false;\n }\n return true;\n }\n if (typeof a === 'object' && a !== null && b !== null) {\n if (!(typeof b === 'object'))\n return false;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length)\n return false;\n for (const key in a) {\n if (!deepEqual(a[key], b[key]))\n return false;\n }\n return true;\n }\n return a === b;\n}\n\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 commands.push(command);\n}\nfunction addSource(sourceId, after, commands) {\n addCommand(commands, { command: 'addSource', args: [sourceId, after[sourceId]] });\n}\nfunction removeSource(sourceId, commands, sourcesRemoved) {\n addCommand(commands, { command: 'removeSource', args: [sourceId] });\n sourcesRemoved[sourceId] = true;\n}\nfunction updateSource(sourceId, after, commands, sourcesRemoved) {\n removeSource(sourceId, commands, sourcesRemoved);\n addSource(sourceId, after, commands);\n}\nfunction canUpdateGeoJSON(before, after, sourceId) {\n let prop;\n for (prop in before[sourceId]) {\n if (!Object.prototype.hasOwnProperty.call(before[sourceId], prop))\n continue;\n if (prop !== 'data' && !deepEqual(before[sourceId][prop], after[sourceId][prop])) {\n return false;\n }\n }\n for (prop in after[sourceId]) {\n if (!Object.prototype.hasOwnProperty.call(after[sourceId], prop))\n continue;\n if (prop !== 'data' && !deepEqual(before[sourceId][prop], after[sourceId][prop])) {\n return false;\n }\n }\n return true;\n}\nfunction diffSources(before, after, commands, sourcesRemoved) {\n before = before || {};\n after = after || {};\n let sourceId;\n // look for sources to remove\n for (sourceId in before) {\n if (!Object.prototype.hasOwnProperty.call(before, sourceId))\n continue;\n if (!Object.prototype.hasOwnProperty.call(after, sourceId)) {\n removeSource(sourceId, commands, sourcesRemoved);\n }\n }\n // look for sources to add/update\n for (sourceId in after) {\n if (!Object.prototype.hasOwnProperty.call(after, sourceId))\n continue;\n if (!Object.prototype.hasOwnProperty.call(before, sourceId)) {\n addSource(sourceId, after, commands);\n }\n else if (!deepEqual(before[sourceId], after[sourceId])) {\n if (before[sourceId].type === 'geojson' && after[sourceId].type === 'geojson' && canUpdateGeoJSON(before, after, sourceId)) {\n addCommand(commands, { command: 'setGeoJSONSourceData', args: [sourceId, after[sourceId].data] });\n }\n else {\n // no update command, must remove then add\n updateSource(sourceId, after, commands, sourcesRemoved);\n }\n }\n }\n}\nfunction diffLayerPropertyChanges(before, after, commands, layerId, klass, command) {\n before = before || {};\n after = after || {};\n for (const prop in before) {\n if (!Object.prototype.hasOwnProperty.call(before, prop))\n continue;\n if (!deepEqual(before[prop], after[prop])) {\n commands.push({ command, args: [layerId, prop, after[prop], klass] });\n }\n }\n for (const prop in after) {\n if (!Object.prototype.hasOwnProperty.call(after, prop) || Object.prototype.hasOwnProperty.call(before, prop))\n continue;\n if (!deepEqual(before[prop], after[prop])) {\n commands.push({ command, args: [layerId, prop, after[prop], klass] });\n }\n }\n}\nfunction pluckId(layer) {\n return layer.id;\n}\nfunction indexById(group, layer) {\n group[layer.id] = layer;\n return group;\n}\nfunction diffLayers(before, after, commands) {\n before = before || [];\n after = after || [];\n // order of layers by id\n const beforeOrder = before.map(pluckId);\n const afterOrder = after.map(pluckId);\n // index of layer by id\n const beforeIndex = before.reduce(indexById, {});\n const afterIndex = after.reduce(indexById, {});\n // track order of layers as if they have been mutated\n const tracker = beforeOrder.slice();\n // layers that have been added do not need to be diffed\n const clean = Object.create(null);\n let layerId;\n let beforeLayer;\n let afterLayer;\n let insertBeforeLayerId;\n let prop;\n // remove layers\n for (let i = 0, d = 0; i < beforeOrder.length; i++) {\n layerId = beforeOrder[i];\n if (!Object.prototype.hasOwnProperty.call(afterIndex, layerId)) {\n addCommand(commands, { command: 'removeLayer', args: [layerId] });\n tracker.splice(tracker.indexOf(layerId, d), 1);\n }\n else {\n // limit where in tracker we need to look for a match\n d++;\n }\n }\n // add/reorder layers\n for (let i = 0, d = 0; i < afterOrder.length; i++) {\n // work backwards as insert is before an existing layer\n layerId = afterOrder[afterOrder.length - 1 - i];\n if (tracker[tracker.length - 1 - i] === layerId)\n continue;\n if (Object.prototype.hasOwnProperty.call(beforeIndex, layerId)) {\n // remove the layer before we insert at the correct position\n addCommand(commands, { command: 'removeLayer', args: [layerId] });\n tracker.splice(tracker.lastIndexOf(layerId, tracker.length - d), 1);\n }\n else {\n // limit where in tracker we need to look for a match\n d++;\n }\n // add layer at correct position\n insertBeforeLayerId = tracker[tracker.length - i];\n addCommand(commands, { command: 'addLayer', args: [afterIndex[layerId], insertBeforeLayerId] });\n tracker.splice(tracker.length - i, 0, layerId);\n clean[layerId] = true;\n }\n // update layers\n for (let i = 0; i < afterOrder.length; i++) {\n layerId = afterOrder[i];\n beforeLayer = beforeIndex[layerId];\n afterLayer = afterIndex[layerId];\n // no need to update if previously added (new or moved)\n if (clean[layerId] || deepEqual(beforeLayer, afterLayer))\n continue;\n // If source, source-layer, or type have changes, then remove the layer\n // and add it back 'from scratch'.\n if (!deepEqual(beforeLayer.source, afterLayer.source) || !deepEqual(beforeLayer['source-layer'], afterLayer['source-layer']) || !deepEqual(beforeLayer.type, afterLayer.type)) {\n addCommand(commands, { command: 'removeLayer', args: [layerId] });\n // we add the layer back at the same position it was already in, so\n // there's no need to update the `tracker`\n insertBeforeLayerId = tracker[tracker.lastIndexOf(layerId) + 1];\n addCommand(commands, { command: 'addLayer', args: [afterLayer, insertBeforeLayerId] });\n continue;\n }\n // layout, paint, filter, minzoom, maxzoom\n diffLayerPropertyChanges(beforeLayer.layout, afterLayer.layout, commands, layerId, null, 'setLayoutProperty');\n diffLayerPropertyChanges(beforeLayer.paint, afterLayer.paint, commands, layerId, null, 'setPaintProperty');\n if (!deepEqual(beforeLayer.filter, afterLayer.filter)) {\n addCommand(commands, { command: 'setFilter', args: [layerId, afterLayer.filter] });\n }\n if (!deepEqual(beforeLayer.minzoom, afterLayer.minzoom) || !deepEqual(beforeLayer.maxzoom, afterLayer.maxzoom)) {\n addCommand(commands, { command: 'setLayerZoomRange', args: [layerId, afterLayer.minzoom, afterLayer.maxzoom] });\n }\n // handle all other layer props, including paint.*\n for (prop in beforeLayer) {\n if (!Object.prototype.hasOwnProperty.call(beforeLayer, prop))\n continue;\n if (prop === 'layout' || prop === 'paint' || prop === 'filter' ||\n prop === 'metadata' || prop === 'minzoom' || prop === 'maxzoom')\n continue;\n if (prop.indexOf('paint.') === 0) {\n diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), 'setPaintProperty');\n }\n else if (!deepEqual(beforeLayer[prop], afterLayer[prop])) {\n addCommand(commands, { command: 'setLayerProperty', args: [layerId, prop, afterLayer[prop]] });\n }\n }\n for (prop in afterLayer) {\n if (!Object.prototype.hasOwnProperty.call(afterLayer, prop) || Object.prototype.hasOwnProperty.call(beforeLayer, prop))\n continue;\n if (prop === 'layout' || prop === 'paint' || prop === 'filter' ||\n prop === 'metadata' || prop === 'minzoom' || prop === 'maxzoom')\n continue;\n if (prop.indexOf('paint.') === 0) {\n diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), 'setPaintProperty');\n }\n else if (!deepEqual(beforeLayer[prop], afterLayer[prop])) {\n addCommand(commands, { command: 'setLayerProperty', args: [layerId, prop, afterLayer[prop]] });\n }\n }\n }\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 diffStyles(before, after) {\n if (!before)\n return [{ command: 'setStyle', args: [after] }];\n let commands = [];\n try {\n // Handle changes to top-level properties\n if (!deepEqual(before.version, after.version)) {\n return [{ command: 'setStyle', args: [after] }];\n }\n if (!deepEqual(before.center, after.center)) {\n commands.push({ command: 'setCenter', args: [after.center] });\n }\n if (!deepEqual(before.zoom, after.zoom)) {\n commands.push({ command: 'setZoom', args: [after.zoom] });\n }\n if (!deepEqual(before.bearing, after.bearing)) {\n commands.push({ command: 'setBearing', args: [after.bearing] });\n }\n if (!deepEqual(before.pitch, after.pitch)) {\n commands.push({ command: 'setPitch', args: [after.pitch] });\n }\n if (!deepEqual(before.sprite, after.sprite)) {\n commands.push({ command: 'setSprite', args: [after.sprite] });\n }\n if (!deepEqual(before.glyphs, after.glyphs)) {\n commands.push({ command: 'setGlyphs', args: [after.glyphs] });\n }\n if (!deepEqual(before.transition, after.transition)) {\n commands.push({ command: 'setTransition', args: [after.transition] });\n }\n if (!deepEqual(before.light, after.light)) {\n commands.push({ command: 'setLight', args: [after.light] });\n }\n if (!deepEqual(before.terrain, after.terrain)) {\n commands.push({ command: 'setTerrain', args: [after.terrain] });\n }\n if (!deepEqual(before.sky, after.sky)) {\n commands.push({ command: 'setSky', args: [after.sky] });\n }\n if (!deepEqual(before.projection, after.projection)) {\n commands.push({ command: 'setProjection', args: [after.projection] });\n }\n // Handle changes to `sources`\n // If a source is to be removed, we also--before the removeSource\n // command--need to remove all the style layers that depend on it.\n const sourcesRemoved = {};\n // First collect the {add,remove}Source commands\n const removeOrAddSourceCommands = [];\n diffSources(before.sources, after.sources, removeOrAddSourceCommands, sourcesRemoved);\n // Push a removeLayer command for each style layer that depends on a\n // source that's being removed.\n // Also, exclude any such layers them from the input to `diffLayers`\n // below, so that diffLayers produces the appropriate `addLayers`\n // command\n const beforeLayers = [];\n if (before.layers) {\n before.layers.forEach((layer) => {\n if ('source' in layer && sourcesRemoved[layer.source]) {\n commands.push({ command: 'removeLayer', args: [layer.id] });\n }\n else {\n beforeLayers.push(layer);\n }\n });\n }\n commands = commands.concat(removeOrAddSourceCommands);\n // Handle changes to `layers`\n diffLayers(beforeLayers, after.layers, commands);\n }\n catch (e) {\n // fall back to setStyle\n console.warn('Unable to compute style diff:', e);\n commands = [{ command: 'setStyle', args: [after] }];\n }\n return commands;\n}\n\n// Note: Do not inherit from Error. It breaks when transpiling to ES5.\nclass ValidationError {\n constructor(key, value, message, identifier) {\n this.message = (key ? `${key}: ` : '') + message;\n if (identifier)\n this.identifier = identifier;\n if (value !== null && value !== undefined && value.__line__) {\n this.line = value.__line__;\n }\n }\n}\n\n// Note: Do not inherit from Error. It breaks when transpiling to ES5.\nclass ParsingError {\n constructor(error) {\n this.error = error;\n this.message = error.message;\n const match = error.message.match(/line (\\d+)/);\n this.line = match ? parseInt(match[1], 10) : 0;\n }\n}\n\nfunction extendBy(output, ...inputs) {\n for (const input of inputs) {\n for (const k in input) {\n output[k] = input[k];\n }\n }\n return output;\n}\n\nclass ExpressionParsingError extends Error {\n constructor(key, message) {\n super(message);\n this.message = message;\n this.key = key;\n }\n}\n\n/**\n * Tracks `let` bindings during expression parsing.\n * @private\n */\nclass Scope {\n constructor(parent, bindings = []) {\n this.parent = parent;\n this.bindings = {};\n for (const [name, expression] of bindings) {\n this.bindings[name] = expression;\n }\n }\n concat(bindings) {\n return new Scope(this, bindings);\n }\n get(name) {\n if (this.bindings[name]) {\n return this.bindings[name];\n }\n if (this.parent) {\n return this.parent.get(name);\n }\n throw new Error(`${name} not found in scope.`);\n }\n has(name) {\n if (this.bindings[name])\n return true;\n return this.parent ? this.parent.has(name) : false;\n }\n}\n\nconst NullType = { kind: 'null' };\nconst NumberType = { kind: 'number' };\nconst StringType = { kind: 'string' };\nconst BooleanType = { kind: 'boolean' };\nconst ColorType = { kind: 'color' };\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 ResolvedImageType = { kind: 'resolvedImage' };\nconst VariableAnchorOffsetCollectionType = { kind: 'variableAnchorOffsetCollection' };\nfunction array$1(itemType, N) {\n return {\n kind: 'array',\n itemType,\n N\n };\n}\nfunction toString$1(type) {\n if (type.kind === 'array') {\n const itemType = toString$1(type.itemType);\n return typeof type.N === 'number' ?\n `array<${itemType}, ${type.N}>` :\n type.itemType.kind === 'value' ? 'array' : `array<${itemType}>`;\n }\n else {\n return type.kind;\n }\n}\nconst valueMemberTypes = [\n NullType,\n NumberType,\n StringType,\n BooleanType,\n ColorType,\n FormattedType,\n ObjectType,\n array$1(ValueType),\n PaddingType,\n ResolvedImageType,\n VariableAnchorOffsetCollectionType\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 if (t.kind === 'error') {\n // Error is a subtype of every type\n return null;\n }\n else if (expected.kind === 'array') {\n if (t.kind === 'array' &&\n ((t.N === 0 && t.itemType.kind === 'value') || !checkSubtype(expected.itemType, t.itemType)) &&\n (typeof expected.N !== 'number' || expected.N === t.N)) {\n return null;\n }\n }\n else if (expected.kind === t.kind) {\n return null;\n }\n else if (expected.kind === 'value') {\n for (const memberType of valueMemberTypes) {\n if (!checkSubtype(memberType, t)) {\n return null;\n }\n }\n }\n return `Expected ${toString$1(expected)} but found ${toString$1(t)} instead.`;\n}\nfunction isValidType(provided, allowedTypes) {\n return allowedTypes.some(t => t.kind === provided.kind);\n}\nfunction isValidNativeType(provided, allowedTypes) {\n return allowedTypes.some(t => {\n if (t === 'null') {\n return provided === null;\n }\n else if (t === 'array') {\n return Array.isArray(provided);\n }\n else if (t === 'object') {\n return provided && !Array.isArray(provided) && typeof provided === 'object';\n }\n else {\n return t === typeof provided;\n }\n });\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 if (provided.kind === 'array' && sample.kind === 'array') {\n return provided.itemType.kind === sample.itemType.kind && typeof provided.N === 'number';\n }\n return provided.kind === sample.kind;\n}\n\n// See https://observablehq.com/@mbostock/lab-and-rgb\nconst Xn = 0.96422, Yn = 1, Zn = 0.82521, t0 = 4 / 29, t1 = 6 / 29, t2 = 3 * t1 * t1, t3 = t1 * t1 * t1, deg2rad = Math.PI / 180, rad2deg = 180 / Math.PI;\nfunction constrainAngle(angle) {\n angle = angle % 360;\n if (angle < 0) {\n angle += 360;\n }\n return angle;\n}\nfunction rgbToLab([r, g, b, alpha]) {\n r = rgb2xyz(r);\n g = rgb2xyz(g);\n b = rgb2xyz(b);\n let x, z;\n const y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn);\n if (r === g && g === b) {\n x = z = y;\n }\n else {\n x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn);\n z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn);\n }\n const l = 116 * y - 16;\n return [(l < 0) ? 0 : l, 500 * (x - y), 200 * (y - z), alpha];\n}\nfunction rgb2xyz(x) {\n return (x <= 0.04045) ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);\n}\nfunction xyz2lab(t) {\n return (t > t3) ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\nfunction labToRgb([l, a, b, alpha]) {\n let y = (l + 16) / 116, x = isNaN(a) ? y : y + a / 500, z = isNaN(b) ? y : y - b / 200;\n y = Yn * lab2xyz(y);\n x = Xn * lab2xyz(x);\n z = Zn * lab2xyz(z);\n return [\n xyz2rgb(3.1338561 * x - 1.6168667 * y - 0.4906146 * z), // D50 -> sRGB\n xyz2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z),\n xyz2rgb(0.0719453 * x - 0.2289914 * y + 1.4052427 * z),\n alpha,\n ];\n}\nfunction xyz2rgb(x) {\n x = (x <= 0.00304) ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055;\n return (x < 0) ? 0 : (x > 1) ? 1 : x; // clip to 0..1 range\n}\nfunction lab2xyz(t) {\n return (t > t1) ? t * t * t : t2 * (t - t0);\n}\nfunction rgbToHcl(rgbColor) {\n const [l, a, b, alpha] = rgbToLab(rgbColor);\n const c = Math.sqrt(a * a + b * b);\n const h = Math.round(c * 10000) ? constrainAngle(Math.atan2(b, a) * rad2deg) : NaN;\n return [h, c, l, alpha];\n}\nfunction hclToRgb([h, c, l, alpha]) {\n h = isNaN(h) ? 0 : h * deg2rad;\n return labToRgb([l, Math.cos(h) * c, Math.sin(h) * c, alpha]);\n}\n// https://drafts.csswg.org/css-color-4/#hsl-to-rgb\nfunction hslToRgb([h, s, l, alpha]) {\n h = constrainAngle(h);\n s /= 100;\n l /= 100;\n function f(n) {\n const k = (n + h / 30) % 12;\n const a = s * Math.min(l, 1 - l);\n return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n }\n return [f(0), f(8), f(4), alpha];\n}\n\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 input = input.toLowerCase().trim();\n if (input === 'transparent') {\n return [0, 0, 0, 0];\n }\n // 'white', 'black', 'blue'\n const namedColorsMatch = namedColors[input];\n if (namedColorsMatch) {\n const [r, g, b] = namedColorsMatch;\n return [r / 255, g / 255, b / 255, 1];\n }\n // #f0c, #f0cf, #ff00cc, #ff00ccff\n if (input.startsWith('#')) {\n const hexRegexp = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/;\n if (hexRegexp.test(input)) {\n const step = input.length < 6 ? 1 : 2;\n let i = 1;\n return [\n parseHex(input.slice(i, i += step)),\n parseHex(input.slice(i, i += step)),\n parseHex(input.slice(i, i += step)),\n parseHex(input.slice(i, i + step) || 'ff'),\n ];\n }\n }\n // rgb(128 0 0), rgb(50% 0% 0%), rgba(255,0,255,0.6), rgb(255 0 255 / 60%), rgb(100% 0% 100% /.6)\n if (input.startsWith('rgb')) {\n const rgbRegExp = /^rgba?\\(\\s*([\\de.+-]+)(%)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)(%)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)(%)?(?:\\s*([,\\/])\\s*([\\de.+-]+)(%)?)?\\s*\\)$/;\n const rgbMatch = input.match(rgbRegExp);\n if (rgbMatch) {\n const [_, // eslint-disable-line @typescript-eslint/no-unused-vars\n r, // \n rp, // % (optional)\n f1, // , (optional)\n g, // \n gp, // % (optional)\n f2, // , (optional)\n b, // \n bp, // % (optional)\n f3, // ,|/ (optional)\n a, // (optional)\n ap, // % (optional)\n ] = rgbMatch;\n const argFormat = [f1 || ' ', f2 || ' ', f3].join('');\n if (argFormat === ' ' ||\n argFormat === ' /' ||\n argFormat === ',,' ||\n argFormat === ',,,') {\n const valFormat = [rp, gp, bp].join('');\n const maxValue = (valFormat === '%%%') ? 100 :\n (valFormat === '') ? 255 : 0;\n if (maxValue) {\n const rgba = [\n clamp(+r / maxValue, 0, 1),\n clamp(+g / maxValue, 0, 1),\n clamp(+b / maxValue, 0, 1),\n a ? parseAlpha(+a, ap) : 1,\n ];\n if (validateNumbers(rgba)) {\n return rgba;\n }\n // invalid numbers\n }\n // values must be all numbers or all percentages\n }\n return; // comma optional syntax requires no commas at all\n }\n }\n // hsl(120 50% 80%), hsla(120deg,50%,80%,.9), hsl(12e1 50% 80% / 90%)\n const hslRegExp = /^hsla?\\(\\s*([\\de.+-]+)(?:deg)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)%(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)%(?:\\s*([,\\/])\\s*([\\de.+-]+)(%)?)?\\s*\\)$/;\n const hslMatch = input.match(hslRegExp);\n if (hslMatch) {\n const [_, // eslint-disable-line @typescript-eslint/no-unused-vars\n h, // \n f1, // , (optional)\n s, // \n f2, // , (optional)\n l, // \n f3, // ,|/ (optional)\n a, // (optional)\n ap, // % (optional)\n ] = hslMatch;\n const argFormat = [f1 || ' ', f2 || ' ', f3].join('');\n if (argFormat === ' ' ||\n argFormat === ' /' ||\n argFormat === ',,' ||\n argFormat === ',,,') {\n const hsla = [\n +h,\n clamp(+s, 0, 100),\n clamp(+l, 0, 100),\n a ? parseAlpha(+a, ap) : 1,\n ];\n if (validateNumbers(hsla)) {\n return hslToRgb(hsla);\n }\n // invalid numbers\n }\n // comma optional syntax requires no commas at all\n }\n}\nfunction parseHex(hex) {\n return parseInt(hex.padEnd(2, hex), 16) / 255;\n}\nfunction parseAlpha(a, asPercentage) {\n return clamp(asPercentage ? (a / 100) : a, 0, 1);\n}\nfunction clamp(n, min, max) {\n return 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 return !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 aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n grey: [128, 128, 128],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n rebeccapurple: [102, 51, 153],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50],\n};\n\n/**\n * Color representation used by WebGL.\n * Defined in sRGB color space and pre-blended with alpha.\n * @private\n */\nclass Color {\n /**\n * @param r Red component premultiplied by `alpha` 0..1\n * @param g Green component premultiplied by `alpha` 0..1\n * @param b Blue component premultiplied by `alpha` 0..1\n * @param [alpha=1] Alpha component 0..1\n * @param [premultiplied=true] Whether the `r`, `g` and `b` values have already\n * been multiplied by alpha. If `true` nothing happens if `false` then they will\n * be multiplied automatically.\n */\n constructor(r, g, b, alpha = 1, premultiplied = true) {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = alpha;\n if (!premultiplied) {\n this.r *= alpha;\n this.g *= alpha;\n this.b *= alpha;\n if (!alpha) {\n // alpha = 0 erases completely rgb channels. This behavior is not desirable\n // if this particular color is later used in color interpolation.\n // Because of that, a reference to original color is saved.\n this.overwriteGetter('rgb', [r, g, b, alpha]);\n }\n }\n }\n /**\n * Parses CSS color strings and converts colors to sRGB color space if needed.\n * Officially supported color formats:\n * - keyword, e.g. 'aquamarine' or 'steelblue'\n * - hex (with 3, 4, 6 or 8 digits), e.g. '#f0f' or '#e9bebea9'\n * - rgb and rgba, e.g. 'rgb(0,240,120)' or 'rgba(0%,94%,47%,0.1)' or 'rgb(0 240 120 / .3)'\n * - hsl and hsla, e.g. 'hsl(0,0%,83%)' or 'hsla(0,0%,83%,.5)' or 'hsl(0 0% 83% / 20%)'\n *\n * @param input CSS color string to parse.\n * @returns A `Color` instance, or `undefined` if the input is not a valid color string.\n */\n static parse(input) {\n // in zoom-and-property function input could be an instance of Color class\n if (input instanceof Color) {\n return input;\n }\n if (typeof input !== 'string') {\n return;\n }\n const rgba = parseCssColor(input);\n if (rgba) {\n return new Color(...rgba, false);\n }\n }\n /**\n * Used in color interpolation and by 'to-rgba' expression.\n *\n * @returns Gien color, with reversed alpha blending, in sRGB color space.\n */\n get rgb() {\n const { r, g, b, a } = this;\n const f = a || Infinity; // reverse alpha blending factor\n return this.overwriteGetter('rgb', [r / f, g / f, b / f, a]);\n }\n /**\n * Used in color interpolation.\n *\n * @returns Gien color, with reversed alpha blending, in HCL color space.\n */\n get hcl() {\n return this.overwriteGetter('hcl', rgbToHcl(this.rgb));\n }\n /**\n * Used in color interpolation.\n *\n * @returns Gien color, with reversed alpha blending, in LAB color space.\n */\n get lab() {\n return this.overwriteGetter('lab', rgbToLab(this.rgb));\n }\n /**\n * Lazy getter pattern. When getter is called for the first time lazy value\n * is calculated and then overwrites getter function in given object instance.\n *\n * @example:\n * const redColor = Color.parse('red');\n * let x = redColor.hcl; // this will invoke `get hcl()`, which will calculate\n * // the value of red in HCL space and invoke this `overwriteGetter` function\n * // which in turn will set a field with a key 'hcl' in the `redColor` object.\n * // In other words it will override `get hcl()` from its `Color` prototype\n * // with its own property: hcl = [calculated red value in hcl].\n * let y = redColor.hcl; // next call will no longer invoke getter but simply\n * // return the previously calculated value\n * x === y; // true - `x` is exactly the same object as `y`\n *\n * @param getterKey Getter key\n * @param lazyValue Lazily calculated value to be memoized by current instance\n * @private\n */\n overwriteGetter(getterKey, lazyValue) {\n Object.defineProperty(this, getterKey, { value: lazyValue });\n return lazyValue;\n }\n /**\n * Used by 'to-string' expression.\n *\n * @returns Serialized color in format `rgba(r,g,b,a)`\n * where r,g,b are numbers within 0..255 and alpha is number within 1..0\n *\n * @example\n * var purple = new Color.parse('purple');\n * purple.toString; // = \"rgba(128,0,128,1)\"\n * var translucentGreen = new Color.parse('rgba(26, 207, 26, .73)');\n * translucentGreen.toString(); // = \"rgba(26,207,26,0.73)\"\n */\n toString() {\n const [r, g, b, a] = this.rgb;\n return `rgba(${[r, g, b].map(n => Math.round(n * 255)).join(',')},${a})`;\n }\n}\nColor.black = new Color(0, 0, 0, 1);\nColor.white = new Color(1, 1, 1, 1);\nColor.transparent = new Color(0, 0, 0, 0);\nColor.red = new Color(1, 0, 0, 1);\n\n// Flow type declarations for Intl cribbed from\n// https://github.com/facebook/flow/issues/1270\nclass Collator {\n constructor(caseSensitive, diacriticSensitive, locale) {\n if (caseSensitive)\n this.sensitivity = diacriticSensitive ? 'variant' : 'case';\n else\n this.sensitivity = diacriticSensitive ? 'accent' : 'base';\n this.locale = locale;\n this.collator = new Intl.Collator(this.locale ? this.locale : [], { sensitivity: this.sensitivity, usage: 'search' });\n }\n compare(lhs, rhs) {\n return this.collator.compare(lhs, rhs);\n }\n resolvedLocale() {\n // We create a Collator without \"usage: search\" because we don't want\n // the search options encoded in our result (e.g. \"en-u-co-search\")\n return new Intl.Collator(this.locale ? this.locale : [])\n .resolvedOptions().locale;\n }\n}\n\nclass FormattedSection {\n constructor(text, image, scale, fontStack, textColor) {\n this.text = text;\n this.image = image;\n this.scale = scale;\n this.fontStack = fontStack;\n this.textColor = textColor;\n }\n}\nclass Formatted {\n constructor(sections) {\n this.sections = sections;\n }\n static fromString(unformatted) {\n return new Formatted([new FormattedSection(unformatted, null, null, null, null)]);\n }\n isEmpty() {\n if (this.sections.length === 0)\n return true;\n return !this.sections.some(section => section.text.length !== 0 ||\n (section.image && section.image.name.length !== 0));\n }\n static factory(text) {\n if (text instanceof Formatted) {\n return text;\n }\n else {\n return Formatted.fromString(text);\n }\n }\n toString() {\n if (this.sections.length === 0)\n return '';\n return this.sections.map(section => section.text).join('');\n }\n}\n\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 */\nclass Padding {\n constructor(values) {\n this.values = values.slice();\n }\n /**\n * Numeric padding values\n * @param input A padding value\n * @returns A `Padding` instance, or `undefined` if the input is not a valid padding value.\n */\n static parse(input) {\n if (input instanceof Padding) {\n return input;\n }\n // Backwards compatibility: bare number is treated the same as array with single value.\n // Padding applies to all four sides.\n if (typeof input === 'number') {\n return new Padding([input, input, input, input]);\n }\n if (!Array.isArray(input)) {\n return undefined;\n }\n if (input.length < 1 || input.length > 4) {\n return undefined;\n }\n for (const val of input) {\n if (typeof val !== 'number') {\n return undefined;\n }\n }\n // Expand shortcut properties into explicit 4-sided values\n switch (input.length) {\n case 1:\n input = [input[0], input[0], input[0], input[0]];\n break;\n case 2:\n input = [input[0], input[1], input[0], input[1]];\n break;\n case 3:\n input = [input[0], input[1], input[2], input[1]];\n break;\n }\n return new Padding(input);\n }\n toString() {\n return JSON.stringify(this.values);\n }\n}\n\n/** Set of valid anchor positions, as a set for validation */\nconst anchors = new Set(['center', 'left', 'right', 'top', 'bottom', 'top-left', 'top-right', 'bottom-left', 'bottom-right']);\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 */\nclass VariableAnchorOffsetCollection {\n constructor(values) {\n this.values = values.slice();\n }\n static parse(input) {\n if (input instanceof VariableAnchorOffsetCollection) {\n return input;\n }\n if (!Array.isArray(input) ||\n input.length < 1 ||\n input.length % 2 !== 0) {\n return undefined;\n }\n for (let i = 0; i < input.length; i += 2) {\n // Elements in even positions should be anchor positions; Elements in odd positions should be offset values\n const anchorValue = input[i];\n const offsetValue = input[i + 1];\n if (typeof anchorValue !== 'string' || !anchors.has(anchorValue)) {\n return undefined;\n }\n if (!Array.isArray(offsetValue) || offsetValue.length !== 2 || typeof offsetValue[0] !== 'number' || typeof offsetValue[1] !== 'number') {\n return undefined;\n }\n }\n return new VariableAnchorOffsetCollection(input);\n }\n toString() {\n return JSON.stringify(this.values);\n }\n}\n\nclass ResolvedImage {\n constructor(options) {\n this.name = options.name;\n this.available = options.available;\n }\n toString() {\n return this.name;\n }\n static fromString(name) {\n if (!name)\n return null; // treat empty values as no image\n return new ResolvedImage({ name, available: false });\n }\n}\n\nfunction validateRGBA(r, g, b, a) {\n if (!(typeof r === 'number' && r >= 0 && r <= 255 &&\n typeof g === 'number' && g >= 0 && g <= 255 &&\n typeof b === 'number' && b >= 0 && b <= 255)) {\n const value = typeof a === 'number' ? [r, g, b, a] : [r, g, b];\n return `Invalid rgba value [${value.join(', ')}]: 'r', 'g', and 'b' must be between 0 and 255.`;\n }\n if (!(typeof a === 'undefined' || (typeof a === 'number' && a >= 0 && a <= 1))) {\n return `Invalid rgba value [${[r, g, b, a].join(', ')}]: 'a' must be between 0 and 1.`;\n }\n return null;\n}\nfunction isValue(mixed) {\n if (mixed === null ||\n typeof mixed === 'string' ||\n typeof mixed === 'boolean' ||\n typeof mixed === 'number' ||\n mixed instanceof Color ||\n mixed instanceof Collator ||\n mixed instanceof Formatted ||\n mixed instanceof Padding ||\n mixed instanceof VariableAnchorOffsetCollection ||\n mixed instanceof ResolvedImage) {\n return true;\n }\n else if (Array.isArray(mixed)) {\n for (const item of mixed) {\n if (!isValue(item)) {\n return false;\n }\n }\n return true;\n }\n else if (typeof mixed === 'object') {\n for (const key in mixed) {\n if (!isValue(mixed[key])) {\n return false;\n }\n }\n return true;\n }\n else {\n return false;\n }\n}\nfunction typeOf(value) {\n if (value === null) {\n return NullType;\n }\n else if (typeof value === 'string') {\n return StringType;\n }\n else if (typeof value === 'boolean') {\n return BooleanType;\n }\n else if (typeof value === 'number') {\n return NumberType;\n }\n else if (value instanceof Color) {\n return ColorType;\n }\n else if (value instanceof Collator) {\n return CollatorType;\n }\n else if (value instanceof Formatted) {\n return FormattedType;\n }\n else if (value instanceof Padding) {\n return PaddingType;\n }\n else if (value instanceof VariableAnchorOffsetCollection) {\n return VariableAnchorOffsetCollectionType;\n }\n else if (value instanceof ResolvedImage) {\n return ResolvedImageType;\n }\n else if (Array.isArray(value)) {\n const length = value.length;\n let itemType;\n for (const item of value) {\n const t = typeOf(item);\n if (!itemType) {\n itemType = t;\n }\n else if (itemType === t) {\n continue;\n }\n else {\n itemType = ValueType;\n break;\n }\n }\n return array$1(itemType || ValueType, length);\n }\n else {\n return ObjectType;\n }\n}\nfunction toString(value) {\n const type = typeof value;\n if (value === null) {\n return '';\n }\n else if (type === 'string' || type === 'number' || type === 'boolean') {\n return String(value);\n }\n else if (value instanceof Color || value instanceof Formatted || value instanceof Padding || value instanceof VariableAnchorOffsetCollection || value instanceof ResolvedImage) {\n return value.toString();\n }\n else {\n return JSON.stringify(value);\n }\n}\n\nclass Literal {\n constructor(type, value) {\n this.type = type;\n this.value = value;\n }\n static parse(args, context) {\n if (args.length !== 2)\n return context.error(`'literal' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n if (!isValue(args[1]))\n return context.error('invalid value');\n const value = args[1];\n let type = typeOf(value);\n // special case: infer the item type if possible for zero-length arrays\n const expected = context.expectedType;\n if (type.kind === 'array' &&\n type.N === 0 &&\n expected &&\n expected.kind === 'array' &&\n (typeof expected.N !== 'number' || expected.N === 0)) {\n type = expected;\n }\n return new Literal(type, value);\n }\n evaluate() {\n return this.value;\n }\n eachChild() { }\n outputDefined() {\n return true;\n }\n}\n\nclass RuntimeError {\n constructor(message) {\n this.name = 'ExpressionEvaluationError';\n this.message = message;\n }\n toJSON() {\n return this.message;\n }\n}\n\nconst types$1 = {\n string: StringType,\n number: NumberType,\n boolean: BooleanType,\n object: ObjectType\n};\nclass Assertion {\n constructor(type, args) {\n this.type = type;\n this.args = args;\n }\n static parse(args, context) {\n if (args.length < 2)\n return context.error('Expected at least one argument.');\n let i = 1;\n let type;\n const name = args[0];\n if (name === 'array') {\n let itemType;\n if (args.length > 2) {\n const type = args[1];\n if (typeof type !== 'string' || !(type in types$1) || type === 'object')\n return context.error('The item type argument of \"array\" must be one of string, number, boolean', 1);\n itemType = types$1[type];\n i++;\n }\n else {\n itemType = ValueType;\n }\n let N;\n if (args.length > 3) {\n if (args[2] !== null &&\n (typeof args[2] !== 'number' ||\n args[2] < 0 ||\n args[2] !== Math.floor(args[2]))) {\n return context.error('The length argument to \"array\" must be a positive integer literal', 2);\n }\n N = args[2];\n i++;\n }\n type = array$1(itemType, N);\n }\n else {\n if (!types$1[name])\n throw new Error(`Types doesn't contain name = ${name}`);\n type = types$1[name];\n }\n const parsed = [];\n for (; i < args.length; i++) {\n const input = context.parse(args[i], i, ValueType);\n if (!input)\n return null;\n parsed.push(input);\n }\n return new Assertion(type, parsed);\n }\n evaluate(ctx) {\n for (let i = 0; i < this.args.length; i++) {\n const value = this.args[i].evaluate(ctx);\n const error = checkSubtype(this.type, typeOf(value));\n if (!error) {\n return value;\n }\n else if (i === this.args.length - 1) {\n throw new RuntimeError(`Expected value to be of type ${toString$1(this.type)}, but found ${toString$1(typeOf(value))} instead.`);\n }\n }\n throw new Error();\n }\n eachChild(fn) {\n this.args.forEach(fn);\n }\n outputDefined() {\n return this.args.every(arg => arg.outputDefined());\n }\n}\n\nconst types = {\n 'to-boolean': BooleanType,\n 'to-color': ColorType,\n 'to-number': NumberType,\n '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 */\nclass Coercion {\n constructor(type, args) {\n this.type = type;\n this.args = args;\n }\n static parse(args, context) {\n if (args.length < 2)\n return context.error('Expected at least one argument.');\n const name = args[0];\n if (!types[name])\n throw new Error(`Can't parse ${name} as it is not part of the known types`);\n if ((name === 'to-boolean' || name === 'to-string') && args.length !== 2)\n return context.error('Expected one argument.');\n const type = types[name];\n const parsed = [];\n for (let i = 1; i < args.length; i++) {\n const input = context.parse(args[i], i, ValueType);\n if (!input)\n return null;\n parsed.push(input);\n }\n return new Coercion(type, parsed);\n }\n evaluate(ctx) {\n switch (this.type.kind) {\n case 'boolean':\n return Boolean(this.args[0].evaluate(ctx));\n case 'color': {\n let input;\n let error;\n for (const arg of this.args) {\n input = arg.evaluate(ctx);\n error = null;\n if (input instanceof Color) {\n return input;\n }\n else if (typeof input === 'string') {\n const c = ctx.parseColor(input);\n if (c)\n return c;\n }\n else if (Array.isArray(input)) {\n if (input.length < 3 || input.length > 4) {\n error = `Invalid rbga value ${JSON.stringify(input)}: expected an array containing either three or four numeric values.`;\n }\n else {\n error = validateRGBA(input[0], input[1], input[2], input[3]);\n }\n if (!error) {\n return new Color(input[0] / 255, input[1] / 255, input[2] / 255, input[3]);\n }\n }\n }\n throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);\n }\n case 'padding': {\n let input;\n for (const arg of this.args) {\n input = arg.evaluate(ctx);\n const pad = Padding.parse(input);\n if (pad) {\n return pad;\n }\n }\n throw new RuntimeError(`Could not parse padding from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);\n }\n case 'variableAnchorOffsetCollection': {\n let input;\n for (const arg of this.args) {\n input = arg.evaluate(ctx);\n const coll = VariableAnchorOffsetCollection.parse(input);\n if (coll) {\n return coll;\n }\n }\n throw new RuntimeError(`Could not parse variableAnchorOffsetCollection from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);\n }\n case 'number': {\n let value = null;\n for (const arg of this.args) {\n value = arg.evaluate(ctx);\n if (value === null)\n return 0;\n const num = Number(value);\n if (isNaN(num))\n continue;\n return num;\n }\n throw new RuntimeError(`Could not convert ${JSON.stringify(value)} to number.`);\n }\n case 'formatted':\n // There is no explicit 'to-formatted' but this coercion can be implicitly\n // created by properties that expect the 'formatted' type.\n return Formatted.fromString(toString(this.args[0].evaluate(ctx)));\n case 'resolvedImage':\n return ResolvedImage.fromString(toString(this.args[0].evaluate(ctx)));\n default:\n return toString(this.args[0].evaluate(ctx));\n }\n }\n eachChild(fn) {\n this.args.forEach(fn);\n }\n outputDefined() {\n return this.args.every(arg => arg.outputDefined());\n }\n}\n\nconst geometryTypes = ['Unknown', 'Point', 'LineString', 'Polygon'];\nclass EvaluationContext {\n constructor() {\n this.globals = null;\n this.feature = null;\n this.featureState = null;\n this.formattedSection = null;\n this._parseColorCache = {};\n this.availableImages = null;\n this.canonical = null;\n }\n id() {\n return this.feature && 'id' in this.feature ? this.feature.id : null;\n }\n geometryType() {\n return this.feature ? typeof this.feature.type === 'number' ? geometryTypes[this.feature.type] : this.feature.type : null;\n }\n geometry() {\n return this.feature && 'geometry' in this.feature ? this.feature.geometry : null;\n }\n canonicalID() {\n return this.canonical;\n }\n properties() {\n return this.feature && this.feature.properties || {};\n }\n parseColor(input) {\n let cached = this._parseColorCache[input];\n if (!cached) {\n cached = this._parseColorCache[input] = Color.parse(input);\n }\n return cached;\n }\n}\n\n/**\n * State associated parsing at a given point in an expression tree.\n * @private\n */\nclass ParsingContext {\n constructor(registry, isConstantFunc, path = [], expectedType, scope = new Scope(), errors = []) {\n this.registry = registry;\n this.path = path;\n this.key = path.map(part => `[${part}]`).join('');\n this.scope = scope;\n this.errors = errors;\n this.expectedType = expectedType;\n this._isConstant = isConstantFunc;\n }\n /**\n * @param expr the JSON expression to parse\n * @param index the optional argument index if this expression is an argument of a parent expression that's being parsed\n * @param options\n * @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 * @private\n */\n parse(expr, index, expectedType, bindings, options = {}) {\n if (index) {\n return this.concat(index, expectedType, bindings)._parse(expr, options);\n }\n return this._parse(expr, options);\n }\n _parse(expr, options) {\n if (expr === null || typeof expr === 'string' || typeof expr === 'boolean' || typeof expr === 'number') {\n expr = ['literal', expr];\n }\n function annotate(parsed, type, typeAnnotation) {\n if (typeAnnotation === 'assert') {\n return new Assertion(type, [parsed]);\n }\n else if (typeAnnotation === 'coerce') {\n return new Coercion(type, [parsed]);\n }\n else {\n return parsed;\n }\n }\n if (Array.isArray(expr)) {\n if (expr.length === 0) {\n return this.error('Expected an array with at least one element. If you wanted a literal array, use [\"literal\", []].');\n }\n const op = expr[0];\n if (typeof op !== 'string') {\n this.error(`Expression name must be a string, but found ${typeof op} instead. If you wanted a literal array, use [\"literal\", [...]].`, 0);\n return null;\n }\n const Expr = this.registry[op];\n if (Expr) {\n let parsed = Expr.parse(expr, this);\n if (!parsed)\n return null;\n if (this.expectedType) {\n const expected = this.expectedType;\n const actual = parsed.type;\n // When we expect a number, string, boolean, or array but have a value, wrap it in an assertion.\n // When we expect a color or formatted string, but have a string or value, wrap it in a coercion.\n // Otherwise, we do static type-checking.\n //\n // These behaviors are overridable for:\n // * The \"coalesce\" operator, which needs to omit type annotations.\n // * String-valued properties (e.g. `text-field`), where coercion is more convenient than assertion.\n //\n if ((expected.kind === 'string' || expected.kind === 'number' || expected.kind === 'boolean' || expected.kind === 'object' || expected.kind === 'array') && actual.kind === 'value') {\n parsed = annotate(parsed, expected, options.typeAnnotation || 'assert');\n }\n else if ((expected.kind === 'color' || expected.kind === 'formatted' || expected.kind === 'resolvedImage') && (actual.kind === 'value' || actual.kind === 'string')) {\n parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');\n }\n else if (expected.kind === 'padding' && (actual.kind === 'value' || actual.kind === 'number' || actual.kind === 'array')) {\n parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');\n }\n else if (expected.kind === 'variableAnchorOffsetCollection' && (actual.kind === 'value' || actual.kind === 'array')) {\n parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');\n }\n else if (this.checkSubtype(expected, actual)) {\n return null;\n }\n }\n // If an expression's arguments are all literals, we can evaluate\n // it immediately and replace it with a literal value in the\n // parsed/compiled result. Expressions that expect an image should\n // not be resolved here so we can later get the available images.\n if (!(parsed instanceof Literal) && (parsed.type.kind !== 'resolvedImage') && this._isConstant(parsed)) {\n const ec = new EvaluationContext();\n try {\n parsed = new Literal(parsed.type, parsed.evaluate(ec));\n }\n catch (e) {\n this.error(e.message);\n return null;\n }\n }\n return parsed;\n }\n return this.error(`Unknown expression \"${op}\". If you wanted a literal array, use [\"literal\", [...]].`, 0);\n }\n else if (typeof expr === 'undefined') {\n return this.error('\\'undefined\\' value invalid. Use null instead.');\n }\n else if (typeof expr === 'object') {\n return this.error('Bare objects invalid. Use [\"literal\", {...}] instead.');\n }\n else {\n return this.error(`Expected an array, but found ${typeof expr} instead.`);\n }\n }\n /**\n * Returns a copy of this context suitable for parsing the subexpression at\n * index `index`, optionally appending to 'let' binding map.\n *\n * Note that `errors` property, intended for collecting errors while\n * parsing, is copied by reference rather than cloned.\n * @private\n */\n concat(index, expectedType, bindings) {\n const path = typeof index === 'number' ? this.path.concat(index) : this.path;\n const scope = bindings ? this.scope.concat(bindings) : this.scope;\n return new ParsingContext(this.registry, this._isConstant, path, expectedType || null, scope, this.errors);\n }\n /**\n * Push a parsing (or type checking) error into the `this.errors`\n * @param error The message\n * @param keys Optionally specify the source of the error at a child\n * of the current expression at `this.key`.\n * @private\n */\n error(error, ...keys) {\n const key = `${this.key}${keys.map(k => `[${k}]`).join('')}`;\n this.errors.push(new ExpressionParsingError(key, error));\n }\n /**\n * Returns null if `t` is a subtype of `expected`; otherwise returns an\n * error message and also pushes it to `this.errors`.\n * @param expected The expected type\n * @param t The actual type\n * @returns null if `t` is a subtype of `expected`; otherwise returns an error message\n */\n checkSubtype(expected, t) {\n const error = checkSubtype(expected, t);\n if (error)\n this.error(error);\n return error;\n }\n}\n\nclass Let {\n constructor(bindings, result) {\n this.type = result.type;\n this.bindings = [].concat(bindings);\n this.result = result;\n }\n evaluate(ctx) {\n return this.result.evaluate(ctx);\n }\n eachChild(fn) {\n for (const binding of this.bindings) {\n fn(binding[1]);\n }\n fn(this.result);\n }\n static parse(args, context) {\n if (args.length < 4)\n return context.error(`Expected at least 3 arguments, but found ${args.length - 1} instead.`);\n const bindings = [];\n for (let i = 1; i < args.length - 1; i += 2) {\n const name = args[i];\n if (typeof name !== 'string') {\n return context.error(`Expected string, but found ${typeof name} instead.`, i);\n }\n if (/[^a-zA-Z0-9_]/.test(name)) {\n return context.error('Variable names must contain only alphanumeric characters or \\'_\\'.', i);\n }\n const value = context.parse(args[i + 1], i + 1);\n if (!value)\n return null;\n bindings.push([name, value]);\n }\n const result = context.parse(args[args.length - 1], args.length - 1, context.expectedType, bindings);\n if (!result)\n return null;\n return new Let(bindings, result);\n }\n outputDefined() {\n return this.result.outputDefined();\n }\n}\n\nclass Var {\n constructor(name, boundExpression) {\n this.type = boundExpression.type;\n this.name = name;\n this.boundExpression = boundExpression;\n }\n static parse(args, context) {\n if (args.length !== 2 || typeof args[1] !== 'string')\n return context.error('\\'var\\' expression requires exactly one string literal argument.');\n const name = args[1];\n if (!context.scope.has(name)) {\n return context.error(`Unknown variable \"${name}\". Make sure \"${name}\" has been bound in an enclosing \"let\" expression before using it.`, 1);\n }\n return new Var(name, context.scope.get(name));\n }\n evaluate(ctx) {\n return this.boundExpression.evaluate(ctx);\n }\n eachChild() { }\n outputDefined() {\n return false;\n }\n}\n\nclass At {\n constructor(type, index, input) {\n this.type = type;\n this.index = index;\n this.input = input;\n }\n static parse(args, context) {\n if (args.length !== 3)\n return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);\n const index = context.parse(args[1], 1, NumberType);\n const input = context.parse(args[2], 2, array$1(context.expectedType || ValueType));\n if (!index || !input)\n return null;\n const t = input.type;\n return new At(t.itemType, index, input);\n }\n evaluate(ctx) {\n const index = this.index.evaluate(ctx);\n const array = this.input.evaluate(ctx);\n if (index < 0) {\n throw new RuntimeError(`Array index out of bounds: ${index} < 0.`);\n }\n if (index >= array.length) {\n throw new RuntimeError(`Array index out of bounds: ${index} > ${array.length - 1}.`);\n }\n if (index !== Math.floor(index)) {\n throw new RuntimeError(`Array index must be an integer, but found ${index} instead.`);\n }\n return array[index];\n }\n eachChild(fn) {\n fn(this.index);\n fn(this.input);\n }\n outputDefined() {\n return false;\n }\n}\n\nclass In {\n constructor(needle, haystack) {\n this.type = BooleanType;\n this.needle = needle;\n this.haystack = haystack;\n }\n static parse(args, context) {\n if (args.length !== 3) {\n return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);\n }\n const needle = context.parse(args[1], 1, ValueType);\n const haystack = context.parse(args[2], 2, ValueType);\n if (!needle || !haystack)\n return null;\n if (!isValidType(needle.type, [BooleanType, StringType, NumberType, NullType, ValueType])) {\n return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(needle.type)} instead`);\n }\n return new In(needle, haystack);\n }\n evaluate(ctx) {\n const needle = this.needle.evaluate(ctx);\n const haystack = this.haystack.evaluate(ctx);\n if (!haystack)\n return false;\n if (!isValidNativeType(needle, ['boolean', 'string', 'number', 'null'])) {\n throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(typeOf(needle))} instead.`);\n }\n if (!isValidNativeType(haystack, ['string', 'array'])) {\n throw new RuntimeError(`Expected second argument to be of type array or string, but found ${toString$1(typeOf(haystack))} instead.`);\n }\n return haystack.indexOf(needle) >= 0;\n }\n eachChild(fn) {\n fn(this.needle);\n fn(this.haystack);\n }\n outputDefined() {\n return true;\n }\n}\n\nclass IndexOf {\n constructor(needle, haystack, fromIndex) {\n this.type = NumberType;\n this.needle = needle;\n this.haystack = haystack;\n this.fromIndex = fromIndex;\n }\n static parse(args, context) {\n if (args.length <= 2 || args.length >= 5) {\n return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`);\n }\n const needle = context.parse(args[1], 1, ValueType);\n const haystack = context.parse(args[2], 2, ValueType);\n if (!needle || !haystack)\n return null;\n if (!isValidType(needle.type, [BooleanType, StringType, NumberType, NullType, ValueType])) {\n return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(needle.type)} instead`);\n }\n if (args.length === 4) {\n const fromIndex = context.parse(args[3], 3, NumberType);\n if (!fromIndex)\n return null;\n return new IndexOf(needle, haystack, fromIndex);\n }\n else {\n return new IndexOf(needle, haystack);\n }\n }\n evaluate(ctx) {\n const needle = this.needle.evaluate(ctx);\n const haystack = this.haystack.evaluate(ctx);\n if (!isValidNativeType(needle, ['boolean', 'string', 'number', 'null'])) {\n throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(typeOf(needle))} instead.`);\n }\n let fromIndex;\n if (this.fromIndex) {\n fromIndex = this.fromIndex.evaluate(ctx);\n }\n if (isValidNativeType(haystack, ['string'])) {\n const rawIndex = haystack.indexOf(needle, fromIndex);\n if (rawIndex === -1) {\n return -1;\n }\n else {\n // The index may be affected by surrogate pairs, so get the length of the preceding substring.\n return [...haystack.slice(0, rawIndex)].length;\n }\n }\n else if (isValidNativeType(haystack, ['array'])) {\n return haystack.indexOf(needle, fromIndex);\n }\n else {\n throw new RuntimeError(`Expected second argument to be of type array or string, but found ${toString$1(typeOf(haystack))} instead.`);\n }\n }\n eachChild(fn) {\n fn(this.needle);\n fn(this.haystack);\n if (this.fromIndex) {\n fn(this.fromIndex);\n }\n }\n outputDefined() {\n return false;\n }\n}\n\nclass Match {\n constructor(inputType, outputType, input, cases, outputs, otherwise) {\n this.inputType = inputType;\n this.type = outputType;\n this.input = input;\n this.cases = cases;\n this.outputs = outputs;\n this.otherwise = otherwise;\n }\n static parse(args, context) {\n if (args.length < 5)\n return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n if (args.length % 2 !== 1)\n return context.error('Expected an even number of arguments.');\n let inputType;\n let outputType;\n if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n const cases = {};\n const outputs = [];\n for (let i = 2; i < args.length - 1; i += 2) {\n let labels = args[i];\n const value = args[i + 1];\n if (!Array.isArray(labels)) {\n labels = [labels];\n }\n const labelContext = context.concat(i);\n if (labels.length === 0) {\n return labelContext.error('Expected at least one branch label.');\n }\n for (const label of labels) {\n if (typeof label !== 'number' && typeof label !== 'string') {\n return labelContext.error('Branch labels must be numbers or strings.');\n }\n else if (typeof label === 'number' && Math.abs(label) > Number.MAX_SAFE_INTEGER) {\n return labelContext.error(`Branch labels must be integers no larger than ${Number.MAX_SAFE_INTEGER}.`);\n }\n else if (typeof label === 'number' && Math.floor(label) !== label) {\n return labelContext.error('Numeric branch labels must be integer values.');\n }\n else if (!inputType) {\n inputType = typeOf(label);\n }\n else if (labelContext.checkSubtype(inputType, typeOf(label))) {\n return null;\n }\n if (typeof cases[String(label)] !== 'undefined') {\n return labelContext.error('Branch labels must be unique.');\n }\n cases[String(label)] = outputs.length;\n }\n const result = context.parse(value, i, outputType);\n if (!result)\n return null;\n outputType = outputType || result.type;\n outputs.push(result);\n }\n const input = context.parse(args[1], 1, ValueType);\n if (!input)\n return null;\n const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);\n if (!otherwise)\n return null;\n if (input.type.kind !== 'value' && context.concat(1).checkSubtype(inputType, input.type)) {\n return null;\n }\n return new Match(inputType, outputType, input, cases, outputs, otherwise);\n }\n evaluate(ctx) {\n const input = this.input.evaluate(ctx);\n const output = (typeOf(input) === this.inputType && this.outputs[this.cases[input]]) || this.otherwise;\n return output.evaluate(ctx);\n }\n eachChild(fn) {\n fn(this.input);\n this.outputs.forEach(fn);\n fn(this.otherwise);\n }\n outputDefined() {\n return this.outputs.every(out => out.outputDefined()) && this.otherwise.outputDefined();\n }\n}\n\nclass Case {\n constructor(type, branches, otherwise) {\n this.type = type;\n this.branches = branches;\n this.otherwise = otherwise;\n }\n static parse(args, context) {\n if (args.length < 4)\n return context.error(`Expected at least 3 arguments, but found only ${args.length - 1}.`);\n if (args.length % 2 !== 0)\n return context.error('Expected an odd number of arguments.');\n let outputType;\n if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n const branches = [];\n for (let i = 1; i < args.length - 1; i += 2) {\n const test = context.parse(args[i], i, BooleanType);\n if (!test)\n return null;\n const result = context.parse(args[i + 1], i + 1, outputType);\n if (!result)\n return null;\n branches.push([test, result]);\n outputType = outputType || result.type;\n }\n const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);\n if (!otherwise)\n return null;\n if (!outputType)\n throw new Error('Can\\'t infer output type');\n return new Case(outputType, branches, otherwise);\n }\n evaluate(ctx) {\n for (const [test, expression] of this.branches) {\n if (test.evaluate(ctx)) {\n return expression.evaluate(ctx);\n }\n }\n return this.otherwise.evaluate(ctx);\n }\n eachChild(fn) {\n for (const [test, expression] of this.branches) {\n fn(test);\n fn(expression);\n }\n fn(this.otherwise);\n }\n outputDefined() {\n return this.branches.every(([_, out]) => out.outputDefined()) && this.otherwise.outputDefined();\n }\n}\n\nclass Slice {\n constructor(type, input, beginIndex, endIndex) {\n this.type = type;\n this.input = input;\n this.beginIndex = beginIndex;\n this.endIndex = endIndex;\n }\n static parse(args, context) {\n if (args.length <= 2 || args.length >= 5) {\n return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`);\n }\n const input = context.parse(args[1], 1, ValueType);\n const beginIndex = context.parse(args[2], 2, NumberType);\n if (!input || !beginIndex)\n return null;\n if (!isValidType(input.type, [array$1(ValueType), StringType, ValueType])) {\n return context.error(`Expected first argument to be of type array or string, but found ${toString$1(input.type)} instead`);\n }\n if (args.length === 4) {\n const endIndex = context.parse(args[3], 3, NumberType);\n if (!endIndex)\n return null;\n return new Slice(input.type, input, beginIndex, endIndex);\n }\n else {\n return new Slice(input.type, input, beginIndex);\n }\n }\n evaluate(ctx) {\n const input = this.input.evaluate(ctx);\n const beginIndex = this.beginIndex.evaluate(ctx);\n let endIndex;\n if (this.endIndex) {\n endIndex = this.endIndex.evaluate(ctx);\n }\n if (isValidNativeType(input, ['string'])) {\n // Indices may be affected by surrogate pairs.\n return [...input].slice(beginIndex, endIndex).join('');\n }\n else if (isValidNativeType(input, ['array'])) {\n return input.slice(beginIndex, endIndex);\n }\n else {\n throw new RuntimeError(`Expected first argument to be of type array or string, but found ${toString$1(typeOf(input))} instead.`);\n }\n }\n eachChild(fn) {\n fn(this.input);\n fn(this.beginIndex);\n if (this.endIndex) {\n fn(this.endIndex);\n }\n }\n outputDefined() {\n return false;\n }\n}\n\n/**\n * Returns the index of the last stop <= input, or 0 if it doesn't exist.\n * @private\n */\nfunction findStopLessThanOrEqualTo(stops, input) {\n const lastIndex = stops.length - 1;\n let lowerIndex = 0;\n let upperIndex = lastIndex;\n let currentIndex = 0;\n let currentValue, nextValue;\n while (lowerIndex <= upperIndex) {\n currentIndex = Math.floor((lowerIndex + upperIndex) / 2);\n currentValue = stops[currentIndex];\n nextValue = stops[currentIndex + 1];\n if (currentValue <= input) {\n if (currentIndex === lastIndex || input < nextValue) { // Search complete\n return currentIndex;\n }\n lowerIndex = currentIndex + 1;\n }\n else if (currentValue > input) {\n upperIndex = currentIndex - 1;\n }\n else {\n throw new RuntimeError('Input is not a number.');\n }\n }\n return 0;\n}\n\nclass Step {\n constructor(type, input, stops) {\n this.type = type;\n this.input = input;\n this.labels = [];\n this.outputs = [];\n for (const [label, expression] of stops) {\n this.labels.push(label);\n this.outputs.push(expression);\n }\n }\n static parse(args, context) {\n if (args.length - 1 < 4) {\n return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n }\n if ((args.length - 1) % 2 !== 0) {\n return context.error('Expected an even number of arguments.');\n }\n const input = context.parse(args[1], 1, NumberType);\n if (!input)\n return null;\n const stops = [];\n let outputType = null;\n if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n for (let i = 1; i < args.length; i += 2) {\n const label = i === 1 ? -Infinity : args[i];\n const value = args[i + 1];\n const labelKey = i;\n const valueKey = i + 1;\n if (typeof label !== 'number') {\n 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 }\n if (stops.length && stops[stops.length - 1][0] >= label) {\n return context.error('Input/output pairs for \"step\" expressions must be arranged with input values in strictly ascending order.', labelKey);\n }\n const parsed = context.parse(value, valueKey, outputType);\n if (!parsed)\n return null;\n outputType = outputType || parsed.type;\n stops.push([label, parsed]);\n }\n return new Step(outputType, input, stops);\n }\n evaluate(ctx) {\n const labels = this.labels;\n const outputs = this.outputs;\n if (labels.length === 1) {\n return outputs[0].evaluate(ctx);\n }\n const value = this.input.evaluate(ctx);\n if (value <= labels[0]) {\n return outputs[0].evaluate(ctx);\n }\n const stopCount = labels.length;\n if (value >= labels[stopCount - 1]) {\n return outputs[stopCount - 1].evaluate(ctx);\n }\n const index = findStopLessThanOrEqualTo(labels, value);\n return outputs[index].evaluate(ctx);\n }\n eachChild(fn) {\n fn(this.input);\n for (const expression of this.outputs) {\n fn(expression);\n }\n }\n outputDefined() {\n return this.outputs.every(out => out.outputDefined());\n }\n}\n\nfunction getDefaultExportFromCjs (x) {\n\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\n}\n\nvar unitbezier = UnitBezier;\n\nfunction UnitBezier(p1x, p1y, p2x, p2y) {\n // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).\n this.cx = 3.0 * p1x;\n this.bx = 3.0 * (p2x - p1x) - this.cx;\n this.ax = 1.0 - this.cx - this.bx;\n\n this.cy = 3.0 * p1y;\n this.by = 3.0 * (p2y - p1y) - this.cy;\n this.ay = 1.0 - this.cy - this.by;\n\n this.p1x = p1x;\n this.p1y = p1y;\n this.p2x = p2x;\n this.p2y = p2y;\n}\n\nUnitBezier.prototype = {\n sampleCurveX: function (t) {\n // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.\n return ((this.ax * t + this.bx) * t + this.cx) * t;\n },\n\n sampleCurveY: function (t) {\n return ((this.ay * t + this.by) * t + this.cy) * t;\n },\n\n sampleCurveDerivativeX: function (t) {\n return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;\n },\n\n solveCurveX: function (x, epsilon) {\n if (epsilon === undefined) epsilon = 1e-6;\n\n if (x < 0.0) return 0.0;\n if (x > 1.0) return 1.0;\n\n var t = x;\n\n // First try a few iterations of Newton's method - normally very fast.\n for (var i = 0; i < 8; i++) {\n var x2 = this.sampleCurveX(t) - x;\n if (Math.abs(x2) < epsilon) return t;\n\n var d2 = this.sampleCurveDerivativeX(t);\n if (Math.abs(d2) < 1e-6) break;\n\n t = t - x2 / d2;\n }\n\n // Fall back to the bisection method for reliability.\n var t0 = 0.0;\n var t1 = 1.0;\n t = x;\n\n for (i = 0; i < 20; i++) {\n x2 = this.sampleCurveX(t);\n if (Math.abs(x2 - x) < epsilon) break;\n\n if (x > x2) {\n t0 = t;\n } else {\n t1 = t;\n }\n\n t = (t1 - t0) * 0.5 + t0;\n }\n\n return t;\n },\n\n solve: function (x, epsilon) {\n return this.sampleCurveY(this.solveCurveX(x, epsilon));\n }\n};\n\nvar UnitBezier$1 = /*@__PURE__*/getDefaultExportFromCjs(unitbezier);\n\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 return colorSpace === 'rgb' || colorSpace === 'hcl' || colorSpace === 'lab';\n}\n/**\n * @param interpolationType Interpolation type\n * @returns interpolation fn\n * @deprecated use `interpolate[type]` instead\n */\nconst interpolateFactory = (interpolationType) => {\n switch (interpolationType) {\n case 'number': return number;\n case 'color': return color;\n case 'array': return array;\n case 'padding': return padding;\n case 'variableAnchorOffsetCollection': return variableAnchorOffsetCollection;\n }\n};\nfunction number(from, to, t) {\n return from + t * (to - from);\n}\nfunction color(from, to, t, spaceKey = 'rgb') {\n switch (spaceKey) {\n case 'rgb': {\n const [r, g, b, alpha] = array(from.rgb, to.rgb, t);\n return new Color(r, g, b, alpha, false);\n }\n case 'hcl': {\n const [hue0, chroma0, light0, alphaF] = from.hcl;\n const [hue1, chroma1, light1, alphaT] = to.hcl;\n // https://github.com/gka/chroma.js/blob/cd1b3c0926c7a85cbdc3b1453b3a94006de91a92/src/interpolator/_hsx.js\n let hue, chroma;\n if (!isNaN(hue0) && !isNaN(hue1)) {\n let dh = hue1 - hue0;\n if (hue1 > hue0 && dh > 180) {\n dh -= 360;\n }\n else if (hue1 < hue0 && hue0 - hue1 > 180) {\n dh += 360;\n }\n hue = hue0 + t * dh;\n }\n else if (!isNaN(hue0)) {\n hue = hue0;\n if (light1 === 1 || light1 === 0)\n chroma = chroma0;\n }\n else if (!isNaN(hue1)) {\n hue = hue1;\n if (light0 === 1 || light0 === 0)\n chroma = chroma1;\n }\n else {\n hue = NaN;\n }\n const [r, g, b, alpha] = hclToRgb([\n hue,\n chroma !== null && chroma !== void 0 ? chroma : number(chroma0, chroma1, t),\n number(light0, light1, t),\n number(alphaF, alphaT, t),\n ]);\n return new Color(r, g, b, alpha, false);\n }\n case 'lab': {\n const [r, g, b, alpha] = labToRgb(array(from.lab, to.lab, t));\n return new Color(r, g, b, alpha, false);\n }\n }\n}\nfunction array(from, to, t) {\n return from.map((d, i) => {\n return number(d, to[i], t);\n });\n}\nfunction padding(from, to, t) {\n return new Padding(array(from.values, to.values, t));\n}\nfunction variableAnchorOffsetCollection(from, to, t) {\n const fromValues = from.values;\n const toValues = to.values;\n if (fromValues.length !== toValues.length) {\n throw new RuntimeError(`Cannot interpolate values of different length. from: ${from.toString()}, to: ${to.toString()}`);\n }\n const output = [];\n for (let i = 0; i < fromValues.length; i += 2) {\n // Anchor entries must match\n if (fromValues[i] !== toValues[i]) {\n throw new RuntimeError(`Cannot interpolate values containing mismatched anchors. from[${i}]: ${fromValues[i]}, to[${i}]: ${toValues[i]}`);\n }\n output.push(fromValues[i]);\n // Interpolate the offset values for each anchor\n const [fx, fy] = fromValues[i + 1];\n const [tx, ty] = toValues[i + 1];\n output.push([number(fx, tx, t), number(fy, ty, t)]);\n }\n return new VariableAnchorOffsetCollection(output);\n}\nconst interpolate = {\n number,\n color,\n array,\n padding,\n variableAnchorOffsetCollection\n};\n\nclass Interpolate {\n constructor(type, operator, interpolation, input, stops) {\n this.type = type;\n this.operator = operator;\n this.interpolation = interpolation;\n this.input = input;\n this.labels = [];\n this.outputs = [];\n for (const [label, expression] of stops) {\n this.labels.push(label);\n this.outputs.push(expression);\n }\n }\n static interpolationFactor(interpolation, input, lower, upper) {\n let t = 0;\n if (interpolation.name === 'exponential') {\n t = exponentialInterpolation(input, interpolation.base, lower, upper);\n }\n else if (interpolation.name === 'linear') {\n t = exponentialInterpolation(input, 1, lower, upper);\n }\n else if (interpolation.name === 'cubic-bezier') {\n const c = interpolation.controlPoints;\n const ub = new UnitBezier$1(c[0], c[1], c[2], c[3]);\n t = ub.solve(exponentialInterpolation(input, 1, lower, upper));\n }\n return t;\n }\n static parse(args, context) {\n let [operator, interpolation, input, ...rest] = args;\n if (!Array.isArray(interpolation) || interpolation.length === 0) {\n return context.error('Expected an interpolation type expression.', 1);\n }\n if (interpolation[0] === 'linear') {\n interpolation = { name: 'linear' };\n }\n else if (interpolation[0] === 'exponential') {\n const base = interpolation[1];\n if (typeof base !== 'number')\n return context.error('Exponential interpolation requires a numeric base.', 1, 1);\n interpolation = {\n name: 'exponential',\n base\n };\n }\n else if (interpolation[0] === 'cubic-bezier') {\n const controlPoints = interpolation.slice(1);\n if (controlPoints.length !== 4 ||\n controlPoints.some(t => typeof t !== 'number' || t < 0 || t > 1)) {\n return context.error('Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.', 1);\n }\n interpolation = {\n name: 'cubic-bezier',\n controlPoints: controlPoints\n };\n }\n else {\n return context.error(`Unknown interpolation type ${String(interpolation[0])}`, 1, 0);\n }\n if (args.length - 1 < 4) {\n return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n }\n if ((args.length - 1) % 2 !== 0) {\n return context.error('Expected an even number of arguments.');\n }\n input = context.parse(input, 2, NumberType);\n if (!input)\n return null;\n const stops = [];\n let outputType = null;\n if (operator === 'interpolate-hcl' || operator === 'interpolate-lab') {\n outputType = ColorType;\n }\n else if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n for (let i = 0; i < rest.length; i += 2) {\n const label = rest[i];\n const value = rest[i + 1];\n const labelKey = i + 3;\n const valueKey = i + 4;\n if (typeof label !== 'number') {\n 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 }\n if (stops.length && stops[stops.length - 1][0] >= label) {\n return context.error('Input/output pairs for \"interpolate\" expressions must be arranged with input values in strictly ascending order.', labelKey);\n }\n const parsed = context.parse(value, valueKey, outputType);\n if (!parsed)\n return null;\n outputType = outputType || parsed.type;\n stops.push([label, parsed]);\n }\n if (!verifyType(outputType, NumberType) &&\n !verifyType(outputType, ColorType) &&\n !verifyType(outputType, PaddingType) &&\n !verifyType(outputType, VariableAnchorOffsetCollectionType) &&\n !verifyType(outputType, array$1(NumberType))) {\n return context.error(`Type ${toString$1(outputType)} is not interpolatable.`);\n }\n return new Interpolate(outputType, operator, interpolation, input, stops);\n }\n evaluate(ctx) {\n const labels = this.labels;\n const outputs = this.outputs;\n if (labels.length === 1) {\n return outputs[0].evaluate(ctx);\n }\n const value = this.input.evaluate(ctx);\n if (value <= labels[0]) {\n return outputs[0].evaluate(ctx);\n }\n const stopCount = labels.length;\n if (value >= labels[stopCount - 1]) {\n return outputs[stopCount - 1].evaluate(ctx);\n }\n const index = findStopLessThanOrEqualTo(labels, value);\n const lower = labels[index];\n const upper = labels[index + 1];\n const t = Interpolate.interpolationFactor(this.interpolation, value, lower, upper);\n const outputLower = outputs[index].evaluate(ctx);\n const outputUpper = outputs[index + 1].evaluate(ctx);\n switch (this.operator) {\n case 'interpolate':\n return interpolate[this.type.kind](outputLower, outputUpper, t);\n case 'interpolate-hcl':\n return interpolate.color(outputLower, outputUpper, t, 'hcl');\n case 'interpolate-lab':\n return interpolate.color(outputLower, outputUpper, t, 'lab');\n }\n }\n eachChild(fn) {\n fn(this.input);\n for (const expression of this.outputs) {\n fn(expression);\n }\n }\n outputDefined() {\n return this.outputs.every(out => out.outputDefined());\n }\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 const difference = upperValue - lowerValue;\n const progress = input - lowerValue;\n if (difference === 0) {\n return 0;\n }\n else if (base === 1) {\n return progress / difference;\n }\n else {\n return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);\n }\n}\n\nclass Coalesce {\n constructor(type, args) {\n this.type = type;\n this.args = args;\n }\n static parse(args, context) {\n if (args.length < 2) {\n return context.error('Expectected at least one argument.');\n }\n let outputType = null;\n const expectedType = context.expectedType;\n if (expectedType && expectedType.kind !== 'value') {\n outputType = expectedType;\n }\n const parsedArgs = [];\n for (const arg of args.slice(1)) {\n const parsed = context.parse(arg, 1 + parsedArgs.length, outputType, undefined, { typeAnnotation: 'omit' });\n if (!parsed)\n return null;\n outputType = outputType || parsed.type;\n parsedArgs.push(parsed);\n }\n if (!outputType)\n throw new Error('No output type');\n // Above, we parse arguments without inferred type annotation so that\n // they don't produce a runtime error for `null` input, which would\n // preempt the desired null-coalescing behavior.\n // Thus, if any of our arguments would have needed an annotation, we\n // need to wrap the enclosing coalesce expression with it instead.\n const needsAnnotation = expectedType &&\n parsedArgs.some(arg => checkSubtype(expectedType, arg.type));\n return needsAnnotation ?\n new Coalesce(ValueType, parsedArgs) :\n new Coalesce(outputType, parsedArgs);\n }\n evaluate(ctx) {\n let result = null;\n let argCount = 0;\n let requestedImageName;\n for (const arg of this.args) {\n argCount++;\n result = arg.evaluate(ctx);\n // we need to keep track of the first requested image in a coalesce statement\n // if coalesce can't find a valid image, we return the first image name so styleimagemissing can fire\n if (result && result instanceof ResolvedImage && !result.available) {\n if (!requestedImageName) {\n requestedImageName = result.name;\n }\n result = null;\n if (argCount === this.args.length) {\n result = requestedImageName;\n }\n }\n if (result !== null)\n break;\n }\n return result;\n }\n eachChild(fn) {\n this.args.forEach(fn);\n }\n outputDefined() {\n return this.args.every(arg => arg.outputDefined());\n }\n}\n\nfunction isComparableType(op, type) {\n if (op === '==' || op === '!=') {\n // equality operator\n return type.kind === 'boolean' ||\n type.kind === 'string' ||\n type.kind === 'number' ||\n type.kind === 'null' ||\n type.kind === 'value';\n }\n else {\n // ordering operator\n return type.kind === 'string' ||\n type.kind === 'number' ||\n type.kind === 'value';\n }\n}\nfunction eq(ctx, a, b) { return a === b; }\nfunction neq(ctx, a, b) { return a !== b; }\nfunction lt(ctx, a, b) { return a < b; }\nfunction gt(ctx, a, b) { return a > b; }\nfunction lteq(ctx, a, b) { return a <= b; }\nfunction gteq(ctx, a, b) { return a >= b; }\nfunction eqCollate(ctx, a, b, c) { return c.compare(a, b) === 0; }\nfunction neqCollate(ctx, a, b, c) { return !eqCollate(ctx, a, b, c); }\nfunction ltCollate(ctx, a, b, c) { return c.compare(a, b) < 0; }\nfunction gtCollate(ctx, a, b, c) { return c.compare(a, b) > 0; }\nfunction lteqCollate(ctx, a, b, c) { return c.compare(a, b) <= 0; }\nfunction gteqCollate(ctx, a, b, c) { return c.compare(a, b) >= 0; }\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 const isOrderComparison = op !== '==' && op !== '!=';\n return class Comparison {\n constructor(lhs, rhs, collator) {\n this.type = BooleanType;\n this.lhs = lhs;\n this.rhs = rhs;\n this.collator = collator;\n this.hasUntypedArgument = lhs.type.kind === 'value' || rhs.type.kind === 'value';\n }\n static parse(args, context) {\n if (args.length !== 3 && args.length !== 4)\n return context.error('Expected two or three arguments.');\n const op = args[0];\n let lhs = context.parse(args[1], 1, ValueType);\n if (!lhs)\n return null;\n if (!isComparableType(op, lhs.type)) {\n return context.concat(1).error(`\"${op}\" comparisons are not supported for type '${toString$1(lhs.type)}'.`);\n }\n let rhs = context.parse(args[2], 2, ValueType);\n if (!rhs)\n return null;\n if (!isComparableType(op, rhs.type)) {\n return context.concat(2).error(`\"${op}\" comparisons are not supported for type '${toString$1(rhs.type)}'.`);\n }\n if (lhs.type.kind !== rhs.type.kind &&\n lhs.type.kind !== 'value' &&\n rhs.type.kind !== 'value') {\n return context.error(`Cannot compare types '${toString$1(lhs.type)}' and '${toString$1(rhs.type)}'.`);\n }\n if (isOrderComparison) {\n // typing rules specific to less/greater than operators\n if (lhs.type.kind === 'value' && rhs.type.kind !== 'value') {\n // (value, T)\n lhs = new Assertion(rhs.type, [lhs]);\n }\n else if (lhs.type.kind !== 'value' && rhs.type.kind === 'value') {\n // (T, value)\n rhs = new Assertion(lhs.type, [rhs]);\n }\n }\n let collator = null;\n if (args.length === 4) {\n if (lhs.type.kind !== 'string' &&\n rhs.type.kind !== 'string' &&\n lhs.type.kind !== 'value' &&\n rhs.type.kind !== 'value') {\n return context.error('Cannot use collator to compare non-string types.');\n }\n collator = context.parse(args[3], 3, CollatorType);\n if (!collator)\n return null;\n }\n return new Comparison(lhs, rhs, collator);\n }\n evaluate(ctx) {\n const lhs = this.lhs.evaluate(ctx);\n const rhs = this.rhs.evaluate(ctx);\n if (isOrderComparison && this.hasUntypedArgument) {\n const lt = typeOf(lhs);\n const rt = typeOf(rhs);\n // check that type is string or number, and equal\n if (lt.kind !== rt.kind || !(lt.kind === 'string' || lt.kind === 'number')) {\n throw new RuntimeError(`Expected arguments for \"${op}\" to be (string, string) or (number, number), but found (${lt.kind}, ${rt.kind}) instead.`);\n }\n }\n if (this.collator && !isOrderComparison && this.hasUntypedArgument) {\n const lt = typeOf(lhs);\n const rt = typeOf(rhs);\n if (lt.kind !== 'string' || rt.kind !== 'string') {\n return compareBasic(ctx, lhs, rhs);\n }\n }\n return this.collator ?\n compareWithCollator(ctx, lhs, rhs, this.collator.evaluate(ctx)) :\n compareBasic(ctx, lhs, rhs);\n }\n eachChild(fn) {\n fn(this.lhs);\n fn(this.rhs);\n if (this.collator) {\n fn(this.collator);\n }\n }\n outputDefined() {\n return true;\n }\n };\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\nclass CollatorExpression {\n constructor(caseSensitive, diacriticSensitive, locale) {\n this.type = CollatorType;\n this.locale = locale;\n this.caseSensitive = caseSensitive;\n this.diacriticSensitive = diacriticSensitive;\n }\n static parse(args, context) {\n if (args.length !== 2)\n return context.error('Expected one argument.');\n const options = args[1];\n if (typeof options !== 'object' || Array.isArray(options))\n return context.error('Collator options argument must be an object.');\n const caseSensitive = context.parse(options['case-sensitive'] === undefined ? false : options['case-sensitive'], 1, BooleanType);\n if (!caseSensitive)\n return null;\n const diacriticSensitive = context.parse(options['diacritic-sensitive'] === undefined ? false : options['diacritic-sensitive'], 1, BooleanType);\n if (!diacriticSensitive)\n return null;\n let locale = null;\n if (options['locale']) {\n locale = context.parse(options['locale'], 1, StringType);\n if (!locale)\n return null;\n }\n return new CollatorExpression(caseSensitive, diacriticSensitive, locale);\n }\n evaluate(ctx) {\n return new Collator(this.caseSensitive.evaluate(ctx), this.diacriticSensitive.evaluate(ctx), this.locale ? this.locale.evaluate(ctx) : null);\n }\n eachChild(fn) {\n fn(this.caseSensitive);\n fn(this.diacriticSensitive);\n if (this.locale) {\n fn(this.locale);\n }\n }\n outputDefined() {\n // Technically the set of possible outputs is the combinatoric set of Collators produced\n // by all possible outputs of locale/caseSensitive/diacriticSensitive\n // But for the primary use of Collators in comparison operators, we ignore the Collator's\n // possible outputs anyway, so we can get away with leaving this false for now.\n return false;\n }\n}\n\nclass NumberFormat {\n constructor(number, locale, currency, minFractionDigits, maxFractionDigits) {\n this.type = StringType;\n this.number = number;\n this.locale = locale;\n this.currency = currency;\n this.minFractionDigits = minFractionDigits;\n this.maxFractionDigits = maxFractionDigits;\n }\n static parse(args, context) {\n if (args.length !== 3)\n return context.error('Expected two arguments.');\n const number = context.parse(args[1], 1, NumberType);\n if (!number)\n return null;\n const options = args[2];\n if (typeof options !== 'object' || Array.isArray(options))\n return context.error('NumberFormat options argument must be an object.');\n let locale = null;\n if (options['locale']) {\n locale = context.parse(options['locale'], 1, StringType);\n if (!locale)\n return null;\n }\n let currency = null;\n if (options['currency']) {\n currency = context.parse(options['currency'], 1, StringType);\n if (!currency)\n return null;\n }\n let minFractionDigits = null;\n if (options['min-fraction-digits']) {\n minFractionDigits = context.parse(options['min-fraction-digits'], 1, NumberType);\n if (!minFractionDigits)\n return null;\n }\n let maxFractionDigits = null;\n if (options['max-fraction-digits']) {\n maxFractionDigits = context.parse(options['max-fraction-digits'], 1, NumberType);\n if (!maxFractionDigits)\n return null;\n }\n return new NumberFormat(number, locale, currency, minFractionDigits, maxFractionDigits);\n }\n evaluate(ctx) {\n return new Intl.NumberFormat(this.locale ? this.locale.evaluate(ctx) : [], {\n style: this.currency ? 'currency' : 'decimal',\n currency: this.currency ? this.currency.evaluate(ctx) : undefined,\n minimumFractionDigits: this.minFractionDigits ? this.minFractionDigits.evaluate(ctx) : undefined,\n maximumFractionDigits: this.maxFractionDigits ? this.maxFractionDigits.evaluate(ctx) : undefined,\n }).format(this.number.evaluate(ctx));\n }\n eachChild(fn) {\n fn(this.number);\n if (this.locale) {\n fn(this.locale);\n }\n if (this.currency) {\n fn(this.currency);\n }\n if (this.minFractionDigits) {\n fn(this.minFractionDigits);\n }\n if (this.maxFractionDigits) {\n fn(this.maxFractionDigits);\n }\n }\n outputDefined() {\n return false;\n }\n}\n\nclass FormatExpression {\n constructor(sections) {\n this.type = FormattedType;\n this.sections = sections;\n }\n static parse(args, context) {\n if (args.length < 2) {\n return context.error('Expected at least one argument.');\n }\n const firstArg = args[1];\n if (!Array.isArray(firstArg) && typeof firstArg === 'object') {\n return context.error('First argument must be an image or text section.');\n }\n const sections = [];\n let nextTokenMayBeObject = false;\n for (let i = 1; i <= args.length - 1; ++i) {\n const arg = args[i];\n if (nextTokenMayBeObject && typeof arg === 'object' && !Array.isArray(arg)) {\n nextTokenMayBeObject = false;\n let scale = null;\n if (arg['font-scale']) {\n scale = context.parse(arg['font-scale'], 1, NumberType);\n if (!scale)\n return null;\n }\n let font = null;\n if (arg['text-font']) {\n font = context.parse(arg['text-font'], 1, array$1(StringType));\n if (!font)\n return null;\n }\n let textColor = null;\n if (arg['text-color']) {\n textColor = context.parse(arg['text-color'], 1, ColorType);\n if (!textColor)\n return null;\n }\n const lastExpression = sections[sections.length - 1];\n lastExpression.scale = scale;\n lastExpression.font = font;\n lastExpression.textColor = textColor;\n }\n else {\n const content = context.parse(args[i], 1, ValueType);\n if (!content)\n return null;\n const kind = content.type.kind;\n if (kind !== 'string' && kind !== 'value' && kind !== 'null' && kind !== 'resolvedImage')\n return context.error('Formatted text type must be \\'string\\', \\'value\\', \\'image\\' or \\'null\\'.');\n nextTokenMayBeObject = true;\n sections.push({ content, scale: null, font: null, textColor: null });\n }\n }\n return new FormatExpression(sections);\n }\n evaluate(ctx) {\n const evaluateSection = section => {\n const evaluatedContent = section.content.evaluate(ctx);\n if (typeOf(evaluatedContent) === ResolvedImageType) {\n return new FormattedSection('', evaluatedContent, null, null, null);\n }\n return new FormattedSection(toString(evaluatedContent), null, section.scale ? section.scale.evaluate(ctx) : null, section.font ? section.font.evaluate(ctx).join(',') : null, section.textColor ? section.textColor.evaluate(ctx) : null);\n };\n return new Formatted(this.sections.map(evaluateSection));\n }\n eachChild(fn) {\n for (const section of this.sections) {\n fn(section.content);\n if (section.scale) {\n fn(section.scale);\n }\n if (section.font) {\n fn(section.font);\n }\n if (section.textColor) {\n fn(section.textColor);\n }\n }\n }\n outputDefined() {\n // Technically the combinatoric set of all children\n // Usually, this.text will be undefined anyway\n return false;\n }\n}\n\nclass ImageExpression {\n constructor(input) {\n this.type = ResolvedImageType;\n this.input = input;\n }\n static parse(args, context) {\n if (args.length !== 2) {\n return context.error('Expected two arguments.');\n }\n const name = context.parse(args[1], 1, StringType);\n if (!name)\n return context.error('No image name provided.');\n return new ImageExpression(name);\n }\n evaluate(ctx) {\n const evaluatedImageName = this.input.evaluate(ctx);\n const value = ResolvedImage.fromString(evaluatedImageName);\n if (value && ctx.availableImages)\n value.available = ctx.availableImages.indexOf(evaluatedImageName) > -1;\n return value;\n }\n eachChild(fn) {\n fn(this.input);\n }\n outputDefined() {\n // The output of image is determined by the list of available images in the evaluation context\n return false;\n }\n}\n\nclass Length {\n constructor(input) {\n this.type = NumberType;\n this.input = input;\n }\n static parse(args, context) {\n if (args.length !== 2)\n return context.error(`Expected 1 argument, but found ${args.length - 1} instead.`);\n const input = context.parse(args[1], 1);\n if (!input)\n return null;\n if (input.type.kind !== 'array' && input.type.kind !== 'string' && input.type.kind !== 'value')\n return context.error(`Expected argument of type string or array, but found ${toString$1(input.type)} instead.`);\n return new Length(input);\n }\n evaluate(ctx) {\n const input = this.input.evaluate(ctx);\n if (typeof input === 'string') {\n // The length may be affected by surrogate pairs.\n return [...input].length;\n }\n else if (Array.isArray(input)) {\n return input.length;\n }\n else {\n throw new RuntimeError(`Expected value to be of type string or array, but found ${toString$1(typeOf(input))} instead.`);\n }\n }\n eachChild(fn) {\n fn(this.input);\n }\n outputDefined() {\n return false;\n }\n}\n\nconst EXTENT = 8192;\nfunction getTileCoordinates(p, canonical) {\n const x = mercatorXfromLng(p[0]);\n const y = mercatorYfromLat(p[1]);\n const tilesAtZoom = Math.pow(2, canonical.z);\n return [Math.round(x * tilesAtZoom * EXTENT), Math.round(y * tilesAtZoom * EXTENT)];\n}\nfunction getLngLatFromTileCoord(coord, canonical) {\n const tilesAtZoom = Math.pow(2, canonical.z);\n const x = (coord[0] / EXTENT + canonical.x) / tilesAtZoom;\n const y = (coord[1] / EXTENT + canonical.y) / tilesAtZoom;\n return [lngFromMercatorXfromLng(x), latFromMercatorY(y)];\n}\nfunction mercatorXfromLng(lng) {\n return (180 + lng) / 360;\n}\nfunction lngFromMercatorXfromLng(mercatorX) {\n return mercatorX * 360 - 180;\n}\nfunction mercatorYfromLat(lat) {\n return (180 - (180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)))) / 360;\n}\nfunction latFromMercatorY(mercatorY) {\n return 360 / Math.PI * Math.atan(Math.exp((180 - mercatorY * 360) * Math.PI / 180)) - 90;\n}\nfunction updateBBox(bbox, coord) {\n bbox[0] = Math.min(bbox[0], coord[0]);\n bbox[1] = Math.min(bbox[1], coord[1]);\n bbox[2] = Math.max(bbox[2], coord[0]);\n bbox[3] = Math.max(bbox[3], coord[1]);\n}\nfunction boxWithinBox(bbox1, bbox2) {\n if (bbox1[0] <= bbox2[0])\n return false;\n if (bbox1[2] >= bbox2[2])\n return false;\n if (bbox1[1] <= bbox2[1])\n return false;\n if (bbox1[3] >= bbox2[3])\n return false;\n return true;\n}\nfunction rayIntersect(p, p1, p2) {\n return ((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 const x1 = p[0] - p1[0];\n const y1 = p[1] - p1[1];\n const x2 = p[0] - p2[0];\n const y2 = p[1] - p2[1];\n return (x1 * y2 - x2 * y1 === 0) && (x1 * x2 <= 0) && (y1 * y2 <= 0);\n}\n// a, b are end points for line segment1, c and d are end points for line segment2\nfunction segmentIntersectSegment(a, b, c, d) {\n // check if two segments are parallel or not\n // precondition is end point a, b is inside polygon, if line a->b is\n // parallel to polygon edge c->d, then a->b won't intersect with c->d\n const vectorP = [b[0] - a[0], b[1] - a[1]];\n const vectorQ = [d[0] - c[0], d[1] - c[1]];\n if (perp(vectorQ, vectorP) === 0)\n return false;\n // If lines are intersecting with each other, the relative location should be:\n // a and b lie in different sides of segment c->d\n // c and d lie in different sides of segment a->b\n if (twoSided(a, b, c, d) && twoSided(c, d, a, b))\n return true;\n return false;\n}\nfunction lineIntersectPolygon(p1, p2, polygon) {\n for (const ring of polygon) {\n // loop through every edge of the ring\n for (let j = 0; j < ring.length - 1; ++j) {\n if (segmentIntersectSegment(p1, p2, ring[j], ring[j + 1])) {\n return true;\n }\n }\n }\n return false;\n}\n// ray casting algorithm for detecting if point is in polygon\nfunction pointWithinPolygon(point, rings, trueIfOnBoundary = false) {\n let inside = false;\n for (const ring of rings) {\n for (let j = 0; j < ring.length - 1; j++) {\n if (pointOnBoundary(point, ring[j], ring[j + 1]))\n return trueIfOnBoundary;\n if (rayIntersect(point, ring[j], ring[j + 1]))\n inside = !inside;\n }\n }\n return inside;\n}\nfunction pointWithinPolygons(point, polygons) {\n for (const polygon of polygons) {\n if (pointWithinPolygon(point, polygon))\n return true;\n }\n return false;\n}\nfunction lineStringWithinPolygon(line, polygon) {\n // First, check if geometry points of line segments are all inside polygon\n for (const point of line) {\n if (!pointWithinPolygon(point, polygon)) {\n return false;\n }\n }\n // Second, check if there is line segment intersecting polygon edge\n for (let i = 0; i < line.length - 1; ++i) {\n if (lineIntersectPolygon(line[i], line[i + 1], polygon)) {\n return false;\n }\n }\n return true;\n}\nfunction lineStringWithinPolygons(line, polygons) {\n for (const polygon of polygons) {\n if (lineStringWithinPolygon(line, polygon))\n return true;\n }\n return false;\n}\nfunction perp(v1, v2) {\n return (v1[0] * v2[1] - v1[1] * v2[0]);\n}\n// check if p1 and p2 are in different sides of line segment q1->q2\nfunction twoSided(p1, p2, q1, q2) {\n // q1->p1 (x1, y1), q1->p2 (x2, y2), q1->q2 (x3, y3)\n const x1 = p1[0] - q1[0];\n const y1 = p1[1] - q1[1];\n const x2 = p2[0] - q1[0];\n const y2 = p2[1] - q1[1];\n const x3 = q2[0] - q1[0];\n const y3 = q2[1] - q1[1];\n const det1 = (x1 * y3 - x3 * y1);\n const det2 = (x2 * y3 - x3 * y2);\n if ((det1 > 0 && det2 < 0) || (det1 < 0 && det2 > 0))\n return true;\n return false;\n}\n\nfunction getTilePolygon(coordinates, bbox, canonical) {\n const polygon = [];\n for (let i = 0; i < coordinates.length; i++) {\n const ring = [];\n for (let j = 0; j < coordinates[i].length; j++) {\n const coord = getTileCoordinates(coordinates[i][j], canonical);\n updateBBox(bbox, coord);\n ring.push(coord);\n }\n polygon.push(ring);\n }\n return polygon;\n}\nfunction getTilePolygons(coordinates, bbox, canonical) {\n const polygons = [];\n for (let i = 0; i < coordinates.length; i++) {\n const polygon = getTilePolygon(coordinates[i], bbox, canonical);\n polygons.push(polygon);\n }\n return polygons;\n}\nfunction updatePoint(p, bbox, polyBBox, worldSize) {\n if (p[0] < polyBBox[0] || p[0] > polyBBox[2]) {\n const halfWorldSize = worldSize * 0.5;\n let shift = (p[0] - polyBBox[0] > halfWorldSize) ? -worldSize : (polyBBox[0] - p[0] > halfWorldSize) ? worldSize : 0;\n if (shift === 0) {\n shift = (p[0] - polyBBox[2] > halfWorldSize) ? -worldSize : (polyBBox[2] - p[0] > halfWorldSize) ? worldSize : 0;\n }\n p[0] += shift;\n }\n updateBBox(bbox, p);\n}\nfunction resetBBox(bbox) {\n bbox[0] = bbox[1] = Infinity;\n bbox[2] = bbox[3] = -Infinity;\n}\nfunction getTilePoints(geometry, pointBBox, polyBBox, canonical) {\n const worldSize = Math.pow(2, canonical.z) * EXTENT;\n const shifts = [canonical.x * EXTENT, canonical.y * EXTENT];\n const tilePoints = [];\n for (const points of geometry) {\n for (const point of points) {\n const p = [point.x + shifts[0], point.y + shifts[1]];\n updatePoint(p, pointBBox, polyBBox, worldSize);\n tilePoints.push(p);\n }\n }\n return tilePoints;\n}\nfunction getTileLines(geometry, lineBBox, polyBBox, canonical) {\n const worldSize = Math.pow(2, canonical.z) * EXTENT;\n const shifts = [canonical.x * EXTENT, canonical.y * EXTENT];\n const tileLines = [];\n for (const line of geometry) {\n const tileLine = [];\n for (const point of line) {\n const p = [point.x + shifts[0], point.y + shifts[1]];\n updateBBox(lineBBox, p);\n tileLine.push(p);\n }\n tileLines.push(tileLine);\n }\n if (lineBBox[2] - lineBBox[0] <= worldSize / 2) {\n resetBBox(lineBBox);\n for (const line of tileLines) {\n for (const p of line) {\n updatePoint(p, lineBBox, polyBBox, worldSize);\n }\n }\n }\n return tileLines;\n}\nfunction pointsWithinPolygons(ctx, polygonGeometry) {\n const pointBBox = [Infinity, Infinity, -Infinity, -Infinity];\n const polyBBox = [Infinity, Infinity, -Infinity, -Infinity];\n const canonical = ctx.canonicalID();\n if (polygonGeometry.type === 'Polygon') {\n const tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);\n const tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);\n if (!boxWithinBox(pointBBox, polyBBox))\n return false;\n for (const point of tilePoints) {\n if (!pointWithinPolygon(point, tilePolygon))\n return false;\n }\n }\n if (polygonGeometry.type === 'MultiPolygon') {\n const tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);\n const tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);\n if (!boxWithinBox(pointBBox, polyBBox))\n return false;\n for (const point of tilePoints) {\n if (!pointWithinPolygons(point, tilePolygons))\n return false;\n }\n }\n return true;\n}\nfunction linesWithinPolygons(ctx, polygonGeometry) {\n const lineBBox = [Infinity, Infinity, -Infinity, -Infinity];\n const polyBBox = [Infinity, Infinity, -Infinity, -Infinity];\n const canonical = ctx.canonicalID();\n if (polygonGeometry.type === 'Polygon') {\n const tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);\n const tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);\n if (!boxWithinBox(lineBBox, polyBBox))\n return false;\n for (const line of tileLines) {\n if (!lineStringWithinPolygon(line, tilePolygon))\n return false;\n }\n }\n if (polygonGeometry.type === 'MultiPolygon') {\n const tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);\n const tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);\n if (!boxWithinBox(lineBBox, polyBBox))\n return false;\n for (const line of tileLines) {\n if (!lineStringWithinPolygons(line, tilePolygons))\n return false;\n }\n }\n return true;\n}\nclass Within {\n constructor(geojson, geometries) {\n this.type = BooleanType;\n this.geojson = geojson;\n this.geometries = geometries;\n }\n static parse(args, context) {\n if (args.length !== 2)\n return context.error(`'within' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n if (isValue(args[1])) {\n const geojson = args[1];\n if (geojson.type === 'FeatureCollection') {\n const polygonsCoords = [];\n for (const polygon of geojson.features) {\n const { type, coordinates } = polygon.geometry;\n if (type === 'Polygon') {\n polygonsCoords.push(coordinates);\n }\n if (type === 'MultiPolygon') {\n polygonsCoords.push(...coordinates);\n }\n }\n if (polygonsCoords.length) {\n const multipolygonWrapper = {\n type: 'MultiPolygon',\n coordinates: polygonsCoords\n };\n return new Within(geojson, multipolygonWrapper);\n }\n }\n else if (geojson.type === 'Feature') {\n const type = geojson.geometry.type;\n if (type === 'Polygon' || type === 'MultiPolygon') {\n return new Within(geojson, geojson.geometry);\n }\n }\n else if (geojson.type === 'Polygon' || geojson.type === 'MultiPolygon') {\n return new Within(geojson, geojson);\n }\n }\n return context.error('\\'within\\' expression requires valid geojson object that contains polygon geometry type.');\n }\n evaluate(ctx) {\n if (ctx.geometry() != null && ctx.canonicalID() != null) {\n if (ctx.geometryType() === 'Point') {\n return pointsWithinPolygons(ctx, this.geometries);\n }\n else if (ctx.geometryType() === 'LineString') {\n return linesWithinPolygons(ctx, this.geometries);\n }\n }\n return false;\n }\n eachChild() { }\n outputDefined() {\n return true;\n }\n}\n\nclass TinyQueue {\n constructor(data = [], compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0)) {\n this.data = data;\n this.length = this.data.length;\n this.compare = compare;\n\n if (this.length > 0) {\n for (let i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);\n }\n }\n\n push(item) {\n this.data.push(item);\n this._up(this.length++);\n }\n\n pop() {\n if (this.length === 0) return undefined;\n\n const top = this.data[0];\n const bottom = this.data.pop();\n\n if (--this.length > 0) {\n this.data[0] = bottom;\n this._down(0);\n }\n\n return top;\n }\n\n peek() {\n return this.data[0];\n }\n\n _up(pos) {\n const {data, compare} = this;\n const item = data[pos];\n\n while (pos > 0) {\n const parent = (pos - 1) >> 1;\n const current = data[parent];\n if (compare(item, current) >= 0) break;\n data[pos] = current;\n pos = parent;\n }\n\n data[pos] = item;\n }\n\n _down(pos) {\n const {data, compare} = this;\n const halfLength = this.length >> 1;\n const item = data[pos];\n\n while (pos < halfLength) {\n let bestChild = (pos << 1) + 1; // initially it is the left child\n const right = bestChild + 1;\n\n if (right < this.length && compare(data[right], data[bestChild]) < 0) {\n bestChild = right;\n }\n if (compare(data[bestChild], item) >= 0) break;\n\n data[pos] = data[bestChild];\n pos = bestChild;\n }\n\n data[pos] = item;\n }\n}\n\nfunction quickselect(arr, k, left, right, compare) {\n quickselectStep(arr, k, left, right || (arr.length - 1), compare || defaultCompare);\n}\n\nfunction quickselectStep(arr, k, left, right, compare) {\n\n while (right > left) {\n if (right - left > 600) {\n var n = right - left + 1;\n var m = k - left + 1;\n var z = Math.log(n);\n var s = 0.5 * Math.exp(2 * z / 3);\n var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselectStep(arr, k, newLeft, newRight, compare);\n }\n\n var t = arr[k];\n var i = left;\n var j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap(arr, i, j) {\n var tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\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 const len = rings.length;\n if (len <= 1)\n return [rings];\n const polygons = [];\n let polygon;\n let ccw;\n for (const ring of rings) {\n const area = calculateSignedArea(ring);\n if (area === 0)\n continue;\n ring.area = Math.abs(area);\n if (ccw === undefined)\n ccw = area < 0;\n if (ccw === area < 0) {\n if (polygon)\n polygons.push(polygon);\n polygon = [ring];\n }\n else {\n polygon.push(ring);\n }\n }\n if (polygon)\n polygons.push(polygon);\n // Earcut performance degrades with the # of rings in a polygon. For this\n // reason, we limit strip out all but the `maxRings` largest rings.\n if (maxRings > 1) {\n for (let j = 0; j < polygons.length; j++) {\n if (polygons[j].length <= maxRings)\n continue;\n quickselect(polygons[j], maxRings, 1, polygons[j].length - 1, compareAreas);\n polygons[j] = polygons[j].slice(0, maxRings);\n }\n }\n return polygons;\n}\nfunction compareAreas(a, b) {\n return 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 let sum = 0;\n for (let i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {\n p1 = ring[i];\n p2 = ring[j];\n sum += (p2.x - p1.x) * (p1.y + p2.y);\n }\n return sum;\n}\n\n// This is taken from https://github.com/mapbox/cheap-ruler/ in order to take only the relevant parts\n// Values that define WGS84 ellipsoid model of the Earth\nconst RE = 6378.137; // equatorial radius\nconst FE = 1 / 298.257223563; // flattening\nconst E2 = FE * (2 - FE);\nconst RAD = Math.PI / 180;\nclass CheapRuler {\n constructor(lat) {\n // Curvature formulas from https://en.wikipedia.org/wiki/Earth_radius#Meridional\n const m = RAD * RE * 1000;\n const coslat = Math.cos(lat * RAD);\n const w2 = 1 / (1 - E2 * (1 - coslat * coslat));\n const w = Math.sqrt(w2);\n // multipliers for converting longitude and latitude degrees into distance\n this.kx = m * w * coslat; // based on normal radius of curvature\n this.ky = m * w * w2 * (1 - E2); // based on meridonal radius of curvature\n }\n /**\n * Given two points of the form [longitude, latitude], returns the distance.\n *\n * @param a - point [longitude, latitude]\n * @param b - point [longitude, latitude]\n * @returns distance\n * @example\n * const distance = ruler.distance([30.5, 50.5], [30.51, 50.49]);\n * //=distance\n */\n distance(a, b) {\n const dx = this.wrap(a[0] - b[0]) * this.kx;\n const dy = (a[1] - b[1]) * this.ky;\n return Math.sqrt(dx * dx + dy * dy);\n }\n /**\n * Returns an object of the form {point, index, t}, where point is closest point on the line\n * from the given point, index is the start index of the segment with the closest point,\n * and t is a parameter from 0 to 1 that indicates where the closest point is on that segment.\n *\n * @param line - an array of points that form the line\n * @param p - point [longitude, latitude]\n * @returns the nearest point, its index in the array and the proportion along the line\n * @example\n * const point = ruler.pointOnLine(line, [-67.04, 50.5]).point;\n * //=point\n */\n pointOnLine(line, p) {\n let minDist = Infinity;\n let minX, minY, minI, minT;\n for (let i = 0; i < line.length - 1; i++) {\n let x = line[i][0];\n let y = line[i][1];\n let dx = this.wrap(line[i + 1][0] - x) * this.kx;\n let dy = (line[i + 1][1] - y) * this.ky;\n let t = 0;\n if (dx !== 0 || dy !== 0) {\n t = (this.wrap(p[0] - x) * this.kx * dx + (p[1] - y) * this.ky * dy) / (dx * dx + dy * dy);\n if (t > 1) {\n x = line[i + 1][0];\n y = line[i + 1][1];\n }\n else if (t > 0) {\n x += (dx / this.kx) * t;\n y += (dy / this.ky) * t;\n }\n }\n dx = this.wrap(p[0] - x) * this.kx;\n dy = (p[1] - y) * this.ky;\n const sqDist = dx * dx + dy * dy;\n if (sqDist < minDist) {\n minDist = sqDist;\n minX = x;\n minY = y;\n minI = i;\n minT = t;\n }\n }\n return {\n point: [minX, minY],\n index: minI,\n t: Math.max(0, Math.min(1, minT))\n };\n }\n wrap(deg) {\n while (deg < -180)\n deg += 360;\n while (deg > 180)\n deg -= 360;\n return deg;\n }\n}\n\nconst MinPointsSize = 100;\nconst MinLinePointsSize = 50;\nfunction compareDistPair(a, b) {\n return b[0] - a[0];\n}\nfunction getRangeSize(range) {\n return range[1] - range[0] + 1;\n}\nfunction isRangeSafe(range, threshold) {\n return range[1] >= range[0] && range[1] < threshold;\n}\nfunction splitRange(range, isLine) {\n if (range[0] > range[1]) {\n return [null, null];\n }\n const size = getRangeSize(range);\n if (isLine) {\n if (size === 2) {\n return [range, null];\n }\n const size1 = Math.floor(size / 2);\n return [[range[0], range[0] + size1],\n [range[0] + size1, range[1]]];\n }\n if (size === 1) {\n return [range, null];\n }\n const size1 = Math.floor(size / 2) - 1;\n return [[range[0], range[0] + size1],\n [range[0] + size1 + 1, range[1]]];\n}\nfunction getBBox(coords, range) {\n if (!isRangeSafe(range, coords.length)) {\n return [Infinity, Infinity, -Infinity, -Infinity];\n }\n const bbox = [Infinity, Infinity, -Infinity, -Infinity];\n for (let i = range[0]; i <= range[1]; ++i) {\n updateBBox(bbox, coords[i]);\n }\n return bbox;\n}\nfunction getPolygonBBox(polygon) {\n const bbox = [Infinity, Infinity, -Infinity, -Infinity];\n for (const ring of polygon) {\n for (const coord of ring) {\n updateBBox(bbox, coord);\n }\n }\n return bbox;\n}\nfunction isValidBBox(bbox) {\n return bbox[0] !== -Infinity && bbox[1] !== -Infinity && bbox[2] !== Infinity && bbox[3] !== Infinity;\n}\n// Calculate the distance between two bounding boxes.\n// Calculate the delta in x and y direction, and use two fake points {0.0, 0.0}\n// and {dx, dy} to calculate the distance. Distance will be 0.0 if bounding box are overlapping.\nfunction bboxToBBoxDistance(bbox1, bbox2, ruler) {\n if (!isValidBBox(bbox1) || !isValidBBox(bbox2)) {\n return NaN;\n }\n let dx = 0.0;\n let dy = 0.0;\n // bbox1 in left side\n if (bbox1[2] < bbox2[0]) {\n dx = bbox2[0] - bbox1[2];\n }\n // bbox1 in right side\n if (bbox1[0] > bbox2[2]) {\n dx = bbox1[0] - bbox2[2];\n }\n // bbox1 in above side\n if (bbox1[1] > bbox2[3]) {\n dy = bbox1[1] - bbox2[3];\n }\n // bbox1 in down side\n if (bbox1[3] < bbox2[1]) {\n dy = bbox2[1] - bbox1[3];\n }\n return ruler.distance([0.0, 0.0], [dx, dy]);\n}\nfunction pointToLineDistance(point, line, ruler) {\n const nearestPoint = ruler.pointOnLine(line, point);\n return ruler.distance(point, nearestPoint.point);\n}\nfunction segmentToSegmentDistance(p1, p2, q1, q2, ruler) {\n const dist1 = Math.min(pointToLineDistance(p1, [q1, q2], ruler), pointToLineDistance(p2, [q1, q2], ruler));\n const dist2 = Math.min(pointToLineDistance(q1, [p1, p2], ruler), pointToLineDistance(q2, [p1, p2], ruler));\n return Math.min(dist1, dist2);\n}\nfunction lineToLineDistance(line1, range1, line2, range2, ruler) {\n const rangeSafe = isRangeSafe(range1, line1.length) && isRangeSafe(range2, line2.length);\n if (!rangeSafe) {\n return Infinity;\n }\n let dist = Infinity;\n for (let i = range1[0]; i < range1[1]; ++i) {\n const p1 = line1[i];\n const p2 = line1[i + 1];\n for (let j = range2[0]; j < range2[1]; ++j) {\n const q1 = line2[j];\n const q2 = line2[j + 1];\n if (segmentIntersectSegment(p1, p2, q1, q2)) {\n return 0.0;\n }\n dist = Math.min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));\n }\n }\n return dist;\n}\nfunction pointsToPointsDistance(points1, range1, points2, range2, ruler) {\n const rangeSafe = isRangeSafe(range1, points1.length) && isRangeSafe(range2, points2.length);\n if (!rangeSafe) {\n return NaN;\n }\n let dist = Infinity;\n for (let i = range1[0]; i <= range1[1]; ++i) {\n for (let j = range2[0]; j <= range2[1]; ++j) {\n dist = Math.min(dist, ruler.distance(points1[i], points2[j]));\n if (dist === 0.0) {\n return dist;\n }\n }\n }\n return dist;\n}\nfunction pointToPolygonDistance(point, polygon, ruler) {\n if (pointWithinPolygon(point, polygon, true)) {\n return 0.0;\n }\n let dist = Infinity;\n for (const ring of polygon) {\n const front = ring[0];\n const back = ring[ring.length - 1];\n if (front !== back) {\n dist = Math.min(dist, pointToLineDistance(point, [back, front], ruler));\n if (dist === 0.0) {\n return dist;\n }\n }\n const nearestPoint = ruler.pointOnLine(ring, point);\n dist = Math.min(dist, ruler.distance(point, nearestPoint.point));\n if (dist === 0.0) {\n return dist;\n }\n }\n return dist;\n}\nfunction lineToPolygonDistance(line, range, polygon, ruler) {\n if (!isRangeSafe(range, line.length)) {\n return NaN;\n }\n for (let i = range[0]; i <= range[1]; ++i) {\n if (pointWithinPolygon(line[i], polygon, true)) {\n return 0.0;\n }\n }\n let dist = Infinity;\n for (let i = range[0]; i < range[1]; ++i) {\n const p1 = line[i];\n const p2 = line[i + 1];\n for (const ring of polygon) {\n for (let j = 0, len = ring.length, k = len - 1; j < len; k = j++) {\n const q1 = ring[k];\n const q2 = ring[j];\n if (segmentIntersectSegment(p1, p2, q1, q2)) {\n return 0.0;\n }\n dist = Math.min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));\n }\n }\n }\n return dist;\n}\nfunction polygonIntersect(poly1, poly2) {\n for (const ring of poly1) {\n for (const point of ring) {\n if (pointWithinPolygon(point, poly2, true)) {\n return true;\n }\n }\n }\n return false;\n}\nfunction polygonToPolygonDistance(polygon1, polygon2, ruler, currentMiniDist = Infinity) {\n const bbox1 = getPolygonBBox(polygon1);\n const bbox2 = getPolygonBBox(polygon2);\n if (currentMiniDist !== Infinity && bboxToBBoxDistance(bbox1, bbox2, ruler) >= currentMiniDist) {\n return currentMiniDist;\n }\n if (boxWithinBox(bbox1, bbox2)) {\n if (polygonIntersect(polygon1, polygon2)) {\n return 0.0;\n }\n }\n else if (polygonIntersect(polygon2, polygon1)) {\n return 0.0;\n }\n let dist = Infinity;\n for (const ring1 of polygon1) {\n for (let i = 0, len1 = ring1.length, l = len1 - 1; i < len1; l = i++) {\n const p1 = ring1[l];\n const p2 = ring1[i];\n for (const ring2 of polygon2) {\n for (let j = 0, len2 = ring2.length, k = len2 - 1; j < len2; k = j++) {\n const q1 = ring2[k];\n const q2 = ring2[j];\n if (segmentIntersectSegment(p1, p2, q1, q2)) {\n return 0.0;\n }\n dist = Math.min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));\n }\n }\n }\n }\n return dist;\n}\nfunction updateQueue(distQueue, miniDist, ruler, points, polyBBox, rangeA) {\n if (!rangeA) {\n return;\n }\n const tempDist = bboxToBBoxDistance(getBBox(points, rangeA), polyBBox, ruler);\n // Insert new pair to the queue if the bbox distance is less than\n // miniDist, The pair with biggest distance will be at the top\n if (tempDist < miniDist) {\n distQueue.push([tempDist, rangeA, [0, 0]]);\n }\n}\nfunction updateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, range1, range2) {\n if (!range1 || !range2) {\n return;\n }\n const tempDist = bboxToBBoxDistance(getBBox(pointSet1, range1), getBBox(pointSet2, range2), ruler);\n // Insert new pair to the queue if the bbox distance is less than\n // miniDist, The pair with biggest distance will be at the top\n if (tempDist < miniDist) {\n distQueue.push([tempDist, range1, range2]);\n }\n}\n// Divide and conquer, the time complexity is O(n*lgn), faster than Brute force\n// O(n*n) Most of the time, use index for in-place processing.\nfunction pointsToPolygonDistance(points, isLine, polygon, ruler, currentMiniDist = Infinity) {\n let miniDist = Math.min(ruler.distance(points[0], polygon[0][0]), currentMiniDist);\n if (miniDist === 0.0) {\n return miniDist;\n }\n const distQueue = new TinyQueue([[0, [0, points.length - 1], [0, 0]]], compareDistPair);\n const polyBBox = getPolygonBBox(polygon);\n while (distQueue.length > 0) {\n const distPair = distQueue.pop();\n if (distPair[0] >= miniDist) {\n continue;\n }\n const range = distPair[1];\n // In case the set size are relatively small, we could use brute-force directly\n const threshold = isLine ? MinLinePointsSize : MinPointsSize;\n if (getRangeSize(range) <= threshold) {\n if (!isRangeSafe(range, points.length)) {\n return NaN;\n }\n if (isLine) {\n const tempDist = lineToPolygonDistance(points, range, polygon, ruler);\n if (isNaN(tempDist) || tempDist === 0.0) {\n return tempDist;\n }\n miniDist = Math.min(miniDist, tempDist);\n }\n else {\n for (let i = range[0]; i <= range[1]; ++i) {\n const tempDist = pointToPolygonDistance(points[i], polygon, ruler);\n miniDist = Math.min(miniDist, tempDist);\n if (miniDist === 0.0) {\n return 0.0;\n }\n }\n }\n }\n else {\n const newRangesA = splitRange(range, isLine);\n updateQueue(distQueue, miniDist, ruler, points, polyBBox, newRangesA[0]);\n updateQueue(distQueue, miniDist, ruler, points, polyBBox, newRangesA[1]);\n }\n }\n return miniDist;\n}\nfunction pointSetToPointSetDistance(pointSet1, isLine1, pointSet2, isLine2, ruler, currentMiniDist = Infinity) {\n let miniDist = Math.min(currentMiniDist, ruler.distance(pointSet1[0], pointSet2[0]));\n if (miniDist === 0.0) {\n return miniDist;\n }\n const distQueue = new TinyQueue([[0, [0, pointSet1.length - 1], [0, pointSet2.length - 1]]], compareDistPair);\n while (distQueue.length > 0) {\n const distPair = distQueue.pop();\n if (distPair[0] >= miniDist) {\n continue;\n }\n const rangeA = distPair[1];\n const rangeB = distPair[2];\n const threshold1 = isLine1 ? MinLinePointsSize : MinPointsSize;\n const threshold2 = isLine2 ? MinLinePointsSize : MinPointsSize;\n // In case the set size are relatively small, we could use brute-force directly\n if (getRangeSize(rangeA) <= threshold1 && getRangeSize(rangeB) <= threshold2) {\n if (!isRangeSafe(rangeA, pointSet1.length) && isRangeSafe(rangeB, pointSet2.length)) {\n return NaN;\n }\n let tempDist;\n if (isLine1 && isLine2) {\n tempDist = lineToLineDistance(pointSet1, rangeA, pointSet2, rangeB, ruler);\n miniDist = Math.min(miniDist, tempDist);\n }\n else if (isLine1 && !isLine2) {\n const sublibe = pointSet1.slice(rangeA[0], rangeA[1] + 1);\n for (let i = rangeB[0]; i <= rangeB[1]; ++i) {\n tempDist = pointToLineDistance(pointSet2[i], sublibe, ruler);\n miniDist = Math.min(miniDist, tempDist);\n if (miniDist === 0.0) {\n return miniDist;\n }\n }\n }\n else if (!isLine1 && isLine2) {\n const sublibe = pointSet2.slice(rangeB[0], rangeB[1] + 1);\n for (let i = rangeA[0]; i <= rangeA[1]; ++i) {\n tempDist = pointToLineDistance(pointSet1[i], sublibe, ruler);\n miniDist = Math.min(miniDist, tempDist);\n if (miniDist === 0.0) {\n return miniDist;\n }\n }\n }\n else {\n tempDist = pointsToPointsDistance(pointSet1, rangeA, pointSet2, rangeB, ruler);\n miniDist = Math.min(miniDist, tempDist);\n }\n }\n else {\n const newRangesA = splitRange(rangeA, isLine1);\n const newRangesB = splitRange(rangeB, isLine2);\n updateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[0], newRangesB[0]);\n updateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[0], newRangesB[1]);\n updateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[1], newRangesB[0]);\n updateQueueTwoSets(distQueue, miniDist, ruler, pointSet1, pointSet2, newRangesA[1], newRangesB[1]);\n }\n }\n return miniDist;\n}\nfunction pointToGeometryDistance(ctx, geometries) {\n const tilePoints = ctx.geometry();\n const pointPosition = tilePoints.flat().map(p => getLngLatFromTileCoord([p.x, p.y], ctx.canonical));\n if (tilePoints.length === 0) {\n return NaN;\n }\n const ruler = new CheapRuler(pointPosition[0][1]);\n let dist = Infinity;\n for (const geometry of geometries) {\n switch (geometry.type) {\n case 'Point':\n dist = Math.min(dist, pointSetToPointSetDistance(pointPosition, false, [geometry.coordinates], false, ruler, dist));\n break;\n case 'LineString':\n dist = Math.min(dist, pointSetToPointSetDistance(pointPosition, false, geometry.coordinates, true, ruler, dist));\n break;\n case 'Polygon':\n dist = Math.min(dist, pointsToPolygonDistance(pointPosition, false, geometry.coordinates, ruler, dist));\n break;\n }\n if (dist === 0.0) {\n return dist;\n }\n }\n return dist;\n}\nfunction lineStringToGeometryDistance(ctx, geometries) {\n const tileLine = ctx.geometry();\n const linePositions = tileLine.flat().map(p => getLngLatFromTileCoord([p.x, p.y], ctx.canonical));\n if (tileLine.length === 0) {\n return NaN;\n }\n const ruler = new CheapRuler(linePositions[0][1]);\n let dist = Infinity;\n for (const geometry of geometries) {\n switch (geometry.type) {\n case 'Point':\n dist = Math.min(dist, pointSetToPointSetDistance(linePositions, true, [geometry.coordinates], false, ruler, dist));\n break;\n case 'LineString':\n dist = Math.min(dist, pointSetToPointSetDistance(linePositions, true, geometry.coordinates, true, ruler, dist));\n break;\n case 'Polygon':\n dist = Math.min(dist, pointsToPolygonDistance(linePositions, true, geometry.coordinates, ruler, dist));\n break;\n }\n if (dist === 0.0) {\n return dist;\n }\n }\n return dist;\n}\nfunction polygonToGeometryDistance(ctx, geometries) {\n const tilePolygon = ctx.geometry();\n if (tilePolygon.length === 0 || tilePolygon[0].length === 0) {\n return NaN;\n }\n const polygons = classifyRings(tilePolygon, 0).map(polygon => {\n return polygon.map(ring => {\n return ring.map(p => getLngLatFromTileCoord([p.x, p.y], ctx.canonical));\n });\n });\n const ruler = new CheapRuler(polygons[0][0][0][1]);\n let dist = Infinity;\n for (const geometry of geometries) {\n for (const polygon of polygons) {\n switch (geometry.type) {\n case 'Point':\n dist = Math.min(dist, pointsToPolygonDistance([geometry.coordinates], false, polygon, ruler, dist));\n break;\n case 'LineString':\n dist = Math.min(dist, pointsToPolygonDistance(geometry.coordinates, true, polygon, ruler, dist));\n break;\n case 'Polygon':\n dist = Math.min(dist, polygonToPolygonDistance(polygon, geometry.coordinates, ruler, dist));\n break;\n }\n if (dist === 0.0) {\n return dist;\n }\n }\n }\n return dist;\n}\nfunction toSimpleGeometry(geometry) {\n if (geometry.type === 'MultiPolygon') {\n return geometry.coordinates.map(polygon => {\n return {\n type: 'Polygon',\n coordinates: polygon\n };\n });\n }\n if (geometry.type === 'MultiLineString') {\n return geometry.coordinates.map(lineString => {\n return {\n type: 'LineString',\n coordinates: lineString\n };\n });\n }\n if (geometry.type === 'MultiPoint') {\n return geometry.coordinates.map(point => {\n return {\n type: 'Point',\n coordinates: point\n };\n });\n }\n return [geometry];\n}\nclass Distance {\n constructor(geojson, geometries) {\n this.type = NumberType;\n this.geojson = geojson;\n this.geometries = geometries;\n }\n static parse(args, context) {\n if (args.length !== 2)\n return context.error(`'distance' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n if (isValue(args[1])) {\n const geojson = args[1];\n if (geojson.type === 'FeatureCollection') {\n return new Distance(geojson, geojson.features.map(feature => toSimpleGeometry(feature.geometry)).flat());\n }\n else if (geojson.type === 'Feature') {\n return new Distance(geojson, toSimpleGeometry(geojson.geometry));\n }\n else if ('type' in geojson && 'coordinates' in geojson) {\n return new Distance(geojson, toSimpleGeometry(geojson));\n }\n }\n return context.error('\\'distance\\' expression requires valid geojson object that contains polygon geometry type.');\n }\n evaluate(ctx) {\n if (ctx.geometry() != null && ctx.canonicalID() != null) {\n if (ctx.geometryType() === 'Point') {\n return pointToGeometryDistance(ctx, this.geometries);\n }\n else if (ctx.geometryType() === 'LineString') {\n return lineStringToGeometryDistance(ctx, this.geometries);\n }\n else if (ctx.geometryType() === 'Polygon') {\n return polygonToGeometryDistance(ctx, this.geometries);\n }\n }\n return NaN;\n }\n eachChild() { }\n outputDefined() {\n return true;\n }\n}\n\nconst expressions$1 = {\n // special forms\n '==': Equals,\n '!=': NotEquals,\n '>': GreaterThan,\n '<': LessThan,\n '>=': GreaterThanOrEqual,\n '<=': LessThanOrEqual,\n 'array': Assertion,\n 'at': At,\n 'boolean': Assertion,\n 'case': Case,\n 'coalesce': Coalesce,\n 'collator': CollatorExpression,\n 'format': FormatExpression,\n 'image': ImageExpression,\n 'in': In,\n 'index-of': IndexOf,\n 'interpolate': Interpolate,\n 'interpolate-hcl': Interpolate,\n 'interpolate-lab': Interpolate,\n 'length': Length,\n 'let': Let,\n 'literal': Literal,\n 'match': Match,\n 'number': Assertion,\n 'number-format': NumberFormat,\n 'object': Assertion,\n 'slice': Slice,\n 'step': Step,\n 'string': Assertion,\n 'to-boolean': Coercion,\n 'to-color': Coercion,\n 'to-number': Coercion,\n 'to-string': Coercion,\n 'var': Var,\n 'within': Within,\n 'distance': Distance\n};\n\nclass CompoundExpression {\n constructor(name, type, evaluate, args) {\n this.name = name;\n this.type = type;\n this._evaluate = evaluate;\n this.args = args;\n }\n evaluate(ctx) {\n return this._evaluate(ctx, this.args);\n }\n eachChild(fn) {\n this.args.forEach(fn);\n }\n outputDefined() {\n return false;\n }\n static parse(args, context) {\n const op = args[0];\n const definition = CompoundExpression.definitions[op];\n if (!definition) {\n return context.error(`Unknown expression \"${op}\". If you wanted a literal array, use [\"literal\", [...]].`, 0);\n }\n // Now check argument types against each signature\n const type = Array.isArray(definition) ?\n definition[0] : definition.type;\n const availableOverloads = Array.isArray(definition) ?\n [[definition[1], definition[2]]] :\n definition.overloads;\n const overloads = availableOverloads.filter(([signature]) => (!Array.isArray(signature) || // varags\n signature.length === args.length - 1 // correct param count\n ));\n let signatureContext = null;\n for (const [params, evaluate] of overloads) {\n // Use a fresh context for each attempted signature so that, if\n // we eventually succeed, we haven't polluted `context.errors`.\n signatureContext = new ParsingContext(context.registry, isExpressionConstant, context.path, null, context.scope);\n // First parse all the args, potentially coercing to the\n // types expected by this overload.\n const parsedArgs = [];\n let argParseFailed = false;\n for (let i = 1; i < args.length; i++) {\n const arg = args[i];\n const expectedType = Array.isArray(params) ?\n params[i - 1] :\n params.type;\n const parsed = signatureContext.parse(arg, 1 + parsedArgs.length, expectedType);\n if (!parsed) {\n argParseFailed = true;\n break;\n }\n parsedArgs.push(parsed);\n }\n if (argParseFailed) {\n // Couldn't coerce args of this overload to expected type, move\n // on to next one.\n continue;\n }\n if (Array.isArray(params)) {\n if (params.length !== parsedArgs.length) {\n signatureContext.error(`Expected ${params.length} arguments, but found ${parsedArgs.length} instead.`);\n continue;\n }\n }\n for (let i = 0; i < parsedArgs.length; i++) {\n const expected = Array.isArray(params) ? params[i] : params.type;\n const arg = parsedArgs[i];\n signatureContext.concat(i + 1).checkSubtype(expected, arg.type);\n }\n if (signatureContext.errors.length === 0) {\n return new CompoundExpression(op, type, evaluate, parsedArgs);\n }\n }\n if (overloads.length === 1) {\n context.errors.push(...signatureContext.errors);\n }\n else {\n const expected = overloads.length ? overloads : availableOverloads;\n const signatures = expected\n .map(([params]) => stringifySignature(params))\n .join(' | ');\n const actualTypes = [];\n // For error message, re-parse arguments without trying to\n // apply any coercions\n for (let i = 1; i < args.length; i++) {\n const parsed = context.parse(args[i], 1 + actualTypes.length);\n if (!parsed)\n return null;\n actualTypes.push(toString$1(parsed.type));\n }\n context.error(`Expected arguments of type ${signatures}, but found (${actualTypes.join(', ')}) instead.`);\n }\n return null;\n }\n static register(registry, definitions) {\n CompoundExpression.definitions = definitions;\n for (const name in definitions) {\n registry[name] = CompoundExpression;\n }\n }\n}\nfunction rgba(ctx, [r, g, b, a]) {\n r = r.evaluate(ctx);\n g = g.evaluate(ctx);\n b = b.evaluate(ctx);\n const alpha = a ? a.evaluate(ctx) : 1;\n const error = validateRGBA(r, g, b, alpha);\n if (error)\n throw new RuntimeError(error);\n return new Color(r / 255, g / 255, b / 255, alpha, false);\n}\nfunction has(key, obj) {\n return key in obj;\n}\nfunction get(key, obj) {\n const v = obj[key];\n return typeof v === 'undefined' ? null : v;\n}\nfunction binarySearch(v, a, i, j) {\n while (i <= j) {\n const m = (i + j) >> 1;\n if (a[m] === v)\n return true;\n if (a[m] > v)\n j = m - 1;\n else\n i = m + 1;\n }\n return false;\n}\nfunction varargs(type) {\n return { type };\n}\nCompoundExpression.register(expressions$1, {\n 'error': [\n ErrorType,\n [StringType],\n (ctx, [v]) => { throw new RuntimeError(v.evaluate(ctx)); }\n ],\n 'typeof': [\n StringType,\n [ValueType],\n (ctx, [v]) => toString$1(typeOf(v.evaluate(ctx)))\n ],\n 'to-rgba': [\n array$1(NumberType, 4),\n [ColorType],\n (ctx, [v]) => {\n const [r, g, b, a] = v.evaluate(ctx).rgb;\n return [r * 255, g * 255, b * 255, a];\n },\n ],\n 'rgb': [\n ColorType,\n [NumberType, NumberType, NumberType],\n rgba\n ],\n 'rgba': [\n ColorType,\n [NumberType, NumberType, NumberType, NumberType],\n rgba\n ],\n 'has': {\n type: BooleanType,\n overloads: [\n [\n [StringType],\n (ctx, [key]) => has(key.evaluate(ctx), ctx.properties())\n ], [\n [StringType, ObjectType],\n (ctx, [key, obj]) => has(key.evaluate(ctx), obj.evaluate(ctx))\n ]\n ]\n },\n 'get': {\n type: ValueType,\n overloads: [\n [\n [StringType],\n (ctx, [key]) => get(key.evaluate(ctx), ctx.properties())\n ], [\n [StringType, ObjectType],\n (ctx, [key, obj]) => get(key.evaluate(ctx), obj.evaluate(ctx))\n ]\n ]\n },\n 'feature-state': [\n ValueType,\n [StringType],\n (ctx, [key]) => get(key.evaluate(ctx), ctx.featureState || {})\n ],\n 'properties': [\n ObjectType,\n [],\n (ctx) => ctx.properties()\n ],\n 'geometry-type': [\n StringType,\n [],\n (ctx) => ctx.geometryType()\n ],\n 'id': [\n ValueType,\n [],\n (ctx) => ctx.id()\n ],\n 'zoom': [\n NumberType,\n [],\n (ctx) => ctx.globals.zoom\n ],\n 'heatmap-density': [\n NumberType,\n [],\n (ctx) => ctx.globals.heatmapDensity || 0\n ],\n 'line-progress': [\n NumberType,\n [],\n (ctx) => ctx.globals.lineProgress || 0\n ],\n 'accumulated': [\n ValueType,\n [],\n (ctx) => ctx.globals.accumulated === undefined ? null : ctx.globals.accumulated\n ],\n '+': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => {\n let result = 0;\n for (const arg of args) {\n result += arg.evaluate(ctx);\n }\n return result;\n }\n ],\n '*': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => {\n let result = 1;\n for (const arg of args) {\n result *= arg.evaluate(ctx);\n }\n return result;\n }\n ],\n '-': {\n type: NumberType,\n overloads: [\n [\n [NumberType, NumberType],\n (ctx, [a, b]) => a.evaluate(ctx) - b.evaluate(ctx)\n ], [\n [NumberType],\n (ctx, [a]) => -a.evaluate(ctx)\n ]\n ]\n },\n '/': [\n NumberType,\n [NumberType, NumberType],\n (ctx, [a, b]) => a.evaluate(ctx) / b.evaluate(ctx)\n ],\n '%': [\n NumberType,\n [NumberType, NumberType],\n (ctx, [a, b]) => a.evaluate(ctx) % b.evaluate(ctx)\n ],\n 'ln2': [\n NumberType,\n [],\n () => Math.LN2\n ],\n 'pi': [\n NumberType,\n [],\n () => Math.PI\n ],\n 'e': [\n NumberType,\n [],\n () => Math.E\n ],\n '^': [\n NumberType,\n [NumberType, NumberType],\n (ctx, [b, e]) => Math.pow(b.evaluate(ctx), e.evaluate(ctx))\n ],\n 'sqrt': [\n NumberType,\n [NumberType],\n (ctx, [x]) => Math.sqrt(x.evaluate(ctx))\n ],\n 'log10': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN10\n ],\n 'ln': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.log(n.evaluate(ctx))\n ],\n 'log2': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN2\n ],\n 'sin': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.sin(n.evaluate(ctx))\n ],\n 'cos': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.cos(n.evaluate(ctx))\n ],\n 'tan': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.tan(n.evaluate(ctx))\n ],\n 'asin': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.asin(n.evaluate(ctx))\n ],\n 'acos': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.acos(n.evaluate(ctx))\n ],\n 'atan': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.atan(n.evaluate(ctx))\n ],\n 'min': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => Math.min(...args.map(arg => arg.evaluate(ctx)))\n ],\n 'max': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => Math.max(...args.map(arg => arg.evaluate(ctx)))\n ],\n 'abs': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.abs(n.evaluate(ctx))\n ],\n 'round': [\n NumberType,\n [NumberType],\n (ctx, [n]) => {\n const v = n.evaluate(ctx);\n // Javascript's Math.round() rounds towards +Infinity for halfway\n // values, even when they're negative. It's more common to round\n // away from 0 (e.g., this is what python and C++ do)\n return v < 0 ? -Math.round(-v) : Math.round(v);\n }\n ],\n 'floor': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.floor(n.evaluate(ctx))\n ],\n 'ceil': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.ceil(n.evaluate(ctx))\n ],\n 'filter-==': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => ctx.properties()[k.value] === v.value\n ],\n 'filter-id-==': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => ctx.id() === v.value\n ],\n 'filter-type-==': [\n BooleanType,\n [StringType],\n (ctx, [v]) => ctx.geometryType() === v.value\n ],\n 'filter-<': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[k.value];\n const b = v.value;\n return typeof a === typeof b && a < b;\n }\n ],\n 'filter-id-<': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = v.value;\n return typeof a === typeof b && a < b;\n }\n ],\n 'filter->': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[k.value];\n const b = v.value;\n return typeof a === typeof b && a > b;\n }\n ],\n 'filter-id->': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = v.value;\n return typeof a === typeof b && a > b;\n }\n ],\n 'filter-<=': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[k.value];\n const b = v.value;\n return typeof a === typeof b && a <= b;\n }\n ],\n 'filter-id-<=': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = v.value;\n return typeof a === typeof b && a <= b;\n }\n ],\n 'filter->=': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[k.value];\n const b = v.value;\n return typeof a === typeof b && a >= b;\n }\n ],\n 'filter-id->=': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = v.value;\n return typeof a === typeof b && a >= b;\n }\n ],\n 'filter-has': [\n BooleanType,\n [ValueType],\n (ctx, [k]) => k.value in ctx.properties()\n ],\n 'filter-has-id': [\n BooleanType,\n [],\n (ctx) => (ctx.id() !== null && ctx.id() !== undefined)\n ],\n 'filter-type-in': [\n BooleanType,\n [array$1(StringType)],\n (ctx, [v]) => v.value.indexOf(ctx.geometryType()) >= 0\n ],\n 'filter-id-in': [\n BooleanType,\n [array$1(ValueType)],\n (ctx, [v]) => v.value.indexOf(ctx.id()) >= 0\n ],\n 'filter-in-small': [\n BooleanType,\n [StringType, array$1(ValueType)],\n // assumes v is an array literal\n (ctx, [k, v]) => v.value.indexOf(ctx.properties()[k.value]) >= 0\n ],\n 'filter-in-large': [\n BooleanType,\n [StringType, array$1(ValueType)],\n // assumes v is a array literal with values sorted in ascending order and of a single type\n (ctx, [k, v]) => binarySearch(ctx.properties()[k.value], v.value, 0, v.value.length - 1)\n ],\n 'all': {\n type: BooleanType,\n overloads: [\n [\n [BooleanType, BooleanType],\n (ctx, [a, b]) => a.evaluate(ctx) && b.evaluate(ctx)\n ],\n [\n varargs(BooleanType),\n (ctx, args) => {\n for (const arg of args) {\n if (!arg.evaluate(ctx))\n return false;\n }\n return true;\n }\n ]\n ]\n },\n 'any': {\n type: BooleanType,\n overloads: [\n [\n [BooleanType, BooleanType],\n (ctx, [a, b]) => a.evaluate(ctx) || b.evaluate(ctx)\n ],\n [\n varargs(BooleanType),\n (ctx, args) => {\n for (const arg of args) {\n if (arg.evaluate(ctx))\n return true;\n }\n return false;\n }\n ]\n ]\n },\n '!': [\n BooleanType,\n [BooleanType],\n (ctx, [b]) => !b.evaluate(ctx)\n ],\n 'is-supported-script': [\n BooleanType,\n [StringType],\n // At parse time this will always return true, so we need to exclude this expression with isGlobalPropertyConstant\n (ctx, [s]) => {\n const isSupportedScript = ctx.globals && ctx.globals.isSupportedScript;\n if (isSupportedScript) {\n return isSupportedScript(s.evaluate(ctx));\n }\n return true;\n }\n ],\n 'upcase': [\n StringType,\n [StringType],\n (ctx, [s]) => s.evaluate(ctx).toUpperCase()\n ],\n 'downcase': [\n StringType,\n [StringType],\n (ctx, [s]) => s.evaluate(ctx).toLowerCase()\n ],\n 'concat': [\n StringType,\n varargs(ValueType),\n (ctx, args) => args.map(arg => toString(arg.evaluate(ctx))).join('')\n ],\n 'resolved-locale': [\n StringType,\n [CollatorType],\n (ctx, [collator]) => collator.evaluate(ctx).resolvedLocale()\n ]\n});\nfunction stringifySignature(signature) {\n if (Array.isArray(signature)) {\n return `(${signature.map(toString$1).join(', ')})`;\n }\n else {\n return `(${toString$1(signature.type)}...)`;\n }\n}\nfunction isExpressionConstant(expression) {\n if (expression instanceof Var) {\n return isExpressionConstant(expression.boundExpression);\n }\n else if (expression instanceof CompoundExpression && expression.name === 'error') {\n return false;\n }\n else if (expression instanceof CollatorExpression) {\n // Although the results of a Collator expression with fixed arguments\n // generally shouldn't change between executions, we can't serialize them\n // as constant expressions because results change based on environment.\n return false;\n }\n else if (expression instanceof Within) {\n return false;\n }\n else if (expression instanceof Distance) {\n return false;\n }\n const isTypeAnnotation = expression instanceof Coercion ||\n expression instanceof Assertion;\n let childrenConstant = true;\n expression.eachChild(child => {\n // We can _almost_ assume that if `expressions` children are constant,\n // they would already have been evaluated to Literal values when they\n // were parsed. Type annotations are the exception, because they might\n // have been inferred and added after a child was parsed.\n // So we recurse into isConstant() for the children of type annotations,\n // but otherwise simply check whether they are Literals.\n if (isTypeAnnotation) {\n childrenConstant = childrenConstant && isExpressionConstant(child);\n }\n else {\n childrenConstant = childrenConstant && child instanceof Literal;\n }\n });\n if (!childrenConstant) {\n return false;\n }\n return isFeatureConstant(expression) &&\n isGlobalPropertyConstant(expression, ['zoom', 'heatmap-density', 'line-progress', 'accumulated', 'is-supported-script']);\n}\nfunction isFeatureConstant(e) {\n if (e instanceof CompoundExpression) {\n if (e.name === 'get' && e.args.length === 1) {\n return false;\n }\n else if (e.name === 'feature-state') {\n return false;\n }\n else if (e.name === 'has' && e.args.length === 1) {\n return false;\n }\n else if (e.name === 'properties' ||\n e.name === 'geometry-type' ||\n e.name === 'id') {\n return false;\n }\n else if (/^filter-/.test(e.name)) {\n return false;\n }\n }\n if (e instanceof Within) {\n return false;\n }\n if (e instanceof Distance) {\n return false;\n }\n let result = true;\n e.eachChild(arg => {\n if (result && !isFeatureConstant(arg)) {\n result = false;\n }\n });\n return result;\n}\nfunction isStateConstant(e) {\n if (e instanceof CompoundExpression) {\n if (e.name === 'feature-state') {\n return false;\n }\n }\n let result = true;\n e.eachChild(arg => {\n if (result && !isStateConstant(arg)) {\n result = false;\n }\n });\n return result;\n}\nfunction isGlobalPropertyConstant(e, properties) {\n if (e instanceof CompoundExpression && properties.indexOf(e.name) >= 0) {\n return false;\n }\n let result = true;\n e.eachChild((arg) => {\n if (result && !isGlobalPropertyConstant(arg, properties)) {\n result = false;\n }\n });\n return result;\n}\n\nfunction success(value) {\n return { result: 'success', value };\n}\nfunction error(value) {\n return { result: 'error', value };\n}\n\nfunction supportsPropertyExpression(spec) {\n return spec['property-type'] === 'data-driven' || spec['property-type'] === 'cross-faded-data-driven';\n}\nfunction supportsZoomExpression(spec) {\n return !!spec.expression && spec.expression.parameters.indexOf('zoom') > -1;\n}\nfunction supportsInterpolation(spec) {\n return !!spec.expression && spec.expression.interpolated;\n}\n\nfunction getType(val) {\n if (val instanceof Number) {\n return 'number';\n }\n else if (val instanceof String) {\n return 'string';\n }\n else if (val instanceof Boolean) {\n return 'boolean';\n }\n else if (Array.isArray(val)) {\n return 'array';\n }\n else if (val === null) {\n return 'null';\n }\n else {\n return typeof val;\n }\n}\n\nfunction isFunction$1(value) {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\nfunction identityFunction(x) {\n return x;\n}\nfunction createFunction(parameters, propertySpec) {\n const isColor = propertySpec.type === 'color';\n const zoomAndFeatureDependent = parameters.stops && typeof parameters.stops[0][0] === 'object';\n const featureDependent = zoomAndFeatureDependent || parameters.property !== undefined;\n const zoomDependent = zoomAndFeatureDependent || !featureDependent;\n const type = parameters.type || (supportsInterpolation(propertySpec) ? 'exponential' : 'interval');\n if (isColor || propertySpec.type === 'padding') {\n const parseFn = isColor ? Color.parse : Padding.parse;\n parameters = extendBy({}, parameters);\n if (parameters.stops) {\n parameters.stops = parameters.stops.map((stop) => {\n return [stop[0], parseFn(stop[1])];\n });\n }\n if (parameters.default) {\n parameters.default = parseFn(parameters.default);\n }\n else {\n parameters.default = parseFn(propertySpec.default);\n }\n }\n if (parameters.colorSpace && !isSupportedInterpolationColorSpace(parameters.colorSpace)) {\n throw new Error(`Unknown color space: \"${parameters.colorSpace}\"`);\n }\n let innerFun;\n let hashedStops;\n let categoricalKeyType;\n if (type === 'exponential') {\n innerFun = evaluateExponentialFunction;\n }\n else if (type === 'interval') {\n innerFun = evaluateIntervalFunction;\n }\n else if (type === 'categorical') {\n innerFun = evaluateCategoricalFunction;\n // For categorical functions, generate an Object as a hashmap of the stops for fast searching\n hashedStops = Object.create(null);\n for (const stop of parameters.stops) {\n hashedStops[stop[0]] = stop[1];\n }\n // Infer key type based on first stop key-- used to encforce strict type checking later\n categoricalKeyType = typeof parameters.stops[0][0];\n }\n else if (type === 'identity') {\n innerFun = evaluateIdentityFunction;\n }\n else {\n throw new Error(`Unknown function type \"${type}\"`);\n }\n if (zoomAndFeatureDependent) {\n const featureFunctions = {};\n const zoomStops = [];\n for (let s = 0; s < parameters.stops.length; s++) {\n const stop = parameters.stops[s];\n const zoom = stop[0].zoom;\n if (featureFunctions[zoom] === undefined) {\n featureFunctions[zoom] = {\n zoom,\n type: parameters.type,\n property: parameters.property,\n default: parameters.default,\n stops: []\n };\n zoomStops.push(zoom);\n }\n featureFunctions[zoom].stops.push([stop[0].value, stop[1]]);\n }\n const featureFunctionStops = [];\n for (const z of zoomStops) {\n featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z], propertySpec)]);\n }\n const interpolationType = { name: 'linear' };\n return {\n kind: 'composite',\n interpolationType,\n interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType),\n zoomStops: featureFunctionStops.map(s => s[0]),\n evaluate({ zoom }, properties) {\n return evaluateExponentialFunction({\n stops: featureFunctionStops,\n base: parameters.base\n }, propertySpec, zoom).evaluate(zoom, properties);\n }\n };\n }\n else if (zoomDependent) {\n const interpolationType = type === 'exponential' ?\n { name: 'exponential', base: parameters.base !== undefined ? parameters.base : 1 } : null;\n return {\n kind: 'camera',\n interpolationType,\n interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType),\n zoomStops: parameters.stops.map(s => s[0]),\n evaluate: ({ zoom }) => innerFun(parameters, propertySpec, zoom, hashedStops, categoricalKeyType)\n };\n }\n else {\n return {\n kind: 'source',\n evaluate(_, feature) {\n const value = feature && feature.properties ? feature.properties[parameters.property] : undefined;\n if (value === undefined) {\n return coalesce$1(parameters.default, propertySpec.default);\n }\n return innerFun(parameters, propertySpec, value, hashedStops, categoricalKeyType);\n }\n };\n }\n}\nfunction coalesce$1(a, b, c) {\n if (a !== undefined)\n return a;\n if (b !== undefined)\n return b;\n if (c !== undefined)\n return c;\n}\nfunction evaluateCategoricalFunction(parameters, propertySpec, input, hashedStops, keyType) {\n const evaluated = typeof input === keyType ? hashedStops[input] : undefined; // Enforce strict typing on input\n return coalesce$1(evaluated, parameters.default, propertySpec.default);\n}\nfunction evaluateIntervalFunction(parameters, propertySpec, input) {\n // Edge cases\n if (getType(input) !== 'number')\n return coalesce$1(parameters.default, propertySpec.default);\n const n = parameters.stops.length;\n if (n === 1)\n return parameters.stops[0][1];\n if (input <= parameters.stops[0][0])\n return parameters.stops[0][1];\n if (input >= parameters.stops[n - 1][0])\n return parameters.stops[n - 1][1];\n const index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input);\n return parameters.stops[index][1];\n}\nfunction evaluateExponentialFunction(parameters, propertySpec, input) {\n const base = parameters.base !== undefined ? parameters.base : 1;\n // Edge cases\n if (getType(input) !== 'number')\n return coalesce$1(parameters.default, propertySpec.default);\n const n = parameters.stops.length;\n if (n === 1)\n return parameters.stops[0][1];\n if (input <= parameters.stops[0][0])\n return parameters.stops[0][1];\n if (input >= parameters.stops[n - 1][0])\n return parameters.stops[n - 1][1];\n const index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input);\n const t = interpolationFactor(input, base, parameters.stops[index][0], parameters.stops[index + 1][0]);\n const outputLower = parameters.stops[index][1];\n const outputUpper = parameters.stops[index + 1][1];\n const interp = interpolate[propertySpec.type] || identityFunction;\n if (typeof outputLower.evaluate === 'function') {\n return {\n evaluate(...args) {\n const evaluatedLower = outputLower.evaluate.apply(undefined, args);\n const evaluatedUpper = outputUpper.evaluate.apply(undefined, args);\n // Special case for fill-outline-color, which has no spec default.\n if (evaluatedLower === undefined || evaluatedUpper === undefined) {\n return undefined;\n }\n return interp(evaluatedLower, evaluatedUpper, t, parameters.colorSpace);\n }\n };\n }\n return interp(outputLower, outputUpper, t, parameters.colorSpace);\n}\nfunction evaluateIdentityFunction(parameters, propertySpec, input) {\n switch (propertySpec.type) {\n case 'color':\n input = Color.parse(input);\n break;\n case 'formatted':\n input = Formatted.fromString(input.toString());\n break;\n case 'resolvedImage':\n input = ResolvedImage.fromString(input.toString());\n break;\n case 'padding':\n input = Padding.parse(input);\n break;\n default:\n if (getType(input) !== propertySpec.type && (propertySpec.type !== 'enum' || !propertySpec.values[input])) {\n input = undefined;\n }\n }\n return 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 const difference = upperValue - lowerValue;\n const progress = input - lowerValue;\n if (difference === 0) {\n return 0;\n }\n else if (base === 1) {\n return progress / difference;\n }\n else {\n return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);\n }\n}\n\nclass StyleExpression {\n constructor(expression, propertySpec) {\n this.expression = expression;\n this._warningHistory = {};\n this._evaluator = new EvaluationContext();\n this._defaultValue = propertySpec ? getDefaultValue(propertySpec) : null;\n this._enumValues = propertySpec && propertySpec.type === 'enum' ? propertySpec.values : null;\n }\n evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) {\n this._evaluator.globals = globals;\n this._evaluator.feature = feature;\n this._evaluator.featureState = featureState;\n this._evaluator.canonical = canonical;\n this._evaluator.availableImages = availableImages || null;\n this._evaluator.formattedSection = formattedSection;\n return this.expression.evaluate(this._evaluator);\n }\n evaluate(globals, feature, featureState, canonical, availableImages, formattedSection) {\n this._evaluator.globals = globals;\n this._evaluator.feature = feature || null;\n this._evaluator.featureState = featureState || null;\n this._evaluator.canonical = canonical;\n this._evaluator.availableImages = availableImages || null;\n this._evaluator.formattedSection = formattedSection || null;\n try {\n const val = this.expression.evaluate(this._evaluator);\n // eslint-disable-next-line no-self-compare\n if (val === null || val === undefined || (typeof val === 'number' && val !== val)) {\n return this._defaultValue;\n }\n if (this._enumValues && !(val in this._enumValues)) {\n 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 }\n return val;\n }\n catch (e) {\n if (!this._warningHistory[e.message]) {\n this._warningHistory[e.message] = true;\n if (typeof console !== 'undefined') {\n console.warn(e.message);\n }\n }\n return this._defaultValue;\n }\n }\n}\nfunction isExpression(expression) {\n return Array.isArray(expression) && expression.length > 0 &&\n typeof expression[0] === 'string' && expression[0] in expressions$1;\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, propertySpec) {\n const parser = new ParsingContext(expressions$1, isExpressionConstant, [], propertySpec ? getExpectedType(propertySpec) : undefined);\n // For string-valued properties, coerce to string at the top level rather than asserting.\n const parsed = parser.parse(expression, undefined, undefined, undefined, propertySpec && propertySpec.type === 'string' ? { typeAnnotation: 'coerce' } : undefined);\n if (!parsed) {\n return error(parser.errors);\n }\n return success(new StyleExpression(parsed, propertySpec));\n}\nclass ZoomConstantExpression {\n constructor(kind, expression) {\n this.kind = kind;\n this._styleExpression = expression;\n this.isStateDependent = kind !== 'constant' && !isStateConstant(expression.expression);\n }\n evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) {\n return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n evaluate(globals, feature, featureState, canonical, availableImages, formattedSection) {\n return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n}\nclass ZoomDependentExpression {\n constructor(kind, expression, zoomStops, interpolationType) {\n this.kind = kind;\n this.zoomStops = zoomStops;\n this._styleExpression = expression;\n this.isStateDependent = kind !== 'camera' && !isStateConstant(expression.expression);\n this.interpolationType = interpolationType;\n }\n evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) {\n return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n evaluate(globals, feature, featureState, canonical, availableImages, formattedSection) {\n return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n interpolationFactor(input, lower, upper) {\n if (this.interpolationType) {\n return Interpolate.interpolationFactor(this.interpolationType, input, lower, upper);\n }\n else {\n return 0;\n }\n }\n}\nfunction isZoomExpression(expression) {\n return expression._styleExpression !== undefined;\n}\nfunction createPropertyExpression(expressionInput, propertySpec) {\n const expression = createExpression(expressionInput, propertySpec);\n if (expression.result === 'error') {\n return expression;\n }\n const parsed = expression.value.expression;\n const isFeatureConstantResult = isFeatureConstant(parsed);\n if (!isFeatureConstantResult && !supportsPropertyExpression(propertySpec)) {\n return error([new ExpressionParsingError('', 'data expressions not supported')]);\n }\n const isZoomConstant = isGlobalPropertyConstant(parsed, ['zoom']);\n if (!isZoomConstant && !supportsZoomExpression(propertySpec)) {\n return error([new ExpressionParsingError('', 'zoom expressions not supported')]);\n }\n const zoomCurve = findZoomCurve(parsed);\n if (!zoomCurve && !isZoomConstant) {\n return error([new ExpressionParsingError('', '\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression.')]);\n }\n else if (zoomCurve instanceof ExpressionParsingError) {\n return error([zoomCurve]);\n }\n else if (zoomCurve instanceof Interpolate && !supportsInterpolation(propertySpec)) {\n return error([new ExpressionParsingError('', '\"interpolate\" expressions cannot be used with this property')]);\n }\n if (!zoomCurve) {\n return success(isFeatureConstantResult ?\n new ZoomConstantExpression('constant', expression.value) :\n new ZoomConstantExpression('source', expression.value));\n }\n const interpolationType = zoomCurve instanceof Interpolate ? zoomCurve.interpolation : undefined;\n return success(isFeatureConstantResult ?\n new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType) :\n new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType));\n}\n// serialization wrapper for old-style stop functions normalized to the\n// expression interface\nclass StylePropertyFunction {\n constructor(parameters, specification) {\n this._parameters = parameters;\n this._specification = specification;\n extendBy(this, createFunction(this._parameters, this._specification));\n }\n static deserialize(serialized) {\n return new StylePropertyFunction(serialized._parameters, serialized._specification);\n }\n static serialize(input) {\n return {\n _parameters: input._parameters,\n _specification: input._specification\n };\n }\n}\nfunction normalizePropertyExpression(value, specification) {\n if (isFunction$1(value)) {\n return new StylePropertyFunction(value, specification);\n }\n else if (isExpression(value)) {\n const expression = createPropertyExpression(value, specification);\n if (expression.result === 'error') {\n // this should have been caught in validation\n throw new Error(expression.value.map(err => `${err.key}: ${err.message}`).join(', '));\n }\n return expression.value;\n }\n else {\n let constant = value;\n if (specification.type === 'color' && typeof value === 'string') {\n constant = Color.parse(value);\n }\n else if (specification.type === 'padding' && (typeof value === 'number' || Array.isArray(value))) {\n constant = Padding.parse(value);\n }\n else if (specification.type === 'variableAnchorOffsetCollection' && Array.isArray(value)) {\n constant = VariableAnchorOffsetCollection.parse(value);\n }\n return {\n kind: 'constant',\n evaluate: () => constant\n };\n }\n}\n// Zoom-dependent expressions may only use [\"zoom\"] as the input to a top-level \"step\" or \"interpolate\"\n// expression (collectively referred to as a \"curve\"). The curve may be wrapped in one or more \"let\" or\n// \"coalesce\" expressions.\nfunction findZoomCurve(expression) {\n let result = null;\n if (expression instanceof Let) {\n result = findZoomCurve(expression.result);\n }\n else if (expression instanceof Coalesce) {\n for (const arg of expression.args) {\n result = findZoomCurve(arg);\n if (result) {\n break;\n }\n }\n }\n else if ((expression instanceof Step || expression instanceof Interpolate) &&\n expression.input instanceof CompoundExpression &&\n expression.input.name === 'zoom') {\n result = expression;\n }\n if (result instanceof ExpressionParsingError) {\n return result;\n }\n expression.eachChild((child) => {\n const childResult = findZoomCurve(child);\n if (childResult instanceof ExpressionParsingError) {\n result = childResult;\n }\n else if (!result && childResult) {\n result = new ExpressionParsingError('', '\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression.');\n }\n else if (result && childResult && result !== childResult) {\n result = new ExpressionParsingError('', 'Only one zoom-based \"step\" or \"interpolate\" subexpression may be used in an expression.');\n }\n });\n return result;\n}\nfunction getExpectedType(spec) {\n const types = {\n color: ColorType,\n string: StringType,\n number: NumberType,\n enum: StringType,\n boolean: BooleanType,\n formatted: FormattedType,\n padding: PaddingType,\n resolvedImage: ResolvedImageType,\n variableAnchorOffsetCollection: VariableAnchorOffsetCollectionType\n };\n if (spec.type === 'array') {\n return array$1(types[spec.value] || ValueType, spec.length);\n }\n return types[spec.type];\n}\nfunction getDefaultValue(spec) {\n if (spec.type === 'color' && isFunction$1(spec.default)) {\n // Special case for heatmap-color: it uses the 'default:' to define a\n // default color ramp, but createExpression expects a simple value to fall\n // back to in case of runtime errors\n return new Color(0, 0, 0, 0);\n }\n else if (spec.type === 'color') {\n return Color.parse(spec.default) || null;\n }\n else if (spec.type === 'padding') {\n return Padding.parse(spec.default) || null;\n }\n else if (spec.type === 'variableAnchorOffsetCollection') {\n return VariableAnchorOffsetCollection.parse(spec.default) || null;\n }\n else if (spec.default === undefined) {\n return null;\n }\n else {\n return spec.default;\n }\n}\n\nfunction isExpressionFilter(filter) {\n if (filter === true || filter === false) {\n return true;\n }\n if (!Array.isArray(filter) || filter.length === 0) {\n return false;\n }\n switch (filter[0]) {\n case 'has':\n return filter.length >= 2 && filter[1] !== '$id' && filter[1] !== '$type';\n case 'in':\n return filter.length >= 3 && (typeof filter[1] !== 'string' || Array.isArray(filter[2]));\n case '!in':\n case '!has':\n case 'none':\n return false;\n case '==':\n case '!=':\n case '>':\n case '>=':\n case '<':\n case '<=':\n return filter.length !== 3 || (Array.isArray(filter[1]) || Array.isArray(filter[2]));\n case 'any':\n case 'all':\n for (const f of filter.slice(1)) {\n if (!isExpressionFilter(f) && typeof f !== 'boolean') {\n return false;\n }\n }\n return true;\n default:\n return true;\n }\n}\nconst filterSpec = {\n 'type': 'boolean',\n 'default': false,\n 'transition': false,\n 'property-type': 'data-driven',\n 'expression': {\n 'interpolated': false,\n 'parameters': ['zoom', 'feature']\n }\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 {Array} filter MapLibre filter\n * @returns {Function} filter-evaluating function\n */\nfunction createFilter(filter) {\n if (filter === null || filter === undefined) {\n return { filter: () => true, needGeometry: false };\n }\n if (!isExpressionFilter(filter)) {\n filter = convertFilter$1(filter);\n }\n const compiled = createExpression(filter, filterSpec);\n if (compiled.result === 'error') {\n throw new Error(compiled.value.map(err => `${err.key}: ${err.message}`).join(', '));\n }\n else {\n const needGeometry = geometryNeeded(filter);\n return { filter: (globalProperties, feature, canonical) => compiled.value.evaluate(globalProperties, feature, {}, canonical),\n needGeometry };\n }\n}\n// Comparison function to sort numbers and strings\nfunction compare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\nfunction geometryNeeded(filter) {\n if (!Array.isArray(filter))\n return false;\n if (filter[0] === 'within' || filter[0] === 'distance')\n return true;\n for (let index = 1; index < filter.length; index++) {\n if (geometryNeeded(filter[index]))\n return true;\n }\n return false;\n}\nfunction convertFilter$1(filter) {\n if (!filter)\n return true;\n const op = filter[0];\n if (filter.length <= 1)\n return (op !== 'any');\n const converted = op === '==' ? convertComparisonOp$1(filter[1], filter[2], '==') :\n op === '!=' ? convertNegation(convertComparisonOp$1(filter[1], filter[2], '==')) :\n op === '<' ||\n op === '>' ||\n op === '<=' ||\n op === '>=' ? convertComparisonOp$1(filter[1], filter[2], op) :\n op === 'any' ? convertDisjunctionOp(filter.slice(1)) :\n op === 'all' ? ['all'].concat(filter.slice(1).map(convertFilter$1)) :\n op === 'none' ? ['all'].concat(filter.slice(1).map(convertFilter$1).map(convertNegation)) :\n op === 'in' ? convertInOp$1(filter[1], filter.slice(2)) :\n op === '!in' ? convertNegation(convertInOp$1(filter[1], filter.slice(2))) :\n op === 'has' ? convertHasOp$1(filter[1]) :\n op === '!has' ? convertNegation(convertHasOp$1(filter[1])) :\n true;\n return converted;\n}\nfunction convertComparisonOp$1(property, value, op) {\n switch (property) {\n case '$type':\n return [`filter-type-${op}`, value];\n case '$id':\n return [`filter-id-${op}`, value];\n default:\n return [`filter-${op}`, property, value];\n }\n}\nfunction convertDisjunctionOp(filters) {\n return ['any'].concat(filters.map(convertFilter$1));\n}\nfunction convertInOp$1(property, values) {\n if (values.length === 0) {\n return false;\n }\n switch (property) {\n case '$type':\n return ['filter-type-in', ['literal', values]];\n case '$id':\n return ['filter-id-in', ['literal', values]];\n default:\n if (values.length > 200 && !values.some(v => typeof v !== typeof values[0])) {\n return ['filter-in-large', property, ['literal', values.sort(compare)]];\n }\n else {\n return ['filter-in-small', property, ['literal', values]];\n }\n }\n}\nfunction convertHasOp$1(property) {\n switch (property) {\n case '$type':\n return true;\n case '$id':\n return ['filter-has-id'];\n default:\n return ['filter-has', property];\n }\n}\nfunction convertNegation(filter) {\n return ['!', filter];\n}\n\n/*\n * Convert the given filter to an expression, storing the expected types for\n * any feature properties referenced in expectedTypes.\n *\n * These expected types are needed in order to construct preflight type checks\n * needed for handling 'any' filters. A preflight type check is necessary in\n * order to mimic legacy filters' semantics around expected type mismatches.\n * For example, consider the legacy filter:\n *\n * [\"any\", [\"all\", [\">\", \"y\", 0], [\">\", \"y\", 0]], [\">\", \"x\", 0]]\n *\n * Naively, we might convert this to the expression:\n *\n * [\"any\", [\"all\", [\">\", [\"get\", \"y\"], 0], [\">\", [\"get\", \"z\"], 0]], [\">\", [\"get\", \"x\"], 0]]\n *\n * But if we tried to evaluate this against, say `{x: 1, y: null, z: 0}`, the\n * [\">\", [\"get\", \"y\"], 0] would cause an evaluation error, leading to the\n * entire filter returning false. Legacy filter semantics, though, ask for\n * [\">\", \"y\", 0] to simply return `false` when `y` is of the wrong type,\n * allowing the subsequent terms of the outer \"any\" expression to be evaluated\n * (resulting, in this case, in a `true` value, because x > 0).\n *\n * We account for this by inserting a preflight type-checking expression before\n * each \"any\" term, allowing us to avoid evaluating the actual converted filter\n * if any type mismatches would cause it to produce an evalaution error:\n *\n * [\"any\",\n * [\"case\",\n * [\"all\", [\"==\", [\"typeof\", [\"get\", \"y\"]], \"number\"], [\"==\", [\"typeof\", [\"get\", \"z\"], \"number]],\n * [\"all\", [\">\", [\"get\", \"y\"], 0], [\">\", [\"get\", \"z\"], 0]],\n * false\n * ],\n * [\"case\",\n * [\"==\", [\"typeof\", [\"get\", \"x\"], \"number\"]],\n * [\">\", [\"get\", \"x\"], 0],\n * false\n * ]\n * ]\n *\n * An alternative, possibly more direct approach would be to use type checks\n * in the conversion of each comparison operator, so that the converted version\n * of each individual ==, >=, etc. would mimic the legacy filter semantics. The\n * downside of this approach is that it can lead to many more type checks than\n * would otherwise be necessary: outside the context of an \"any\" expression,\n * bailing out due to a runtime type error (expression semantics) and returning\n * false (legacy filter semantics) are equivalent: they cause the filter to\n * produce a `false` result.\n */\nfunction convertFilter(filter, expectedTypes = {}) {\n if (isExpressionFilter(filter))\n return filter;\n if (!filter)\n return true;\n const legacyFilter = filter;\n const legacyOp = legacyFilter[0];\n if (filter.length <= 1)\n return (legacyOp !== 'any');\n switch (legacyOp) {\n case '==':\n case '!=':\n case '<':\n case '>':\n case '<=':\n case '>=': {\n const [, property, value] = filter;\n return convertComparisonOp(property, value, legacyOp, expectedTypes);\n }\n case 'any': {\n const [, ...conditions] = legacyFilter;\n const children = conditions.map((f) => {\n const types = {};\n const child = convertFilter(f, types);\n const typechecks = runtimeTypeChecks(types);\n return typechecks === true ? child : ['case', typechecks, child, false];\n });\n return ['any', ...children];\n }\n case 'all': {\n const [, ...conditions] = legacyFilter;\n const children = conditions.map(f => convertFilter(f, expectedTypes));\n return children.length > 1 ? ['all', ...children] : children[0];\n }\n case 'none': {\n const [, ...conditions] = legacyFilter;\n return ['!', convertFilter(['any', ...conditions], {})];\n }\n case 'in': {\n const [, property, ...values] = legacyFilter;\n return convertInOp(property, values);\n }\n case '!in': {\n const [, property, ...values] = legacyFilter;\n return convertInOp(property, values, true);\n }\n case 'has':\n return convertHasOp(legacyFilter[1]);\n case '!has':\n return ['!', convertHasOp(legacyFilter[1])];\n default:\n return true;\n }\n}\n// Given a set of feature properties and an expected type for each one,\n// construct an boolean expression that tests whether each property has the\n// right type.\n// E.g.: for {name: 'string', population: 'number'}, return\n// [ 'all',\n// ['==', ['typeof', ['get', 'name'], 'string']],\n// ['==', ['typeof', ['get', 'population'], 'number]]\n// ]\nfunction runtimeTypeChecks(expectedTypes) {\n const conditions = [];\n for (const property in expectedTypes) {\n const get = property === '$id' ? ['id'] : ['get', property];\n conditions.push(['==', ['typeof', get], expectedTypes[property]]);\n }\n if (conditions.length === 0)\n return true;\n if (conditions.length === 1)\n return conditions[0];\n return ['all', ...conditions];\n}\nfunction convertComparisonOp(property, value, op, expectedTypes) {\n let get;\n if (property === '$type') {\n return [op, ['geometry-type'], value];\n }\n else if (property === '$id') {\n get = ['id'];\n }\n else {\n get = ['get', property];\n }\n if (expectedTypes && value !== null) {\n const type = typeof value;\n expectedTypes[property] = type;\n }\n if (op === '==' && property !== '$id' && value === null) {\n return [\n 'all',\n ['has', property], // missing property != null for legacy filters\n ['==', get, null]\n ];\n }\n else if (op === '!=' && property !== '$id' && value === null) {\n return [\n 'any',\n ['!', ['has', property]], // missing property != null for legacy filters\n ['!=', get, null]\n ];\n }\n return [op, get, value];\n}\nfunction convertInOp(property, values, negate = false) {\n if (values.length === 0)\n return negate;\n let get;\n if (property === '$type') {\n get = ['geometry-type'];\n }\n else if (property === '$id') {\n get = ['id'];\n }\n else {\n get = ['get', property];\n }\n // Determine if the list of values to be searched is homogenously typed.\n // If so (and if the type is string or number), then we can use a\n // [match, input, [...values], true, false] construction rather than a\n // bunch of `==` tests.\n let uniformTypes = true;\n const type = typeof values[0];\n for (const value of values) {\n if (typeof value !== type) {\n uniformTypes = false;\n break;\n }\n }\n if (uniformTypes && (type === 'string' || type === 'number')) {\n // Match expressions must have unique values.\n const uniqueValues = values.sort().filter((v, i) => i === 0 || values[i - 1] !== v);\n return ['match', get, uniqueValues, !negate, negate];\n }\n if (negate) {\n return ['all', ...values.map(v => ['!=', get, v])];\n }\n else {\n return ['any', ...values.map(v => ['==', get, v])];\n }\n}\nfunction convertHasOp(property) {\n if (property === '$type') {\n return true;\n }\n else if (property === '$id') {\n return ['!=', ['id'], null];\n }\n else {\n return ['has', property];\n }\n}\n\nfunction convertLiteral(value) {\n return typeof value === 'object' ? ['literal', value] : value;\n}\nfunction convertFunction(parameters, propertySpec) {\n let stops = parameters.stops;\n if (!stops) {\n // identity function\n return convertIdentityFunction(parameters, propertySpec);\n }\n const zoomAndFeatureDependent = stops && typeof stops[0][0] === 'object';\n const featureDependent = zoomAndFeatureDependent || parameters.property !== undefined;\n const zoomDependent = zoomAndFeatureDependent || !featureDependent;\n stops = stops.map((stop) => {\n if (!featureDependent && propertySpec.tokens && typeof stop[1] === 'string') {\n return [stop[0], convertTokenString(stop[1])];\n }\n return [stop[0], convertLiteral(stop[1])];\n });\n if (zoomAndFeatureDependent) {\n return convertZoomAndPropertyFunction(parameters, propertySpec, stops);\n }\n else if (zoomDependent) {\n return convertZoomFunction(parameters, propertySpec, stops);\n }\n else {\n return convertPropertyFunction(parameters, propertySpec, stops);\n }\n}\nfunction convertIdentityFunction(parameters, propertySpec) {\n const get = ['get', parameters.property];\n if (parameters.default === undefined) {\n // By default, expressions for string-valued properties get coerced. To preserve\n // legacy function semantics, insert an explicit assertion instead.\n return propertySpec.type === 'string' ? ['string', get] : get;\n }\n else if (propertySpec.type === 'enum') {\n return [\n 'match',\n get,\n Object.keys(propertySpec.values),\n get,\n parameters.default\n ];\n }\n else {\n const expression = [propertySpec.type === 'color' ? 'to-color' : propertySpec.type, get, convertLiteral(parameters.default)];\n if (propertySpec.type === 'array') {\n expression.splice(1, 0, propertySpec.value, propertySpec.length || null);\n }\n return expression;\n }\n}\nfunction getInterpolateOperator(parameters) {\n switch (parameters.colorSpace) {\n case 'hcl': return 'interpolate-hcl';\n case 'lab': return 'interpolate-lab';\n default: return 'interpolate';\n }\n}\nfunction convertZoomAndPropertyFunction(parameters, propertySpec, stops) {\n const featureFunctionParameters = {};\n const featureFunctionStops = {};\n const zoomStops = [];\n for (let s = 0; s < stops.length; s++) {\n const stop = stops[s];\n const zoom = stop[0].zoom;\n if (featureFunctionParameters[zoom] === undefined) {\n featureFunctionParameters[zoom] = {\n zoom,\n type: parameters.type,\n property: parameters.property,\n default: parameters.default,\n };\n featureFunctionStops[zoom] = [];\n zoomStops.push(zoom);\n }\n featureFunctionStops[zoom].push([stop[0].value, stop[1]]);\n }\n // the interpolation type for the zoom dimension of a zoom-and-property\n // function is determined directly from the style property specification\n // for which it's being used: linear for interpolatable properties, step\n // otherwise.\n const functionType = getFunctionType({}, propertySpec);\n if (functionType === 'exponential') {\n const expression = [getInterpolateOperator(parameters), ['linear'], ['zoom']];\n for (const z of zoomStops) {\n const output = convertPropertyFunction(featureFunctionParameters[z], propertySpec, featureFunctionStops[z]);\n appendStopPair(expression, z, output, false);\n }\n return expression;\n }\n else {\n const expression = ['step', ['zoom']];\n for (const z of zoomStops) {\n const output = convertPropertyFunction(featureFunctionParameters[z], propertySpec, featureFunctionStops[z]);\n appendStopPair(expression, z, output, true);\n }\n fixupDegenerateStepCurve(expression);\n return expression;\n }\n}\nfunction coalesce(a, b) {\n if (a !== undefined)\n return a;\n if (b !== undefined)\n return b;\n}\nfunction getFallback(parameters, propertySpec) {\n const defaultValue = convertLiteral(coalesce(parameters.default, propertySpec.default));\n /*\n * Some fields with type: resolvedImage have an undefined default.\n * Because undefined is an invalid value for resolvedImage, set fallback to\n * an empty string instead of undefined to ensure output\n * passes validation.\n */\n if (defaultValue === undefined && propertySpec.type === 'resolvedImage') {\n return '';\n }\n return defaultValue;\n}\nfunction convertPropertyFunction(parameters, propertySpec, stops) {\n const type = getFunctionType(parameters, propertySpec);\n const get = ['get', parameters.property];\n if (type === 'categorical' && typeof stops[0][0] === 'boolean') {\n const expression = ['case'];\n for (const stop of stops) {\n expression.push(['==', get, stop[0]], stop[1]);\n }\n expression.push(getFallback(parameters, propertySpec));\n return expression;\n }\n else if (type === 'categorical') {\n const expression = ['match', get];\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], false);\n }\n expression.push(getFallback(parameters, propertySpec));\n return expression;\n }\n else if (type === 'interval') {\n const expression = ['step', ['number', get]];\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], true);\n }\n fixupDegenerateStepCurve(expression);\n return parameters.default === undefined ? expression : [\n 'case',\n ['==', ['typeof', get], 'number'],\n expression,\n convertLiteral(parameters.default)\n ];\n }\n else if (type === 'exponential') {\n const base = parameters.base !== undefined ? parameters.base : 1;\n const expression = [\n getInterpolateOperator(parameters),\n base === 1 ? ['linear'] : ['exponential', base],\n ['number', get]\n ];\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], false);\n }\n return parameters.default === undefined ? expression : [\n 'case',\n ['==', ['typeof', get], 'number'],\n expression,\n convertLiteral(parameters.default)\n ];\n }\n else {\n throw new Error(`Unknown property function type ${type}`);\n }\n}\nfunction convertZoomFunction(parameters, propertySpec, stops, input = ['zoom']) {\n const type = getFunctionType(parameters, propertySpec);\n let expression;\n let isStep = false;\n if (type === 'interval') {\n expression = ['step', input];\n isStep = true;\n }\n else if (type === 'exponential') {\n const base = parameters.base !== undefined ? parameters.base : 1;\n expression = [getInterpolateOperator(parameters), base === 1 ? ['linear'] : ['exponential', base], input];\n }\n else {\n throw new Error(`Unknown zoom function type \"${type}\"`);\n }\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], isStep);\n }\n fixupDegenerateStepCurve(expression);\n return expression;\n}\nfunction fixupDegenerateStepCurve(expression) {\n // degenerate step curve (i.e. a constant function): add a noop stop\n if (expression[0] === 'step' && expression.length === 3) {\n expression.push(0);\n expression.push(expression[3]);\n }\n}\nfunction appendStopPair(curve, input, output, isStep) {\n // Skip duplicate stop values. They were not validated for functions, but they are for expressions.\n // https://github.com/mapbox/mapbox-gl-js/issues/4107\n if (curve.length > 3 && input === curve[curve.length - 2]) {\n return;\n }\n // step curves don't get the first input value, as it is redundant.\n if (!(isStep && curve.length === 2)) {\n curve.push(input);\n }\n curve.push(output);\n}\nfunction getFunctionType(parameters, propertySpec) {\n if (parameters.type) {\n return parameters.type;\n }\n else {\n return propertySpec.expression.interpolated ? 'exponential' : 'interval';\n }\n}\n// \"String with {name} token\" => [\"concat\", \"String with \", [\"get\", \"name\"], \" token\"]\nfunction convertTokenString(s) {\n const result = ['concat'];\n const re = /{([^{}]+)}/g;\n let pos = 0;\n for (let match = re.exec(s); match !== null; match = re.exec(s)) {\n const literal = s.slice(pos, re.lastIndex - match[0].length);\n pos = re.lastIndex;\n if (literal.length > 0)\n result.push(literal);\n result.push(['get', match[1]]);\n }\n if (result.length === 1) {\n return s;\n }\n if (pos < s.length) {\n result.push(s.slice(pos));\n }\n else if (result.length === 2) {\n return ['to-string', result[1]];\n }\n return result;\n}\n\nfunction getPropertyReference(propertyName) {\n for (let i = 0; i < v8Spec.layout.length; i++) {\n for (const key in v8Spec[v8Spec.layout[i]]) {\n if (key === propertyName)\n return v8Spec[v8Spec.layout[i]][key];\n }\n }\n for (let i = 0; i < v8Spec.paint.length; i++) {\n for (const key in v8Spec[v8Spec.paint[i]]) {\n if (key === propertyName)\n return v8Spec[v8Spec.paint[i]][key];\n }\n }\n return null;\n}\nfunction eachSource(style, callback) {\n for (const k in style.sources) {\n callback(style.sources[k]);\n }\n}\nfunction eachLayer(style, callback) {\n for (const layer of style.layers) {\n callback(layer);\n }\n}\nfunction eachProperty(style, options, callback) {\n function inner(layer, propertyType) {\n const properties = layer[propertyType];\n if (!properties)\n return;\n Object.keys(properties).forEach((key) => {\n callback({\n path: [layer.id, propertyType, key],\n key,\n value: properties[key],\n reference: getPropertyReference(key),\n set(x) {\n properties[key] = x;\n }\n });\n });\n }\n eachLayer(style, (layer) => {\n if (options.paint) {\n inner(layer, 'paint');\n }\n if (options.layout) {\n inner(layer, 'layout');\n }\n });\n}\n\nfunction stringify$1(obj) {\n const type = typeof obj;\n if (type === 'number' || type === 'boolean' || type === 'string' || obj === undefined || obj === null)\n return JSON.stringify(obj);\n if (Array.isArray(obj)) {\n let str = '[';\n for (const val of obj) {\n str += `${stringify$1(val)},`;\n }\n return `${str}]`;\n }\n const keys = Object.keys(obj).sort();\n let str = '{';\n for (let i = 0; i < keys.length; i++) {\n str += `${JSON.stringify(keys[i])}:${stringify$1(obj[keys[i]])},`;\n }\n return `${str}}`;\n}\nfunction getKey(layer) {\n let key = '';\n for (const k of refProperties) {\n key += `/${stringify$1(layer[k])}`;\n }\n return key;\n}\n/**\n * Given an array of layers, return an array of arrays of layers where all\n * layers in each group have identical layout-affecting properties. These\n * 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 * @private\n * @param {Array} layers\n * @param {Object} [cachedKeys] - an object to keep already calculated keys.\n * @returns {Array>}\n */\nfunction groupByLayout(layers, cachedKeys) {\n const groups = {};\n for (let i = 0; i < layers.length; i++) {\n const k = (cachedKeys && cachedKeys[layers[i].id]) || getKey(layers[i]);\n // update the cache if there is one\n if (cachedKeys)\n cachedKeys[layers[i].id] = k;\n let group = groups[k];\n if (!group) {\n group = groups[k] = [];\n }\n group.push(layers[i]);\n }\n const result = [];\n for (const k in groups) {\n result.push(groups[k]);\n }\n return result;\n}\n\nfunction emptyStyle() {\n const style = {};\n const version = v8Spec['$version'];\n for (const styleKey in v8Spec['$root']) {\n const spec = v8Spec['$root'][styleKey];\n if (spec.required) {\n let value = null;\n if (styleKey === 'version') {\n value = version;\n }\n else {\n if (spec.type === 'array') {\n value = [];\n }\n else {\n value = {};\n }\n }\n if (value != null) {\n style[styleKey] = value;\n }\n }\n }\n return style;\n}\n\nfunction validateConstants(options) {\n const key = options.key;\n const constants = options.value;\n if (constants) {\n return [new ValidationError(key, constants, 'constants have been deprecated as of v8')];\n }\n else {\n return [];\n }\n}\n\n// Turn jsonlint-lines-primitives objects into primitive objects\nfunction unbundle(value) {\n if (value instanceof Number || value instanceof String || value instanceof Boolean) {\n return value.valueOf();\n }\n else {\n return value;\n }\n}\nfunction deepUnbundle(value) {\n if (Array.isArray(value)) {\n return value.map(deepUnbundle);\n }\n else if (value instanceof Object && !(value instanceof Number || value instanceof String || value instanceof Boolean)) {\n const unbundledValue = {};\n for (const key in value) {\n unbundledValue[key] = deepUnbundle(value[key]);\n }\n return unbundledValue;\n }\n return unbundle(value);\n}\n\nfunction validateObject(options) {\n const key = options.key;\n const object = options.value;\n const elementSpecs = options.valueSpec || {};\n const elementValidators = options.objectElementValidators || {};\n const style = options.style;\n const styleSpec = options.styleSpec;\n const validateSpec = options.validateSpec;\n let errors = [];\n const type = getType(object);\n if (type !== 'object') {\n return [new ValidationError(key, object, `object expected, ${type} found`)];\n }\n for (const objectKey in object) {\n const elementSpecKey = objectKey.split('.')[0]; // treat 'paint.*' as 'paint'\n const elementSpec = elementSpecs[elementSpecKey] || elementSpecs['*'];\n let validateElement;\n if (elementValidators[elementSpecKey]) {\n validateElement = elementValidators[elementSpecKey];\n }\n else if (elementSpecs[elementSpecKey]) {\n validateElement = validateSpec;\n }\n else if (elementValidators['*']) {\n validateElement = elementValidators['*'];\n }\n else if (elementSpecs['*']) {\n validateElement = validateSpec;\n }\n else {\n errors.push(new ValidationError(key, object[objectKey], `unknown property \"${objectKey}\"`));\n continue;\n }\n errors = errors.concat(validateElement({\n key: (key ? `${key}.` : key) + objectKey,\n value: object[objectKey],\n valueSpec: elementSpec,\n style,\n styleSpec,\n object,\n objectKey,\n validateSpec,\n }, object));\n }\n for (const elementSpecKey in elementSpecs) {\n // Don't check `required` when there's a custom validator for that property.\n if (elementValidators[elementSpecKey]) {\n continue;\n }\n if (elementSpecs[elementSpecKey].required && elementSpecs[elementSpecKey]['default'] === undefined && object[elementSpecKey] === undefined) {\n errors.push(new ValidationError(key, object, `missing required property \"${elementSpecKey}\"`));\n }\n }\n return errors;\n}\n\nfunction validateArray(options) {\n const array = options.value;\n const arraySpec = options.valueSpec;\n const validateSpec = options.validateSpec;\n const style = options.style;\n const styleSpec = options.styleSpec;\n const key = options.key;\n const validateArrayElement = options.arrayElementValidator || validateSpec;\n if (getType(array) !== 'array') {\n return [new ValidationError(key, array, `array expected, ${getType(array)} found`)];\n }\n if (arraySpec.length && array.length !== arraySpec.length) {\n return [new ValidationError(key, array, `array length ${arraySpec.length} expected, length ${array.length} found`)];\n }\n if (arraySpec['min-length'] && array.length < arraySpec['min-length']) {\n return [new ValidationError(key, array, `array length at least ${arraySpec['min-length']} expected, length ${array.length} found`)];\n }\n let arrayElementSpec = {\n 'type': arraySpec.value,\n 'values': arraySpec.values\n };\n if (styleSpec.$version < 7) {\n arrayElementSpec['function'] = arraySpec.function;\n }\n if (getType(arraySpec.value) === 'object') {\n arrayElementSpec = arraySpec.value;\n }\n let errors = [];\n for (let i = 0; i < array.length; i++) {\n errors = errors.concat(validateArrayElement({\n array,\n arrayIndex: i,\n value: array[i],\n valueSpec: arrayElementSpec,\n validateSpec: options.validateSpec,\n style,\n styleSpec,\n key: `${key}[${i}]`\n }));\n }\n return errors;\n}\n\nfunction validateNumber(options) {\n const key = options.key;\n const value = options.value;\n const valueSpec = options.valueSpec;\n let type = getType(value);\n // eslint-disable-next-line no-self-compare\n if (type === 'number' && value !== value) {\n type = 'NaN';\n }\n if (type !== 'number') {\n return [new ValidationError(key, value, `number expected, ${type} found`)];\n }\n if ('minimum' in valueSpec && value < valueSpec.minimum) {\n return [new ValidationError(key, value, `${value} is less than the minimum value ${valueSpec.minimum}`)];\n }\n if ('maximum' in valueSpec && value > valueSpec.maximum) {\n return [new ValidationError(key, value, `${value} is greater than the maximum value ${valueSpec.maximum}`)];\n }\n return [];\n}\n\nfunction validateFunction(options) {\n const functionValueSpec = options.valueSpec;\n const functionType = unbundle(options.value.type);\n let stopKeyType;\n let stopDomainValues = {};\n let previousStopDomainValue;\n let previousStopDomainZoom;\n const isZoomFunction = functionType !== 'categorical' && options.value.property === undefined;\n const isPropertyFunction = !isZoomFunction;\n const isZoomAndPropertyFunction = getType(options.value.stops) === 'array' &&\n getType(options.value.stops[0]) === 'array' &&\n getType(options.value.stops[0][0]) === 'object';\n const errors = validateObject({\n key: options.key,\n value: options.value,\n valueSpec: options.styleSpec.function,\n validateSpec: options.validateSpec,\n style: options.style,\n styleSpec: options.styleSpec,\n objectElementValidators: {\n stops: validateFunctionStops,\n default: validateFunctionDefault\n }\n });\n if (functionType === 'identity' && isZoomFunction) {\n errors.push(new ValidationError(options.key, options.value, 'missing required property \"property\"'));\n }\n if (functionType !== 'identity' && !options.value.stops) {\n errors.push(new ValidationError(options.key, options.value, 'missing required property \"stops\"'));\n }\n if (functionType === 'exponential' && options.valueSpec.expression && !supportsInterpolation(options.valueSpec)) {\n errors.push(new ValidationError(options.key, options.value, 'exponential functions not supported'));\n }\n if (options.styleSpec.$version >= 8) {\n if (isPropertyFunction && !supportsPropertyExpression(options.valueSpec)) {\n errors.push(new ValidationError(options.key, options.value, 'property functions not supported'));\n }\n else if (isZoomFunction && !supportsZoomExpression(options.valueSpec)) {\n errors.push(new ValidationError(options.key, options.value, 'zoom functions not supported'));\n }\n }\n if ((functionType === 'categorical' || isZoomAndPropertyFunction) && options.value.property === undefined) {\n errors.push(new ValidationError(options.key, options.value, '\"property\" property is required'));\n }\n return errors;\n function validateFunctionStops(options) {\n if (functionType === 'identity') {\n return [new ValidationError(options.key, options.value, 'identity function may not have a \"stops\" property')];\n }\n let errors = [];\n const value = options.value;\n errors = errors.concat(validateArray({\n key: options.key,\n value,\n valueSpec: options.valueSpec,\n validateSpec: options.validateSpec,\n style: options.style,\n styleSpec: options.styleSpec,\n arrayElementValidator: validateFunctionStop\n }));\n if (getType(value) === 'array' && value.length === 0) {\n errors.push(new ValidationError(options.key, value, 'array must have at least one stop'));\n }\n return errors;\n }\n function validateFunctionStop(options) {\n let errors = [];\n const value = options.value;\n const key = options.key;\n if (getType(value) !== 'array') {\n return [new ValidationError(key, value, `array expected, ${getType(value)} found`)];\n }\n if (value.length !== 2) {\n return [new ValidationError(key, value, `array length 2 expected, length ${value.length} found`)];\n }\n if (isZoomAndPropertyFunction) {\n if (getType(value[0]) !== 'object') {\n return [new ValidationError(key, value, `object expected, ${getType(value[0])} found`)];\n }\n if (value[0].zoom === undefined) {\n return [new ValidationError(key, value, 'object stop key must have zoom')];\n }\n if (value[0].value === undefined) {\n return [new ValidationError(key, value, 'object stop key must have value')];\n }\n if (previousStopDomainZoom && previousStopDomainZoom > unbundle(value[0].zoom)) {\n return [new ValidationError(key, value[0].zoom, 'stop zoom values must appear in ascending order')];\n }\n if (unbundle(value[0].zoom) !== previousStopDomainZoom) {\n previousStopDomainZoom = unbundle(value[0].zoom);\n previousStopDomainValue = undefined;\n stopDomainValues = {};\n }\n errors = errors.concat(validateObject({\n key: `${key}[0]`,\n value: value[0],\n valueSpec: { zoom: {} },\n validateSpec: options.validateSpec,\n style: options.style,\n styleSpec: options.styleSpec,\n objectElementValidators: { zoom: validateNumber, value: validateStopDomainValue }\n }));\n }\n else {\n errors = errors.concat(validateStopDomainValue({\n key: `${key}[0]`,\n value: value[0],\n valueSpec: {},\n validateSpec: options.validateSpec,\n style: options.style,\n styleSpec: options.styleSpec\n }, value));\n }\n if (isExpression(deepUnbundle(value[1]))) {\n return errors.concat([new ValidationError(`${key}[1]`, value[1], 'expressions are not allowed in function stops.')]);\n }\n return errors.concat(options.validateSpec({\n key: `${key}[1]`,\n value: value[1],\n valueSpec: functionValueSpec,\n validateSpec: options.validateSpec,\n style: options.style,\n styleSpec: options.styleSpec\n }));\n }\n function validateStopDomainValue(options, stop) {\n const type = getType(options.value);\n const value = unbundle(options.value);\n const reportValue = options.value !== null ? options.value : stop;\n if (!stopKeyType) {\n stopKeyType = type;\n }\n else if (type !== stopKeyType) {\n return [new ValidationError(options.key, reportValue, `${type} stop domain type must match previous stop domain type ${stopKeyType}`)];\n }\n if (type !== 'number' && type !== 'string' && type !== 'boolean') {\n return [new ValidationError(options.key, reportValue, 'stop domain value must be a number, string, or boolean')];\n }\n if (type !== 'number' && functionType !== 'categorical') {\n let message = `number expected, ${type} found`;\n if (supportsPropertyExpression(functionValueSpec) && functionType === undefined) {\n message += '\\nIf you intended to use a categorical function, specify `\"type\": \"categorical\"`.';\n }\n return [new ValidationError(options.key, reportValue, message)];\n }\n if (functionType === 'categorical' && type === 'number' && (!isFinite(value) || Math.floor(value) !== value)) {\n return [new ValidationError(options.key, reportValue, `integer expected, found ${value}`)];\n }\n if (functionType !== 'categorical' && type === 'number' && previousStopDomainValue !== undefined && value < previousStopDomainValue) {\n return [new ValidationError(options.key, reportValue, 'stop domain values must appear in ascending order')];\n }\n else {\n previousStopDomainValue = value;\n }\n if (functionType === 'categorical' && value in stopDomainValues) {\n return [new ValidationError(options.key, reportValue, 'stop domain values must be unique')];\n }\n else {\n stopDomainValues[value] = true;\n }\n return [];\n }\n function validateFunctionDefault(options) {\n return options.validateSpec({\n key: options.key,\n value: options.value,\n valueSpec: functionValueSpec,\n validateSpec: options.validateSpec,\n style: options.style,\n styleSpec: options.styleSpec\n });\n }\n}\n\nfunction validateExpression(options) {\n const expression = (options.expressionContext === 'property' ? createPropertyExpression : createExpression)(deepUnbundle(options.value), options.valueSpec);\n if (expression.result === 'error') {\n return expression.value.map((error) => {\n return new ValidationError(`${options.key}${error.key}`, options.value, error.message);\n });\n }\n const expressionObj = expression.value.expression || expression.value._styleExpression.expression;\n if (options.expressionContext === 'property' && (options.propertyKey === 'text-font') &&\n !expressionObj.outputDefined()) {\n return [new ValidationError(options.key, options.value, `Invalid data expression for \"${options.propertyKey}\". Output values must be contained as literals within the expression.`)];\n }\n if (options.expressionContext === 'property' && options.propertyType === 'layout' &&\n (!isStateConstant(expressionObj))) {\n return [new ValidationError(options.key, options.value, '\"feature-state\" data expressions are not supported with layout properties.')];\n }\n if (options.expressionContext === 'filter' && !isStateConstant(expressionObj)) {\n return [new ValidationError(options.key, options.value, '\"feature-state\" data expressions are not supported with filters.')];\n }\n if (options.expressionContext && options.expressionContext.indexOf('cluster') === 0) {\n if (!isGlobalPropertyConstant(expressionObj, ['zoom', 'feature-state'])) {\n return [new ValidationError(options.key, options.value, '\"zoom\" and \"feature-state\" expressions are not supported with cluster properties.')];\n }\n if (options.expressionContext === 'cluster-initial' && !isFeatureConstant(expressionObj)) {\n return [new ValidationError(options.key, options.value, 'Feature data expressions are not supported with initial expression part of cluster properties.')];\n }\n }\n return [];\n}\n\nfunction validateBoolean(options) {\n const value = options.value;\n const key = options.key;\n const type = getType(value);\n if (type !== 'boolean') {\n return [new ValidationError(key, value, `boolean expected, ${type} found`)];\n }\n return [];\n}\n\nfunction validateColor(options) {\n const key = options.key;\n const value = options.value;\n const type = getType(value);\n if (type !== 'string') {\n return [new ValidationError(key, value, `color expected, ${type} found`)];\n }\n if (!Color.parse(String(value))) { // cast String object to string primitive\n return [new ValidationError(key, value, `color expected, \"${value}\" found`)];\n }\n return [];\n}\n\nfunction validateEnum(options) {\n const key = options.key;\n const value = options.value;\n const valueSpec = options.valueSpec;\n const errors = [];\n if (Array.isArray(valueSpec.values)) { // <=v7\n if (valueSpec.values.indexOf(unbundle(value)) === -1) {\n errors.push(new ValidationError(key, value, `expected one of [${valueSpec.values.join(', ')}], ${JSON.stringify(value)} found`));\n }\n }\n else { // >=v8\n if (Object.keys(valueSpec.values).indexOf(unbundle(value)) === -1) {\n errors.push(new ValidationError(key, value, `expected one of [${Object.keys(valueSpec.values).join(', ')}], ${JSON.stringify(value)} found`));\n }\n }\n return errors;\n}\n\nfunction validateFilter(options) {\n if (isExpressionFilter(deepUnbundle(options.value))) {\n return validateExpression(extendBy({}, options, {\n expressionContext: 'filter',\n valueSpec: { value: 'boolean' }\n }));\n }\n else {\n return validateNonExpressionFilter(options);\n }\n}\nfunction validateNonExpressionFilter(options) {\n const value = options.value;\n const key = options.key;\n if (getType(value) !== 'array') {\n return [new ValidationError(key, value, `array expected, ${getType(value)} found`)];\n }\n const styleSpec = options.styleSpec;\n let type;\n let errors = [];\n if (value.length < 1) {\n return [new ValidationError(key, value, 'filter array must have at least 1 element')];\n }\n errors = errors.concat(validateEnum({\n key: `${key}[0]`,\n value: value[0],\n valueSpec: styleSpec.filter_operator,\n style: options.style,\n styleSpec: options.styleSpec\n }));\n switch (unbundle(value[0])) {\n case '<':\n case '<=':\n case '>':\n case '>=':\n if (value.length >= 2 && unbundle(value[1]) === '$type') {\n errors.push(new ValidationError(key, value, `\"$type\" cannot be use with operator \"${value[0]}\"`));\n }\n /* falls through */\n case '==':\n case '!=':\n if (value.length !== 3) {\n errors.push(new ValidationError(key, value, `filter array for operator \"${value[0]}\" must have 3 elements`));\n }\n /* falls through */\n case 'in':\n case '!in':\n if (value.length >= 2) {\n type = getType(value[1]);\n if (type !== 'string') {\n errors.push(new ValidationError(`${key}[1]`, value[1], `string expected, ${type} found`));\n }\n }\n for (let i = 2; i < value.length; i++) {\n type = getType(value[i]);\n if (unbundle(value[1]) === '$type') {\n errors = errors.concat(validateEnum({\n key: `${key}[${i}]`,\n value: value[i],\n valueSpec: styleSpec.geometry_type,\n style: options.style,\n styleSpec: options.styleSpec\n }));\n }\n else if (type !== 'string' && type !== 'number' && type !== 'boolean') {\n errors.push(new ValidationError(`${key}[${i}]`, value[i], `string, number, or boolean expected, ${type} found`));\n }\n }\n break;\n case 'any':\n case 'all':\n case 'none':\n for (let i = 1; i < value.length; i++) {\n errors = errors.concat(validateNonExpressionFilter({\n key: `${key}[${i}]`,\n value: value[i],\n style: options.style,\n styleSpec: options.styleSpec\n }));\n }\n break;\n case 'has':\n case '!has':\n type = getType(value[1]);\n if (value.length !== 2) {\n errors.push(new ValidationError(key, value, `filter array for \"${value[0]}\" operator must have 2 elements`));\n }\n else if (type !== 'string') {\n errors.push(new ValidationError(`${key}[1]`, value[1], `string expected, ${type} found`));\n }\n break;\n }\n return errors;\n}\n\nfunction validateProperty(options, propertyType) {\n const key = options.key;\n const validateSpec = options.validateSpec;\n const style = options.style;\n const styleSpec = options.styleSpec;\n const value = options.value;\n const propertyKey = options.objectKey;\n const layerSpec = styleSpec[`${propertyType}_${options.layerType}`];\n if (!layerSpec)\n return [];\n const transitionMatch = propertyKey.match(/^(.*)-transition$/);\n if (propertyType === 'paint' && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) {\n return validateSpec({\n key,\n value,\n valueSpec: styleSpec.transition,\n style,\n styleSpec\n });\n }\n const valueSpec = options.valueSpec || layerSpec[propertyKey];\n if (!valueSpec) {\n return [new ValidationError(key, value, `unknown property \"${propertyKey}\"`)];\n }\n let tokenMatch;\n if (getType(value) === 'string' && supportsPropertyExpression(valueSpec) && !valueSpec.tokens && (tokenMatch = /^{([^}]+)}$/.exec(value))) {\n return [new ValidationError(key, value, `\"${propertyKey}\" does not support interpolation syntax\\n` +\n `Use an identity property function instead: \\`{ \"type\": \"identity\", \"property\": ${JSON.stringify(tokenMatch[1])} }\\`.`)];\n }\n const errors = [];\n if (options.layerType === 'symbol') {\n if (propertyKey === 'text-field' && style && !style.glyphs) {\n errors.push(new ValidationError(key, value, 'use of \"text-field\" requires a style \"glyphs\" property'));\n }\n if (propertyKey === 'text-font' && isFunction$1(deepUnbundle(value)) && unbundle(value.type) === 'identity') {\n errors.push(new ValidationError(key, value, '\"text-font\" does not support identity functions'));\n }\n }\n return errors.concat(validateSpec({\n key: options.key,\n value,\n valueSpec,\n style,\n styleSpec,\n expressionContext: 'property',\n propertyType,\n propertyKey\n }));\n}\n\nfunction validatePaintProperty(options) {\n return validateProperty(options, 'paint');\n}\n\nfunction validateLayoutProperty(options) {\n return validateProperty(options, 'layout');\n}\n\nfunction validateLayer(options) {\n let errors = [];\n const layer = options.value;\n const key = options.key;\n const style = options.style;\n const styleSpec = options.styleSpec;\n if (!layer.type && !layer.ref) {\n errors.push(new ValidationError(key, layer, 'either \"type\" or \"ref\" is required'));\n }\n let type = unbundle(layer.type);\n const ref = unbundle(layer.ref);\n if (layer.id) {\n const layerId = unbundle(layer.id);\n for (let i = 0; i < options.arrayIndex; i++) {\n const otherLayer = style.layers[i];\n if (unbundle(otherLayer.id) === layerId) {\n errors.push(new ValidationError(key, layer.id, `duplicate layer id \"${layer.id}\", previously used at line ${otherLayer.id.__line__}`));\n }\n }\n }\n if ('ref' in layer) {\n ['type', 'source', 'source-layer', 'filter', 'layout'].forEach((p) => {\n if (p in layer) {\n errors.push(new ValidationError(key, layer[p], `\"${p}\" is prohibited for ref layers`));\n }\n });\n let parent;\n style.layers.forEach((layer) => {\n if (unbundle(layer.id) === ref)\n parent = layer;\n });\n if (!parent) {\n errors.push(new ValidationError(key, layer.ref, `ref layer \"${ref}\" not found`));\n }\n else if (parent.ref) {\n errors.push(new ValidationError(key, layer.ref, 'ref cannot reference another ref layer'));\n }\n else {\n type = unbundle(parent.type);\n }\n }\n else if (type !== 'background') {\n if (!layer.source) {\n errors.push(new ValidationError(key, layer, 'missing required property \"source\"'));\n }\n else {\n const source = style.sources && style.sources[layer.source];\n const sourceType = source && unbundle(source.type);\n if (!source) {\n errors.push(new ValidationError(key, layer.source, `source \"${layer.source}\" not found`));\n }\n else if (sourceType === 'vector' && type === 'raster') {\n errors.push(new ValidationError(key, layer.source, `layer \"${layer.id}\" requires a raster source`));\n }\n else if (sourceType !== 'raster-dem' && type === 'hillshade') {\n errors.push(new ValidationError(key, layer.source, `layer \"${layer.id}\" requires a raster-dem source`));\n }\n else if (sourceType === 'raster' && type !== 'raster') {\n errors.push(new ValidationError(key, layer.source, `layer \"${layer.id}\" requires a vector source`));\n }\n else if (sourceType === 'vector' && !layer['source-layer']) {\n errors.push(new ValidationError(key, layer, `layer \"${layer.id}\" must specify a \"source-layer\"`));\n }\n else if (sourceType === 'raster-dem' && type !== 'hillshade') {\n errors.push(new ValidationError(key, layer.source, 'raster-dem source can only be used with layer type \\'hillshade\\'.'));\n }\n else if (type === 'line' && layer.paint && layer.paint['line-gradient'] &&\n (sourceType !== 'geojson' || !source.lineMetrics)) {\n errors.push(new ValidationError(key, layer, `layer \"${layer.id}\" specifies a line-gradient, which requires a GeoJSON source with \\`lineMetrics\\` enabled.`));\n }\n }\n }\n errors = errors.concat(validateObject({\n key,\n value: layer,\n valueSpec: styleSpec.layer,\n style: options.style,\n styleSpec: options.styleSpec,\n validateSpec: options.validateSpec,\n objectElementValidators: {\n '*'() {\n return [];\n },\n // We don't want to enforce the spec's `\"requires\": true` for backward compatibility with refs;\n // the actual requirement is validated above. See https://github.com/mapbox/mapbox-gl-js/issues/5772.\n type() {\n return options.validateSpec({\n key: `${key}.type`,\n value: layer.type,\n valueSpec: styleSpec.layer.type,\n style: options.style,\n styleSpec: options.styleSpec,\n validateSpec: options.validateSpec,\n object: layer,\n objectKey: 'type'\n });\n },\n filter: validateFilter,\n layout(options) {\n return validateObject({\n layer,\n key: options.key,\n value: options.value,\n style: options.style,\n styleSpec: options.styleSpec,\n validateSpec: options.validateSpec,\n objectElementValidators: {\n '*'(options) {\n return validateLayoutProperty(extendBy({ layerType: type }, options));\n }\n }\n });\n },\n paint(options) {\n return validateObject({\n layer,\n key: options.key,\n value: options.value,\n style: options.style,\n styleSpec: options.styleSpec,\n validateSpec: options.validateSpec,\n objectElementValidators: {\n '*'(options) {\n return validatePaintProperty(extendBy({ layerType: type }, options));\n }\n }\n });\n }\n }\n }));\n return errors;\n}\n\nfunction validateString(options) {\n const value = options.value;\n const key = options.key;\n const type = getType(value);\n if (type !== 'string') {\n return [new ValidationError(key, value, `string expected, ${type} found`)];\n }\n return [];\n}\n\nfunction validateRasterDEMSource(options) {\n var _a;\n const sourceName = (_a = options.sourceName) !== null && _a !== void 0 ? _a : '';\n const rasterDEM = options.value;\n const styleSpec = options.styleSpec;\n const rasterDEMSpec = styleSpec.source_raster_dem;\n const style = options.style;\n let errors = [];\n const rootType = getType(rasterDEM);\n if (rasterDEM === undefined) {\n return errors;\n }\n else if (rootType !== 'object') {\n errors.push(new ValidationError('source_raster_dem', rasterDEM, `object expected, ${rootType} found`));\n return errors;\n }\n const encoding = unbundle(rasterDEM.encoding);\n const isCustomEncoding = encoding === 'custom';\n const customEncodingKeys = ['redFactor', 'greenFactor', 'blueFactor', 'baseShift'];\n const encodingName = options.value.encoding ? `\"${options.value.encoding}\"` : 'Default';\n for (const key in rasterDEM) {\n if (!isCustomEncoding && customEncodingKeys.includes(key)) {\n errors.push(new ValidationError(key, rasterDEM[key], `In \"${sourceName}\": \"${key}\" is only valid when \"encoding\" is set to \"custom\". ${encodingName} encoding found`));\n }\n else if (rasterDEMSpec[key]) {\n errors = errors.concat(options.validateSpec({\n key,\n value: rasterDEM[key],\n valueSpec: rasterDEMSpec[key],\n validateSpec: options.validateSpec,\n style,\n styleSpec\n }));\n }\n else {\n errors.push(new ValidationError(key, rasterDEM[key], `unknown property \"${key}\"`));\n }\n }\n return errors;\n}\n\nconst objectElementValidators = {\n promoteId: validatePromoteId\n};\nfunction validateSource(options) {\n const value = options.value;\n const key = options.key;\n const styleSpec = options.styleSpec;\n const style = options.style;\n const validateSpec = options.validateSpec;\n if (!value.type) {\n return [new ValidationError(key, value, '\"type\" is required')];\n }\n const type = unbundle(value.type);\n let errors;\n switch (type) {\n case 'vector':\n case 'raster':\n errors = validateObject({\n key,\n value,\n valueSpec: styleSpec[`source_${type.replace('-', '_')}`],\n style: options.style,\n styleSpec,\n objectElementValidators,\n validateSpec,\n });\n return errors;\n case 'raster-dem':\n errors = validateRasterDEMSource({\n sourceName: key,\n value,\n style: options.style,\n styleSpec,\n validateSpec,\n });\n return errors;\n case 'geojson':\n errors = validateObject({\n key,\n value,\n valueSpec: styleSpec.source_geojson,\n style,\n styleSpec,\n validateSpec,\n objectElementValidators\n });\n if (value.cluster) {\n for (const prop in value.clusterProperties) {\n const [operator, mapExpr] = value.clusterProperties[prop];\n const reduceExpr = typeof operator === 'string' ? [operator, ['accumulated'], ['get', prop]] : operator;\n errors.push(...validateExpression({\n key: `${key}.${prop}.map`,\n value: mapExpr,\n validateSpec,\n expressionContext: 'cluster-map'\n }));\n errors.push(...validateExpression({\n key: `${key}.${prop}.reduce`,\n value: reduceExpr,\n validateSpec,\n expressionContext: 'cluster-reduce'\n }));\n }\n }\n return errors;\n case 'video':\n return validateObject({\n key,\n value,\n valueSpec: styleSpec.source_video,\n style,\n validateSpec,\n styleSpec\n });\n case 'image':\n return validateObject({\n key,\n value,\n valueSpec: styleSpec.source_image,\n style,\n validateSpec,\n styleSpec\n });\n case 'canvas':\n return [new ValidationError(key, null, 'Please use runtime APIs to add canvas sources, rather than including them in stylesheets.', 'source.canvas')];\n default:\n return validateEnum({\n key: `${key}.type`,\n value: value.type,\n valueSpec: { values: ['vector', 'raster', 'raster-dem', 'geojson', 'video', 'image'] },\n style,\n validateSpec,\n styleSpec\n });\n }\n}\nfunction validatePromoteId({ key, value }) {\n if (getType(value) === 'string') {\n return validateString({ key, value });\n }\n else {\n const errors = [];\n for (const prop in value) {\n errors.push(...validateString({ key: `${key}.${prop}`, value: value[prop] }));\n }\n return errors;\n }\n}\n\nfunction validateLight(options) {\n const light = options.value;\n const styleSpec = options.styleSpec;\n const lightSpec = styleSpec.light;\n const style = options.style;\n let errors = [];\n const rootType = getType(light);\n if (light === undefined) {\n return errors;\n }\n else if (rootType !== 'object') {\n errors = errors.concat([new ValidationError('light', light, `object expected, ${rootType} found`)]);\n return errors;\n }\n for (const key in light) {\n const transitionMatch = key.match(/^(.*)-transition$/);\n if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {\n errors = errors.concat(options.validateSpec({\n key,\n value: light[key],\n valueSpec: styleSpec.transition,\n validateSpec: options.validateSpec,\n style,\n styleSpec\n }));\n }\n else if (lightSpec[key]) {\n errors = errors.concat(options.validateSpec({\n key,\n value: light[key],\n valueSpec: lightSpec[key],\n validateSpec: options.validateSpec,\n style,\n styleSpec\n }));\n }\n else {\n errors = errors.concat([new ValidationError(key, light[key], `unknown property \"${key}\"`)]);\n }\n }\n return errors;\n}\n\nfunction validateSky(options) {\n const sky = options.value;\n const styleSpec = options.styleSpec;\n const skySpec = styleSpec.sky;\n const style = options.style;\n const rootType = getType(sky);\n if (sky === undefined) {\n return [];\n }\n else if (rootType !== 'object') {\n return [new ValidationError('sky', sky, `object expected, ${rootType} found`)];\n }\n let errors = [];\n for (const key in sky) {\n if (skySpec[key]) {\n errors = errors.concat(options.validateSpec({\n key,\n value: sky[key],\n valueSpec: skySpec[key],\n style,\n styleSpec\n }));\n }\n else {\n errors = errors.concat([new ValidationError(key, sky[key], `unknown property \"${key}\"`)]);\n }\n }\n return errors;\n}\n\nfunction validateTerrain(options) {\n const terrain = options.value;\n const styleSpec = options.styleSpec;\n const terrainSpec = styleSpec.terrain;\n const style = options.style;\n let errors = [];\n const rootType = getType(terrain);\n if (terrain === undefined) {\n return errors;\n }\n else if (rootType !== 'object') {\n errors = errors.concat([new ValidationError('terrain', terrain, `object expected, ${rootType} found`)]);\n return errors;\n }\n for (const key in terrain) {\n if (terrainSpec[key]) {\n errors = errors.concat(options.validateSpec({\n key,\n value: terrain[key],\n valueSpec: terrainSpec[key],\n validateSpec: options.validateSpec,\n style,\n styleSpec\n }));\n }\n else {\n errors = errors.concat([new ValidationError(key, terrain[key], `unknown property \"${key}\"`)]);\n }\n }\n return errors;\n}\n\nfunction validateFormatted(options) {\n if (validateString(options).length === 0) {\n return [];\n }\n return validateExpression(options);\n}\n\nfunction validateImage(options) {\n if (validateString(options).length === 0) {\n return [];\n }\n return validateExpression(options);\n}\n\nfunction validatePadding(options) {\n const key = options.key;\n const value = options.value;\n const type = getType(value);\n if (type === 'array') {\n if (value.length < 1 || value.length > 4) {\n return [new ValidationError(key, value, `padding requires 1 to 4 values; ${value.length} values found`)];\n }\n const arrayElementSpec = {\n type: 'number'\n };\n let errors = [];\n for (let i = 0; i < value.length; i++) {\n errors = errors.concat(options.validateSpec({\n key: `${key}[${i}]`,\n value: value[i],\n validateSpec: options.validateSpec,\n valueSpec: arrayElementSpec\n }));\n }\n return errors;\n }\n else {\n return validateNumber({\n key,\n value,\n valueSpec: {}\n });\n }\n}\n\nfunction validateVariableAnchorOffsetCollection(options) {\n const key = options.key;\n const value = options.value;\n const type = getType(value);\n const styleSpec = options.styleSpec;\n if (type !== 'array' || value.length < 1 || value.length % 2 !== 0) {\n return [new ValidationError(key, value, 'variableAnchorOffsetCollection requires a non-empty array of even length')];\n }\n let errors = [];\n for (let i = 0; i < value.length; i += 2) {\n // Elements in even positions should be values from text-anchor enum\n errors = errors.concat(validateEnum({\n key: `${key}[${i}]`,\n value: value[i],\n valueSpec: styleSpec['layout_symbol']['text-anchor']\n }));\n // Elements in odd positions should be points (2-element numeric arrays)\n errors = errors.concat(validateArray({\n key: `${key}[${i + 1}]`,\n value: value[i + 1],\n valueSpec: {\n length: 2,\n value: 'number'\n },\n validateSpec: options.validateSpec,\n style: options.style,\n styleSpec\n }));\n }\n return errors;\n}\n\nfunction validateSprite(options) {\n let errors = [];\n const sprite = options.value;\n const key = options.key;\n if (!Array.isArray(sprite)) {\n return validateString({\n key,\n value: sprite\n });\n }\n else {\n const allSpriteIds = [];\n const allSpriteURLs = [];\n for (const i in sprite) {\n if (sprite[i].id && allSpriteIds.includes(sprite[i].id))\n errors.push(new ValidationError(key, sprite, `all the sprites' ids must be unique, but ${sprite[i].id} is duplicated`));\n allSpriteIds.push(sprite[i].id);\n if (sprite[i].url && allSpriteURLs.includes(sprite[i].url))\n errors.push(new ValidationError(key, sprite, `all the sprites' URLs must be unique, but ${sprite[i].url} is duplicated`));\n allSpriteURLs.push(sprite[i].url);\n const pairSpec = {\n id: {\n type: 'string',\n required: true,\n },\n url: {\n type: 'string',\n required: true,\n }\n };\n errors = errors.concat(validateObject({\n key: `${key}[${i}]`,\n value: sprite[i],\n valueSpec: pairSpec,\n validateSpec: options.validateSpec,\n }));\n }\n return errors;\n }\n}\n\nfunction validateProjection(options) {\n const projection = options.value;\n const styleSpec = options.styleSpec;\n const projectionSpec = styleSpec.projection;\n const style = options.style;\n const rootType = getType(projection);\n if (projection === undefined) {\n return [];\n }\n else if (rootType !== 'object') {\n return [new ValidationError('projection', projection, `object expected, ${rootType} found`)];\n }\n let errors = [];\n for (const key in projection) {\n if (projectionSpec[key]) {\n errors = errors.concat(options.validateSpec({\n key,\n value: projection[key],\n valueSpec: projectionSpec[key],\n style,\n styleSpec\n }));\n }\n else {\n errors = errors.concat([new ValidationError(key, projection[key], `unknown property \"${key}\"`)]);\n }\n }\n return errors;\n}\n\nconst VALIDATORS = {\n '*'() {\n return [];\n },\n 'array': validateArray,\n 'boolean': validateBoolean,\n 'number': validateNumber,\n 'color': validateColor,\n 'constants': validateConstants,\n 'enum': validateEnum,\n 'filter': validateFilter,\n 'function': validateFunction,\n 'layer': validateLayer,\n 'object': validateObject,\n 'source': validateSource,\n 'light': validateLight,\n 'sky': validateSky,\n 'terrain': validateTerrain,\n 'projection': validateProjection,\n 'string': validateString,\n 'formatted': validateFormatted,\n 'resolvedImage': validateImage,\n 'padding': validatePadding,\n 'variableAnchorOffsetCollection': validateVariableAnchorOffsetCollection,\n 'sprite': validateSprite,\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 const value = options.value;\n const valueSpec = options.valueSpec;\n const styleSpec = options.styleSpec;\n options.validateSpec = validate;\n if (valueSpec.expression && isFunction$1(unbundle(value))) {\n return validateFunction(options);\n }\n else if (valueSpec.expression && isExpression(deepUnbundle(value))) {\n return validateExpression(options);\n }\n else if (valueSpec.type && VALIDATORS[valueSpec.type]) {\n return VALIDATORS[valueSpec.type](options);\n }\n else {\n const valid = validateObject(extendBy({}, options, {\n valueSpec: valueSpec.type ? styleSpec[valueSpec.type] : valueSpec\n }));\n return valid;\n }\n}\n\nfunction validateGlyphsUrl(options) {\n const value = options.value;\n const key = options.key;\n const errors = validateString(options);\n if (errors.length)\n return errors;\n if (value.indexOf('{fontstack}') === -1) {\n errors.push(new ValidationError(key, value, '\"glyphs\" url must include a \"{fontstack}\" token'));\n }\n if (value.indexOf('{range}') === -1) {\n errors.push(new ValidationError(key, value, '\"glyphs\" url must include a \"{range}\" token'));\n }\n return errors;\n}\n\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 = v8Spec) {\n let errors = [];\n errors = errors.concat(validate({\n key: '',\n value: style,\n valueSpec: styleSpec.$root,\n styleSpec,\n style,\n validateSpec: validate,\n objectElementValidators: {\n glyphs: validateGlyphsUrl,\n '*'() {\n return [];\n }\n }\n }));\n if (style['constants']) {\n errors = errors.concat(validateConstants({\n key: 'constants',\n value: style['constants'],\n style,\n styleSpec,\n validateSpec: validate,\n }));\n }\n return 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.layer = wrapCleanErrors(injectValidateSpec(validateLayer));\nvalidateStyleMin.filter = wrapCleanErrors(injectValidateSpec(validateFilter));\nvalidateStyleMin.paintProperty = wrapCleanErrors(injectValidateSpec(validatePaintProperty));\nvalidateStyleMin.layoutProperty = wrapCleanErrors(injectValidateSpec(validateLayoutProperty));\nfunction injectValidateSpec(validator) {\n return function (options) {\n return validator({\n ...options,\n validateSpec: validate,\n });\n };\n}\nfunction sortErrors(errors) {\n return [].concat(errors).sort((a, b) => {\n return a.line - b.line;\n });\n}\nfunction wrapCleanErrors(inner) {\n return function (...args) {\n return sortErrors(inner.apply(this, args));\n };\n}\n\n// Note: This regex matches even invalid JSON strings, but since we’re\n// working on the output of `JSON.stringify` we know that only valid strings\n// are present (unless the user supplied a weird `options.indent` but in\n// that case we don’t care since the output would be invalid anyway).\nconst stringOrChar = /(\"(?:[^\\\\\"]|\\\\.)*\")|[:,]/g;\n\nfunction stringify(passedObj, options = {}) {\n const indent = JSON.stringify(\n [1],\n undefined,\n options.indent === undefined ? 2 : options.indent\n ).slice(2, -3);\n\n const maxLength =\n indent === \"\"\n ? Infinity\n : options.maxLength === undefined\n ? 80\n : options.maxLength;\n\n let { replacer } = options;\n\n return (function _stringify(obj, currentIndent, reserved) {\n if (obj && typeof obj.toJSON === \"function\") {\n obj = obj.toJSON();\n }\n\n const string = JSON.stringify(obj, replacer);\n\n if (string === undefined) {\n return string;\n }\n\n const length = maxLength - currentIndent.length - reserved;\n\n if (string.length <= length) {\n const prettified = string.replace(\n stringOrChar,\n (match, stringLiteral) => {\n return stringLiteral || `${match} `;\n }\n );\n if (prettified.length <= length) {\n return prettified;\n }\n }\n\n if (replacer != null) {\n obj = JSON.parse(string);\n replacer = undefined;\n }\n\n if (typeof obj === \"object\" && obj !== null) {\n const nextIndent = currentIndent + indent;\n const items = [];\n let index = 0;\n let start;\n let end;\n\n if (Array.isArray(obj)) {\n start = \"[\";\n end = \"]\";\n const { length } = obj;\n for (; index < length; index++) {\n items.push(\n _stringify(obj[index], nextIndent, index === length - 1 ? 0 : 1) ||\n \"null\"\n );\n }\n } else {\n start = \"{\";\n end = \"}\";\n const keys = Object.keys(obj);\n const { length } = keys;\n for (; index < length; index++) {\n const key = keys[index];\n const keyPart = `${JSON.stringify(key)}: `;\n const value = _stringify(\n obj[key],\n nextIndent,\n keyPart.length + (index === length - 1 ? 0 : 1)\n );\n if (value !== undefined) {\n items.push(keyPart + value);\n }\n }\n }\n\n if (items.length > 0) {\n return [start, indent + items.join(`,\\n${nextIndent}`), end].join(\n `\\n${currentIndent}`\n );\n }\n }\n\n return string;\n })(passedObj, \"\", 0);\n}\n\nfunction sortKeysBy(obj, reference) {\n const result = {};\n for (const key in reference) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n for (const key in obj) {\n if (result[key] === undefined) {\n result[key] = obj[key];\n }\n }\n return 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 style = sortKeysBy(style, v8Spec.$root);\n if (style.layers) {\n style.layers = style.layers.map((layer) => sortKeysBy(layer, v8Spec.layer));\n }\n return stringify(style, { indent: space });\n}\n\nfunction eachLayout(layer, callback) {\n for (const k in layer) {\n if (k.indexOf('layout') === 0) {\n callback(layer[k], k);\n }\n }\n}\nfunction eachPaint(layer, callback) {\n for (const k in layer) {\n if (k.indexOf('paint') === 0) {\n callback(layer[k], k);\n }\n }\n}\nfunction resolveConstant(style, value) {\n if (typeof value === 'string' && value[0] === '@') {\n return resolveConstant(style, style.constants[value]);\n }\n else {\n return value;\n }\n}\nfunction isFunction(value) {\n return Array.isArray(value.stops);\n}\nfunction renameProperty(obj, from, to) {\n obj[to] = obj[from];\n delete obj[from];\n}\nfunction migrateV8(style) {\n style.version = 8;\n // Rename properties, reverse coordinates in source and layers\n eachSource(style, (source) => {\n if (source.type === 'video' && source['url'] !== undefined) {\n renameProperty(source, 'url', 'urls');\n }\n if (source.type === 'video') {\n source.coordinates.forEach((coord) => {\n return coord.reverse();\n });\n }\n });\n eachLayer(style, (layer) => {\n eachLayout(layer, (layout) => {\n if (layout['symbol-min-distance'] !== undefined) {\n renameProperty(layout, 'symbol-min-distance', 'symbol-spacing');\n }\n });\n eachPaint(layer, (paint) => {\n if (paint['background-image'] !== undefined) {\n renameProperty(paint, 'background-image', 'background-pattern');\n }\n if (paint['line-image'] !== undefined) {\n renameProperty(paint, 'line-image', 'line-pattern');\n }\n if (paint['fill-image'] !== undefined) {\n renameProperty(paint, 'fill-image', 'fill-pattern');\n }\n });\n });\n // Inline Constants\n eachProperty(style, { paint: true, layout: true }, (property) => {\n const value = resolveConstant(style, property.value);\n if (isFunction(value)) {\n value.stops.forEach((stop) => {\n stop[1] = resolveConstant(style, stop[1]);\n });\n }\n property.set(value);\n });\n delete style['constants'];\n eachLayer(style, (layer) => {\n // get rid of text-max-size, icon-max-size\n // turn text-size, icon-size into layout properties\n // https://github.com/mapbox/mapbox-gl-style-spec/issues/255\n eachLayout(layer, (layout) => {\n delete layout['text-max-size'];\n delete layout['icon-max-size'];\n });\n eachPaint(layer, (paint) => {\n if (paint['text-size']) {\n if (!layer.layout)\n layer.layout = {};\n layer.layout['text-size'] = paint['text-size'];\n delete paint['text-size'];\n }\n if (paint['icon-size']) {\n if (!layer.layout)\n layer.layout = {};\n layer.layout['icon-size'] = paint['icon-size'];\n delete paint['icon-size'];\n }\n });\n });\n function migrateFontStack(font) {\n function splitAndTrim(string) {\n return string.split(',').map((s) => {\n return s.trim();\n });\n }\n if (Array.isArray(font)) {\n // Assume it's a previously migrated font-array.\n return font;\n }\n else if (typeof font === 'string') {\n return splitAndTrim(font);\n }\n else if (typeof font === 'object') {\n font.stops.forEach((stop) => {\n stop[1] = splitAndTrim(stop[1]);\n });\n return font;\n }\n else {\n throw new Error('unexpected font value');\n }\n }\n eachLayer(style, (layer) => {\n eachLayout(layer, (layout) => {\n if (layout['text-font']) {\n layout['text-font'] = migrateFontStack(layout['text-font']);\n }\n });\n });\n // Reverse order of symbol layers. This is an imperfect migration.\n //\n // The order of a symbol layer in the layers list affects two things:\n // - how it is drawn relative to other layers (like oneway arrows below bridges)\n // - the placement priority compared to other layers\n //\n // It's impossible to reverse the placement priority without breaking the draw order\n // in some cases. This migration only reverses the order of symbol layers that\n // are above all other types of layers.\n //\n // Symbol layers that are at the top of the map preserve their priority.\n // Symbol layers that are below another type (line, fill) of layer preserve their draw order.\n let firstSymbolLayer = 0;\n for (let i = style.layers.length - 1; i >= 0; i--) {\n const layer = style.layers[i];\n if (layer.type !== 'symbol') {\n firstSymbolLayer = i + 1;\n break;\n }\n }\n const symbolLayers = style.layers.splice(firstSymbolLayer);\n symbolLayers.reverse();\n style.layers = style.layers.concat(symbolLayers);\n return style;\n}\n\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(style) {\n const converted = [];\n eachLayer(style, (layer) => {\n if (layer.filter) {\n layer.filter = convertFilter(layer.filter);\n }\n });\n eachProperty(style, { paint: true, layout: true }, ({ path, value, reference, set }) => {\n if (isExpression(value))\n return;\n if (typeof value === 'object' && !Array.isArray(value)) {\n set(convertFunction(value, reference));\n converted.push(path.join('.'));\n }\n else if (reference.tokens && typeof value === 'string') {\n set(convertTokenString(value));\n }\n });\n return style;\n}\n\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 return 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 return colorToMigrate.replace(/\"hsla?\\((.+?)\\)\"/gi, (match, hslArgs) => {\n const argsMatch = hslArgs.match(/^(.+?)\\s*,\\s*(.+?)\\s*,\\s*(.+?)(?:\\s*,\\s*(.+))?$/i);\n if (argsMatch) {\n let [h, s, l, a] = argsMatch.slice(1);\n [s, l] = [s, l].map(v => v.endsWith('%') ? v : `${parseFloat(v) * 100}%`);\n return `\"hsl${typeof a === 'string' ? 'a' : ''}(${[h, s, l, a].filter(Boolean).join(',')})\"`;\n }\n return match;\n });\n}\n\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 * csont 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 let migrated = false;\n if (style.version === 7) {\n style = migrateV8(style);\n migrated = true;\n }\n if (style.version === 8) {\n migrated = !!expressions(style);\n migrated = true;\n }\n eachProperty(style, { paint: true, layout: true }, ({ value, reference, set }) => {\n if (reference.type === 'color') {\n set(migrateColors(value));\n }\n });\n if (!migrated) {\n throw new Error(`Cannot migrate from ${style.version}`);\n }\n return style;\n}\n\nconst v8 = v8Spec;\nconst expression = {\n StyleExpression,\n StylePropertyFunction,\n ZoomConstantExpression,\n ZoomDependentExpression,\n createExpression,\n createPropertyExpression,\n isExpression,\n isExpressionFilter,\n isZoomExpression,\n normalizePropertyExpression,\n};\nconst styleFunction = {\n convertFunction,\n createFunction,\n isFunction: isFunction$1\n};\nconst visit = { eachLayer, eachProperty, eachSource };\n\nexport { Color, ColorType, CompoundExpression, EvaluationContext, FormatExpression, Formatted, FormattedSection, FormattedType, Interpolate, Literal, NullType, Padding, ParsingError, ResolvedImage, Step, StyleExpression, StylePropertyFunction, ValidationError, VariableAnchorOffsetCollection, ZoomConstantExpression, ZoomDependentExpression, classifyRings, convertFilter, convertFunction, createExpression, createFunction, createPropertyExpression, derefLayers, diffStyles as diff, emptyStyle, expression, expressions$1 as expressions, createFilter as featureFilter, format, styleFunction as function, groupByLayout, interpolateFactory, interpolate as interpolates, isExpression, isFunction$1 as isFunction, isZoomExpression, v8Spec as latest, migrate, normalizePropertyExpression, supportsPropertyExpression, toString$1 as toString, typeOf, v8, validate, validateStyleMin, visit };\n//# sourceMappingURL=index.mjs.map\n", "import {validateStyleMin} from '@maplibre/maplibre-gl-style-spec';\nimport {ErrorEvent} from '../util/evented';\n\nimport type {Evented} from '../util/evented';\n\ntype ValidationError = {\n message: string;\n line: number;\n identifier?: string;\n};\n\nexport type Validator = (a: any) => ReadonlyArray;\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): ReadonlyArray;\n};\n\nexport const validateStyle = (validateStyleMin as unknown as ValidateStyle);\n\nexport const validateSource = validateStyle.source;\nexport const validateLight = validateStyle.light;\nexport const validateSky = validateStyle.sky;\nexport const validateTerrain = validateStyle.terrain;\nexport const validateFilter = validateStyle.filter;\nexport const validatePaintProperty = validateStyle.paintProperty;\nexport const validateLayoutProperty = validateStyle.layoutProperty;\n\nexport function emitValidationErrors(\n emitter: Evented,\n errors?: ReadonlyArray<{\n message: string;\n identifier?: string;\n }> | null\n): boolean {\n let hasErrors = false;\n if (errors && errors.length) {\n for (const error of errors) {\n emitter.fire(new ErrorEvent(new Error(error.message)));\n hasErrors = true;\n }\n }\n return hasErrors;\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) {\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() {\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) {\n this.cells[cellIndex].push(uid);\n }\n\n query(x1: number, y1: number, x2: number, y2: number, intersectionTest?: Function): number[] {\n const min = this.min;\n const max = this.max;\n if (x1 <= min && y1 <= min && max <= x2 && max <= y2 && !intersectionTest) {\n // We use `Array#slice` because `this.keys` may be a `Int32Array` and\n // some browsers (Safari and IE) do not support `TypedArray#slice`\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice#Browser_compatibility\n return Array.prototype.slice.call(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, seenUids, intersectionTest: Function) {\n const cell = this.cells[cellIndex];\n if (cell !== null) {\n const keys = this.keys;\n const bboxes = this.bboxes;\n for (let u = 0; u < cell.length; u++) {\n const uid = cell[u];\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, arg2, intersectionTest) {\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) {\n return (x - this.padding) / this.scale;\n }\n\n _convertToCellCoord(x) {\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 (let i = 0; i < this.cells.length; i++) {\n totalCellLength += this.cells[i].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?: Array): 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';\nimport {Color, CompoundExpression, expressions, ResolvedImage, StylePropertyFunction,\n StyleExpression, ZoomDependentExpression, ZoomConstantExpression} from '@maplibre/maplibre-gl-style-spec';\nimport {AJAXError} from './ajax';\nimport {isImageBitmap} from './util';\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 | Array | 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: ReadonlyArray;\n shallow: ReadonlyArray;\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) {\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 ReadonlyArray || [],\n shallow: options.shallow as ReadonlyArray || []\n };\n}\n\nregister('Object', Object);\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 && 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 if (classRegistryKey && classRegistryKey !== 'Object') {\n return true;\n }\n return false;\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?: Array | 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 const view = input;\n if (transferables) {\n transferables.push(view.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: Array = [];\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) as SerializedObject) : {};\n\n if (!klass.serialize) {\n for (const key in input) {\n if (!input.hasOwnProperty(key)) continue; // eslint-disable-line no-prototype-builtins\n if (registry[classRegistryKey].omit.indexOf(key) >= 0) continue;\n const property = input[key];\n properties[key] = registry[classRegistryKey].shallow.indexOf(key) >= 0 ?\n property :\n serialize(property, transferables);\n }\n if (input instanceof Error) {\n properties.message = input.message;\n }\n } else {\n if (transferables && 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.indexOf(key) >= 0 ? 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) {\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", "// The following table comes from .\n// Keep it synchronized with .\n\ntype UnicodeBlockLookup = {[key: string]: (char: number) => boolean};\n\nexport const unicodeBlockLookup: UnicodeBlockLookup = {\n // 'Basic Latin': (char) => char >= 0x0000 && char <= 0x007F,\n 'Latin-1 Supplement': (char) => char >= 0x0080 && char <= 0x00FF,\n // 'Latin Extended-A': (char) => char >= 0x0100 && char <= 0x017F,\n // 'Latin Extended-B': (char) => char >= 0x0180 && char <= 0x024F,\n // 'IPA Extensions': (char) => char >= 0x0250 && char <= 0x02AF,\n // 'Spacing Modifier Letters': (char) => char >= 0x02B0 && char <= 0x02FF,\n // 'Combining Diacritical Marks': (char) => char >= 0x0300 && char <= 0x036F,\n // 'Greek and Coptic': (char) => char >= 0x0370 && char <= 0x03FF,\n // 'Cyrillic': (char) => char >= 0x0400 && char <= 0x04FF,\n // 'Cyrillic Supplement': (char) => char >= 0x0500 && char <= 0x052F,\n // 'Armenian': (char) => char >= 0x0530 && char <= 0x058F,\n //'Hebrew': (char) => char >= 0x0590 && char <= 0x05FF,\n // 'Arabic': (char) => char >= 0x0600 && char <= 0x06FF,\n //'Syriac': (char) => char >= 0x0700 && char <= 0x074F,\n // 'Arabic Supplement': (char) => char >= 0x0750 && char <= 0x077F,\n // 'Thaana': (char) => char >= 0x0780 && char <= 0x07BF,\n // 'NKo': (char) => char >= 0x07C0 && char <= 0x07FF,\n // 'Samaritan': (char) => char >= 0x0800 && char <= 0x083F,\n // 'Mandaic': (char) => char >= 0x0840 && char <= 0x085F,\n // 'Syriac Supplement': (char) => char >= 0x0860 && char <= 0x086F,\n // 'Arabic Extended-B': (char) => char >= 0x0870 && char <= 0x089F,\n // 'Arabic Extended-A': (char) => char >= 0x08A0 && char <= 0x08FF,\n // 'Devanagari': (char) => char >= 0x0900 && char <= 0x097F,\n // 'Bengali': (char) => char >= 0x0980 && char <= 0x09FF,\n // 'Gurmukhi': (char) => char >= 0x0A00 && char <= 0x0A7F,\n // 'Gujarati': (char) => char >= 0x0A80 && char <= 0x0AFF,\n // 'Oriya': (char) => char >= 0x0B00 && char <= 0x0B7F,\n // 'Tamil': (char) => char >= 0x0B80 && char <= 0x0BFF,\n // 'Telugu': (char) => char >= 0x0C00 && char <= 0x0C7F,\n // 'Kannada': (char) => char >= 0x0C80 && char <= 0x0CFF,\n // 'Malayalam': (char) => char >= 0x0D00 && char <= 0x0D7F,\n // 'Sinhala': (char) => char >= 0x0D80 && char <= 0x0DFF,\n // 'Thai': (char) => char >= 0x0E00 && char <= 0x0E7F,\n // 'Lao': (char) => char >= 0x0E80 && char <= 0x0EFF,\n // 'Tibetan': (char) => char >= 0x0F00 && char <= 0x0FFF,\n // 'Myanmar': (char) => char >= 0x1000 && char <= 0x109F,\n // 'Georgian': (char) => char >= 0x10A0 && char <= 0x10FF,\n 'Hangul Jamo': (char) => char >= 0x1100 && char <= 0x11FF,\n // 'Ethiopic': (char) => char >= 0x1200 && char <= 0x137F,\n // 'Ethiopic Supplement': (char) => char >= 0x1380 && char <= 0x139F,\n // 'Cherokee': (char) => char >= 0x13A0 && char <= 0x13FF,\n // 'Unified Canadian Aboriginal Syllabics': (char) => char >= 0x1400 && char <= 0x167F,\n // 'Ogham': (char) => char >= 0x1680 && char <= 0x169F,\n // 'Runic': (char) => char >= 0x16A0 && char <= 0x16FF,\n // 'Tagalog': (char) => char >= 0x1700 && char <= 0x171F,\n // 'Hanunoo': (char) => char >= 0x1720 && char <= 0x173F,\n // 'Buhid': (char) => char >= 0x1740 && char <= 0x175F,\n // 'Tagbanwa': (char) => char >= 0x1760 && char <= 0x177F,\n 'Khmer': (char) => char >= 0x1780 && char <= 0x17FF,\n // 'Mongolian': (char) => char >= 0x1800 && char <= 0x18AF,\n // 'Unified Canadian Aboriginal Syllabics Extended': (char) => char >= 0x18B0 && char <= 0x18FF,\n // 'Limbu': (char) => char >= 0x1900 && char <= 0x194F,\n // 'Tai Le': (char) => char >= 0x1950 && char <= 0x197F,\n // 'New Tai Lue': (char) => char >= 0x1980 && char <= 0x19DF,\n // 'Khmer Symbols': (char) => char >= 0x19E0 && char <= 0x19FF,\n // 'Buginese': (char) => char >= 0x1A00 && char <= 0x1A1F,\n // 'Tai Tham': (char) => char >= 0x1A20 && char <= 0x1AAF,\n // 'Combining Diacritical Marks Extended': (char) => char >= 0x1AB0 && char <= 0x1AFF,\n // 'Balinese': (char) => char >= 0x1B00 && char <= 0x1B7F,\n // 'Sundanese': (char) => char >= 0x1B80 && char <= 0x1BBF,\n // 'Batak': (char) => char >= 0x1BC0 && char <= 0x1BFF,\n // 'Lepcha': (char) => char >= 0x1C00 && char <= 0x1C4F,\n // 'Ol Chiki': (char) => char >= 0x1C50 && char <= 0x1C7F,\n // 'Cyrillic Extended-C': (char) => char >= 0x1C80 && char <= 0x1C8F,\n // 'Georgian Extended': (char) => char >= 0x1C90 && char <= 0x1CBF,\n // 'Sundanese Supplement': (char) => char >= 0x1CC0 && char <= 0x1CCF,\n // 'Vedic Extensions': (char) => char >= 0x1CD0 && char <= 0x1CFF,\n // 'Phonetic Extensions': (char) => char >= 0x1D00 && char <= 0x1D7F,\n // 'Phonetic Extensions Supplement': (char) => char >= 0x1D80 && char <= 0x1DBF,\n // 'Combining Diacritical Marks Supplement': (char) => char >= 0x1DC0 && char <= 0x1DFF,\n // 'Latin Extended Additional': (char) => char >= 0x1E00 && char <= 0x1EFF,\n // 'Greek Extended': (char) => char >= 0x1F00 && char <= 0x1FFF,\n 'General Punctuation': (char) => char >= 0x2000 && char <= 0x206F,\n // 'Superscripts and Subscripts': (char) => char >= 0x2070 && char <= 0x209F,\n // 'Currency Symbols': (char) => char >= 0x20A0 && char <= 0x20CF,\n // 'Combining Diacritical Marks for Symbols': (char) => char >= 0x20D0 && char <= 0x20FF,\n 'Letterlike Symbols': (char) => char >= 0x2100 && char <= 0x214F,\n 'Number Forms': (char) => char >= 0x2150 && char <= 0x218F,\n // 'Arrows': (char) => char >= 0x2190 && char <= 0x21FF,\n // 'Mathematical Operators': (char) => char >= 0x2200 && char <= 0x22FF,\n 'Miscellaneous Technical': (char) => char >= 0x2300 && char <= 0x23FF,\n 'Control Pictures': (char) => char >= 0x2400 && char <= 0x243F,\n 'Optical Character Recognition': (char) => char >= 0x2440 && char <= 0x245F,\n 'Enclosed Alphanumerics': (char) => char >= 0x2460 && char <= 0x24FF,\n // 'Box Drawing': (char) => char >= 0x2500 && char <= 0x257F,\n // 'Block Elements': (char) => char >= 0x2580 && char <= 0x259F,\n 'Geometric Shapes': (char) => char >= 0x25A0 && char <= 0x25FF,\n 'Miscellaneous Symbols': (char) => char >= 0x2600 && char <= 0x26FF,\n // 'Dingbats': (char) => char >= 0x2700 && char <= 0x27BF,\n // 'Miscellaneous Mathematical Symbols-A': (char) => char >= 0x27C0 && char <= 0x27EF,\n // 'Supplemental Arrows-A': (char) => char >= 0x27F0 && char <= 0x27FF,\n // 'Braille Patterns': (char) => char >= 0x2800 && char <= 0x28FF,\n // 'Supplemental Arrows-B': (char) => char >= 0x2900 && char <= 0x297F,\n // 'Miscellaneous Mathematical Symbols-B': (char) => char >= 0x2980 && char <= 0x29FF,\n // 'Supplemental Mathematical Operators': (char) => char >= 0x2A00 && char <= 0x2AFF,\n 'Miscellaneous Symbols and Arrows': (char) => char >= 0x2B00 && char <= 0x2BFF,\n // 'Glagolitic': (char) => char >= 0x2C00 && char <= 0x2C5F,\n // 'Latin Extended-C': (char) => char >= 0x2C60 && char <= 0x2C7F,\n // 'Coptic': (char) => char >= 0x2C80 && char <= 0x2CFF,\n // 'Georgian Supplement': (char) => char >= 0x2D00 && char <= 0x2D2F,\n // 'Tifinagh': (char) => char >= 0x2D30 && char <= 0x2D7F,\n // 'Ethiopic Extended': (char) => char >= 0x2D80 && char <= 0x2DDF,\n // 'Cyrillic Extended-A': (char) => char >= 0x2DE0 && char <= 0x2DFF,\n // 'Supplemental Punctuation': (char) => char >= 0x2E00 && char <= 0x2E7F,\n // 'CJK Radicals Supplement': (char) => char >= 0x2E80 && char <= 0x2EFF,\n // 'Kangxi Radicals': (char) => char >= 0x2F00 && char <= 0x2FDF,\n 'Ideographic Description Characters': (char) => char >= 0x2FF0 && char <= 0x2FFF,\n 'CJK Symbols and Punctuation': (char) => char >= 0x3000 && char <= 0x303F,\n // 'Hiragana': (char) => char >= 0x3040 && char <= 0x309F,\n 'Katakana': (char) => char >= 0x30A0 && char <= 0x30FF,\n // 'Bopomofo': (char) => char >= 0x3100 && char <= 0x312F,\n // 'Hangul Compatibility Jamo': (char) => char >= 0x3130 && char <= 0x318F,\n 'Kanbun': (char) => char >= 0x3190 && char <= 0x319F,\n // 'Bopomofo Extended': (char) => char >= 0x31A0 && char <= 0x31BF,\n 'CJK Strokes': (char) => char >= 0x31C0 && char <= 0x31EF,\n // 'Katakana Phonetic Extensions': (char) => char >= 0x31F0 && char <= 0x31FF,\n 'Enclosed CJK Letters and Months': (char) => char >= 0x3200 && char <= 0x32FF,\n 'CJK Compatibility': (char) => char >= 0x3300 && char <= 0x33FF,\n // 'CJK Unified Ideographs Extension A': (char) => char >= 0x3400 && char <= 0x4DBF,\n 'Yijing Hexagram Symbols': (char) => char >= 0x4DC0 && char <= 0x4DFF,\n // 'CJK Unified Ideographs': (char) => char >= 0x4E00 && char <= 0x9FFF,\n // 'Yi Syllables': (char) => char >= 0xA000 && char <= 0xA48F,\n // 'Yi Radicals': (char) => char >= 0xA490 && char <= 0xA4CF,\n // 'Lisu': (char) => char >= 0xA4D0 && char <= 0xA4FF,\n // 'Vai': (char) => char >= 0xA500 && char <= 0xA63F,\n // 'Cyrillic Extended-B': (char) => char >= 0xA640 && char <= 0xA69F,\n // 'Bamum': (char) => char >= 0xA6A0 && char <= 0xA6FF,\n // 'Modifier Tone Letters': (char) => char >= 0xA700 && char <= 0xA71F,\n // 'Latin Extended-D': (char) => char >= 0xA720 && char <= 0xA7FF,\n // 'Syloti Nagri': (char) => char >= 0xA800 && char <= 0xA82F,\n // 'Common Indic Number Forms': (char) => char >= 0xA830 && char <= 0xA83F,\n // 'Phags-pa': (char) => char >= 0xA840 && char <= 0xA87F,\n // 'Saurashtra': (char) => char >= 0xA880 && char <= 0xA8DF,\n // 'Devanagari Extended': (char) => char >= 0xA8E0 && char <= 0xA8FF,\n // 'Kayah Li': (char) => char >= 0xA900 && char <= 0xA92F,\n // 'Rejang': (char) => char >= 0xA930 && char <= 0xA95F,\n // 'Hangul Jamo Extended-A': (char) => char >= 0xA960 && char <= 0xA97F,\n // 'Javanese': (char) => char >= 0xA980 && char <= 0xA9DF,\n // 'Myanmar Extended-B': (char) => char >= 0xA9E0 && char <= 0xA9FF,\n // 'Cham': (char) => char >= 0xAA00 && char <= 0xAA5F,\n // 'Myanmar Extended-A': (char) => char >= 0xAA60 && char <= 0xAA7F,\n // 'Tai Viet': (char) => char >= 0xAA80 && char <= 0xAADF,\n // 'Meetei Mayek Extensions': (char) => char >= 0xAAE0 && char <= 0xAAFF,\n // 'Ethiopic Extended-A': (char) => char >= 0xAB00 && char <= 0xAB2F,\n // 'Latin Extended-E': (char) => char >= 0xAB30 && char <= 0xAB6F,\n // 'Cherokee Supplement': (char) => char >= 0xAB70 && char <= 0xABBF,\n // 'Meetei Mayek': (char) => char >= 0xABC0 && char <= 0xABFF,\n // 'Hangul Syllables': (char) => char >= 0xAC00 && char <= 0xD7AF,\n // 'Hangul Jamo Extended-B': (char) => char >= 0xD7B0 && char <= 0xD7FF,\n // 'High Surrogates': (char) => char >= 0xD800 && char <= 0xDB7F,\n // 'High Private Use Surrogates': (char) => char >= 0xDB80 && char <= 0xDBFF,\n // 'Low Surrogates': (char) => char >= 0xDC00 && char <= 0xDFFF,\n 'Private Use Area': (char) => char >= 0xE000 && char <= 0xF8FF,\n // 'CJK Compatibility Ideographs': (char) => char >= 0xF900 && char <= 0xFAFF,\n // 'Alphabetic Presentation Forms': (char) => char >= 0xFB00 && char <= 0xFB4F,\n // 'Arabic Presentation Forms-A': (char) => char >= 0xFB50 && char <= 0xFDFF,\n // 'Variation Selectors': (char) => char >= 0xFE00 && char <= 0xFE0F,\n 'Vertical Forms': (char) => char >= 0xFE10 && char <= 0xFE1F,\n // 'Combining Half Marks': (char) => char >= 0xFE20 && char <= 0xFE2F,\n 'CJK Compatibility Forms': (char) => char >= 0xFE30 && char <= 0xFE4F,\n 'Small Form Variants': (char) => char >= 0xFE50 && char <= 0xFE6F,\n // 'Arabic Presentation Forms-B': (char) => char >= 0xFE70 && char <= 0xFEFF,\n 'Halfwidth and Fullwidth Forms': (char) => char >= 0xFF00 && char <= 0xFFEF\n // 'Specials': (char) => char >= 0xFFF0 && char <= 0xFFFF,\n // 'Linear B Syllabary': (char) => char >= 0x10000 && char <= 0x1007F,\n // 'Linear B Ideograms': (char) => char >= 0x10080 && char <= 0x100FF,\n // 'Aegean Numbers': (char) => char >= 0x10100 && char <= 0x1013F,\n // 'Ancient Greek Numbers': (char) => char >= 0x10140 && char <= 0x1018F,\n // 'Ancient Symbols': (char) => char >= 0x10190 && char <= 0x101CF,\n // 'Phaistos Disc': (char) => char >= 0x101D0 && char <= 0x101FF,\n // 'Lycian': (char) => char >= 0x10280 && char <= 0x1029F,\n // 'Carian': (char) => char >= 0x102A0 && char <= 0x102DF,\n // 'Coptic Epact Numbers': (char) => char >= 0x102E0 && char <= 0x102FF,\n // 'Old Italic': (char) => char >= 0x10300 && char <= 0x1032F,\n // 'Gothic': (char) => char >= 0x10330 && char <= 0x1034F,\n // 'Old Permic': (char) => char >= 0x10350 && char <= 0x1037F,\n // 'Ugaritic': (char) => char >= 0x10380 && char <= 0x1039F,\n // 'Old Persian': (char) => char >= 0x103A0 && char <= 0x103DF,\n // 'Deseret': (char) => char >= 0x10400 && char <= 0x1044F,\n // 'Shavian': (char) => char >= 0x10450 && char <= 0x1047F,\n // 'Osmanya': (char) => char >= 0x10480 && char <= 0x104AF,\n // 'Osage': (char) => char >= 0x104B0 && char <= 0x104FF,\n // 'Elbasan': (char) => char >= 0x10500 && char <= 0x1052F,\n // 'Caucasian Albanian': (char) => char >= 0x10530 && char <= 0x1056F,\n // 'Vithkuqi': (char) => char >= 0x10570 && char <= 0x105BF,\n // 'Todhri': (char) => char >= 0x105C0 && char <= 0x105FF,\n // 'Linear A': (char) => char >= 0x10600 && char <= 0x1077F,\n // 'Latin Extended-F': (char) => char >= 0x10780 && char <= 0x107BF,\n // 'Cypriot Syllabary': (char) => char >= 0x10800 && char <= 0x1083F,\n // 'Imperial Aramaic': (char) => char >= 0x10840 && char <= 0x1085F,\n // 'Palmyrene': (char) => char >= 0x10860 && char <= 0x1087F,\n // 'Nabataean': (char) => char >= 0x10880 && char <= 0x108AF,\n // 'Hatran': (char) => char >= 0x108E0 && char <= 0x108FF,\n // 'Phoenician': (char) => char >= 0x10900 && char <= 0x1091F,\n // 'Lydian': (char) => char >= 0x10920 && char <= 0x1093F,\n // 'Meroitic Hieroglyphs': (char) => char >= 0x10980 && char <= 0x1099F,\n // 'Meroitic Cursive': (char) => char >= 0x109A0 && char <= 0x109FF,\n // 'Kharoshthi': (char) => char >= 0x10A00 && char <= 0x10A5F,\n // 'Old South Arabian': (char) => char >= 0x10A60 && char <= 0x10A7F,\n // 'Old North Arabian': (char) => char >= 0x10A80 && char <= 0x10A9F,\n // 'Manichaean': (char) => char >= 0x10AC0 && char <= 0x10AFF,\n // 'Avestan': (char) => char >= 0x10B00 && char <= 0x10B3F,\n // 'Inscriptional Parthian': (char) => char >= 0x10B40 && char <= 0x10B5F,\n // 'Inscriptional Pahlavi': (char) => char >= 0x10B60 && char <= 0x10B7F,\n // 'Psalter Pahlavi': (char) => char >= 0x10B80 && char <= 0x10BAF,\n // 'Old Turkic': (char) => char >= 0x10C00 && char <= 0x10C4F,\n // 'Old Hungarian': (char) => char >= 0x10C80 && char <= 0x10CFF,\n // 'Hanifi Rohingya': (char) => char >= 0x10D00 && char <= 0x10D3F,\n // 'Garay': (char) => char >= 0x10D40 && char <= 0x10D8F,\n // 'Rumi Numeral Symbols': (char) => char >= 0x10E60 && char <= 0x10E7F,\n // 'Yezidi': (char) => char >= 0x10E80 && char <= 0x10EBF,\n // 'Arabic Extended-C': (char) => char >= 0x10EC0 && char <= 0x10EFF,\n // 'Old Sogdian': (char) => char >= 0x10F00 && char <= 0x10F2F,\n // 'Sogdian': (char) => char >= 0x10F30 && char <= 0x10F6F,\n // 'Old Uyghur': (char) => char >= 0x10F70 && char <= 0x10FAF,\n // 'Chorasmian': (char) => char >= 0x10FB0 && char <= 0x10FDF,\n // 'Elymaic': (char) => char >= 0x10FE0 && char <= 0x10FFF,\n // 'Brahmi': (char) => char >= 0x11000 && char <= 0x1107F,\n // 'Kaithi': (char) => char >= 0x11080 && char <= 0x110CF,\n // 'Sora Sompeng': (char) => char >= 0x110D0 && char <= 0x110FF,\n // 'Chakma': (char) => char >= 0x11100 && char <= 0x1114F,\n // 'Mahajani': (char) => char >= 0x11150 && char <= 0x1117F,\n // 'Sharada': (char) => char >= 0x11180 && char <= 0x111DF,\n // 'Sinhala Archaic Numbers': (char) => char >= 0x111E0 && char <= 0x111FF,\n // 'Khojki': (char) => char >= 0x11200 && char <= 0x1124F,\n // 'Multani': (char) => char >= 0x11280 && char <= 0x112AF,\n // 'Khudawadi': (char) => char >= 0x112B0 && char <= 0x112FF,\n // 'Grantha': (char) => char >= 0x11300 && char <= 0x1137F,\n // 'Tulu-Tigalari': (char) => char >= 0x11380 && char <= 0x113FF,\n // 'Newa': (char) => char >= 0x11400 && char <= 0x1147F,\n // 'Tirhuta': (char) => char >= 0x11480 && char <= 0x114DF,\n // 'Siddham': (char) => char >= 0x11580 && char <= 0x115FF,\n // 'Modi': (char) => char >= 0x11600 && char <= 0x1165F,\n // 'Mongolian Supplement': (char) => char >= 0x11660 && char <= 0x1167F,\n // 'Takri': (char) => char >= 0x11680 && char <= 0x116CF,\n // 'Myanmar Extended-C': (char) => char >= 0x116D0 && char <= 0x116FF,\n // 'Ahom': (char) => char >= 0x11700 && char <= 0x1174F,\n // 'Dogra': (char) => char >= 0x11800 && char <= 0x1184F,\n // 'Warang Citi': (char) => char >= 0x118A0 && char <= 0x118FF,\n // 'Dives Akuru': (char) => char >= 0x11900 && char <= 0x1195F,\n // 'Nandinagari': (char) => char >= 0x119A0 && char <= 0x119FF,\n // 'Zanabazar Square': (char) => char >= 0x11A00 && char <= 0x11A4F,\n // 'Soyombo': (char) => char >= 0x11A50 && char <= 0x11AAF,\n // 'Unified Canadian Aboriginal Syllabics Extended-A': (char) => char >= 0x11AB0 && char <= 0x11ABF,\n // 'Pau Cin Hau': (char) => char >= 0x11AC0 && char <= 0x11AFF,\n // 'Devanagari Extended-A': (char) => char >= 0x11B00 && char <= 0x11B5F,\n // 'Sunuwar': (char) => char >= 0x11BC0 && char <= 0x11BFF,\n // 'Bhaiksuki': (char) => char >= 0x11C00 && char <= 0x11C6F,\n // 'Marchen': (char) => char >= 0x11C70 && char <= 0x11CBF,\n // 'Masaram Gondi': (char) => char >= 0x11D00 && char <= 0x11D5F,\n // 'Gunjala Gondi': (char) => char >= 0x11D60 && char <= 0x11DAF,\n // 'Makasar': (char) => char >= 0x11EE0 && char <= 0x11EFF,\n // 'Kawi': (char) => char >= 0x11F00 && char <= 0x11F5F,\n // 'Lisu Supplement': (char) => char >= 0x11FB0 && char <= 0x11FBF,\n // 'Tamil Supplement': (char) => char >= 0x11FC0 && char <= 0x11FFF,\n // 'Cuneiform': (char) => char >= 0x12000 && char <= 0x123FF,\n // 'Cuneiform Numbers and Punctuation': (char) => char >= 0x12400 && char <= 0x1247F,\n // 'Early Dynastic Cuneiform': (char) => char >= 0x12480 && char <= 0x1254F,\n // 'Cypro-Minoan': (char) => char >= 0x12F90 && char <= 0x12FFF,\n // 'Egyptian Hieroglyphs': (char) => char >= 0x13000 && char <= 0x1342F,\n // 'Egyptian Hieroglyph Format Controls': (char) => char >= 0x13430 && char <= 0x1345F,\n // 'Egyptian Hieroglyphs Extended-A': (char) => char >= 0x13460 && char <= 0x143FF,\n // 'Anatolian Hieroglyphs': (char) => char >= 0x14400 && char <= 0x1467F,\n // 'Gurung Khema': (char) => char >= 0x16100 && char <= 0x1613F,\n // 'Bamum Supplement': (char) => char >= 0x16800 && char <= 0x16A3F,\n // 'Mro': (char) => char >= 0x16A40 && char <= 0x16A6F,\n // 'Tangsa': (char) => char >= 0x16A70 && char <= 0x16ACF,\n // 'Bassa Vah': (char) => char >= 0x16AD0 && char <= 0x16AFF,\n // 'Pahawh Hmong': (char) => char >= 0x16B00 && char <= 0x16B8F,\n // 'Kirat Rai': (char) => char >= 0x16D40 && char <= 0x16D7F,\n // 'Medefaidrin': (char) => char >= 0x16E40 && char <= 0x16E9F,\n // 'Miao': (char) => char >= 0x16F00 && char <= 0x16F9F,\n // 'Ideographic Symbols and Punctuation': (char) => char >= 0x16FE0 && char <= 0x16FFF,\n // 'Tangut': (char) => char >= 0x17000 && char <= 0x187FF,\n // 'Tangut Components': (char) => char >= 0x18800 && char <= 0x18AFF,\n // 'Khitan Small Script': (char) => char >= 0x18B00 && char <= 0x18CFF,\n // 'Tangut Supplement': (char) => char >= 0x18D00 && char <= 0x18D7F,\n // 'Kana Extended-B': (char) => char >= 0x1AFF0 && char <= 0x1AFFF,\n // 'Kana Supplement': (char) => char >= 0x1B000 && char <= 0x1B0FF,\n // 'Kana Extended-A': (char) => char >= 0x1B100 && char <= 0x1B12F,\n // 'Small Kana Extension': (char) => char >= 0x1B130 && char <= 0x1B16F,\n // 'Nushu': (char) => char >= 0x1B170 && char <= 0x1B2FF,\n // 'Duployan': (char) => char >= 0x1BC00 && char <= 0x1BC9F,\n // 'Shorthand Format Controls': (char) => char >= 0x1BCA0 && char <= 0x1BCAF,\n // 'Symbols for Legacy Computing Supplement': (char) => char >= 0x1CC00 && char <= 0x1CEBF,\n // 'Znamenny Musical Notation': (char) => char >= 0x1CF00 && char <= 0x1CFCF,\n // 'Byzantine Musical Symbols': (char) => char >= 0x1D000 && char <= 0x1D0FF,\n // 'Musical Symbols': (char) => char >= 0x1D100 && char <= 0x1D1FF,\n // 'Ancient Greek Musical Notation': (char) => char >= 0x1D200 && char <= 0x1D24F,\n // 'Kaktovik Numerals': (char) => char >= 0x1D2C0 && char <= 0x1D2DF,\n // 'Mayan Numerals': (char) => char >= 0x1D2E0 && char <= 0x1D2FF,\n // 'Tai Xuan Jing Symbols': (char) => char >= 0x1D300 && char <= 0x1D35F,\n // 'Counting Rod Numerals': (char) => char >= 0x1D360 && char <= 0x1D37F,\n // 'Mathematical Alphanumeric Symbols': (char) => char >= 0x1D400 && char <= 0x1D7FF,\n // 'Sutton SignWriting': (char) => char >= 0x1D800 && char <= 0x1DAAF,\n // 'Latin Extended-G': (char) => char >= 0x1DF00 && char <= 0x1DFFF,\n // 'Glagolitic Supplement': (char) => char >= 0x1E000 && char <= 0x1E02F,\n // 'Cyrillic Extended-D': (char) => char >= 0x1E030 && char <= 0x1E08F,\n // 'Nyiakeng Puachue Hmong': (char) => char >= 0x1E100 && char <= 0x1E14F,\n // 'Toto': (char) => char >= 0x1E290 && char <= 0x1E2BF,\n // 'Wancho': (char) => char >= 0x1E2C0 && char <= 0x1E2FF,\n // 'Nag Mundari': (char) => char >= 0x1E4D0 && char <= 0x1E4FF,\n // 'Ol Onal': (char) => char >= 0x1E5D0 && char <= 0x1E5FF,\n // 'Ethiopic Extended-B': (char) => char >= 0x1E7E0 && char <= 0x1E7FF,\n // 'Mende Kikakui': (char) => char >= 0x1E800 && char <= 0x1E8DF,\n // 'Adlam': (char) => char >= 0x1E900 && char <= 0x1E95F,\n // 'Indic Siyaq Numbers': (char) => char >= 0x1EC70 && char <= 0x1ECBF,\n // 'Ottoman Siyaq Numbers': (char) => char >= 0x1ED00 && char <= 0x1ED4F,\n // 'Arabic Mathematical Alphabetic Symbols': (char) => char >= 0x1EE00 && char <= 0x1EEFF,\n // 'Mahjong Tiles': (char) => char >= 0x1F000 && char <= 0x1F02F,\n // 'Domino Tiles': (char) => char >= 0x1F030 && char <= 0x1F09F,\n // 'Playing Cards': (char) => char >= 0x1F0A0 && char <= 0x1F0FF,\n // 'Enclosed Alphanumeric Supplement': (char) => char >= 0x1F100 && char <= 0x1F1FF,\n // 'Enclosed Ideographic Supplement': (char) => char >= 0x1F200 && char <= 0x1F2FF,\n // 'Miscellaneous Symbols and Pictographs': (char) => char >= 0x1F300 && char <= 0x1F5FF,\n // 'Emoticons': (char) => char >= 0x1F600 && char <= 0x1F64F,\n // 'Ornamental Dingbats': (char) => char >= 0x1F650 && char <= 0x1F67F,\n // 'Transport and Map Symbols': (char) => char >= 0x1F680 && char <= 0x1F6FF,\n // 'Alchemical Symbols': (char) => char >= 0x1F700 && char <= 0x1F77F,\n // 'Geometric Shapes Extended': (char) => char >= 0x1F780 && char <= 0x1F7FF,\n // 'Supplemental Arrows-C': (char) => char >= 0x1F800 && char <= 0x1F8FF,\n // 'Supplemental Symbols and Pictographs': (char) => char >= 0x1F900 && char <= 0x1F9FF,\n // 'Chess Symbols': (char) => char >= 0x1FA00 && char <= 0x1FA6F,\n // 'Symbols and Pictographs Extended-A': (char) => char >= 0x1FA70 && char <= 0x1FAFF,\n // 'Symbols for Legacy Computing': (char) => char >= 0x1FB00 && char <= 0x1FBFF,\n // 'CJK Unified Ideographs Extension B': (char) => char >= 0x20000 && char <= 0x2A6DF,\n // 'CJK Unified Ideographs Extension C': (char) => char >= 0x2A700 && char <= 0x2B73F,\n // 'CJK Unified Ideographs Extension D': (char) => char >= 0x2B740 && char <= 0x2B81F,\n // 'CJK Unified Ideographs Extension E': (char) => char >= 0x2B820 && char <= 0x2CEAF,\n // 'CJK Unified Ideographs Extension F': (char) => char >= 0x2CEB0 && char <= 0x2EBEF,\n // 'CJK Unified Ideographs Extension I': (char) => char >= 0x2EBF0 && char <= 0x2EE5F,\n // 'CJK Unified Ideographs Extension G': (char) => char >= 0x30000 && char <= 0x3134F,\n // 'CJK Unified Ideographs Extension H': (char) => char >= 0x31350 && char <= 0x323AF,\n // 'CJK Compatibility Ideographs Supplement': (char) => char >= 0x2F800 && char <= 0x2FA1F,\n // 'Tags': (char) => char >= 0xE0000 && char <= 0xE007F,\n // 'Variation Selectors Supplement': (char) => char >= 0xE0100 && char <= 0xE01EF,\n // 'Supplementary Private Use Area-A': (char) => char >= 0xF0000 && char <= 0xFFFFF,\n // 'Supplementary Private Use Area-B': (char) => char >= 0x100000 && char <= 0x10FFFF,\n};\n", "/* eslint-disable new-cap */\n\nimport {unicodeBlockLookup as isChar} from './is_char_in_unicode_block';\n\nexport function allowsIdeographicBreaking(chars: string) {\n for (const char of chars) {\n if (!charAllowsIdeographicBreaking(char.charCodeAt(0))) return false;\n }\n return true;\n}\n\nexport function allowsVerticalWritingMode(chars: string) {\n for (const char of chars) {\n if (charHasUprightVerticalOrientation(char.charCodeAt(0))) return true;\n }\n return false;\n}\n\nexport function allowsLetterSpacing(chars: string) {\n for (const char of chars) {\n if (!charAllowsLetterSpacing(char.charCodeAt(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: Array): RegExp {\n const supportedPropertyEscapes = scriptCodes.map(code => {\n try {\n return new RegExp(`\\\\p{sc=${code}}`, 'u').source;\n } catch (e) {\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) {\n return !cursiveScriptRegExp.test(String.fromCodePoint(char));\n}\n\n/**\n * ISO 15924 script codes of scripts that allow ideographic line breaking beyond\n * the CJKV scripts that are considered ideographic in Unicode 16.0.0.\n */\nconst ideographicBreakingScriptCodes = [\n 'Bopo', // Bopomofo\n 'Hani', // Han\n 'Hira', // Hiragana\n 'Kana', // Katakana\n 'Kits', // Khitan Small Script\n 'Nshu', // Nushu\n 'Tang', // Tangut\n 'Yiii', // Yi\n];\n\nconst ideographicBreakingRegExp = sanitizedRegExpFromScriptCodes(ideographicBreakingScriptCodes);\n\nexport function charAllowsIdeographicBreaking(char: number) {\n // Return early for characters outside all ideographic ranges.\n if (char < 0x2E80) return false;\n\n if (isChar['CJK Compatibility Forms'](char)) return true;\n if (isChar['CJK Compatibility'](char)) return true;\n if (isChar['CJK Strokes'](char)) return true;\n if (isChar['CJK Symbols and Punctuation'](char)) return true;\n if (isChar['Enclosed CJK Letters and Months'](char)) return true;\n if (isChar['Halfwidth and Fullwidth Forms'](char)) return true;\n if (isChar['Ideographic Description Characters'](char)) return true;\n if (isChar['Vertical Forms'](char)) return true;\n return ideographicBreakingRegExp.test(String.fromCodePoint(char));\n}\n\n// The following logic comes from\n// .\n// Keep it synchronized with\n// .\n// The data file denotes with “U” or “Tu” any codepoint that may be drawn\n// upright in vertical text but does not distinguish between upright and\n// “neutral” characters.\n\n// Blocks in the Unicode supplementary planes are excluded from this module due\n// to .\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 charHasUprightVerticalOrientation(char: number) {\n if (char === 0x02EA /* modifier letter yin departing tone mark */ ||\n char === 0x02EB /* modifier letter yang departing tone mark */) {\n return true;\n }\n\n // Return early for characters outside all ranges whose characters remain\n // upright in vertical writing mode.\n if (char < 0x1100) return false;\n\n if (isChar['CJK Compatibility Forms'](char)) {\n if (!((char >= 0xFE49 /* dashed overline */ && char <= 0xFE4F) /* wavy low line */)) {\n return true;\n }\n }\n if (isChar['CJK Compatibility'](char)) return true;\n if (isChar['CJK Strokes'](char)) return true;\n if (isChar['CJK Symbols and Punctuation'](char)) {\n if (!((char >= 0x3008 /* left angle bracket */ && char <= 0x3011) /* right black lenticular bracket */) &&\n !((char >= 0x3014 /* left tortoise shell bracket */ && char <= 0x301F) /* low double prime quotation mark */) &&\n char !== 0x3030 /* wavy dash */) {\n return true;\n }\n }\n if (isChar['Enclosed CJK Letters and Months'](char)) return true;\n if (isChar['Ideographic Description Characters'](char)) return true;\n if (isChar['Kanbun'](char)) return true;\n if (isChar['Katakana'](char)) {\n if (char !== 0x30FC /* katakana-hiragana prolonged sound mark */) {\n return true;\n }\n }\n if (isChar['Halfwidth and Fullwidth Forms'](char)) {\n if (char !== 0xFF08 /* fullwidth left parenthesis */ &&\n char !== 0xFF09 /* fullwidth right parenthesis */ &&\n char !== 0xFF0D /* fullwidth hyphen-minus */ &&\n !((char >= 0xFF1A /* fullwidth colon */ && char <= 0xFF1E) /* fullwidth greater-than sign */) &&\n char !== 0xFF3B /* fullwidth left square bracket */ &&\n char !== 0xFF3D /* fullwidth right square bracket */ &&\n char !== 0xFF3F /* fullwidth low line */ &&\n !(char >= 0xFF5B /* fullwidth left curly bracket */ && char <= 0xFFDF) &&\n char !== 0xFFE3 /* fullwidth macron */ &&\n !(char >= 0xFFE8 /* halfwidth forms light vertical */ && char <= 0xFFEF)) {\n return true;\n }\n }\n if (isChar['Small Form Variants'](char)) {\n if (!((char >= 0xFE58 /* small em dash */ && char <= 0xFE5E) /* small right tortoise shell bracket */) &&\n !((char >= 0xFE63 /* small hyphen-minus */ && char <= 0xFE66) /* small equals sign */)) {\n return true;\n }\n }\n if (isChar['Vertical Forms'](char)) return true;\n if (isChar['Yijing Hexagram Symbols'](char)) return true;\n\n if (/* Canadian Aboriginal */ /\\p{sc=Cans}/u.test(String.fromCodePoint(char))) return true;\n if (/* Hangul */ /\\p{sc=Hang}/u.test(String.fromCodePoint(char))) return true;\n if (ideographicBreakingRegExp.test(String.fromCodePoint(char))) return true;\n\n return false;\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 vulgar\n * fraction ½ is drawn upright among Chinese characters but rotated among Latin\n * letters. A neutrally oriented character does not influence whether an\n * adjacent character is drawn upright or rotated.\n */\nexport function charHasNeutralVerticalOrientation(char: number) {\n if (isChar['Latin-1 Supplement'](char)) {\n if (char === 0x00A7 /* section sign */ ||\n char === 0x00A9 /* copyright sign */ ||\n char === 0x00AE /* registered sign */ ||\n char === 0x00B1 /* plus-minus sign */ ||\n char === 0x00BC /* vulgar fraction one quarter */ ||\n char === 0x00BD /* vulgar fraction one half */ ||\n char === 0x00BE /* vulgar fraction three quarters */ ||\n char === 0x00D7 /* multiplication sign */ ||\n char === 0x00F7 /* division sign */) {\n return true;\n }\n }\n if (isChar['General Punctuation'](char)) {\n if (char === 0x2016 /* double vertical line */ ||\n char === 0x2020 /* dagger */ ||\n char === 0x2021 /* double dagger */ ||\n char === 0x2030 /* per mille sign */ ||\n char === 0x2031 /* per ten thousand sign */ ||\n char === 0x203B /* reference mark */ ||\n char === 0x203C /* double exclamation mark */ ||\n char === 0x2042 /* asterism */ ||\n char === 0x2047 /* double question mark */ ||\n char === 0x2048 /* question exclamation mark */ ||\n char === 0x2049 /* exclamation question mark */ ||\n char === 0x2051 /* two asterisks aligned vertically */) {\n return true;\n }\n }\n if (isChar['Letterlike Symbols'](char)) return true;\n if (isChar['Number Forms'](char)) return true;\n if (isChar['Miscellaneous Technical'](char)) {\n if ((char >= 0x2300 /* diameter sign */ && char <= 0x2307 /* wavy line */) ||\n (char >= 0x230C /* bottom right crop */ && char <= 0x231F /* bottom right corner */) ||\n (char >= 0x2324 /* up arrowhead between two horizontal bars */ && char <= 0x2328 /* keyboard */) ||\n char === 0x232B /* erase to the left */ ||\n (char >= 0x237D /* shouldered open box */ && char <= 0x239A /* clear screen symbol */) ||\n (char >= 0x23BE /* dentistry symbol light vertical and top right */ && char <= 0x23CD /* square foot */) ||\n char === 0x23CF /* eject symbol */ ||\n (char >= 0x23D1 /* metrical breve */ && char <= 0x23DB /* fuse */) ||\n (char >= 0x23E2 /* white trapezium */ && char <= 0x23FF)) {\n return true;\n }\n }\n if (isChar['Control Pictures'](char) && char !== 0x2423 /* open box */) return true;\n if (isChar['Optical Character Recognition'](char)) return true;\n if (isChar['Enclosed Alphanumerics'](char)) return true;\n if (isChar['Geometric Shapes'](char)) return true;\n if (isChar['Miscellaneous Symbols'](char)) {\n if (!((char >= 0x261A /* black left pointing index */ && char <= 0x261F) /* white down pointing index */)) {\n return true;\n }\n }\n if (isChar['Miscellaneous Symbols and Arrows'](char)) {\n if ((char >= 0x2B12 /* square with top half black */ && char <= 0x2B2F /* white vertical ellipse */) ||\n (char >= 0x2B50 /* white medium star */ && char <= 0x2B59 /* heavy circled saltire */) ||\n (char >= 0x2BB8 /* upwards white arrow from bar with horizontal bar */ && char <= 0x2BEB)) {\n return true;\n }\n }\n if (isChar['CJK Symbols and Punctuation'](char)) return true;\n if (isChar['Katakana'](char)) return true;\n if (isChar['Private Use Area'](char)) return true;\n if (isChar['CJK Compatibility Forms'](char)) return true;\n if (isChar['Small Form Variants'](char)) return true;\n if (isChar['Halfwidth and Fullwidth Forms'](char)) return true;\n\n if (char === 0x221E /* infinity */ ||\n char === 0x2234 /* therefore */ ||\n char === 0x2235 /* because */ ||\n (char >= 0x2700 /* black safety scissors */ && char <= 0x2767 /* rotated floral heart bullet */) ||\n (char >= 0x2776 /* dingbat negative circled digit one */ && char <= 0x2793 /* dingbat negative circled sans-serif number ten */) ||\n char === 0xFFFC /* object replacement character */ ||\n char === 0xFFFD /* replacement character */) {\n return true;\n }\n\n return false;\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) {\n return !(charHasUprightVerticalOrientation(char) ||\n charHasNeutralVerticalOrientation(char));\n}\n\nexport function charInComplexShapingScript(char: number) {\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) {\n return rtlScriptRegExp.test(String.fromCodePoint(char));\n}\n\nexport function charInSupportedScript(char: number, canRenderRTL: 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 if ((char >= 0x0900 && char <= 0x0DFF) ||\n // Main blocks for Indic scripts and Sinhala\n (char >= 0x0F00 && char <= 0x109F) ||\n // Main blocks for Tibetan and Myanmar\n isChar['Khmer'](char)) {\n // These blocks cover common scripts that require\n // complex text shaping, based on unicode script metadata:\n // https://www.unicode.org/repos/cldr/trunk/common/properties/scriptMetadata.txt\n // where \"Web Rank <= 32\" \"Shaping Required = YES\"\n return false;\n }\n return true;\n}\n\nexport function stringContainsRTLText(chars: string): boolean {\n for (const char of chars) {\n if (charInRTLScript(char.charCodeAt(0))) {\n return true;\n }\n }\n return false;\n}\n\nexport function isStringInSupportedScript(chars: string, canRenderRTL: boolean) {\n for (const char of chars) {\n if (!charInSupportedScript(char.charCodeAt(0), canRenderRTL)) {\n return false;\n }\n }\n return true;\n}\n", "import {PluginState, RTLPluginStatus} from './rtl_text_plugin_status';\n\nexport interface RTLTextPlugin {\n applyArabicShaping: (a: string) => string;\n processBidirectionalText: ((b: string, a: Array) => Array);\n processStyledBidirectionalText: ((c: string, b: Array, a: Array) => Array<[string, Array]>);\n}\n\nclass RTLWorkerPlugin implements RTLTextPlugin {\n applyArabicShaping: (a: string) => string = null;\n processBidirectionalText: ((b: string, a: Array) => Array) = null;\n processStyledBidirectionalText: ((c: string, b: Array, a: Array) => Array<[string, Array]>) = null;\n pluginStatus: RTLPluginStatus = 'unavailable';\n pluginURL: string = null;\n\n setState(state: PluginState) {\n this.pluginStatus = state.pluginStatus;\n this.pluginURL = state.pluginURL;\n }\n\n getState(): PluginState {\n return {\n pluginStatus: this.pluginStatus,\n pluginURL: this.pluginURL\n };\n }\n\n setMethods(rtlTextPlugin: RTLTextPlugin) {\n this.applyArabicShaping = rtlTextPlugin.applyArabicShaping;\n this.processBidirectionalText = rtlTextPlugin.processBidirectionalText;\n this.processStyledBidirectionalText = rtlTextPlugin.processStyledBidirectionalText;\n }\n\n isParsed(): boolean {\n return this.applyArabicShaping != null &&\n this.processBidirectionalText != null &&\n this.processStyledBidirectionalText != null;\n }\n\n getPluginURL(): string {\n return this.pluginURL;\n }\n\n getRTLTextPluginStatus() {\n return this.pluginStatus;\n }\n}\n\nexport const rtlWorkerPlugin = new RTLWorkerPlugin();\n", "import {ZoomHistory} from './zoom_history';\nimport {isStringInSupportedScript} from '../util/script_detection';\nimport {rtlWorkerPlugin} from '../source/rtl_text_plugin_worker';\n\nimport type {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 */\nexport class EvaluationParameters {\n zoom: number;\n now: number;\n fadeDuration: number;\n zoomHistory: ZoomHistory;\n transition: TransitionSpecification;\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;\n this.fadeDuration = options.fadeDuration;\n this.zoomHistory = options.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 isSupportedScript(str: string): boolean {\n return isStringInSupportedScript(str, rtlWorkerPlugin.getRTLTextPluginStatus() === 'loaded');\n }\n\n crossFadingFactor() {\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", "import {clone, extend, easeCubicInOut} from '../util/util';\nimport {interpolates, Color, StylePropertySpecification, normalizePropertyExpression,\n Feature,\n FeatureState,\n StylePropertyExpression,\n SourceExpression,\n CompositeExpression, TransitionSpecification,\n PropertyValueSpecification} from '@maplibre/maplibre-gl-style-spec';\nimport {register} from '../util/web_worker_transfer';\nimport {EvaluationParameters} from './evaluation_parameters';\n\nimport {CanonicalTileID} from '../source/tile_id';\n\ntype TimePoint = number;\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 possiblyEvaluate(\n value: PropertyValue,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: Array\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) {\n this.property = property;\n this.value = value;\n this.expression = normalizePropertyExpression(value === undefined ? property.specification.default : value, property.specification);\n }\n\n isDataDriven(): boolean {\n return this.expression.kind === 'source' || this.expression.kind === 'composite';\n }\n\n possiblyEvaluate(\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: Array\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) {\n this.property = property;\n this.value = new PropertyValue(property, undefined);\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\n constructor(properties: Properties) {\n this._properties = properties;\n this._values = (Object.create(properties.defaultTransitionablePropertyValues) as any);\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) {\n if (!Object.prototype.hasOwnProperty.call(this._values, name)) {\n this._values[name] = new TransitionablePropertyValue(this._values[name].property);\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));\n }\n\n getTransition(name: S): TransitionSpecification | void {\n return clone(this._values[name].transition);\n }\n\n setTransition(name: S, value: TransitionSpecification | void) {\n if (!Object.prototype.hasOwnProperty.call(this._values, name)) {\n this._values[name] = new TransitionablePropertyValue(this._values[name].property);\n }\n this._values[name].transition = clone(value) || undefined;\n }\n\n serialize() {\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`] = 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: Array\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) as any);\n }\n\n possiblyEvaluate(\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: Array\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() {\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\n constructor(properties: Properties) {\n this._properties = properties;\n this._values = (Object.create(properties.defaultPropertyValues) as any);\n }\n\n hasValue(name: S) {\n return this._values[name].value !== undefined;\n }\n\n getValue(name: S) {\n return clone(this._values[name].value);\n }\n\n setValue(name: S, value: any) {\n this._values[name] = new PropertyValue(this._values[name].property, value === null ? undefined : clone(value)) as any;\n }\n\n serialize() {\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?: Array\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?: Array\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 * @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\n constructor(specification: StylePropertySpecification) {\n this.specification = specification;\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 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 overrides: any;\n\n constructor(specification: StylePropertySpecification, overrides?: any) {\n this.specification = specification;\n this.overrides = overrides;\n }\n\n possiblyEvaluate(\n value: PropertyValue>,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: Array\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 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?: Array\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?: Array\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?: Array\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\n constructor(specification: StylePropertySpecification) {\n this.specification = specification;\n }\n\n possiblyEvaluate(\n value: PropertyValue>,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: Array\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\n constructor(specification: StylePropertySpecification) {\n this.specification = specification;\n }\n\n possiblyEvaluate(\n value: PropertyValue,\n parameters: EvaluationParameters,\n canonical?: CanonicalTileID,\n availableImages?: Array\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: Array;\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 = ([] as any);\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 const defaultPropertyValue = this.defaultPropertyValues[property] =\n new PropertyValue(prop, undefined);\n const defaultTransitionablePropertyValue = this.defaultTransitionablePropertyValues[property] =\n new TransitionablePropertyValue(prop);\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';\n\nimport {latest as styleSpec, supportsPropertyExpression} from '@maplibre/maplibre-gl-style-spec';\nimport {\n validateStyle,\n validateLayoutProperty,\n validatePaintProperty,\n emitValidationErrors\n} from './validate_style';\nimport {Evented} from '../util/evented';\nimport {Layout, Transitionable, Transitioning, Properties, PossiblyEvaluated, PossiblyEvaluatedPropertyValue} from './properties';\n\nimport type {Bucket} from '../data/bucket';\nimport type Point from '@mapbox/point-geometry';\nimport type {FeatureFilter, FeatureState,\n LayerSpecification,\n FilterSpecification} from '@maplibre/maplibre-gl-style-spec';\nimport type {TransitionParameters, PropertyValue} from './properties';\nimport {EvaluationParameters} from './evaluation_parameters';\nimport type {CrossfadeParameters} from './evaluation_parameters';\n\nimport type {Transform} from '../geo/transform';\nimport type {CustomLayerInterface} from './style_layer/custom_style_layer';\nimport type {Map} from '../ui/map';\nimport type {StyleSetterOptions} from './style';\nimport {mat4} from 'gl-matrix';\nimport type {VectorTileFeature} from '@mapbox/vector-tile';\n\nconst TRANSITION_SUFFIX = '-transition';\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: 'visible' | 'none' | void;\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 readonly onAdd: ((map: Map) => void);\n readonly onRemove: ((map: Map) => void);\n\n queryRadius?(bucket: Bucket): number;\n queryIntersectsFeature?(\n queryGeometry: Array,\n feature: VectorTileFeature,\n featureState: FeatureState,\n geometry: Array>,\n zoom: number,\n transform: Transform,\n pixelsToTileUnits: number,\n pixelPosMatrix: mat4\n ): boolean | number;\n\n constructor(layer: LayerSpecification | CustomLayerInterface, properties: Readonly<{\n layout?: Properties;\n paint?: Properties;\n }>) {\n super();\n\n this.id = layer.id;\n this.type = layer.type;\n this._featureFilter = {filter: () => true, needGeometry: false};\n\n if (layer.type === 'custom') return;\n\n layer = (layer as any as LayerSpecification);\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 }\n\n if (properties.layout) {\n this._unevaluatedLayout = new Layout(properties.layout);\n }\n\n if (properties.paint) {\n this._transitionablePaint = new Transitionable(properties.paint);\n\n for (const property in layer.paint) {\n this.setPaintProperty(property, layer.paint[property], {validate: false});\n }\n for (const property in layer.layout) {\n this.setLayoutProperty(property, layer.layout[property], {validate: false});\n }\n\n this._transitioningPaint = this._transitionablePaint.untransitioned();\n //$FlowFixMe\n this.paint = new PossiblyEvaluated(properties.paint);\n }\n }\n\n getCrossfadeParameters() {\n return this._crossfadeParameters;\n }\n\n getLayoutProperty(name: string) {\n if (name === 'visibility') {\n return this.visibility;\n }\n\n return this._unevaluatedLayout.getValue(name);\n }\n\n setLayoutProperty(name: string, value: any, options: StyleSetterOptions = {}) {\n if (value !== null && value !== undefined) {\n const key = `layers.${this.id}.layout.${name}`;\n if (this._validate(validateLayoutProperty, key, name, value, options)) {\n return;\n }\n }\n\n if (name === 'visibility') {\n this.visibility = value;\n return;\n }\n\n this._unevaluatedLayout.setValue(name, value);\n }\n\n getPaintProperty(name: string) {\n if (name.endsWith(TRANSITION_SUFFIX)) {\n return this._transitionablePaint.getTransition(name.slice(0, -TRANSITION_SUFFIX.length));\n } else {\n return this._transitionablePaint.getValue(name);\n }\n }\n\n setPaintProperty(name: string, value: unknown, options: StyleSetterOptions = {}) {\n if (value !== null && value !== undefined) {\n const key = `layers.${this.id}.paint.${name}`;\n if (this._validate(validatePaintProperty, key, name, value, options)) {\n return false;\n }\n }\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 this._transitionablePaint.setValue(name, value);\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) {\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) {\n if (this.minzoom && zoom < this.minzoom) return true;\n if (this.maxzoom && zoom >= this.maxzoom) return true;\n return this.visibility === 'none';\n }\n\n updateTransitions(parameters: TransitionParameters) {\n this._transitioningPaint = this._transitionablePaint.transitioned(parameters, this._transitioningPaint);\n }\n\n hasTransition() {\n return this._transitioningPaint.hasTransition();\n }\n\n recalculate(parameters: EvaluationParameters, availableImages: Array) {\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 && this._unevaluatedLayout.serialize(),\n 'paint': this._transitionablePaint && this._transitionablePaint.serialize()\n };\n\n if (this.visibility) {\n output.layout = 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: Function, key: string, name: string, value: unknown, options: StyleSetterOptions = {}) {\n if (options && options.validate === false) {\n return false;\n }\n return emitValidationErrors(this, validate.call(validateStyle, {\n key,\n layerType: this.type,\n objectKey: name,\n value,\n styleSpec,\n // Workaround for https://github.com/mapbox/mapbox-gl-js/issues/2407\n style: {glyphs: true, sprite: true}\n }));\n }\n\n is3D() {\n return false;\n }\n\n isTileClipped() {\n return false;\n }\n\n hasOffscreenPass() {\n return false;\n }\n\n resize() {\n // noop\n }\n\n isStateDependent() {\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", "// Note: all \"sizes\" are measured in bytes\n\n/**\n * @internal\n * A view type size\n */\nconst viewTypes = {\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: Array;\n size: number;\n alignment: number;\n};\n\n/**\n * An array that can be desialized\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: Array;\n bytesPerElement: number;\n abstract emplaceBack(...v: number[]);\n abstract emplace(i: number, ...v: 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?: Array): 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(input: SerializedStructArray) {\n const structArray = 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() {\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() {\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) {\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) {\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() {\n throw new Error('_refreshViews() must be implemented by each concrete StructArray layout');\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';\nimport {register} from '../util/web_worker_transfer';\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() {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: 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) {\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() {\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) {\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) {\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() {\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) {\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) {\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() {\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) {\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) {\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() {\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) {\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) {\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() {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: 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) {\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() {\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) {\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) {\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] - Int16[4]\n * [8] - Uint16[4]\n * [16] - Int16[4]\n *\n */\nclass StructArrayLayout4i4ui4i24 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n uint16: Uint16Array;\n\n _refreshViews() {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.int16 = new Int16Array(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, v10: number, v11: 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);\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) {\n const o2 = i * 12;\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 return i;\n }\n}\n\nStructArrayLayout4i4ui4i24.prototype.bytesPerElement = 24;\nregister('StructArrayLayout4i4ui4i24', StructArrayLayout4i4ui4i24);\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() {\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) {\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) {\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() {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint32 = new Uint32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: 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) {\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() {\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) {\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) {\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() {\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) {\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) {\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() {\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) {\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) {\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() {\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) {\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) {\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() {\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) {\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) {\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 *\n */\nclass StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n uint16: Uint16Array;\n uint32: Uint32Array;\n float32: Float32Array;\n\n _refreshViews() {\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) {\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);\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) {\n const o2 = i * 24;\n const o4 = i * 12;\n const o1 = i * 48;\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 return i;\n }\n}\n\nStructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype.bytesPerElement = 48;\nregister('StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48', StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48);\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 *\n */\nclass StructArrayLayout8i15ui1ul2f2ui64 extends StructArray {\n uint8: Uint8Array;\n int16: Int16Array;\n uint16: Uint16Array;\n uint32: Uint32Array;\n float32: Float32Array;\n\n _refreshViews() {\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) {\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);\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) {\n const o2 = i * 32;\n const o4 = i * 16;\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 return i;\n }\n}\n\nStructArrayLayout8i15ui1ul2f2ui64.prototype.bytesPerElement = 64;\nregister('StructArrayLayout8i15ui1ul2f2ui64', StructArrayLayout8i15ui1ul2f2ui64);\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() {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.float32 = new Float32Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: 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) {\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() {\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) {\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) {\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() {\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) {\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) {\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() {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: number, v1: 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) {\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() {\n this.uint8 = new Uint8Array(this.arrayBuffer);\n this.uint16 = new Uint16Array(this.arrayBuffer);\n }\n\n public emplaceBack(v0: 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) {\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() {\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) {\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) {\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() { return this._structArray.int16[this._pos2 + 0]; }\n get anchorPointY() { return this._structArray.int16[this._pos2 + 1]; }\n get x1() { return this._structArray.int16[this._pos2 + 2]; }\n get y1() { return this._structArray.int16[this._pos2 + 3]; }\n get x2() { return this._structArray.int16[this._pos2 + 4]; }\n get y2() { return this._structArray.int16[this._pos2 + 5]; }\n get featureIndex() { return this._structArray.uint32[this._pos4 + 3]; }\n get sourceLayerIndex() { return this._structArray.uint16[this._pos2 + 8]; }\n get bucketIndex() { return this._structArray.uint16[this._pos2 + 9]; }\n get anchorPoint() { 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() { return this._structArray.int16[this._pos2 + 0]; }\n get anchorY() { return this._structArray.int16[this._pos2 + 1]; }\n get glyphStartIndex() { return this._structArray.uint16[this._pos2 + 2]; }\n get numGlyphs() { return this._structArray.uint16[this._pos2 + 3]; }\n get vertexStartIndex() { return this._structArray.uint32[this._pos4 + 2]; }\n get lineStartIndex() { return this._structArray.uint32[this._pos4 + 3]; }\n get lineLength() { return this._structArray.uint32[this._pos4 + 4]; }\n get segment() { return this._structArray.uint16[this._pos2 + 10]; }\n get lowerSize() { return this._structArray.uint16[this._pos2 + 11]; }\n get upperSize() { return this._structArray.uint16[this._pos2 + 12]; }\n get lineOffsetX() { return this._structArray.float32[this._pos4 + 7]; }\n get lineOffsetY() { return this._structArray.float32[this._pos4 + 8]; }\n get writingMode() { return this._structArray.uint8[this._pos1 + 36]; }\n get placedOrientation() { return this._structArray.uint8[this._pos1 + 37]; }\n set placedOrientation(x: number) { this._structArray.uint8[this._pos1 + 37] = x; }\n get hidden() { return this._structArray.uint8[this._pos1 + 38]; }\n set hidden(x: number) { this._structArray.uint8[this._pos1 + 38] = x; }\n get crossTileID() { return this._structArray.uint32[this._pos4 + 10]; }\n set crossTileID(x: number) { this._structArray.uint32[this._pos4 + 10] = x; }\n get associatedIconIndex() { return this._structArray.int16[this._pos2 + 22]; }\n}\n\nPlacedSymbolStruct.prototype.size = 48;\n\nexport type PlacedSymbol = PlacedSymbolStruct;\n\n/** @internal */\nexport class PlacedSymbolArray extends StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48 {\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() { return this._structArray.int16[this._pos2 + 0]; }\n get anchorY() { return this._structArray.int16[this._pos2 + 1]; }\n get rightJustifiedTextSymbolIndex() { return this._structArray.int16[this._pos2 + 2]; }\n get centerJustifiedTextSymbolIndex() { return this._structArray.int16[this._pos2 + 3]; }\n get leftJustifiedTextSymbolIndex() { return this._structArray.int16[this._pos2 + 4]; }\n get verticalPlacedTextSymbolIndex() { return this._structArray.int16[this._pos2 + 5]; }\n get placedIconSymbolIndex() { return this._structArray.int16[this._pos2 + 6]; }\n get verticalPlacedIconSymbolIndex() { return this._structArray.int16[this._pos2 + 7]; }\n get key() { return this._structArray.uint16[this._pos2 + 8]; }\n get textBoxStartIndex() { return this._structArray.uint16[this._pos2 + 9]; }\n get textBoxEndIndex() { return this._structArray.uint16[this._pos2 + 10]; }\n get verticalTextBoxStartIndex() { return this._structArray.uint16[this._pos2 + 11]; }\n get verticalTextBoxEndIndex() { return this._structArray.uint16[this._pos2 + 12]; }\n get iconBoxStartIndex() { return this._structArray.uint16[this._pos2 + 13]; }\n get iconBoxEndIndex() { return this._structArray.uint16[this._pos2 + 14]; }\n get verticalIconBoxStartIndex() { return this._structArray.uint16[this._pos2 + 15]; }\n get verticalIconBoxEndIndex() { return this._structArray.uint16[this._pos2 + 16]; }\n get featureIndex() { return this._structArray.uint16[this._pos2 + 17]; }\n get numHorizontalGlyphVertices() { return this._structArray.uint16[this._pos2 + 18]; }\n get numVerticalGlyphVertices() { return this._structArray.uint16[this._pos2 + 19]; }\n get numIconVertices() { return this._structArray.uint16[this._pos2 + 20]; }\n get numVerticalIconVertices() { return this._structArray.uint16[this._pos2 + 21]; }\n get useRuntimeCollisionCircles() { return this._structArray.uint16[this._pos2 + 22]; }\n get crossTileID() { return this._structArray.uint32[this._pos4 + 12]; }\n set crossTileID(x: number) { this._structArray.uint32[this._pos4 + 12] = x; }\n get textBoxScale() { return this._structArray.float32[this._pos4 + 13]; }\n get collisionCircleDiameter() { return this._structArray.float32[this._pos4 + 14]; }\n get textAnchorOffsetStartIndex() { return this._structArray.uint16[this._pos2 + 30]; }\n get textAnchorOffsetEndIndex() { return this._structArray.uint16[this._pos2 + 31]; }\n}\n\nSymbolInstanceStruct.prototype.size = 64;\n\nexport type SymbolInstance = SymbolInstanceStruct;\n\n/** @internal */\nexport class SymbolInstanceArray extends StructArrayLayout8i15ui1ul2f2ui64 {\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) { return this.float32[index * 1 + 0]; }\n}\n\nregister('GlyphOffsetArray', GlyphOffsetArray);\n\n/** @internal */\nexport class SymbolLineVertexArray extends StructArrayLayout3i6 {\n getx(index: number) { return this.int16[index * 3 + 0]; }\n gety(index: number) { return this.int16[index * 3 + 1]; }\n gettileUnitDistanceFromAnchor(index: 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() { return this._structArray.uint16[this._pos2 + 0]; }\n get textOffset0() { return this._structArray.float32[this._pos4 + 1]; }\n get textOffset1() { 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() { return this._structArray.uint32[this._pos4 + 0]; }\n get sourceLayerIndex() { return this._structArray.uint16[this._pos2 + 2]; }\n get bucketIndex() { 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 SymbolLayoutArray extends StructArrayLayout4i4ui4i24 {}\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 StructArrayLayout4i4ui4i24,\n StructArrayLayout3f12,\n StructArrayLayout1ul4,\n StructArrayLayout6i1ul2ui20,\n StructArrayLayout2i2i2i12,\n StructArrayLayout2f1f2i16,\n StructArrayLayout2ub2f2i16,\n StructArrayLayout3ui6,\n StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48,\n StructArrayLayout8i15ui1ul2f2ui64,\n StructArrayLayout1f4,\n StructArrayLayout1ui2f12,\n StructArrayLayout1ul2ui8,\n StructArrayLayout2ui4,\n StructArrayLayout1ui2,\n StructArrayLayout4f16\n};\n", "import {createLayout} from '../../util/struct_array';\n\nconst layout = createLayout([\n {name: 'a_pos', components: 2, type: 'Int16'}\n], 4);\n\nexport default layout;\nexport const {members, size, alignment} = layout;\n", "import {warnOnce} from '../util/util';\n\nimport {register} from '../util/web_worker_transfer';\n\nimport type {VertexArrayObject} from '../render/vertex_array_object';\nimport type {StructArray} from '../util/struct_array';\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: Array;\n\n constructor(segments: Array = []) {\n this.segments = segments;\n }\n\n prepareSegment(\n numVertices: number,\n layoutVertexArray: StructArray,\n indexArray: StructArray,\n sortKey?: number\n ): Segment {\n let segment: Segment = this.segments[this.segments.length - 1];\n if (numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) warnOnce(`Max vertices per segment is ${SegmentVector.MAX_VERTEX_ARRAY_LENGTH}: bucket requested ${numVertices}`);\n if (!segment || segment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH || segment.sortKey !== sortKey) {\n segment = ({\n vertexOffset: layoutVertexArray.length,\n primitiveOffset: indexArray.length,\n vertexLength: 0,\n primitiveLength: 0\n } as any);\n if (sortKey !== undefined) segment.sortKey = sortKey;\n this.segments.push(segment);\n }\n return segment;\n }\n\n get() {\n return this.segments;\n }\n\n destroy() {\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';\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) {\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} from '../../util/struct_array';\n\nexport const patternAttributes = 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", "/**\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';\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: Array;\n positions: Array;\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) {\n this.ids.push(getNumericId(id));\n this.positions.push(index, start, end);\n }\n\n getPositions(id: unknown): Array {\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: Array): 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 '../gl/context';\nimport {mat4, vec2, vec3, 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: WebGLRenderingContext|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 {\n constructor(context: Context, location: WebGLUniformLocation) {\n super(context, location);\n this.current = [0, 0];\n }\n\n set(v: vec2): void {\n if (v[0] !== this.current[0] || v[1] !== this.current[1]) {\n this.current = v;\n this.gl.uniform2f(this.location, v[0], v[1]);\n }\n }\n}\n\nclass Uniform3f extends Uniform {\n constructor(context: Context, location: WebGLUniformLocation) {\n super(context, location);\n this.current = [0, 0, 0];\n }\n\n set(v: vec3): void {\n if (v[0] !== this.current[0] || v[1] !== this.current[1] || v[2] !== this.current[2]) {\n this.current = v;\n this.gl.uniform3f(this.location, v[0], v[1], v[2]);\n }\n }\n}\n\nclass Uniform4f extends Uniform {\n constructor(context: Context, location: WebGLUniformLocation) {\n super(context, location);\n this.current = [0, 0, 0, 0];\n }\n\n set(v: vec4): void {\n if (v[0] !== this.current[0] || v[1] !== this.current[1] ||\n v[2] !== this.current[2] || v[3] !== this.current[3]) {\n this.current = v;\n this.gl.uniform4f(this.location, v[0], v[1], v[2], v[3]);\n }\n }\n}\n\nclass UniformColor extends Uniform {\n constructor(context: Context, location: WebGLUniformLocation) {\n super(context, location);\n this.current = Color.transparent;\n }\n\n set(v: Color): void {\n if (v.r !== this.current.r || v.g !== this.current.g ||\n v.b !== this.current.b || v.a !== this.current.a) {\n this.current = v;\n this.gl.uniform4f(this.location, v.r, v.g, v.b, v.a);\n }\n }\n}\n\nconst emptyMat4 = new Float32Array(16) as mat4;\nclass UniformMatrix4f extends Uniform {\n constructor(context: Context, location: WebGLUniformLocation) {\n super(context, location);\n this.current = emptyMat4;\n }\n\n set(v: mat4): void {\n // The vast majority of matrix comparisons that will trip this set\n // happen at i=12 or i=0, so we check those first to avoid lots of\n // unnecessary iteration:\n if (v[12] !== this.current[12] || v[0] !== this.current[0]) {\n this.current = v;\n this.gl.uniformMatrix4fv(this.location, false, v);\n return;\n }\n for (let i = 1; i < 16; i++) {\n if (v[i] !== this.current[i]) {\n this.current = v;\n this.gl.uniformMatrix4fv(this.location, false, v);\n break;\n }\n }\n }\n}\n\nexport {\n Uniform,\n Uniform1i,\n Uniform1f,\n Uniform2f,\n Uniform3f,\n Uniform4f,\n UniformColor,\n UniformMatrix4f\n};\n\n/**\n * @internal\n * A uniform bindings\n */\nexport type UniformBindings = {[_: string]: Uniform};\n", "import {packUint8ToFloat} from '../shaders/encode_attribute';\nimport {Color, supportsPropertyExpression} from '@maplibre/maplibre-gl-style-spec';\nimport {register} from '../util/web_worker_transfer';\nimport {PossiblyEvaluatedPropertyValue} from '../style/properties';\nimport {StructArrayLayout1f4, StructArrayLayout2f8, StructArrayLayout4f16, PatternLayoutArray} from './array_types.g';\nimport {clamp} from '../util/util';\nimport {patternAttributes} from './bucket/pattern_attributes';\nimport {EvaluationParameters} from '../style/evaluation_parameters';\nimport {FeaturePositionMap} from './feature_position_map';\nimport {Uniform, Uniform1f, UniformColor, Uniform4f} from '../render/uniform_binding';\n\nimport type {UniformLocations} from '../render/uniform_binding';\n\nimport type {CanonicalTileID} from '../source/tile_id';\nimport type {Context} from '../gl/context';\nimport type {TypedStyleLayer} from '../style/style_layer/typed_style_layer';\nimport type {CrossfadeParameters} from '../style/evaluation_parameters';\nimport type {StructArray, StructArrayMember} from '../util/struct_array';\nimport type {VertexBuffer} from '../gl/vertex_buffer';\nimport type {ImagePosition} from '../render/image_atlas';\nimport type {\n Feature,\n FeatureState,\n GlobalProperties,\n SourceExpression,\n CompositeExpression,\n FormattedSection\n} from '@maplibre/maplibre-gl-style-spec';\nimport type {FeatureStates} from '../source/source_state';\nimport type {VectorTileLayer} from '@mapbox/vector-tile';\n\nexport type BinderUniform = {\n name: string;\n property: string;\n binding: Uniform;\n};\n\nfunction packColor(color: Color): [number, number] {\n return [\n packUint8ToFloat(255 * color.r, 255 * color.g),\n packUint8ToFloat(255 * color.b, 255 * color.a)\n ];\n}\n\n/**\n * `Binder` is the interface definition for the strategies for constructing,\n * uploading, and binding paint property data as GLSL attributes. Most style-\n * spec properties have a 1:1 relationship to shader attribute/uniforms, but\n * some require multiple values per feature to be passed to the GPU, and in\n * those cases we bind multiple attributes/uniforms.\n *\n * It has three implementations, one for each of the three strategies we use:\n *\n * * For _constant_ properties -- those whose value is a constant, or the constant\n * result of evaluating a camera expression at a particular camera position -- we\n * don't need a vertex attribute buffer, and instead use a uniform.\n * * For data expressions, we use a vertex buffer with a single attribute value,\n * the evaluated result of the source function for the given feature.\n * * For composite expressions, we use a vertex buffer with two attributes: min and\n * max values covering the range of zooms at which we expect the tile to be\n * displayed. These values are calculated by evaluating the composite expression for\n * the given feature at strategically chosen zoom levels. In addition to this\n * attribute data, we also use a uniform value which the shader uses to interpolate\n * between the min and max value at the final displayed zoom level. The use of a\n * uniform allows us to cheaply update the value on every frame.\n *\n * Note that the shader source varies depending on whether we're using a uniform or\n * attribute. We dynamically compile shaders at runtime to accommodate this.\n */\ninterface AttributeBinder {\n populatePaintArray(\n length: number,\n feature: Feature,\n imagePositions: {[_: string]: ImagePosition},\n canonical?: CanonicalTileID,\n formattedSection?: FormattedSection\n ): void;\n updatePaintArray(\n start: number,\n length: number,\n feature: Feature,\n featureState: FeatureState,\n imagePositions: {[_: string]: ImagePosition}\n ): void;\n upload(a: Context): void;\n destroy(): void;\n}\n\ninterface UniformBinder {\n uniformNames: Array;\n setUniform(\n uniform: Uniform,\n globals: GlobalProperties,\n currentValue: PossiblyEvaluatedPropertyValue