diff --git a/dist/tangram.debug.js b/dist/tangram.debug.js index ccd9ee09f..c7623190f 100644 --- a/dist/tangram.debug.js +++ b/dist/tangram.debug.js @@ -1912,7 +1912,7 @@ function _wrapNativeSuper(Class) { return _wrapNativeSuper(Class); } -var version = "0.18.0"; +var version = "0.18.1"; var version$1 = 'v' + version; @@ -2661,377 +2661,6 @@ if (_fails(function () { return $toString.call({ source: 'a', flags: 'b' }) != ' }); } -// Miscellaneous geo functions -var Geo; -var Geo$1 = Geo = {}; // Projection constants - -Geo.default_source_max_zoom = 18; -Geo.default_view_max_zoom = 20; -Geo.max_style_zoom = 25; // max zoom at which styles will be evaluated - -Geo.tile_size = 256; -Geo.half_circumference_meters = 20037508.342789244; -Geo.circumference_meters = Geo.half_circumference_meters * 2; -Geo.min_zoom_meters_per_pixel = Geo.circumference_meters / Geo.tile_size; // min zoom draws world as 2 tiles wide - -var meters_per_pixel = []; - -Geo.metersPerPixel = function (z) { - meters_per_pixel[z] = meters_per_pixel[z] || Geo.min_zoom_meters_per_pixel / Math.pow(2, z); - return meters_per_pixel[z]; -}; - -var meters_per_tile = []; - -Geo.metersPerTile = function (z) { - meters_per_tile[z] = meters_per_tile[z] || Geo.circumference_meters / Math.pow(2, z); - return meters_per_tile[z]; -}; // Conversion functions based on an defined tile scale - - -Geo.tile_scale = 4096; // coordinates are locally scaled to the range [0, tile_scale] - -Geo.units_per_pixel = Geo.tile_scale / Geo.tile_size; -Geo.height_scale = 16; // provides sub-meter precision for height values (16ths of a meters) - -var units_per_meter = []; - -Geo.unitsPerMeter = function (z) { - units_per_meter[z] = units_per_meter[z] || Geo.tile_scale / (Geo.tile_size * Geo.metersPerPixel(z)); - return units_per_meter[z]; -}; // Convert tile location to mercator meters - multiply by pixels per tile, then by meters per pixel, adjust for map origin - - -Geo.metersForTile = function (tile) { - return { - x: tile.x * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters, - y: -(tile.y * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters) - }; -}; -/** - Given a point in mercator meters and a zoom level, return the tile X/Y/Z that the point lies in -*/ - - -Geo.tileForMeters = function (_ref, zoom) { - var x = _ref[0], - y = _ref[1]; - return { - x: Math.floor((x + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))), - y: Math.floor((-y + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))), - z: zoom - }; -}; // Wrap a tile to positive #s for zoom -// Optionally specify the axes to wrap - - -Geo.wrapTile = function (_ref2, mask) { - var x = _ref2.x, - y = _ref2.y, - z = _ref2.z; - - if (mask === void 0) { - mask = { - x: true, - y: false - }; - } - - var m = (1 << z) - 1; - - if (mask.x) { - x = x & m; - } - - if (mask.y) { - y = y & m; - } - - return { - x: x, - y: y, - z: z - }; -}; -/** - Convert mercator meters to lat-lng -*/ - - -Geo.metersToLatLng = function (_ref3) { - var x = _ref3[0], - y = _ref3[1]; - x /= Geo.half_circumference_meters; - y /= Geo.half_circumference_meters; - y = (2 * Math.atan(Math.exp(y * Math.PI)) - Math.PI / 2) / Math.PI; - x *= 180; - y *= 180; - return [x, y]; -}; -/** - Convert lat-lng to mercator meters -*/ - - -Geo.latLngToMeters = function (_ref4) { - var x = _ref4[0], - y = _ref4[1]; - // Latitude - y = Math.log(Math.tan(y * Math.PI / 360 + Math.PI / 4)) / Math.PI; - y *= Geo.half_circumference_meters; // Longitude - - x *= Geo.half_circumference_meters / 180; - return [x, y]; -}; // Transform from local tile coordinats to lat lng - - -Geo.tileSpaceToLatlng = function (geometry, z, min) { - var units_per_meter = Geo.unitsPerMeter(z); - Geo.transformGeometry(geometry, function (coord) { - coord[0] = coord[0] / units_per_meter + min.x; - coord[1] = coord[1] / units_per_meter + min.y; - - var _Geo$metersToLatLng = Geo.metersToLatLng(coord), - x = _Geo$metersToLatLng[0], - y = _Geo$metersToLatLng[1]; - - coord[0] = x; - coord[1] = y; - }); - return geometry; -}; // Copy GeoJSON geometry - - -Geo.copyGeometry = function (geometry) { - if (geometry == null) { - return; // skip if missing geometry (valid GeoJSON) - } - - var copy = { - type: geometry.type - }; - - if (geometry.type === 'Point') { - copy.coordinates = [geometry.coordinates[0], geometry.coordinates[1]]; - } else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') { - copy.coordinates = geometry.coordinates.map(function (c) { - return [c[0], c[1]]; - }); - } else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') { - copy.coordinates = geometry.coordinates.map(function (ring) { - return ring.map(function (c) { - return [c[0], c[1]]; - }); - }); - } else if (geometry.type === 'MultiPolygon') { - copy.coordinates = geometry.coordinates.map(function (polygon) { - return polygon.map(function (ring) { - return ring.map(function (c) { - return [c[0], c[1]]; - }); - }); - }); - } // TODO: support GeometryCollection - - - return copy; -}; // Run an in-place transform function on each cooordinate in a GeoJSON geometry - - -Geo.transformGeometry = function (geometry, transform) { - if (geometry == null) { - return; // skip if missing geometry (valid GeoJSON) - } - - if (geometry.type === 'Point') { - transform(geometry.coordinates); - } else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') { - geometry.coordinates.forEach(transform); - } else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') { - geometry.coordinates.forEach(function (ring) { - return ring.forEach(transform); - }); - } else if (geometry.type === 'MultiPolygon') { - geometry.coordinates.forEach(function (polygon) { - polygon.forEach(function (ring) { - return ring.forEach(transform); - }); - }); - } // TODO: support GeometryCollection - -}; - -Geo.boxIntersect = function (b1, b2) { - return !(b2.sw.x > b1.ne.x || b2.ne.x < b1.sw.x || b2.sw.y > b1.ne.y || b2.ne.y < b1.sw.y); -}; // Finds the axis-aligned bounding box for a polygon - - -Geo.findBoundingBox = function (polygon) { - var min_x = Infinity, - max_x = -Infinity, - min_y = Infinity, - max_y = -Infinity; // Only need to examine outer ring (polygon[0]) - - var num_coords = polygon[0].length; - - for (var c = 0; c < num_coords; c++) { - var coord = polygon[0][c]; - - if (coord[0] < min_x) { - min_x = coord[0]; - } - - if (coord[1] < min_y) { - min_y = coord[1]; - } - - if (coord[0] > max_x) { - max_x = coord[0]; - } - - if (coord[1] > max_y) { - max_y = coord[1]; - } - } - - return [min_x, min_y, max_x, max_y]; -}; // Convert geometry type to one of: 'point', 'line', 'polygon' - - -Geo.geometryType = function (type) { - if (type === 'Polygon' || type === 'MultiPolygon') { - return 'polygon'; - } else if (type === 'LineString' || type === 'MultiLineString') { - return 'line'; - } - - if (type === 'Point' || type === 'MultiPoint') { - return 'point'; - } -}; // Geometric / weighted centroid of polygon -// Adapted from https://github.com/Leaflet/Leaflet/blob/c10f405a112142b19785967ce0e142132a6095ad/src/layer/vector/Polygon.js#L57 - - -Geo.centroid = function (polygon, relative) { - if (relative === void 0) { - relative = true; - } - - if (!polygon || polygon.length === 0) { - return; - } - - var x = 0, - y = 0, - area = 0; - var ring = polygon[0]; // only use first ring for now - - var len = ring.length; // optionally calculate relative to first coordinate to avoid precision issues w/small polygons - - var origin; - - if (relative) { - origin = ring[0]; - ring = ring.map(function (v) { - return [v[0] - origin[0], v[1] - origin[1]]; - }); - } - - for (var i = 0, j = len - 1; i < len; j = i, i++) { - var p0 = ring[i]; - var p1 = ring[j]; - var f = p0[1] * p1[0] - p1[1] * p0[0]; - x += (p0[0] + p1[0]) * f; - y += (p0[1] + p1[1]) * f; - area += f * 3; - } - - if (!area) { - return; // skip degenerate polygons - } - - var c = [x / area, y / area]; - - if (relative) { - c[0] += origin[0]; - c[1] += origin[1]; - } - - return c; -}; - -Geo.multiCentroid = function (polygons) { - var n = 0; - var centroid = null; - - for (var p = 0; p < polygons.length; p++) { - var c = Geo.centroid(polygons[p]); - - if (c) { - // skip degenerate polygons - centroid = centroid || [0, 0]; - centroid[0] += c[0]; - centroid[1] += c[1]; - n++; - } - } - - if (n > 0) { - centroid[0] /= n; - centroid[1] /= n; - } - - return centroid; // will return null if all polygons were degenerate -}; - -Geo.signedPolygonRingAreaSum = function (ring) { - var area = 0; - var n = ring.length; - - for (var i = 0; i < n - 1; i++) { - var p0 = ring[i]; - var p1 = ring[i + 1]; - area += p0[0] * p1[1] - p1[0] * p0[1]; - } - - area += ring[n - 1][0] * ring[0][1] - ring[0][0] * ring[n - 1][1]; - return area; -}; - -Geo.polygonRingArea = function (ring) { - return Math.abs(Geo.signedPolygonRingAreaSum(ring)) / 2; -}; // TODO: subtract inner rings - - -Geo.polygonArea = function (polygon) { - if (!polygon) { - return; - } - - return Geo.polygonRingArea(polygon[0]); -}; - -Geo.multiPolygonArea = function (polygons) { - var area = 0; - - for (var p = 0; p < polygons.length; p++) { - area += Geo.polygonArea(polygons[p]); - } - - return area; -}; - -Geo.ringWinding = function (ring) { - var area = Geo.signedPolygonRingAreaSum(ring); - - if (area > 0) { - return 'CW'; - } else if (area < 0) { - return 'CCW'; - } // return undefined on zero area polygon - -}; - var Utils = {}; WorkerBroker$1.addTarget('Utils', Utils); // Basic Safari detection // http://stackoverflow.com/questions/7944460/detect-safari-browser @@ -3292,10 +2921,6 @@ Utils.toCSSColor = function (color) { }).join(', ') + ")"; }; -Utils.pointInTile = function (point) { - return point[0] >= 0 && point[1] > -Geo$1.tile_scale && point[0] < Geo$1.tile_scale && point[1] <= 0; -}; - var debugSettings; var debugSettings$1 = debugSettings = { // draws a blue rectangle border around the collision box of a label @@ -6545,6 +6170,367 @@ function mergeObjects(dest) { return dest; } +// Miscellaneous geo functions +var Geo; +var Geo$1 = Geo = {}; // Projection constants + +Geo.default_source_max_zoom = 18; +Geo.default_view_max_zoom = 20; +Geo.max_style_zoom = 25; // max zoom at which styles will be evaluated + +Geo.tile_size = 256; +Geo.half_circumference_meters = 20037508.342789244; +Geo.circumference_meters = Geo.half_circumference_meters * 2; +Geo.min_zoom_meters_per_pixel = Geo.circumference_meters / Geo.tile_size; // min zoom draws world as 2 tiles wide + +var meters_per_pixel = []; + +Geo.metersPerPixel = function (z) { + meters_per_pixel[z] = meters_per_pixel[z] || Geo.min_zoom_meters_per_pixel / Math.pow(2, z); + return meters_per_pixel[z]; +}; + +var meters_per_tile = []; + +Geo.metersPerTile = function (z) { + meters_per_tile[z] = meters_per_tile[z] || Geo.circumference_meters / Math.pow(2, z); + return meters_per_tile[z]; +}; // Conversion functions based on an defined tile scale + + +Geo.tile_scale = 4096; // coordinates are locally scaled to the range [0, tile_scale] + +Geo.units_per_pixel = Geo.tile_scale / Geo.tile_size; +Geo.height_scale = 16; // provides sub-meter precision for height values (16ths of a meters) + +var units_per_meter = []; + +Geo.unitsPerMeter = function (z) { + units_per_meter[z] = units_per_meter[z] || Geo.tile_scale / (Geo.tile_size * Geo.metersPerPixel(z)); + return units_per_meter[z]; +}; // Convert tile location to mercator meters - multiply by pixels per tile, then by meters per pixel, adjust for map origin + + +Geo.metersForTile = function (tile) { + return { + x: tile.x * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters, + y: -(tile.y * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters) + }; +}; +/** + Given a point in mercator meters and a zoom level, return the tile X/Y/Z that the point lies in +*/ + + +Geo.tileForMeters = function (_ref, zoom) { + var x = _ref[0], + y = _ref[1]; + return { + x: Math.floor((x + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))), + y: Math.floor((-y + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))), + z: zoom + }; +}; // Wrap a tile to positive #s for zoom +// Optionally specify the axes to wrap + + +Geo.wrapTile = function (_ref2, mask) { + var x = _ref2.x, + y = _ref2.y, + z = _ref2.z; + + if (mask === void 0) { + mask = { + x: true, + y: false + }; + } + + var m = (1 << z) - 1; + + if (mask.x) { + x = x & m; + } + + if (mask.y) { + y = y & m; + } + + return { + x: x, + y: y, + z: z + }; +}; +/** + Convert mercator meters to lat-lng, in-place +*/ + + +Geo.metersToLatLng = function (c) { + c[0] /= Geo.half_circumference_meters; + c[1] /= Geo.half_circumference_meters; + c[1] = (2 * Math.atan(Math.exp(c[1] * Math.PI)) - Math.PI / 2) / Math.PI; + c[0] *= 180; + c[1] *= 180; + return c; +}; +/** + Convert lat-lng to mercator meters, in-place +*/ + + +Geo.latLngToMeters = function (c) { + // Latitude + c[1] = Math.log(Math.tan(c[1] * Math.PI / 360 + Math.PI / 4)) / Math.PI; + c[1] *= Geo.half_circumference_meters; // Longitude + + c[0] *= Geo.half_circumference_meters / 180; + return c; +}; // Transform from local tile coordinats to lat lng + + +Geo.tileSpaceToLatlng = function (geometry, z, min) { + var units_per_meter = Geo.unitsPerMeter(z); + Geo.transformGeometry(geometry, function (coord) { + coord[0] = coord[0] / units_per_meter + min.x; + coord[1] = coord[1] / units_per_meter + min.y; + Geo.metersToLatLng(coord); + }); + return geometry; +}; // Copy GeoJSON geometry + + +Geo.copyGeometry = function (geometry) { + if (geometry == null) { + return; // skip if missing geometry (valid GeoJSON) + } + + var copy = { + type: geometry.type + }; + + if (geometry.type === 'Point') { + copy.coordinates = [geometry.coordinates[0], geometry.coordinates[1]]; + } else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') { + copy.coordinates = geometry.coordinates.map(function (c) { + return [c[0], c[1]]; + }); + } else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') { + copy.coordinates = geometry.coordinates.map(function (ring) { + return ring.map(function (c) { + return [c[0], c[1]]; + }); + }); + } else if (geometry.type === 'MultiPolygon') { + copy.coordinates = geometry.coordinates.map(function (polygon) { + return polygon.map(function (ring) { + return ring.map(function (c) { + return [c[0], c[1]]; + }); + }); + }); + } // TODO: support GeometryCollection + + + return copy; +}; // Run an in-place transform function on each cooordinate in a GeoJSON geometry + + +Geo.transformGeometry = function (geometry, transform) { + if (geometry == null) { + return; // skip if missing geometry (valid GeoJSON) + } + + if (geometry.type === 'Point') { + transform(geometry.coordinates); + } else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') { + geometry.coordinates.forEach(transform); + } else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') { + geometry.coordinates.forEach(function (ring) { + return ring.forEach(transform); + }); + } else if (geometry.type === 'MultiPolygon') { + geometry.coordinates.forEach(function (polygon) { + polygon.forEach(function (ring) { + return ring.forEach(transform); + }); + }); + } // TODO: support GeometryCollection + +}; + +Geo.boxIntersect = function (b1, b2) { + return !(b2.sw.x > b1.ne.x || b2.ne.x < b1.sw.x || b2.sw.y > b1.ne.y || b2.ne.y < b1.sw.y); +}; // Finds the axis-aligned bounding box for a polygon + + +Geo.findBoundingBox = function (polygon) { + var min_x = Infinity, + max_x = -Infinity, + min_y = Infinity, + max_y = -Infinity; // Only need to examine outer ring (polygon[0]) + + var num_coords = polygon[0].length; + + for (var c = 0; c < num_coords; c++) { + var coord = polygon[0][c]; + + if (coord[0] < min_x) { + min_x = coord[0]; + } + + if (coord[1] < min_y) { + min_y = coord[1]; + } + + if (coord[0] > max_x) { + max_x = coord[0]; + } + + if (coord[1] > max_y) { + max_y = coord[1]; + } + } + + return [min_x, min_y, max_x, max_y]; +}; // Convert geometry type to one of: 'point', 'line', 'polygon' + + +Geo.geometryType = function (type) { + if (type === 'Polygon' || type === 'MultiPolygon') { + return 'polygon'; + } else if (type === 'LineString' || type === 'MultiLineString') { + return 'line'; + } + + if (type === 'Point' || type === 'MultiPoint') { + return 'point'; + } +}; // Geometric / weighted centroid of polygon +// Adapted from https://github.com/Leaflet/Leaflet/blob/c10f405a112142b19785967ce0e142132a6095ad/src/layer/vector/Polygon.js#L57 + + +Geo.centroid = function (polygon, relative) { + if (relative === void 0) { + relative = true; + } + + if (!polygon || polygon.length === 0) { + return; + } + + var x = 0, + y = 0, + area = 0; + var ring = polygon[0]; // only use first ring for now + + var len = ring.length; // optionally calculate relative to first coordinate to avoid precision issues w/small polygons + + var origin; + + if (relative) { + origin = ring[0]; + ring = ring.map(function (v) { + return [v[0] - origin[0], v[1] - origin[1]]; + }); + } + + for (var i = 0, j = len - 1; i < len; j = i, i++) { + var p0 = ring[i]; + var p1 = ring[j]; + var f = p0[1] * p1[0] - p1[1] * p0[0]; + x += (p0[0] + p1[0]) * f; + y += (p0[1] + p1[1]) * f; + area += f * 3; + } + + if (!area) { + return; // skip degenerate polygons + } + + var c = [x / area, y / area]; + + if (relative) { + c[0] += origin[0]; + c[1] += origin[1]; + } + + return c; +}; + +Geo.multiCentroid = function (polygons) { + var n = 0; + var centroid = null; + + for (var p = 0; p < polygons.length; p++) { + var c = Geo.centroid(polygons[p]); + + if (c) { + // skip degenerate polygons + centroid = centroid || [0, 0]; + centroid[0] += c[0]; + centroid[1] += c[1]; + n++; + } + } + + if (n > 0) { + centroid[0] /= n; + centroid[1] /= n; + } + + return centroid; // will return null if all polygons were degenerate +}; + +Geo.signedPolygonRingAreaSum = function (ring) { + var area = 0; + var n = ring.length; + + for (var i = 0; i < n - 1; i++) { + var p0 = ring[i]; + var p1 = ring[i + 1]; + area += p0[0] * p1[1] - p1[0] * p0[1]; + } + + area += ring[n - 1][0] * ring[0][1] - ring[0][0] * ring[n - 1][1]; + return area; +}; + +Geo.polygonRingArea = function (ring) { + return Math.abs(Geo.signedPolygonRingAreaSum(ring)) / 2; +}; // TODO: subtract inner rings + + +Geo.polygonArea = function (polygon) { + if (!polygon) { + return; + } + + return Geo.polygonRingArea(polygon[0]); +}; + +Geo.multiPolygonArea = function (polygons) { + var area = 0; + + for (var p = 0; p < polygons.length; p++) { + area += Geo.polygonArea(polygons[p]); + } + + return area; +}; + +Geo.ringWinding = function (ring) { + var area = Geo.signedPolygonRingAreaSum(ring); + + if (area > 0) { + return 'CW'; + } else if (area < 0) { + return 'CCW'; + } // return undefined on zero area polygon + +}; + var _stringWs = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; @@ -8724,12 +8710,9 @@ function (_Light3) { if (this.origin === 'world') { // For world origin, format is: [longitude, latitude, meters (default) or pixels w/px units] // Move light's world position into camera space - var _Geo$latLngToMeters = Geo$1.latLngToMeters(this.position), - x = _Geo$latLngToMeters[0], - y = _Geo$latLngToMeters[1]; - - this.position_eye[0] = x - this.view.camera.position_meters[0]; - this.position_eye[1] = y - this.view.camera.position_meters[1]; + var m = Geo$1.latLngToMeters([].concat(this.position)); + this.position_eye[0] = m[0] - this.view.camera.position_meters[0]; + this.position_eye[1] = m[1] - this.view.camera.position_meters[1]; this.position_eye[2] = StyleParser.convertUnits(this.position[2], { zoom: this.view.zoom, meters_per_pixel: Geo$1.metersPerPixel(this.view.zoom) @@ -8969,20 +8952,17 @@ function () { for (var f = 0; f < num_features; f++) { var feature = source.layers[t].features[f]; - Geo$1.transformGeometry(feature.geometry, function (coord) { - var _Geo$latLngToMeters = Geo$1.latLngToMeters(coord), - x = _Geo$latLngToMeters[0], - y = _Geo$latLngToMeters[1]; - - coord[0] = x; - coord[1] = y; - }); + Geo$1.transformGeometry(feature.geometry, this.projectCoord); } } if (source.debug !== undefined) { source.debug.projection = +new Date() - timer; } + }; + + DataSource.projectCoord = function projectCoord(coord) { + Geo$1.latLngToMeters(coord); } /** Re-scale geometries within each source to internal tile units @@ -9318,13 +9298,13 @@ function (_NetworkSource) { var min = bounds.tiles.min[coords.z]; if (!min) { - min = bounds.tiles.min[coords.z] = Geo$1.wrapTile(Geo$1.tileForMeters(bounds.meters.min, coords.z)); + min = bounds.tiles.min[coords.z] = Geo$1.tileForMeters(bounds.meters.min, coords.z); } var max = bounds.tiles.max[coords.z]; if (!max) { - max = bounds.tiles.max[coords.z] = Geo$1.wrapTile(Geo$1.tileForMeters(bounds.meters.max, coords.z)); + max = bounds.tiles.max[coords.z] = Geo$1.tileForMeters(bounds.meters.max, coords.z); } // check latitude @@ -10041,22 +10021,6 @@ var Style = { WorkerBroker$1.addTarget(this.main_thread_target, this); } }, - fillVertexTemplate: function fillVertexTemplate(vertex_layout, attribute, value, _ref2) { - var size = _ref2.size, - offset = _ref2.offset; - offset = offset === undefined ? 0 : offset; - var index = vertex_layout.index[attribute]; - - if (index === undefined) { - log('warn', "Style: in style '" + this.name + "', no index found in vertex layout for attribute '" + attribute + "'"); - return; - } - - for (var i = 0; i < size; ++i) { - var v = value.length > i ? value[i] : value; - this.vertex_template[index + i + offset] = v; - } - }, /*** Style parsing and geometry construction ***/ // Returns an object to hold feature data (for a tile or other object) @@ -12256,38 +12220,23 @@ var JOIN_TYPE = { bevel: 1, round: 2 }; -var DEFAULT = { - MITER_LIMIT: 3, - TEXCOORD_NORMALIZE: 1, - TEXCOORD_RATIO: 1, - MIN_FAN_WIDTH: 5 // Width of line in tile units to place 1 triangle per fan +var DEFAULT_MITER_LIMIT = 3; +var MIN_FAN_WIDTH = 5; // Width of line in tile units to place 1 triangle per fan -}; // Scaling factor to add precision to line texture V coordinate packed as normalized short +var TEXCOORD_NORMALIZE = 65536; // Scaling factor for UV attribute values +// Scaling factor to add precision to line texture V coordinate packed as normalized short -var v_scale_adjust = Geo$1.tile_scale; +var V_SCALE_ADJUST = Geo$1.tile_scale; var zero_v = [0, 0], one_v = [1, 0], mid_v = [0.5, 0]; // reusable instances, updated with V coordinate -function buildPolylines(lines, width, vertex_data, vertex_template, _ref) { - var closed_polygon = _ref.closed_polygon, - remove_tile_edges = _ref.remove_tile_edges, - tile_edge_tolerance = _ref.tile_edge_tolerance, - texcoord_index = _ref.texcoord_index, - texcoord_width = _ref.texcoord_width, - texcoord_ratio = _ref.texcoord_ratio, - texcoord_normalize = _ref.texcoord_normalize, - extrude_index = _ref.extrude_index, - offset_index = _ref.offset_index, - join = _ref.join, - cap = _ref.cap, - miter_limit = _ref.miter_limit, - offset = _ref.offset; - var cap_type = cap ? CAP_TYPE[cap] : CAP_TYPE.butt; - var join_type = join ? JOIN_TYPE[join] : JOIN_TYPE.miter; // Configure miter limit +function buildPolylines(lines, style, vertex_data, vertex_template, vindex, closed_polygon, remove_tile_edges, tile_edge_tolerance) { + var cap_type = style.cap ? CAP_TYPE[style.cap] : CAP_TYPE.butt; + var join_type = style.join ? JOIN_TYPE[style.join] : JOIN_TYPE.miter; // Configure miter limit if (join_type === JOIN_TYPE.miter) { - miter_limit = miter_limit || DEFAULT.MITER_LIMIT; // default miter limit + var miter_limit = style.miter_limit || DEFAULT_MITER_LIMIT; // default miter limit var miter_len_sq = miter_limit * miter_limit; } // Texture Variables @@ -12295,10 +12244,8 @@ function buildPolylines(lines, width, vertex_data, vertex_template, _ref) { var v_scale; - if (texcoord_index) { - texcoord_normalize = texcoord_normalize || DEFAULT.TEXCOORD_NORMALIZE; - texcoord_ratio = texcoord_ratio || DEFAULT.TEXCOORD_RATIO; - v_scale = 1 / (texcoord_width * texcoord_ratio * v_scale_adjust); // scales line texture as a ratio of the line's width + if (vindex.a_texcoord) { + v_scale = 1 / (style.texcoord_width * V_SCALE_ADJUST); // scales line texture as a ratio of the line's width } // Values that are constant for each line and are passed to helper functions @@ -12311,25 +12258,24 @@ function buildPolylines(lines, width, vertex_data, vertex_template, _ref) { cap_type: cap_type, vertex_data: vertex_data, vertex_template: vertex_template, - half_width: width / 2, - extrude_index: extrude_index, - offset_index: offset_index, + half_width: style.width / 2, + extrude_index: vindex.a_extrude, + offset_index: vindex.a_offset, v_scale: v_scale, - texcoord_index: texcoord_index, - texcoord_width: texcoord_width, - texcoord_normalize: texcoord_normalize, - offset: offset, + texcoord_index: vindex.a_texcoord, + texcoord_width: style.texcoord_width, + offset: style.offset, geom_count: 0 }; // Process lines - for (var index = 0; index < lines.length; index++) { - buildPolyline(lines[index], context); + for (var i = 0; i < lines.length; i++) { + buildPolyline(lines[i], context); } // Process extra lines (which are created above if lines need to be mutated for easier processing) if (context.extra_lines) { - for (var _index = 0; _index < context.extra_lines.length; _index++) { - buildPolyline(context.extra_lines[_index], context); + for (var _i = 0; _i < context.extra_lines.length; _i++) { + buildPolyline(context.extra_lines[_i], context); } } @@ -12672,8 +12618,8 @@ function addVertex(position, extrude, normal, u, v, context, flip) { if (context.texcoord_index != null) { - vertex_template[context.texcoord_index + 0] = u * context.texcoord_normalize; - vertex_template[context.texcoord_index + 1] = v * context.texcoord_normalize; + vertex_template[context.texcoord_index + 0] = u * TEXCOORD_NORMALIZE; + vertex_template[context.texcoord_index + 1] = v * TEXCOORD_NORMALIZE; } vertex_data.addVertex(vertex_template); @@ -12860,7 +12806,7 @@ function trianglesPerArc(angle, width) { angle = -angle; } - var numTriangles = width > 2 * DEFAULT.MIN_FAN_WIDTH ? Math.log2(width / DEFAULT.MIN_FAN_WIDTH) : 1; + var numTriangles = width > 2 * MIN_FAN_WIDTH ? Math.log2(width / MIN_FAN_WIDTH) : 1; return Math.ceil(angle / Math.PI * numTriangles); } // Cyclically permute closed line starting at an index @@ -13606,21 +13552,10 @@ Object.assign(Lines, { var vertex_data = mesh.vertex_data; var vertex_layout = vertex_data.vertex_layout; var vertex_template = this.makeVertexTemplate(style, mesh); - return buildPolylines(lines, style.width, vertex_data, vertex_template, { - cap: style.cap, - join: style.join, - miter_limit: style.miter_limit, - extrude_index: vertex_layout.index.a_extrude, - offset_index: vertex_layout.index.a_offset, - texcoord_index: vertex_layout.index.a_texcoord, - texcoord_width: style.texcoord_width, - texcoord_normalize: 65535, - // scale UVs to unsigned shorts - closed_polygon: options && options.closed_polygon, - remove_tile_edges: !style.tile_edges && options && options.remove_tile_edges, - tile_edge_tolerance: Geo$1.tile_scale * context.tile.pad_scale * 2, - offset: style.offset - }); + return buildPolylines(lines, style, vertex_data, vertex_template, vertex_layout.index, options && options.closed_polygon, // closed_polygon + !style.tile_edges && options && options.remove_tile_edges, // remove_tile_edges + Geo$1.tile_scale * context.tile.pad_scale * 2 // tile_edge_tolerance + ); }, buildPolygons: function buildPolygons(polygons, style, context) { // Render polygons as individual lines @@ -13657,108 +13592,87 @@ _stringHtml('anchor', function (createHTML) { }); // Point builders -// properties for width, height, angle, and a scale factor that can be used to interpolate the screenspace size -// of a sprite between two zoom levels. -function buildQuadsForPoints(points, vertex_data, vertex_template, _ref, _ref2) { - var texcoord_index = _ref.texcoord_index, - position_index = _ref.position_index, - shape_index = _ref.shape_index, - offset_index = _ref.offset_index, - offsets_index = _ref.offsets_index, - pre_angles_index = _ref.pre_angles_index, - angles_index = _ref.angles_index; - var quad = _ref2.quad, - quad_normalize = _ref2.quad_normalize, - offset = _ref2.offset, - offsets = _ref2.offsets, - pre_angles = _ref2.pre_angles, - angle = _ref2.angle, - angles = _ref2.angles, - curve = _ref2.curve, - texcoord_scale = _ref2.texcoord_scale, - texcoord_normalize = _ref2.texcoord_normalize, - pre_angles_normalize = _ref2.pre_angles_normalize, - angles_normalize = _ref2.angles_normalize, - offsets_normalize = _ref2.offsets_normalize; - quad_normalize = quad_normalize || 1; - var w2 = quad[0] / 2 * quad_normalize; - var h2 = quad[1] / 2 * quad_normalize; - var scaling = [[-w2, -h2], [w2, -h2], [w2, h2], [-w2, h2]]; +var pre_angles_normalize = 128 / Math.PI; +var angles_normalize = 16384 / Math.PI; +var offsets_normalize = 64; +var texcoord_normalize = 65535; +var size_normalize = 128; // width/height are 8.8 fixed-point, but are halved (so multiply by 128 instead of 256) +// These index values map a 4-element vertex position counter from this pattern (used for size and UVs): +// [min_x, min_y, max_x, max_y] +// to this pattern: +// [min_x, min_y], +// [max_x, min_y], +// [max_x, max_y], +// [min_x, max_y] + +var ix = [0, 2, 2, 0]; +var iy = [1, 1, 3, 3]; +var shape = new Array(4); // single, reusable allocation +// Build a billboard sprite quad centered on a point. Sprites are intended to be drawn in screenspace, and have +// properties for width, height, angle, and texture UVs. Curved label segment sprites have additional properties +// for interpolating their position and angle across zooms. + +function buildQuadForPoint(point, vertex_data, vertex_template, vindex, size, offset, offsets, pre_angles, angle, angles, texcoords, curve) { + // Half-sized point dimensions in fixed point + var w2 = size[0] * size_normalize; + var h2 = size[1] * size_normalize; + shape[0] = -w2; + shape[1] = -h2; + shape[2] = w2; + shape[3] = h2; + var uvs = texcoords || default_uvs; var vertex_elements = vertex_data.vertex_elements; var element_offset = vertex_data.vertex_count; - var texcoords; - if (texcoord_index) { - texcoord_normalize = texcoord_normalize || 1; + for (var p = 0; p < 4; p++) { + vertex_template[vindex.a_position + 0] = point[0]; + vertex_template[vindex.a_position + 1] = point[1]; + vertex_template[vindex.a_shape + 0] = shape[ix[p]]; + vertex_template[vindex.a_shape + 1] = shape[iy[p]]; + vertex_template[vindex.a_shape + 2] = angle; + vertex_template[vindex.a_offset + 0] = offset[0]; + vertex_template[vindex.a_offset + 1] = offset[1]; // Add texcoords - var _ref3 = texcoord_scale || default_uvs, - min_u = _ref3[0], - min_v = _ref3[1], - max_u = _ref3[2], - max_v = _ref3[3]; + if (vindex.a_texcoord) { + vertex_template[vindex.a_texcoord + 0] = uvs[ix[p]] * texcoord_normalize; + vertex_template[vindex.a_texcoord + 1] = uvs[iy[p]] * texcoord_normalize; + } // Add curved label segment props - texcoords = [[min_u, min_v], [max_u, min_v], [max_u, max_v], [min_u, max_v]]; - } - var geom_count = 0; - var num_points = points.length; + if (curve) { + // 1 byte (signed) range: [-127, 128] + // actual range: [-2pi, 2pi] + // total: multiply by 128 / (2 PI) + vertex_template[vindex.a_pre_angles + 0] = pre_angles_normalize * pre_angles[0]; + vertex_template[vindex.a_pre_angles + 1] = pre_angles_normalize * pre_angles[1]; + vertex_template[vindex.a_pre_angles + 2] = pre_angles_normalize * pre_angles[2]; + vertex_template[vindex.a_pre_angles + 3] = pre_angles_normalize * pre_angles[3]; // 2 byte (signed) of resolution [-32767, 32768] + // actual range: [-2pi, 2pi] + // total: multiply by 32768 / (2 PI) = 16384 / PI - for (var p = 0; p < num_points; p++) { - var point = points[p]; + vertex_template[vindex.a_angles + 0] = angles_normalize * angles[0]; + vertex_template[vindex.a_angles + 1] = angles_normalize * angles[1]; + vertex_template[vindex.a_angles + 2] = angles_normalize * angles[2]; + vertex_template[vindex.a_angles + 3] = angles_normalize * angles[3]; // offset range can be [0, 65535] + // actual range: [0, 1024] - for (var pos = 0; pos < 4; pos++) { - // Add texcoords - if (texcoord_index) { - vertex_template[texcoord_index + 0] = texcoords[pos][0] * texcoord_normalize; - vertex_template[texcoord_index + 1] = texcoords[pos][1] * texcoord_normalize; - } - - vertex_template[position_index + 0] = point[0]; - vertex_template[position_index + 1] = point[1]; - vertex_template[shape_index + 0] = scaling[pos][0]; - vertex_template[shape_index + 1] = scaling[pos][1]; - vertex_template[shape_index + 2] = angle; - vertex_template[offset_index + 0] = offset[0]; - vertex_template[offset_index + 1] = offset[1]; - - if (curve) { - // 1 byte (signed) range: [-127, 128] - // actual range: [-2pi, 2pi] - // total: multiply by 128 / (2 PI) - vertex_template[pre_angles_index + 0] = pre_angles_normalize * pre_angles[0]; - vertex_template[pre_angles_index + 1] = pre_angles_normalize * pre_angles[1]; - vertex_template[pre_angles_index + 2] = pre_angles_normalize * pre_angles[2]; - vertex_template[pre_angles_index + 3] = pre_angles_normalize * pre_angles[3]; // 2 byte (signed) of resolution [-32767, 32768] - // actual range: [-2pi, 2pi] - // total: multiply by 32768 / (2 PI) = 16384 / PI - - vertex_template[angles_index + 0] = angles_normalize * angles[0]; - vertex_template[angles_index + 1] = angles_normalize * angles[1]; - vertex_template[angles_index + 2] = angles_normalize * angles[2]; - vertex_template[angles_index + 3] = angles_normalize * angles[3]; // offset range can be [0, 65535] - // actual range: [0, 1024] - - vertex_template[offsets_index + 0] = offsets_normalize * offsets[0]; - vertex_template[offsets_index + 1] = offsets_normalize * offsets[1]; - vertex_template[offsets_index + 2] = offsets_normalize * offsets[2]; - vertex_template[offsets_index + 3] = offsets_normalize * offsets[3]; - } - - vertex_data.addVertex(vertex_template); - } - - vertex_elements.push(element_offset + 0); - vertex_elements.push(element_offset + 1); - vertex_elements.push(element_offset + 2); - vertex_elements.push(element_offset + 2); - vertex_elements.push(element_offset + 3); - vertex_elements.push(element_offset + 0); - element_offset += 4; - geom_count += 2; + vertex_template[vindex.a_offsets + 0] = offsets_normalize * offsets[0]; + vertex_template[vindex.a_offsets + 1] = offsets_normalize * offsets[1]; + vertex_template[vindex.a_offsets + 2] = offsets_normalize * offsets[2]; + vertex_template[vindex.a_offsets + 3] = offsets_normalize * offsets[3]; + } + + vertex_data.addVertex(vertex_template); } - return geom_count; + vertex_elements.push(element_offset + 0); + vertex_elements.push(element_offset + 1); + vertex_elements.push(element_offset + 2); + vertex_elements.push(element_offset + 2); + vertex_elements.push(element_offset + 3); + vertex_elements.push(element_offset + 0); + return 2; // geom count is always two triangles, for one quad } // Sets of values to match for directional and corner anchors @@ -13863,15 +13777,22 @@ function boxIntersectsList(a, boxes, callback) { } } +var ZERO_AXES = [[1, 0], [0, 1]]; +var proj_a = [], + proj_b = []; +var d0, d1, d2, d3; + var OBB = /*#__PURE__*/ function () { function OBB(x, y, a, w, h) { - this.dimension = [w, h]; + this.dimension = [w / 2, h / 2]; // store half-dimension as that's what's needed in calculations below + this.angle = a; this.centroid = [x, y]; - this.quad = []; - this.axes = []; + this.quad = null; + this.axis_0 = null; + this.axis_1 = null; this.update(); } @@ -13888,68 +13809,90 @@ function () { }; _proto.getExtent = function getExtent() { - var aabb = [Infinity, Infinity, -Infinity, -Infinity]; - - for (var i = 0; i < 4; ++i) { - aabb[0] = Math.min(this.quad[i][0], aabb[0]); - aabb[1] = Math.min(this.quad[i][1], aabb[1]); - aabb[2] = Math.max(this.quad[i][0], aabb[2]); - aabb[3] = Math.max(this.quad[i][1], aabb[3]); + // special handling to skip calculations for 0-angle + if (this.angle === 0) { + return [this.quad[0], this.quad[1], // lower-left + this.quad[4], this.quad[5] // upper-right + ]; } + var aabb = [Math.min(this.quad[0], this.quad[2], this.quad[4], this.quad[6]), // min x + Math.min(this.quad[1], this.quad[3], this.quad[5], this.quad[7]), // min y + Math.max(this.quad[0], this.quad[2], this.quad[4], this.quad[6]), // max x + Math.max(this.quad[1], this.quad[3], this.quad[5], this.quad[7]) // max y + ]; return aabb; }; - _proto.perpAxes = function perpAxes() { - this.axes[0] = Vector$1.normalize(Vector$1.sub(this.quad[2], this.quad[3])); - this.axes[1] = Vector$1.normalize(Vector$1.sub(this.quad[2], this.quad[1])); + _proto.updateAxes = function updateAxes() { + // upper-left to upper-right + this.axis_0 = Vector$1.normalize([this.quad[4] - this.quad[6], this.quad[5] - this.quad[7]]); // lower-right to upper-right + + this.axis_1 = Vector$1.normalize([this.quad[4] - this.quad[2], this.quad[5] - this.quad[3]]); }; _proto.update = function update() { - var x = [Math.cos(this.angle), Math.sin(this.angle)]; - var y = [-Math.sin(this.angle), Math.cos(this.angle)]; - x = Vector$1.mult(x, this.dimension[0] / 2.0); - y = Vector$1.mult(y, this.dimension[1] / 2.0); - this.quad[0] = Vector$1.sub(Vector$1.sub(this.centroid, x), y); // lower-left - - this.quad[1] = Vector$1.sub(Vector$1.add(this.centroid, x), y); // lower-right - - this.quad[2] = Vector$1.add(Vector$1.add(this.centroid, x), y); // uper-right + var c = this.centroid; + var w2 = this.dimension[0]; + var h2 = this.dimension[1]; // special handling to skip calculations for 0-angle + + if (this.angle === 0) { + // quad is a flat array storing 4 [x, y] vectors + this.quad = [c[0] - w2, c[1] - h2, // lower-left + c[0] + w2, c[1] - h2, // lower-right + c[0] + w2, c[1] + h2, // upper-right + c[0] - w2, c[1] + h2 // upper-left + ]; + this.axis_0 = ZERO_AXES[0]; + this.axis_1 = ZERO_AXES[1]; + } // calculate axes and enclosing quad + else { + var x0 = Math.cos(this.angle) * w2; + var x1 = Math.sin(this.angle) * w2; + var y0 = -Math.sin(this.angle) * h2; + var y1 = Math.cos(this.angle) * h2; // quad is a flat array storing 4 [x, y] vectors - this.quad[3] = Vector$1.add(Vector$1.sub(this.centroid, x), y); // uper-left + this.quad = [c[0] - x0 - y0, c[1] - x1 - y1, // lower-left + c[0] + x0 - y0, c[1] + x1 - y1, // lower-right + c[0] + x0 + y0, c[1] + x1 + y1, // upper-right + c[0] - x0 + y0, c[1] - x1 + y1 // upper-left + ]; + this.updateAxes(); + } + }; - this.perpAxes(); + OBB.projectToAxis = function projectToAxis(obb, axis, proj) { + // for each axis, project obb quad to it and find min and max values + var quad = obb.quad; + d0 = quad[0] * axis[0] + quad[1] * axis[1]; + d1 = quad[2] * axis[0] + quad[3] * axis[1]; + d2 = quad[4] * axis[0] + quad[5] * axis[1]; + d3 = quad[6] * axis[0] + quad[7] * axis[1]; + proj[0] = Math.min(d0, d1, d2, d3); + proj[1] = Math.max(d0, d1, d2, d3); + return proj; }; - OBB.projectToAxis = function projectToAxis(obb, axis) { - var min = Infinity; - var max = -Infinity; - var quad = obb.quad; // for each axis, project obb quad to it and find min and max values + OBB.axisCollide = function axisCollide(obb_a, obb_b, axis_0, axis_1) { + OBB.projectToAxis(obb_a, axis_0, proj_a); + OBB.projectToAxis(obb_b, axis_0, proj_b); - for (var i = 0; i < 4; ++i) { - var d = Vector$1.dot(quad[i], axis); - min = Math.min(min, d); - max = Math.max(max, d); + if (proj_b[0] > proj_a[1] || proj_b[1] < proj_a[0]) { + return false; } - return [min, max]; - }; - - OBB.axisCollide = function axisCollide(obb_a, obb_b, axes) { - for (var i = 0; i < 2; ++i) { - var a_proj = OBB.projectToAxis(obb_a, axes[i]); - var b_proj = OBB.projectToAxis(obb_b, axes[i]); + OBB.projectToAxis(obb_a, axis_1, proj_a); + OBB.projectToAxis(obb_b, axis_1, proj_b); - if (b_proj[0] > a_proj[1] || b_proj[1] < a_proj[0]) { - return false; - } + if (proj_b[0] > proj_a[1] || proj_b[1] < proj_a[0]) { + return false; } return true; }; OBB.intersect = function intersect(obb_a, obb_b) { - return OBB.axisCollide(obb_a, obb_b, obb_a.axes) && OBB.axisCollide(obb_a, obb_b, obb_b.axes); + return OBB.axisCollide(obb_a, obb_b, obb_a.axis_0, obb_a.axis_1) && OBB.axisCollide(obb_a, obb_b, obb_b.axis_0, obb_b.axis_1); }; return OBB; @@ -13969,6 +13912,7 @@ function () { this.size = size; this.layout = layout; this.position = null; + this.angle = 0; this.anchor = Array.isArray(this.layout.anchor) ? this.layout.anchor[0] : this.layout.anchor; // initial anchor this.placed = null; @@ -13989,6 +13933,7 @@ function () { type: this.type, obb: this.obb.toJSON(), position: this.position, + angle: this.angle, size: this.size, offset: this.offset, breach: this.breach, @@ -14043,10 +13988,7 @@ function () { ; _proto.inTileBounds = function inTileBounds() { - var min = [this.aabb[0], this.aabb[1]]; - var max = [this.aabb[2], this.aabb[3]]; - - if (!Utils.pointInTile(min) || !Utils.pointInTile(max)) { + if (this.aabb[0] >= 0 && this.aabb[1] > -Geo$1.tile_scale && this.aabb[0] < Geo$1.tile_scale && this.aabb[1] <= 0 || this.aabb[2] >= 0 && this.aabb[3] > -Geo$1.tile_scale && this.aabb[2] < Geo$1.tile_scale && this.aabb[3] <= 0) { return false; } @@ -14103,10 +14045,12 @@ Label.add = function (label, bboxes) { }; Label.id = 0; -Label.id_prefix = ''; // id prefix scoped to worker thread +Label.id_prefix = 0; // id prefix scoped to worker thread + +Label.id_multiplier = 0; // multiplier to keep label ids distinct across threads Label.nextLabelId = function () { - return Label.id_prefix + '/' + Label.id++; + return Label.id_prefix + Label.id++ * Label.id_multiplier; }; Label.epsilon = 0.9999; // tolerance around collision boxes, prevent perfectly adjacent objects from colliding @@ -14398,12 +14342,17 @@ var LabelPoint = function (_Label) { _inheritsLoose(LabelPoint, _Label); - function LabelPoint(position, size, layout) { + function LabelPoint(position, size, layout, angle) { var _this; + if (angle === void 0) { + angle = 0; + } + _this = _Label.call(this, size, layout) || this; _this.type = 'point'; _this.position = [position[0], position[1]]; + _this.angle = angle; _this.parent = _this.layout.parent; _this.update(); @@ -14454,10 +14403,11 @@ function (_Label) { if (this.layout.italic) { width += 5 * this.unit_scale; - } + } // make bounding boxes + - var p = [this.position[0] + this.offset[0] * this.unit_scale, this.position[1] - this.offset[1] * this.unit_scale]; - this.obb = new OBB(p[0], p[1], 0, width, height); + this.obb = new OBB(this.position[0] + this.offset[0] * this.unit_scale, this.position[1] - this.offset[1] * this.unit_scale, -this.angle, // angle is negative because tile system y axis is pointing down + width, height); this.aabb = this.obb.getExtent(); if (this.inTileBounds) { @@ -14515,13 +14465,13 @@ LabelPoint.PLACEMENT = { var PLACEMENT = LabelPoint.PLACEMENT; var default_spacing = 80; // spacing of points along line in pixels -function placePointsOnLine(line, size, options) { +function placePointsOnLine(line, size, layout) { var labels = []; - var strategy = options.placement; - var min_length = Math.max(size[0], size[1]) * options.placement_min_length_ratio * options.units_per_pixel; + var strategy = layout.placement; + var min_length = Math.max(size[0], size[1]) * layout.placement_min_length_ratio * layout.units_per_pixel; if (strategy === PLACEMENT.SPACED) { - var result = getPositionsAndAngles(line, min_length, options); // false will be returned if line have no length + var result = getPositionsAndAngles(line, min_length, layout); // false will be returned if line have no length if (!result) { return []; @@ -14534,42 +14484,39 @@ function placePointsOnLine(line, size, options) { var position = positions[i]; var angle = angles[i]; - if (options.tile_edges === true || !isCoordOutsideTile(position)) { - var label = new LabelPoint(position, size, options); - label.angle = angle; - labels.push(label); + if (layout.tile_edges === true || !isCoordOutsideTile(position)) { + labels.push(new LabelPoint(position, size, layout, angle)); } } } else if (strategy === PLACEMENT.VERTEX) { - var p, q, _label; + var p, q; for (var _i = 0; _i < line.length - 1; _i++) { p = line[_i]; q = line[_i + 1]; - if (options.tile_edges === true || !isCoordOutsideTile(p)) { - _label = new LabelPoint(p, size, options); - _label.angle = getAngle(p, q, options.angle); - labels.push(_label); + if (layout.tile_edges === true || !isCoordOutsideTile(p)) { + var _angle2 = getAngle(p, q, layout.angle); + + labels.push(new LabelPoint(p, size, layout, _angle2)); } } // add last endpoint - _label = new LabelPoint(q, size, options); - _label.angle = getAngle(p, q, options.angle); - labels.push(_label); + var _angle = getAngle(p, q, layout.angle); + + labels.push(new LabelPoint(q, size, layout, _angle)); } else if (strategy === PLACEMENT.MIDPOINT) { for (var _i2 = 0; _i2 < line.length - 1; _i2++) { var _p = line[_i2]; var _q = line[_i2 + 1]; var _position = [0.5 * (_p[0] + _q[0]), 0.5 * (_p[1] + _q[1])]; - if (options.tile_edges === true || !isCoordOutsideTile(_position)) { + if (layout.tile_edges === true || !isCoordOutsideTile(_position)) { if (!min_length || norm(_p, _q) > min_length) { - var _label2 = new LabelPoint(_position, size, options); + var _angle3 = getAngle(_p, _q, layout.angle); - _label2.angle = getAngle(_p, _q, options.angle); - labels.push(_label2); + labels.push(new LabelPoint(_position, size, layout, _angle3)); } } } @@ -14578,9 +14525,9 @@ function placePointsOnLine(line, size, options) { return labels; } -function getPositionsAndAngles(line, min_length, options) { - var upp = options.units_per_pixel; - var spacing = (options.placement_spacing || default_spacing) * upp; +function getPositionsAndAngles(line, min_length, layout) { + var upp = layout.units_per_pixel; + var spacing = (layout.placement_spacing || default_spacing) * upp; var length = getLineLength(line); if (length <= min_length) { @@ -14594,7 +14541,7 @@ function getPositionsAndAngles(line, min_length, options) { var distance = 0.5 * remainder; for (var i = 0; i < num_labels; i++) { - var _interpolateLine = interpolateLine(line, distance, min_length, options), + var _interpolateLine = interpolateLine(line, distance, min_length, layout), position = _interpolateLine.position, angle = _interpolateLine.angle; @@ -14636,7 +14583,7 @@ function norm(p, q) { // you don't have to start from the first index every time for placement -function interpolateLine(line, distance, min_length, options) { +function interpolateLine(line, distance, min_length, layout) { var sum = 0; var position, angle; @@ -14653,7 +14600,7 @@ function interpolateLine(line, distance, min_length, options) { if (sum > distance) { position = interpolateSegment(p, q, sum - distance); - angle = getAngle(p, q, options.angle); + angle = getAngle(p, q, layout.angle); break; } } @@ -17301,13 +17248,10 @@ function () { y: this.size.css.height * this.meters_per_pixel }; // Center of viewport in meters, and tile - var _Geo$latLngToMeters = Geo$1.latLngToMeters([this.center.lng, this.center.lat]), - x = _Geo$latLngToMeters[0], - y = _Geo$latLngToMeters[1]; - + var m = Geo$1.latLngToMeters([this.center.lng, this.center.lat]); this.center.meters = { - x: x, - y: y + x: m[0], + y: m[1] }; this.center.tile = Geo$1.tileForMeters([this.center.meters.x, this.center.meters.y], this.tile_zoom); // Bounds in meters @@ -17448,15 +17392,11 @@ function () { return View; }(); -var points_vs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_tile_proxy_order_offset;\nuniform bool u_tile_fade_in;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\nuniform float u_visible_time;\nuniform bool u_view_panning;\nuniform float u_view_pan_snap_timer;\n\nuniform mat4 u_model;\nuniform mat4 u_modelView;\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nattribute vec4 a_position;\nattribute vec4 a_shape;\nattribute vec4 a_color;\nattribute vec2 a_texcoord;\nattribute vec2 a_offset;\n\nuniform float u_point_type;\n\n#ifdef TANGRAM_CURVED_LABEL\n attribute vec4 a_offsets;\n attribute vec4 a_pre_angles;\n attribute vec4 a_angles;\n#endif\n\nvarying vec4 v_color;\nvarying vec2 v_texcoord;\nvarying vec4 v_world_position;\nvarying float v_alpha_factor;\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n attribute float a_outline_edge;\n attribute vec4 a_outline_color;\n\n varying float v_outline_edge;\n varying vec4 v_outline_color;\n varying float v_aa_offset;\n#endif\n\n#ifdef TANGRAM_SHOW_HIDDEN_LABELS\n varying float v_label_hidden;\n#endif\n\n#define TANGRAM_PI 3.14159265359\n#define TANGRAM_NORMAL vec3(0., 0., 1.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\nvec2 rotate2D(vec2 _st, float _angle) {\n return mat2(cos(_angle),-sin(_angle),\n sin(_angle),cos(_angle)) * _st;\n}\n\n#ifdef TANGRAM_CURVED_LABEL\n // Assumes stops are [0, 0.33, 0.66, 0.99];\n float mix4linear(float a, float b, float c, float d, float x) {\n x = clamp(x, 0., 1.);\n return mix(mix(a, b, 3. * x),\n mix(b,\n mix(c, d, 3. * (max(x, .66) - .66)),\n 3. * (clamp(x, .33, .66) - .33)),\n step(0.33, x)\n );\n }\n#endif\n\nvoid main() {\n // Initialize globals\n #pragma tangram: setup\n\n // discard hidden labels by collapsing into degenerate triangle\n #ifndef TANGRAM_SHOW_HIDDEN_LABELS\n if (a_shape.w == 0.) {\n gl_Position = vec4(0., 0., 0., 1.);\n return;\n }\n #else\n // highlight hidden label in fragment shader for debugging\n if (a_shape.w == 0.) {\n v_label_hidden = 1.; // label debug testing\n }\n else {\n v_label_hidden = 0.;\n }\n #endif\n\n\n v_alpha_factor = 1.0;\n v_color = a_color;\n v_texcoord = a_texcoord; // UV from vertex\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n float size = abs(a_shape.x/128.); // radius in pixels\n v_texcoord = sign(a_shape.xy)*(size+1.)/(size);\n size+=2.;\n v_aa_offset=2./size;\n }\n #endif\n\n // Position\n vec4 position = u_modelView * vec4(a_position.xyz, 1.);\n\n // Apply positioning and scaling in screen space\n vec2 shape = a_shape.xy / 256.; // values have an 8-bit fraction\n vec2 offset = vec2(a_offset.x, -a_offset.y); // flip y to make it point down\n\n float zoom = clamp(u_map_position.z - u_tile_origin.z, 0., 1.); //fract(u_map_position.z);\n float theta = a_shape.z / 4096.;\n\n #ifdef TANGRAM_CURVED_LABEL\n //TODO: potential bug? null is passed in for non-curved labels, otherwise the first offset will be 0\n if (a_offsets[0] != 0.){\n vec4 angles_scaled = (TANGRAM_PI / 16384.) * a_angles;\n vec4 pre_angles_scaled = (TANGRAM_PI / 128.) * a_pre_angles;\n vec4 offsets_scaled = (1. / 64.) * a_offsets;\n\n float pre_angle = mix4linear(pre_angles_scaled[0], pre_angles_scaled[1], pre_angles_scaled[2], pre_angles_scaled[3], zoom);\n float angle = mix4linear(angles_scaled[0], angles_scaled[1], angles_scaled[2], angles_scaled[3], zoom);\n float offset_curve = mix4linear(offsets_scaled[0], offsets_scaled[1], offsets_scaled[2], offsets_scaled[3], zoom);\n\n shape = rotate2D(shape, pre_angle); // rotate in place\n shape.x += offset_curve; // offset for curved label segment\n shape = rotate2D(shape, angle); // rotate relative to curved label anchor\n shape += rotate2D(offset, theta); // offset if specified in the scene file\n }\n else {\n shape = rotate2D(shape + offset, theta);\n }\n #else\n shape = rotate2D(shape + offset, theta);\n #endif\n\n // Fade in (if requested) based on time mesh has been visible.\n // Value passed to fragment shader in the v_alpha_factor varying\n #ifdef TANGRAM_FADE_IN_RATE\n if (u_tile_fade_in) {\n v_alpha_factor *= clamp(u_visible_time * TANGRAM_FADE_IN_RATE, 0., 1.);\n }\n #endif\n\n // World coordinates for 3d procedural textures\n v_world_position = u_model * position;\n v_world_position.xy += shape * u_meters_per_pixel;\n v_world_position = wrapWorldPosition(v_world_position);\n\n // Modify position before camera projection\n #pragma tangram: position\n\n cameraProjection(position);\n\n #ifdef TANGRAM_LAYER_ORDER\n // +1 is to keep all layers including proxies > 0\n applyLayerOrder(a_position.w + u_tile_proxy_order_offset + 1., position);\n #endif\n\n // Apply pixel offset in screen-space\n // Multiply by 2 is because screen is 2 units wide Normalized Device Coords (and u_resolution device pixels wide)\n // Device pixel ratio adjustment is because shape is in logical pixels\n position.xy += shape * position.w * 2. * u_device_pixel_ratio / u_resolution;\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n // enlarge by 1px to catch missed MSAA fragments\n position.xy += sign(shape) * position.w * u_device_pixel_ratio / u_resolution;\n }\n #endif\n\n // Snap to pixel grid\n // Only applied to fully upright sprites/labels (not shader-drawn points), while panning is not active\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON) && u_point_type != TANGRAM_POINT_TYPE_SHADER) {\n #else\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON)) {\n #endif\n vec2 position_fract = fract((((position.xy / position.w) + 1.) * .5) * u_resolution);\n vec2 position_snap = position.xy + ((step(0.5, position_fract) - position_fract) * position.w * 2. / u_resolution);\n\n // Animate the snapping to smooth the transition and make it less noticeable\n #ifdef TANGRAM_VIEW_PAN_SNAP_RATE\n position.xy = mix(position.xy, position_snap, clamp(u_view_pan_snap_timer * TANGRAM_VIEW_PAN_SNAP_RATE, 0., 1.));\n #else\n position.xy = position_snap;\n #endif\n }\n\n gl_Position = position;\n}\n"; +var points_vs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_tile_proxy_order_offset;\nuniform bool u_tile_fade_in;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\nuniform float u_visible_time;\nuniform bool u_view_panning;\nuniform float u_view_pan_snap_timer;\n\nuniform mat4 u_model;\nuniform mat4 u_modelView;\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nattribute vec4 a_position;\nattribute vec4 a_shape;\nattribute vec4 a_color;\nattribute vec2 a_texcoord;\nattribute vec2 a_offset;\n\nuniform float u_point_type;\n\n#ifdef TANGRAM_CURVED_LABEL\n attribute vec4 a_offsets;\n attribute vec4 a_pre_angles;\n attribute vec4 a_angles;\n#endif\n\nvarying vec4 v_color;\nvarying vec2 v_texcoord;\nvarying vec4 v_world_position;\nvarying float v_alpha_factor;\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n attribute float a_outline_edge;\n attribute vec4 a_outline_color;\n\n varying float v_outline_edge;\n varying vec4 v_outline_color;\n varying float v_aa_offset;\n#endif\n\n#ifdef TANGRAM_SHOW_HIDDEN_LABELS\n varying float v_label_hidden;\n#endif\n\n#define TANGRAM_PI 3.14159265359\n#define TANGRAM_NORMAL vec3(0., 0., 1.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\nvec2 rotate2D(vec2 _st, float _angle) {\n return mat2(cos(_angle),-sin(_angle),\n sin(_angle),cos(_angle)) * _st;\n}\n\n#ifdef TANGRAM_CURVED_LABEL\n // Assumes stops are [0, 0.33, 0.66, 0.99];\n float mix4linear(float a, float b, float c, float d, float x) {\n x = clamp(x, 0., 1.);\n return mix(mix(a, b, 3. * x),\n mix(b,\n mix(c, d, 3. * (max(x, .66) - .66)),\n 3. * (clamp(x, .33, .66) - .33)),\n step(0.33, x)\n );\n }\n#endif\n\nvoid main() {\n // Initialize globals\n #pragma tangram: setup\n\n // discard hidden labels by collapsing into degenerate triangle\n #ifndef TANGRAM_SHOW_HIDDEN_LABELS\n if (a_shape.w == 0.) {\n gl_Position = vec4(0., 0., 0., 1.);\n return;\n }\n #else\n // highlight hidden label in fragment shader for debugging\n if (a_shape.w == 0.) {\n v_label_hidden = 1.; // label debug testing\n }\n else {\n v_label_hidden = 0.;\n }\n #endif\n\n v_alpha_factor = 1.0;\n v_color = a_color;\n v_texcoord = a_texcoord; // UV from vertex attribute\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n v_outline_color = a_outline_color;\n v_outline_edge = a_outline_edge;\n\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n // use point dimensions for UVs instead (ignore attribute), add antialiasing info for fragment shader\n float size = abs(a_shape.x / 128.); // radius in pixels\n v_texcoord = sign(a_shape.xy) * (size + 1.) / size;\n size += 2.;\n v_aa_offset = 2. / size;\n }\n #endif\n\n // Position\n vec4 position = u_modelView * vec4(a_position.xyz, 1.);\n\n // Apply positioning and scaling in screen space\n vec2 shape = a_shape.xy / 256.; // values have an 8-bit fraction\n vec2 offset = vec2(a_offset.x, -a_offset.y); // flip y to make it point down\n\n float zoom = clamp(u_map_position.z - u_tile_origin.z, 0., 1.); //fract(u_map_position.z);\n float theta = a_shape.z / 4096.;\n\n #ifdef TANGRAM_CURVED_LABEL\n //TODO: potential bug? null is passed in for non-curved labels, otherwise the first offset will be 0\n if (a_offsets[0] != 0.){\n vec4 angles_scaled = (TANGRAM_PI / 16384.) * a_angles;\n vec4 pre_angles_scaled = (TANGRAM_PI / 128.) * a_pre_angles;\n vec4 offsets_scaled = (1. / 64.) * a_offsets;\n\n float pre_angle = mix4linear(pre_angles_scaled[0], pre_angles_scaled[1], pre_angles_scaled[2], pre_angles_scaled[3], zoom);\n float angle = mix4linear(angles_scaled[0], angles_scaled[1], angles_scaled[2], angles_scaled[3], zoom);\n float offset_curve = mix4linear(offsets_scaled[0], offsets_scaled[1], offsets_scaled[2], offsets_scaled[3], zoom);\n\n shape = rotate2D(shape, pre_angle); // rotate in place\n shape.x += offset_curve; // offset for curved label segment\n shape = rotate2D(shape, angle); // rotate relative to curved label anchor\n shape += rotate2D(offset, theta); // offset if specified in the scene file\n }\n else {\n shape = rotate2D(shape + offset, theta);\n }\n #else\n shape = rotate2D(shape + offset, theta);\n #endif\n\n // Fade in (if requested) based on time mesh has been visible.\n // Value passed to fragment shader in the v_alpha_factor varying\n #ifdef TANGRAM_FADE_IN_RATE\n if (u_tile_fade_in) {\n v_alpha_factor *= clamp(u_visible_time * TANGRAM_FADE_IN_RATE, 0., 1.);\n }\n #endif\n\n // World coordinates for 3d procedural textures\n v_world_position = u_model * position;\n v_world_position.xy += shape * u_meters_per_pixel;\n v_world_position = wrapWorldPosition(v_world_position);\n\n // Modify position before camera projection\n #pragma tangram: position\n\n cameraProjection(position);\n\n #ifdef TANGRAM_LAYER_ORDER\n // +1 is to keep all layers including proxies > 0\n applyLayerOrder(a_position.w + u_tile_proxy_order_offset + 1., position);\n #endif\n\n // Apply pixel offset in screen-space\n // Multiply by 2 is because screen is 2 units wide Normalized Device Coords (and u_resolution device pixels wide)\n // Device pixel ratio adjustment is because shape is in logical pixels\n position.xy += shape * position.w * 2. * u_device_pixel_ratio / u_resolution;\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n // enlarge by 1px to catch missed MSAA fragments\n position.xy += sign(shape) * position.w * u_device_pixel_ratio / u_resolution;\n }\n #endif\n\n // Snap to pixel grid\n // Only applied to fully upright sprites/labels (not shader-drawn points), while panning is not active\n #ifdef TANGRAM_HAS_SHADER_POINTS\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON) && u_point_type != TANGRAM_POINT_TYPE_SHADER) {\n #else\n if (!u_view_panning && (abs(theta) < TANGRAM_EPSILON)) {\n #endif\n vec2 position_fract = fract((((position.xy / position.w) + 1.) * .5) * u_resolution);\n vec2 position_snap = position.xy + ((step(0.5, position_fract) - position_fract) * position.w * 2. / u_resolution);\n\n // Animate the snapping to smooth the transition and make it less noticeable\n #ifdef TANGRAM_VIEW_PAN_SNAP_RATE\n position.xy = mix(position.xy, position_snap, clamp(u_view_pan_snap_timer * TANGRAM_VIEW_PAN_SNAP_RATE, 0., 1.));\n #else\n position.xy = position_snap;\n #endif\n }\n\n gl_Position = position;\n}\n"; -var points_fs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\nuniform float u_visible_time;\n\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nuniform sampler2D u_texture;\nuniform float u_point_type;\nuniform bool u_apply_color_blocks;\n\nvarying vec4 v_color;\nvarying vec2 v_texcoord;\nvarying vec4 v_world_position;\nvarying float v_alpha_factor;\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n varying vec4 v_outline_color;\n varying float v_outline_edge;\n varying float v_aa_offset;\n#endif\n\n#ifdef TANGRAM_SHOW_HIDDEN_LABELS\n varying float v_label_hidden;\n#endif\n\n#define TANGRAM_NORMAL vec3(0., 0., 1.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n //l is the distance from the center to the fragment, R is the radius of the drawn point\n float _tangram_antialias(float l, float R){\n float low = R - v_aa_offset;\n float high = R + v_aa_offset;\n return 1. - smoothstep(low, high, l);\n }\n#endif\n\nvoid main (void) {\n // Initialize globals\n #pragma tangram: setup\n\n vec4 color = v_color;\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n // Only apply shader blocks to point, not to attached text (N.B.: for compatibility with ES)\n if (u_point_type == TANGRAM_POINT_TYPE_TEXTURE) { // sprite texture\n color *= texture2D(u_texture, v_texcoord);\n }\n else if (u_point_type == TANGRAM_POINT_TYPE_LABEL) { // label texture\n color = texture2D(u_texture, v_texcoord);\n color.rgb /= max(color.a, 0.001); // un-multiply canvas texture\n }\n else if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n float outline_edge = v_outline_edge;\n vec4 outlineColor = v_outline_color;\n // Distance to this fragment from the center.\n float l = length(v_texcoord);\n // Mask of outermost circle, either outline or point boundary.\n float outer_alpha = _tangram_antialias(l, 1.);\n float fill_alpha = _tangram_antialias(l, 1.-v_outline_edge*0.5) * color.a;\n float stroke_alpha = (outer_alpha - _tangram_antialias(l, 1.-v_outline_edge)) * outlineColor.a;\n\n // Apply alpha compositing with stroke 'over' fill.\n #ifdef TANGRAM_BLEND_ADD\n color.a = stroke_alpha + fill_alpha;\n color.rgb = color.rgb * fill_alpha + outlineColor.rgb * stroke_alpha;\n #else // TANGRAM_BLEND_OVERLAY (and fallback for not implemented blending modes)\n color.a = stroke_alpha + fill_alpha * (1. - stroke_alpha);\n color.rgb = mix(color.rgb * fill_alpha, outlineColor.rgb, stroke_alpha) / max(color.a, 0.001); // avoid divide by zero\n #endif\n }\n #else\n // If shader points not supported, assume label texture\n color = texture2D(u_texture, v_texcoord);\n color.rgb /= max(color.a, 0.001); // un-multiply canvas texture\n #endif\n\n // Shader blocks for color/filter are only applied for sprites, shader points, and standalone text,\n // NOT for text attached to a point (N.B.: for compatibility with ES)\n if (u_apply_color_blocks) {\n #pragma tangram: color\n #pragma tangram: filter\n }\n\n color.a *= v_alpha_factor;\n\n // highlight hidden label in fragment shader for debugging\n #ifdef TANGRAM_SHOW_HIDDEN_LABELS\n if (v_label_hidden > 0.) {\n color.a *= 0.5;\n color.rgb = vec3(1., 0., 0.);\n }\n #endif\n\n // Use alpha test as a lower-quality substitute\n // For opaque and translucent: avoid transparent pixels writing to depth buffer, obscuring geometry underneath\n // For multiply: avoid transparent pixels multiplying geometry underneath to zero/full black\n #if defined(TANGRAM_BLEND_OPAQUE) || defined(TANGRAM_BLEND_TRANSLUCENT) || defined(TANGRAM_BLEND_MULTIPLY)\n if (color.a < TANGRAM_ALPHA_TEST) {\n discard;\n }\n #endif\n\n gl_FragColor = color;\n}\n"; +var points_fs = "uniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_map_position;\nuniform vec4 u_tile_origin;\nuniform float u_meters_per_pixel;\nuniform float u_device_pixel_ratio;\nuniform float u_visible_time;\n\nuniform mat3 u_normalMatrix;\nuniform mat3 u_inverseNormalMatrix;\n\nuniform sampler2D u_texture;\nuniform float u_point_type;\nuniform bool u_apply_color_blocks;\n\nvarying vec4 v_color;\nvarying vec2 v_texcoord;\nvarying vec4 v_world_position;\nvarying float v_alpha_factor;\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n varying vec4 v_outline_color;\n varying float v_outline_edge;\n varying float v_aa_offset;\n#endif\n\n#ifdef TANGRAM_SHOW_HIDDEN_LABELS\n varying float v_label_hidden;\n#endif\n\n#define TANGRAM_NORMAL vec3(0., 0., 1.)\n\n#pragma tangram: camera\n#pragma tangram: material\n#pragma tangram: lighting\n#pragma tangram: raster\n#pragma tangram: global\n\n#ifdef TANGRAM_HAS_SHADER_POINTS\n //l is the distance from the center to the fragment, R is the radius of the drawn point\n float _tangram_antialias(float l, float R){\n float low = R - v_aa_offset;\n float high = R + v_aa_offset;\n return 1. - smoothstep(low, high, l);\n }\n#endif\n\nvoid main (void) {\n // Initialize globals\n #pragma tangram: setup\n\n vec4 color = v_color;\n\n #ifdef TANGRAM_HAS_SHADER_POINTS\n // Only apply shader blocks to point, not to attached text (N.B.: for compatibility with ES)\n if (u_point_type == TANGRAM_POINT_TYPE_TEXTURE) { // sprite texture\n color *= texture2D(u_texture, v_texcoord);\n }\n else if (u_point_type == TANGRAM_POINT_TYPE_LABEL) { // label texture\n color = texture2D(u_texture, v_texcoord);\n color.rgb /= max(color.a, 0.001); // un-multiply canvas texture\n }\n else if (u_point_type == TANGRAM_POINT_TYPE_SHADER) { // shader point\n float outline_edge = v_outline_edge;\n vec4 outlineColor = v_outline_color;\n\n // Mask of outermost circle, either outline or point boundary\n float l = length(v_texcoord); // distance to this fragment from the point center\n float outer_alpha = _tangram_antialias(l, 1.);\n float fill_alpha = _tangram_antialias(l, 1. - (v_outline_edge * 0.5)) * color.a;\n float stroke_alpha = (outer_alpha - _tangram_antialias(l, 1. - v_outline_edge)) * outlineColor.a;\n\n // Apply alpha compositing with stroke 'over' fill.\n #ifdef TANGRAM_BLEND_ADD\n color.a = stroke_alpha + fill_alpha;\n color.rgb = color.rgb * fill_alpha + outlineColor.rgb * stroke_alpha;\n #else // TANGRAM_BLEND_OVERLAY (and fallback for not implemented blending modes)\n color.a = stroke_alpha + fill_alpha * (1. - stroke_alpha);\n color.rgb = mix(color.rgb * fill_alpha, outlineColor.rgb, stroke_alpha) / max(color.a, 0.001); // avoid divide by zero\n #endif\n }\n #else\n // If shader points not supported, assume label texture\n color = texture2D(u_texture, v_texcoord);\n color.rgb /= max(color.a, 0.001); // un-multiply canvas texture\n #endif\n\n // Shader blocks for color/filter are only applied for sprites, shader points, and standalone text,\n // NOT for text attached to a point (N.B.: for compatibility with ES)\n if (u_apply_color_blocks) {\n #pragma tangram: color\n #pragma tangram: filter\n }\n\n color.a *= v_alpha_factor;\n\n // highlight hidden label in fragment shader for debugging\n #ifdef TANGRAM_SHOW_HIDDEN_LABELS\n if (v_label_hidden > 0.) {\n color.a *= 0.5;\n color.rgb = vec3(1., 0., 0.);\n }\n #endif\n\n // Use alpha test as a lower-quality substitute\n // For opaque and translucent: avoid transparent pixels writing to depth buffer, obscuring geometry underneath\n // For multiply: avoid transparent pixels multiplying geometry underneath to zero/full black\n #if defined(TANGRAM_BLEND_OPAQUE) || defined(TANGRAM_BLEND_TRANSLUCENT) || defined(TANGRAM_BLEND_MULTIPLY)\n if (color.a < TANGRAM_ALPHA_TEST) {\n discard;\n }\n #endif\n\n gl_FragColor = color;\n}\n"; var PLACEMENT$1 = LabelPoint.PLACEMENT; -var pre_angles_normalize = 128 / Math.PI; -var angles_normalize = 16384 / Math.PI; -var offsets_normalize = 64; -var texcoord_normalize = 65535; var Points = Object.create(Style); Points.variants = {}; // mesh variants by variant key @@ -17808,8 +17748,6 @@ Object.assign(Points, { style.linked = q.linked; // TODO: move linked into label to avoid extra prop tracking? style.size = text_info.size.logical_size; - style.angle = 0; // text attached to point is always upright - style.texcoords = text_info.align[q.label.align].texcoords; style.label_texture = textures[text_info.align[q.label.align].texture_id]; style.blend_order = q.draw.blend_order; // copy blend order from parent point @@ -17982,21 +17920,21 @@ Object.assign(Points, { return labels; }, // Builds one or more point labels for a geometry - buildLabels: function buildLabels(size, geometry, options) { + buildLabels: function buildLabels(size, geometry, layout) { var labels = []; if (geometry.type === 'Point') { - labels.push(new LabelPoint(geometry.coordinates, size, options)); + labels.push(new LabelPoint(geometry.coordinates, size, layout, layout.angle)); } else if (geometry.type === 'MultiPoint') { var points = geometry.coordinates; for (var i = 0; i < points.length; ++i) { var point = points[i]; - labels.push(new LabelPoint(point, size, options)); + labels.push(new LabelPoint(point, size, layout, layout.angle)); } } else if (geometry.type === 'LineString') { var line = geometry.coordinates; - var point_labels = placePointsOnLine(line, size, options); + var point_labels = placePointsOnLine(line, size, layout); for (var _i = 0; _i < point_labels.length; ++_i) { labels.push(point_labels[_i]); @@ -18007,7 +17945,7 @@ Object.assign(Points, { for (var ln = 0; ln < lines.length; ln++) { var _line = lines[ln]; - var _point_labels = placePointsOnLine(_line, size, options); + var _point_labels = placePointsOnLine(_line, size, layout); for (var _i2 = 0; _i2 < _point_labels.length; ++_i2) { labels.push(_point_labels[_i2]); @@ -18015,19 +17953,19 @@ Object.assign(Points, { } } else if (geometry.type === 'Polygon') { // Point at polygon centroid (of outer ring) - if (options.placement === PLACEMENT$1.CENTROID) { + if (layout.placement === PLACEMENT$1.CENTROID) { var centroid = Geo$1.centroid(geometry.coordinates); if (centroid) { // skip degenerate polygons - labels.push(new LabelPoint(centroid, size, options)); + labels.push(new LabelPoint(centroid, size, layout, layout.angle)); } } // Point at each polygon vertex (all rings) else { var rings = geometry.coordinates; for (var _ln = 0; _ln < rings.length; _ln++) { - var _point_labels2 = placePointsOnLine(rings[_ln], size, options); + var _point_labels2 = placePointsOnLine(rings[_ln], size, layout); for (var _i3 = 0; _i3 < _point_labels2.length; ++_i3) { labels.push(_point_labels2[_i3]); @@ -18035,12 +17973,12 @@ Object.assign(Points, { } } } else if (geometry.type === 'MultiPolygon') { - if (options.placement === PLACEMENT$1.CENTROID) { + if (layout.placement === PLACEMENT$1.CENTROID) { var _centroid = Geo$1.multiCentroid(geometry.coordinates); if (_centroid) { // skip degenerate polygons - labels.push(new LabelPoint(_centroid, size, options)); + labels.push(new LabelPoint(_centroid, size, layout, layout.angle)); } } else { var polys = geometry.coordinates; @@ -18049,7 +17987,7 @@ Object.assign(Points, { var _rings = polys[p]; for (var _ln2 = 0; _ln2 < _rings.length; _ln2++) { - var _point_labels3 = placePointsOnLine(_rings[_ln2], size, options); + var _point_labels3 = placePointsOnLine(_rings[_ln2], size, layout); for (var _i4 = 0; _i4 < _point_labels3.length; ++_i4) { labels.push(_point_labels3[_i4]); @@ -18067,89 +18005,65 @@ Object.assign(Points, { * A plain JS array matching the order of the vertex layout. */ makeVertexTemplate: function makeVertexTemplate(style, mesh) { - var color = style.color || StyleParser.defaults.color; - var vertex_layout = mesh.vertex_data.vertex_layout; // position - x & y coords will be filled in per-vertex below + var i = 0; // a_position.xyz - vertex position + // a_position.w - layer order - this.fillVertexTemplate(vertex_layout, 'a_position', 0, { - size: 2 - }); - this.fillVertexTemplate(vertex_layout, 'a_position', style.z || 0, { - size: 1, - offset: 2 - }); // layer order - w coord of 'position' attribute (for packing efficiency) - - this.fillVertexTemplate(vertex_layout, 'a_position', this.scaleOrder(style.order), { - size: 1, - offset: 3 - }); // scaling vector - (x, y) components per pixel, z = angle, w = show/hide - - this.fillVertexTemplate(vertex_layout, 'a_shape', 0, { - size: 4 - }); - this.fillVertexTemplate(vertex_layout, 'a_shape', style.label.layout.collide ? 0 : 1, { - size: 1, - offset: 3 - }); // set initial label hide/show state - // texture coords + this.vertex_template[i++] = 0; + this.vertex_template[i++] = 0; + this.vertex_template[i++] = style.z || 0; + this.vertex_template[i++] = this.scaleOrder(style.order); // a_shape.xy - size of point in pixels (scaling vector) + // a_shape.z - angle of point + // a_shape.w - show/hide flag + + this.vertex_template[i++] = 0; + this.vertex_template[i++] = 0; + this.vertex_template[i++] = 0; + this.vertex_template[i++] = style.label.layout.collide ? 0 : 1; // set initial label hide/show state + // a_texcoord.xy - texture coords - this.fillVertexTemplate(vertex_layout, 'a_texcoord', 0, { - size: 2 - }); // offsets + if (!mesh.variant.shader_point) { + this.vertex_template[i++] = 0; + this.vertex_template[i++] = 0; + } // a_offset.xy - offset of point from center, in pixels - this.fillVertexTemplate(vertex_layout, 'a_offset', 0, { - size: 2 - }); // color - this.fillVertexTemplate(vertex_layout, 'a_color', Vector$1.mult(color, 255), { - size: 4 - }); // outline (can be static or dynamic depending on style) + this.vertex_template[i++] = 0; + this.vertex_template[i++] = 0; // a_color.rgba - feature color + + var color = style.color || StyleParser.defaults.color; + this.vertex_template[i++] = color[0] * 255; + this.vertex_template[i++] = color[1] * 255; + this.vertex_template[i++] = color[2] * 255; + this.vertex_template[i++] = color[3] * 255; // a_selection_color.rgba - selection color - if (this.defines.TANGRAM_HAS_SHADER_POINTS && mesh.variant.shader_point) { + if (mesh.variant.selection) { + this.vertex_template[i++] = style.selection_color[0] * 255; + this.vertex_template[i++] = style.selection_color[1] * 255; + this.vertex_template[i++] = style.selection_color[2] * 255; + this.vertex_template[i++] = style.selection_color[3] * 255; + } // point outline + + + if (mesh.variant.shader_point) { + // a_outline_color.rgba - outline color var outline_color = style.outline_color || StyleParser.defaults.outline.color; - this.fillVertexTemplate(vertex_layout, 'a_outline_color', Vector$1.mult(outline_color, 255), { - size: 4 - }); - this.fillVertexTemplate(vertex_layout, 'a_outline_edge', style.outline_edge_pct || StyleParser.defaults.outline.width, { - size: 1 - }); - } // selection color + this.vertex_template[i++] = outline_color[0] * 255; + this.vertex_template[i++] = outline_color[1] * 255; + this.vertex_template[i++] = outline_color[2] * 255; + this.vertex_template[i++] = outline_color[3] * 255; // a_outline_edge - point outline edge (as % of point size where outline begins) + this.vertex_template[i++] = style.outline_edge_pct || StyleParser.defaults.outline.width; + } - this.fillVertexTemplate(vertex_layout, 'a_selection_color', Vector$1.mult(style.selection_color, 255), { - size: 4 - }); return this.vertex_template; }, - buildQuad: function buildQuad(points, size, angle, angles, pre_angles, offset, offsets, texcoord_scale, curve, vertex_data, vertex_template) { + buildQuad: function buildQuad(point, size, angle, angles, pre_angles, offset, offsets, texcoords, curve, vertex_data, vertex_template) { if (size[0] <= 0 || size[1] <= 0) { return 0; // size must be positive } - return buildQuadsForPoints(points, vertex_data, vertex_template, { - texcoord_index: vertex_data.vertex_layout.index.a_texcoord, - position_index: vertex_data.vertex_layout.index.a_position, - shape_index: vertex_data.vertex_layout.index.a_shape, - offset_index: vertex_data.vertex_layout.index.a_offset, - offsets_index: vertex_data.vertex_layout.index.a_offsets, - pre_angles_index: vertex_data.vertex_layout.index.a_pre_angles, - angles_index: vertex_data.vertex_layout.index.a_angles - }, { - quad: size, - quad_normalize: 256, - // values have an 8-bit fraction - offset: offset, - offsets: offsets, - pre_angles: pre_angles, - angle: angle * 4096, - // values have a 12-bit fraction - angles: angles, - curve: curve, - texcoord_scale: texcoord_scale, - texcoord_normalize: texcoord_normalize, - pre_angles_normalize: pre_angles_normalize, - angles_normalize: angles_normalize, - offsets_normalize: offsets_normalize - }); + return buildQuadForPoint(point, vertex_data, vertex_template, vertex_data.vertex_layout.index, size, offset, offsets, pre_angles, angle * 4096, // angle values have a 12-bit fraction + angles, texcoords, curve); }, // Build quad for point sprite build: function build(style, context) { @@ -18164,7 +18078,6 @@ Object.assign(Points, { buildStraightLabel: function buildStraightLabel(label, style, context) { var mesh = this.getTileMesh(context.tile, this.meshVariantTypeForDraw(style)); var vertex_template = this.makeVertexTemplate(style, mesh); - var angle = label.angle || style.angle; var size, texcoords; if (label.type !== 'point') { @@ -18196,9 +18109,9 @@ Object.assign(Points, { var offset = label.offset; // TODO: instead of passing null, pass arrays with fingerprintable values // This value is checked in the shader to determine whether to apply curving logic - var geom_count = this.buildQuad([label.position], // position + var geom_count = this.buildQuad(label.position, // position size, // size in pixels - angle, // angle in radians + label.angle, // angle in radians null, // placeholder for multiple angles null, // placeholder for multiple pre_angles offset, // offset from center in pixels @@ -18214,7 +18127,6 @@ Object.assign(Points, { }, buildCurvedLabel: function buildCurvedLabel(label, style, context) { var mesh, vertex_template; - var angle = label.angle; var geom_count = 0; // two passes for stroke and fill, where stroke needs to be drawn first (painter's algorithm) // this ensures strokes don't overlap on other fills // pass for stroke @@ -18236,9 +18148,9 @@ Object.assign(Points, { var angles = label.angles[i]; var offsets = label.offsets[i]; var pre_angles = label.pre_angles[i]; - var seg_count = this.buildQuad([position], // position + var seg_count = this.buildQuad(position, // position size, // size in pixels - angle, // angle in degrees + label.angle, // angle in degrees angles, // angles per segment pre_angles, // pre_angle array (rotation applied before offseting) offset, // offset from center in pixels @@ -18274,9 +18186,9 @@ Object.assign(Points, { var _offsets = label.offsets[_i5]; var _pre_angles = label.pre_angles[_i5]; - var _seg_count = this.buildQuad([_position], // position + var _seg_count = this.buildQuad(_position, // position _size, // size in pixels - angle, // angle in degrees + label.angle, // angle in degrees _angles, // angles per segment _pre_angles, // pre_angle array (rotation applied before offseting) _offset, // offset from center in pixels @@ -18357,7 +18269,8 @@ Object.assign(Points, { name: 'a_texcoord', size: 2, type: gl$1.UNSIGNED_SHORT, - normalized: true + normalized: true, + static: variant.shader_point ? [0, 0] : null }, { name: 'a_offset', size: 2, @@ -18368,6 +18281,12 @@ Object.assign(Points, { size: 4, type: gl$1.UNSIGNED_BYTE, normalized: true + }, { + name: 'a_selection_color', + size: 4, + type: gl$1.UNSIGNED_BYTE, + normalized: true, + static: variant.selection ? null : [0, 0, 0, 0] }, { name: 'a_outline_color', size: 4, @@ -18380,11 +18299,6 @@ Object.assign(Points, { type: gl$1.FLOAT, normalized: false, static: variant.shader_point ? null : 0 - }, { - name: 'a_selection_color', - size: 4, - type: gl$1.UNSIGNED_BYTE, - normalized: true }]; Points.vertex_layouts[variant.shader_point] = new VertexLayout(attribs); } @@ -18400,6 +18314,8 @@ Object.assign(Points, { if (Points.variants[key] == null) { Points.variants[key] = { key: key, + selection: 1, + // TODO: make this vary by draw params shader_point: texture === SHADER_POINT_VARIANT, // is shader point blend_order: draw.blend_order, @@ -19238,6 +19154,8 @@ function getAbsAngleDiff(angle1, angle2) { } var TextStyle = Object.create(Points); +TextStyle.vertex_layouts = {}; // vertex layouts by variant key + Object.assign(TextStyle, { name: 'text', super: Points, @@ -19264,15 +19182,14 @@ Object.assign(TextStyle, { makeVertexTemplate: function makeVertexTemplate(style, mesh) { this.super.makeVertexTemplate.apply(this, arguments); var vertex_layout = mesh.vertex_data.vertex_layout; - this.fillVertexTemplate(vertex_layout, 'a_pre_angles', 0, { - size: 4 - }); - this.fillVertexTemplate(vertex_layout, 'a_offsets', 0, { - size: 4 - }); - this.fillVertexTemplate(vertex_layout, 'a_angles', 0, { - size: 4 - }); + var i = vertex_layout.index.a_pre_angles; // a_pre_angles.xyzw - rotation of entire curved label + // a_angles.xyzw - angle of each curved label segment + // a_offsets.xyzw - offset of each curved label segment + + for (var j = 0; j < 12; j++) { + this.vertex_template[i++] = 0; + } + return this.vertex_template; }, reset: function reset() { @@ -19514,8 +19431,9 @@ Object.assign(TextStyle, { }, // Override // Create or return vertex layout - vertexLayoutForMeshVariant: function vertexLayoutForMeshVariant() { - if (this.vertex_layout == null) { + vertexLayoutForMeshVariant: function vertexLayoutForMeshVariant(variant) { + // Vertex layout only depends on shader point flag, so using it as layout key to avoid duplicate layouts + if (TextStyle.vertex_layouts[variant.shader_point] == null) { // TODO: could make selection, offset, and curved label attribs optional, but may not be worth it // since text points generally don't consume much memory anyway var attribs = [{ @@ -19544,30 +19462,31 @@ Object.assign(TextStyle, { type: gl$1.UNSIGNED_BYTE, normalized: true }, { - name: 'a_angles', + name: 'a_selection_color', size: 4, - type: gl$1.SHORT, - normalized: false + type: gl$1.UNSIGNED_BYTE, + normalized: true, + static: variant.selection ? null : [0, 0, 0, 0] }, { - name: 'a_offsets', + name: 'a_pre_angles', size: 4, - type: gl$1.UNSIGNED_SHORT, + type: gl$1.BYTE, normalized: false }, { - name: 'a_pre_angles', + name: 'a_angles', size: 4, - type: gl$1.BYTE, + type: gl$1.SHORT, normalized: false }, { - name: 'a_selection_color', + name: 'a_offsets', size: 4, - type: gl$1.UNSIGNED_BYTE, - normalized: true + type: gl$1.UNSIGNED_SHORT, + normalized: false }]; - this.vertex_layout = new VertexLayout(attribs); + TextStyle.vertex_layouts[variant.shader_point] = new VertexLayout(attribs); } - return this.vertex_layout; + return TextStyle.vertex_layouts[variant.shader_point]; } }); TextStyle.texture_id = 0; // namespaces per-tile label textures @@ -21032,7 +20951,7 @@ function () { styles = _ref3.styles, global = _ref3.global; var data = tile.source_data; - tile.debug.rendering = +new Date(); + tile.debug.building = +new Date(); tile.debug.feature_count = 0; tile.debug.layers = null; Collision.startTile(tile.id, { @@ -21053,7 +20972,7 @@ function () { } // Get data for one or more layers from source - var source_layers = Tile.getDataForSource(data, layer.config_data, layer_name); // Render features in layer + var source_layers = Tile.getDataForSource(data, layer.config_data, layer_name); // Build features in layer for (var s = 0; s < source_layers.length; s++) { var source_layer = source_layers[s]; @@ -21081,7 +21000,7 @@ function () { if (!draw_groups) { continue; - } // Render draw groups + } // Build draw groups for (var group_name in draw_groups) { @@ -21111,17 +21030,15 @@ function () { } } - tile.debug.rendering = +new Date() - tile.debug.rendering; // Send styles back to main thread as they finish building, in two groups: collision vs. non-collision + tile.debug.building = +new Date() - tile.debug.building; // Send styles back to main thread as they finish building, in two groups: collision vs. non-collision var tile_styles = this.stylesForTile(tile, styles).map(function (s) { return styles[s]; }); - Tile.sendStyleGroups(tile, tile_styles, { - scene_id: scene_id - }, function (style) { + Tile.buildStyleGroups(tile, tile_styles, scene_id, function (style) { return style.collision ? 'collision' : 'non-collision'; - }); // Tile.sendStyleGroups(tile, tile_styles, { scene_id }, style => style.name); // call for each style - // Tile.sendStyleGroups(tile, tile_styles, { scene_id }, style => 'styles'); // all styles in single call (previous behavior) + }); // Tile.buildStyleGroups(tile, tile_styles, scene_id, style => style.name); // call for each style + // Tile.buildStyleGroups(tile, tile_styles, scene_id, style => 'styles'); // all styles in single call (previous behavior) }; Tile.stylesForTile = function stylesForTile(tile, styles) { @@ -21134,77 +21051,121 @@ function () { } return tile_styles; - } // Send groups of styles back to main thread, asynchronously (as they finish building), - // grouped by the provided function + } // Build styles (grouped by the provided function) and send back to main thread as they finish building ; - Tile.sendStyleGroups = function sendStyleGroups(tile, styles, _ref4, group_by) { - var scene_id = _ref4.scene_id; - // Group styles - var groups = {}; - styles.forEach(function (s) { - var group_name = group_by(s); - groups[group_name] = groups[group_name] || []; - groups[group_name].push(s); - }); + Tile.buildStyleGroups = function buildStyleGroups(tile, styles, scene_id, group_by) { + // Group the styles; each group will be sent to the main thread when the styles in the group finish building. + var groups = styles.reduce(function (groups, style) { + var group = group_by(style); + groups[group] = groups[group] || []; + groups[group].push(style); + return groups; + }, {}); // If nothing to build, return empty tile to main thread - if (Object.keys(groups).length > 0) { - (function () { - var progress = { - start: true - }; - tile.mesh_data = {}; - - var _loop = function _loop(group_name) { - var group = groups[group_name]; - Promise.all(group.map(function (style) { - return style.endData(tile).then(function (style_data) { - if (style_data) { - tile.mesh_data[style.name] = style_data; - } - }); - })).then(function () { - log('trace', "Finished style group '" + group_name + "' for tile " + tile.key); // Clear group and check if all groups finished + if (Object.keys(groups).length === 0) { + WorkerBroker$1.postMessage("TileManager_" + scene_id + ".buildTileStylesCompleted", WorkerBroker$1.withTransferables({ + tile: Tile.slice(tile), + progress: { + start: true, + done: true + } + })); + Collision.resetTile(tile.id); // clear collision if we're done with the tile - groups[group_name] = []; + return; + } // Build each group of styles + + + var progress = {}; + + for (var group_name in groups) { + Tile.buildStyleGroup({ + group_name: group_name, + groups: groups, + tile: tile, + progress: progress, + scene_id: scene_id + }); + } + } // Build a single group of styles + ; + + Tile.buildStyleGroup = function buildStyleGroup(_ref4) { + return new Promise(function ($return, $error) { + var group_name, groups, tile, progress, scene_id, group, mesh_data; + group_name = _ref4.group_name, groups = _ref4.groups, tile = _ref4.tile, progress = _ref4.progress, scene_id = _ref4.scene_id; + group = groups[group_name]; + mesh_data = {}; + + var $Try_1_Post = function () { + try { + return $return(); + } catch ($boundEx) { + return $error($boundEx); + } + }; + + var $Try_1_Catch = function (e) { + try { + log('error', "Error for style group '" + group_name + "' for tile " + tile.key, e && e.stack || e); + return $Try_1_Post(); + } catch ($boundEx) { + return $error($boundEx); + } + }; + + try { + return Promise.resolve(Promise.all(group.map(function (style) { + return new Promise(function ($return, $error) { + var style_data; + return Promise.resolve(style.endData(tile)).then(function ($await_2) { + try { + style_data = $await_2; + + if (style_data) { + mesh_data[style.name] = style_data; + } + + return $return(); + } catch ($boundEx) { + return $error($boundEx); + } + }, $error); + }); + }))).then(function ($await_3) { + try { + // Mark the group as done, and check if all groups have finished + log('trace', "Finished style group '" + group_name + "' for tile " + tile.key); + groups[group_name] = null; if (Object.keys(groups).every(function (g) { - return groups[g].length === 0; + return groups[g] == null; })) { progress.done = true; } // Send meshes to main thread WorkerBroker$1.postMessage("TileManager_" + scene_id + ".buildTileStylesCompleted", WorkerBroker$1.withTransferables({ - tile: Tile.slice(tile, ['mesh_data']), + tile: Object.assign({}, Tile.slice(tile), { + mesh_data: mesh_data + }), progress: progress })); - progress.start = null; - tile.mesh_data = {}; // reset so each group sends separate set of style meshes if (progress.done) { Collision.resetTile(tile.id); // clear collision if we're done with the tile } - }).catch(function (e) { - log('error', "Error for style group '" + group_name + "' for tile " + tile.key, e && e.stack || e); - }); - }; - for (var group_name in groups) { - _loop(group_name); - } - })(); - } else { - // Nothing to build, return empty tile to main thread - WorkerBroker$1.postMessage("TileManager_" + scene_id + ".buildTileStylesCompleted", WorkerBroker$1.withTransferables({ - tile: Tile.slice(tile), - progress: { - start: true, - done: true - } - })); - Collision.resetTile(tile.id); // clear collision if we're done with the tile - } + return $Try_1_Post(); + } catch ($boundEx) { + return $Try_1_Catch($boundEx); + } + }, $Try_1_Catch); + } catch (e) { + $Try_1_Catch(e); + } + }); } /** Retrieves geometry from a tile according to a data source definition @@ -24373,11 +24334,11 @@ exports.mergeObjects = mergeObjects; exports.isReserved = isReserved; exports.GLSL = GLSL; exports.TileID = TileID; +exports.Collision = Collision; exports.Geo = Geo$1; exports.LabelPoint = LabelPoint; exports.LabelLineStraight = LabelLineStraight; exports.OBB = OBB; -exports.Collision = Collision; exports.Label = Label; exports.WorkerBroker = WorkerBroker$1; exports.Task = Task; @@ -24436,6 +24397,7 @@ var SceneWorker = Object.assign(self, { this.style_manager = new __chunk_1.StyleManager(); this.importExternalScripts(external_scripts); __chunk_1.Label.id_prefix = worker_id; + __chunk_1.Label.id_multiplier = num_workers; return worker_id; }, // Import custom external scripts @@ -24655,7 +24617,7 @@ var SceneWorker = Object.assign(self, { var tiles = tile_keys.map(function (t) { return _this4.tiles[t]; }).filter(function (t) { - return t; + return t && t.loaded; }); // Compile feature filter if (filter != null) { @@ -45707,14 +45669,96 @@ var visible = {}; // currently visible labels var prev_visible = {}; // previously visible labels (in last collision run) function mainThreadLabelCollisionPass(tiles, view_zoom, hide_breach) { - if (hide_breach === void 0) { - hide_breach = false; - } + return new Promise(function ($return, $error) { + var containers, labels, meshes; + + if (hide_breach === void 0) { + hide_breach = false; + } - prev_visible = visible; // save last visible label set + // Swap/reset visible label set + prev_visible = visible; // save last visible label set - visible = {}; // initialize new visible label set + visible = {}; // initialize new visible label set + // Build label containers from tiles + containers = buildLabels(tiles, view_zoom); + // Collide all labels in a single group + // TODO: maybe rename tile and style to group/subgroup? + __chunk_1.Collision.startTile('main', { + apply_repeat_groups: true, + return_hidden: true + }); + __chunk_1.Collision.addStyle('main', 'main'); + return Promise.resolve(__chunk_1.Collision.collide(containers, 'main', 'main')).then(function ($await_1) { + try { + labels = $await_1; + meshes = []; + labels.forEach(function (container) { + // Hide breach labels (those that cross tile boundaries) while tiles are loading, unless they + // were previously visible (otherwise fully loaded/collided breach labels will flicker in and out + // when new tiles load, even if they aren't adjacent) + var show = 0; + + if (container.show === true && (!hide_breach || !container.label.breach || prev_visible[container.label.id])) { + show = 1; + } + + if (show) { + visible[container.label.id] = true; // track visible labels + } + + var changed = true; // check if label visibility changed on this collision pass + + container.ranges.forEach(function (r) { + if (!changed) { + return; // skip rest of label if state hasn't changed + } + + var mesh = container.mesh; + + if (!mesh.valid) { + return; + } + + var off = mesh.vertex_layout.offset.a_shape; // byte offset (within each vertex) of attribute + + var stride = mesh.vertex_layout.stride; // byte stride per vertex + + for (var i = 0; i < r[1]; i++) { + // NB: +6 is because attribute is a short int (2 bytes each), and we're skipping to 3rd element, 6=3*2 + if (mesh.vertex_data[r[0] + i * stride + off + 6] === show) { + changed = false; + return; // label hasn't changed states, skip further updates + } + + mesh.vertex_data[r[0] + i * stride + off + 6] = show; + } + + if (meshes.indexOf(mesh) === -1) { + meshes.push(mesh); + } + }); + }); // Upload updated meshes and make them visible + + meshes.forEach(function (mesh) { + return mesh.upload(); + }); + tiles.forEach(function (t) { + return t.swapPendingLabels(); + }); + return $return({ + labels: labels, + containers: containers + }); // currently returned for debugging + } catch ($boundEx) { + return $error($boundEx); + } + }, $error); + }); +} + +function buildLabels(tiles, view_zoom) { var labels = {}; var containers = {}; // Collect labels from each tile and turn into new label instances @@ -45774,7 +45818,7 @@ function mainThreadLabelCollisionPass(tiles, view_zoom, hide_breach) { __chunk_1.LabelLineStraight.prototype.updateBBoxes.call(label, label.position, label.size, label.angle, label.angle, label.offset); } else if (params.obbs) { // NB: this is a very rough approximation of curved label collision at intermediate zooms, - // becuase the position/scale of each collision box isn't correctly updated; however, + // because the position/scale of each collision box isn't correctly updated; however, // it's good enough to provide some additional label coverage, with less overhead var obbs = params.obbs.map(function (o) { var x = o.x, @@ -45819,76 +45863,12 @@ function mainThreadLabelCollisionPass(tiles, view_zoom, hide_breach) { containers = Object.keys(containers).map(function (k) { return containers[k]; - }); // Collide all labels in a single group - // TODO: maybe rename tile and style to group/subgroup? - - __chunk_1.Collision.startTile('main', { - apply_repeat_groups: true, - return_hidden: true - }); - __chunk_1.Collision.addStyle('main', 'main'); - return __chunk_1.Collision.collide(containers, 'main', 'main').then(function (labels) { - var meshes = []; - labels.forEach(function (container) { - // Hide breach labels (those that cross tile boundaries) while tiles are loading, unless they - // were previously visible (otherwise fully loaded/collided breach labels will flicker in and out - // when new tiles load, even if they aren't adjacent) - var show = 0; - - if (container.show === true && (!hide_breach || !container.label.breach || prev_visible[container.label.id])) { - show = 1; - } - - if (show) { - visible[container.label.id] = true; // track visible labels - } - - var changed = true; // check if label visibility changed on this collision pass - - container.ranges.forEach(function (r) { - if (!changed) { - return; // skip rest of label if state hasn't changed - } - - var mesh = container.mesh; - - if (!mesh.valid) { - return; - } - - var off = mesh.vertex_layout.offset.a_shape; // byte offset (within each vertex) of attribute - - var stride = mesh.vertex_layout.stride; // byte stride per vertex - - for (var i = 0; i < r[1]; i++) { - // NB: +6 is because attribute is a short int (2 bytes each), and we're skipping to 3rd element, 6=3*2 - if (mesh.vertex_data[r[0] + i * stride + off + 6] === show) { - changed = false; - return; // label hasn't changed states, skip further updates - } - - mesh.vertex_data[r[0] + i * stride + off + 6] = show; - } - - if (meshes.indexOf(mesh) === -1) { - meshes.push(mesh); - } - }); - }); - meshes.forEach(function (mesh) { - return mesh.upload(); - }); - tiles.forEach(function (t) { - return t.swapPendingLabels(); - }); - return { - labels: labels, - containers: containers - }; // currently returned for debugging }); + return containers; } // Generic discard function for labels, does simple occlusion with one or more bounding boxes // (no additional logic to try alternate anchors or other layout options, etc.) + function discard(bboxes, exclude) { if (exclude === void 0) { exclude = null; @@ -46090,13 +46070,25 @@ function () { this.collision.task = { type: 'tileManagerUpdateLabels', run: function run(task) { - return mainThreadLabelCollisionPass(tiles, _this2.collision.zoom, _this2.isLoadingVisibleTiles()).then(function (results) { - _this2.collision.task = null; - __chunk_1.Task.finish(task, results); + return new Promise(function ($return, $error) { + var results; + return Promise.resolve(mainThreadLabelCollisionPass(tiles, _this2.collision.zoom, _this2.isLoadingVisibleTiles())).then(function ($await_1) { + try { + results = $await_1; - _this2.updateTileStates().then(function () { - return _this2.scene.immediateRedraw(); - }); + _this2.scene.requestRedraw(); // Clear state to allow another collision pass to start + + + _this2.collision.task = null; + __chunk_1.Task.finish(task, results); // Check if tiles changed during previous collision pass - will start new pass if so + + _this2.updateTileStates(); + + return $return(); + } catch ($boundEx) { + return $error($boundEx); + } + }, $error); }); } }; @@ -48518,7 +48510,7 @@ function () { ; _proto.updateViewComplete = function updateViewComplete() { - if ((this.render_count_changed || this.generation !== this.last_complete_generation) && !this.tile_manager.isLoadingVisibleTiles() && this.tile_manager.allVisibleTilesLabeled()) { + if ((this.render_count_changed || this.generation !== this.last_complete_generation) && !this.building && !this.tile_manager.isLoadingVisibleTiles() && this.tile_manager.allVisibleTilesLabeled()) { this.tile_manager.updateLabels(); this.last_complete_generation = this.generation; this.trigger('view_complete', { @@ -49241,7 +49233,7 @@ return index; // Script modules can't expose exports try { Tangram.debug.ESM = false; // mark build as ES module - Tangram.debug.SHA = 'f4235dbb2a13111efbbb66b24ab2f8258922885c'; + Tangram.debug.SHA = 'b08f8c830cad59c24ca6f79f40b0d1db76b4136e'; if (false === true && typeof window === 'object') { window.Tangram = Tangram; } diff --git a/dist/tangram.debug.js.map b/dist/tangram.debug.js.map index a9386be8a..4e4ad563e 100644 --- a/dist/tangram.debug.js.map +++ b/dist/tangram.debug.js.map @@ -1 +1 @@ -{"version":3,"file":"tangram.debug.js","sources":["../node_modules/core-js/modules/_core.js","../node_modules/core-js/modules/_global.js","../node_modules/core-js/modules/_library.js","../node_modules/core-js/modules/_shared.js","../node_modules/core-js/modules/_uid.js","../node_modules/core-js/modules/_wks.js","../node_modules/core-js/modules/_is-object.js","../node_modules/core-js/modules/_an-object.js","../node_modules/core-js/modules/_fails.js","../node_modules/core-js/modules/_descriptors.js","../node_modules/core-js/modules/_dom-create.js","../node_modules/core-js/modules/_ie8-dom-define.js","../node_modules/core-js/modules/_to-primitive.js","../node_modules/core-js/modules/_object-dp.js","../node_modules/core-js/modules/_property-desc.js","../node_modules/core-js/modules/_hide.js","../node_modules/core-js/modules/_add-to-unscopables.js","../node_modules/core-js/modules/_iter-step.js","../node_modules/core-js/modules/_iterators.js","../node_modules/core-js/modules/_cof.js","../node_modules/core-js/modules/_iobject.js","../node_modules/core-js/modules/_defined.js","../node_modules/core-js/modules/_to-iobject.js","../node_modules/core-js/modules/_has.js","../node_modules/core-js/modules/_redefine.js","../node_modules/core-js/modules/_a-function.js","../node_modules/core-js/modules/_ctx.js","../node_modules/core-js/modules/_export.js","../node_modules/core-js/modules/_to-integer.js","../node_modules/core-js/modules/_to-length.js","../node_modules/core-js/modules/_to-absolute-index.js","../node_modules/core-js/modules/_array-includes.js","../node_modules/core-js/modules/_shared-key.js","../node_modules/core-js/modules/_object-keys-internal.js","../node_modules/core-js/modules/_enum-bug-keys.js","../node_modules/core-js/modules/_object-keys.js","../node_modules/core-js/modules/_object-dps.js","../node_modules/core-js/modules/_html.js","../node_modules/core-js/modules/_object-create.js","../node_modules/core-js/modules/_set-to-string-tag.js","../node_modules/core-js/modules/_iter-create.js","../node_modules/core-js/modules/_to-object.js","../node_modules/core-js/modules/_object-gpo.js","../node_modules/core-js/modules/_iter-define.js","../node_modules/core-js/modules/es6.array.iterator.js","../node_modules/core-js/modules/web.dom.iterable.js","../node_modules/core-js/modules/_object-gops.js","../node_modules/core-js/modules/_object-pie.js","../node_modules/core-js/modules/_object-assign.js","../node_modules/core-js/modules/es6.object.assign.js","../src/utils/thread.js","../node_modules/core-js/modules/_string-at.js","../node_modules/core-js/modules/_advance-string-index.js","../node_modules/core-js/modules/_classof.js","../node_modules/core-js/modules/_regexp-exec-abstract.js","../node_modules/core-js/modules/_flags.js","../node_modules/core-js/modules/_regexp-exec.js","../node_modules/core-js/modules/es6.regexp.exec.js","../node_modules/core-js/modules/_fix-re-wks.js","../node_modules/core-js/modules/es6.regexp.replace.js","../node_modules/core-js/modules/_strict-method.js","../node_modules/core-js/modules/es6.array.sort.js","../node_modules/core-js/modules/_meta.js","../node_modules/core-js/modules/_is-array.js","../node_modules/core-js/modules/_object-gopn.js","../node_modules/core-js/modules/_object-gopd.js","../node_modules/core-js/modules/es6.string.iterator.js","../node_modules/core-js/modules/_an-instance.js","../node_modules/core-js/modules/_iter-call.js","../node_modules/core-js/modules/_is-array-iter.js","../node_modules/core-js/modules/core.get-iterator-method.js","../node_modules/core-js/modules/_for-of.js","../node_modules/core-js/modules/_species-constructor.js","../node_modules/core-js/modules/_invoke.js","../node_modules/core-js/modules/_task.js","../node_modules/core-js/modules/_microtask.js","../node_modules/core-js/modules/_new-promise-capability.js","../node_modules/core-js/modules/_perform.js","../node_modules/core-js/modules/_user-agent.js","../node_modules/core-js/modules/_promise-resolve.js","../node_modules/core-js/modules/_redefine-all.js","../node_modules/core-js/modules/_set-species.js","../node_modules/core-js/modules/_iter-detect.js","../node_modules/core-js/modules/es6.promise.js","../node_modules/core-js/modules/es6.function.name.js","../node_modules/core-js/modules/_object-sap.js","../node_modules/core-js/modules/es6.object.keys.js","../src/utils/version.js","../node_modules/core-js/modules/_is-regexp.js","../node_modules/core-js/modules/es6.regexp.split.js","../src/utils/worker_broker.js","../src/utils/log.js","../node_modules/core-js/modules/es6.regexp.flags.js","../node_modules/core-js/modules/es6.regexp.to-string.js","../src/utils/geo.js","../src/utils/utils.js","../src/utils/debug_settings.js","../node_modules/core-js/modules/_set-proto.js","../node_modules/core-js/modules/_inherit-if-required.js","../node_modules/core-js/modules/es6.regexp.constructor.js","../node_modules/core-js/modules/_same-value.js","../node_modules/core-js/modules/es6.regexp.search.js","../src/utils/urls.js","../src/utils/task.js","../src/utils/subscribe.js","../src/utils/slice.js","../node_modules/core-js/modules/_string-repeat.js","../node_modules/core-js/modules/es6.string.repeat.js","../node_modules/core-js/modules/_typed.js","../node_modules/core-js/modules/_to-index.js","../node_modules/core-js/modules/_array-fill.js","../node_modules/core-js/modules/_typed-buffer.js","../node_modules/core-js/modules/_array-species-constructor.js","../node_modules/core-js/modules/_array-species-create.js","../node_modules/core-js/modules/_array-methods.js","../node_modules/core-js/modules/_array-copy-within.js","../node_modules/core-js/modules/_typed-array.js","../node_modules/core-js/modules/es6.typed.uint8-array.js","../src/gl/texture.js","../node_modules/core-js/modules/_object-to-array.js","../node_modules/core-js/modules/es7.object.entries.js","../node_modules/core-js/modules/es6.regexp.match.js","../src/gl/glsl.js","../src/gl/extensions.js","../src/utils/hash.js","../node_modules/gl-shader-errors/index.js","../src/gl/shader_program.js","../src/gl/vao.js","../node_modules/core-js/modules/es7.object.values.js","../node_modules/core-js/modules/es6.array.find-index.js","../src/utils/merge.js","../node_modules/core-js/modules/_string-ws.js","../node_modules/core-js/modules/_string-trim.js","../node_modules/core-js/modules/es6.number.constructor.js","../node_modules/core-js/modules/es6.number.min-safe-integer.js","../node_modules/core-js/modules/es6.object.freeze.js","../src/utils/functions.js","../node_modules/csscolorparser/csscolorparser.js","../src/styles/style_parser.js","../node_modules/core-js/modules/es6.array.fill.js","../src/selection/selection.js","../node_modules/core-js/modules/es6.typed.uint16-array.js","../src/gl/vbo_mesh.js","../src/lights/material.js","../src/utils/vector.js","../src/lights/light.js","../node_modules/core-js/modules/es6.math.log2.js","../src/utils/errors.js","../src/sources/data_source.js","../src/tile/tile_id.js","../src/sources/raster.js","../src/styles/style.js","../src/gl/constants.js","../node_modules/core-js/modules/es6.typed.int16-array.js","../node_modules/core-js/modules/es6.typed.uint32-array.js","../node_modules/core-js/modules/es6.typed.int32-array.js","../node_modules/core-js/modules/es6.typed.int8-array.js","../node_modules/core-js/modules/es6.typed.float32-array.js","../src/gl/vertex_elements.js","../src/gl/vertex_data.js","../src/gl/vertex_layout.js","../src/builders/common.js","../node_modules/earcut/src/earcut.js","../src/builders/polygons.js","../src/styles/polygons/polygons.js","../node_modules/core-js/modules/_string-html.js","../node_modules/core-js/modules/es6.string.sub.js","../src/builders/polylines.js","../src/styles/lines/dasharray.js","../src/styles/lines/lines.js","../node_modules/core-js/modules/es6.date.to-json.js","../node_modules/core-js/modules/es6.string.anchor.js","../src/builders/points.js","../src/labels/point_anchor.js","../src/labels/intersect.js","../src/utils/obb.js","../src/labels/label.js","../src/labels/repeat_group.js","../src/labels/collision.js","../src/labels/label_point.js","../src/labels/point_placement.js","../src/styles/text/text_settings.js","../node_modules/fontfaceobserver/fontfaceobserver.standalone.js","../src/styles/text/font_manager.js","../src/styles/text/text_segments.js","../src/styles/text/text_wrap.js","../src/styles/text/text_canvas.js","../src/styles/text/text_labels.js","../node_modules/core-js/modules/es6.typed.float64-array.js","../node_modules/gl-mat3/normal-from-mat4.js","../node_modules/gl-mat3/invert.js","../node_modules/gl-mat4/multiply.js","../node_modules/gl-mat4/translate.js","../node_modules/gl-mat4/scale.js","../node_modules/gl-mat4/perspective.js","../node_modules/gl-mat4/identity.js","../node_modules/gl-mat4/lookAt.js","../node_modules/gl-mat4/copy.js","../src/utils/gl-matrix.js","../src/scene/camera.js","../src/scene/view.js","../src/styles/points/points.js","../node_modules/core-js/modules/es6.math.hypot.js","../src/labels/label_line.js","../src/styles/text/text.js","../src/styles/raster/raster.js","../src/styles/style_manager.js","../node_modules/core-js/modules/es6.number.max-safe-integer.js","../src/styles/filter.js","../src/styles/layer.js","../src/tile/tile.js","../node_modules/ieee754/index.js","../node_modules/pbf/index.js","../node_modules/@mapbox/point-geometry/index.js","../node_modules/@mapbox/vector-tile/lib/vectortilefeature.js","../node_modules/@mapbox/vector-tile/lib/vectortilelayer.js","../node_modules/@mapbox/vector-tile/lib/vectortile.js","../node_modules/@mapbox/vector-tile/index.js","../src/sources/mvt.js","../node_modules/geojson-vt/src/simplify.js","../node_modules/geojson-vt/src/feature.js","../node_modules/geojson-vt/src/convert.js","../node_modules/geojson-vt/src/transform.js","../node_modules/geojson-vt/src/clip.js","../node_modules/geojson-vt/src/wrap.js","../node_modules/geojson-vt/src/tile.js","../node_modules/geojson-vt/src/index.js","../src/sources/geojson.js","../node_modules/topojson-client/src/reverse.js","../node_modules/topojson-client/src/identity.js","../node_modules/topojson-client/src/transform.js","../node_modules/topojson-client/src/feature.js","../src/sources/topojson.js","../src/scene/scene_worker.js","../node_modules/core-js/modules/_wks-ext.js","../node_modules/core-js/modules/_wks-define.js","../node_modules/core-js/modules/es7.symbol.async-iterator.js","../node_modules/core-js/modules/_enum-keys.js","../node_modules/core-js/modules/_object-gopn-ext.js","../node_modules/core-js/modules/es6.symbol.js","../src/gl/context.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/buffer-es6/base64.js","../node_modules/buffer-es6/ieee754.js","../node_modules/buffer-es6/isArray.js","../node_modules/buffer-es6/index.js","../node_modules/rollup-plugin-node-builtins/src/es6/events.js","../node_modules/process-es6/browser.js","../node_modules/util/support/isBufferBrowser.js","../node_modules/util/node_modules/inherits/inherits_browser.js","../node_modules/util/util.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/buffer-list.js","../node_modules/safe-buffer/index.js","../node_modules/string_decoder/lib/string_decoder.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/readable.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/writable.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/duplex.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/transform.js","../node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/passthrough.js","../node_modules/rollup-plugin-node-builtins/src/es6/stream.js","../node_modules/jszip/lib/readable-stream-browser.js","../node_modules/jszip/lib/support.js","../node_modules/jszip/lib/base64.js","../node_modules/jszip/lib/nodejsUtils.js","../node_modules/jszip/node_modules/core-js/library/modules/_global.js","../node_modules/jszip/node_modules/core-js/library/modules/_core.js","../node_modules/jszip/node_modules/core-js/library/modules/_a-function.js","../node_modules/jszip/node_modules/core-js/library/modules/_ctx.js","../node_modules/jszip/node_modules/core-js/library/modules/_is-object.js","../node_modules/jszip/node_modules/core-js/library/modules/_an-object.js","../node_modules/jszip/node_modules/core-js/library/modules/_fails.js","../node_modules/jszip/node_modules/core-js/library/modules/_descriptors.js","../node_modules/jszip/node_modules/core-js/library/modules/_dom-create.js","../node_modules/jszip/node_modules/core-js/library/modules/_ie8-dom-define.js","../node_modules/jszip/node_modules/core-js/library/modules/_to-primitive.js","../node_modules/jszip/node_modules/core-js/library/modules/_object-dp.js","../node_modules/jszip/node_modules/core-js/library/modules/_property-desc.js","../node_modules/jszip/node_modules/core-js/library/modules/_hide.js","../node_modules/jszip/node_modules/core-js/library/modules/_export.js","../node_modules/jszip/node_modules/core-js/library/modules/_invoke.js","../node_modules/jszip/node_modules/core-js/library/modules/_html.js","../node_modules/jszip/node_modules/core-js/library/modules/_cof.js","../node_modules/jszip/node_modules/core-js/library/modules/_task.js","../node_modules/jszip/node_modules/core-js/library/modules/web.immediate.js","../node_modules/jszip/node_modules/core-js/library/fn/set-immediate.js","../node_modules/immediate/lib/browser.js","../node_modules/lie/lib/browser.js","../node_modules/jszip/lib/external.js","../node_modules/jszip/lib/utils.js","../node_modules/jszip/lib/stream/GenericWorker.js","../node_modules/jszip/lib/utf8.js","../node_modules/jszip/lib/stream/ConvertWorker.js","../node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js","../node_modules/jszip/lib/stream/StreamHelper.js","../node_modules/jszip/lib/defaults.js","../node_modules/jszip/lib/stream/DataWorker.js","../node_modules/jszip/lib/stream/DataLengthProbe.js","../node_modules/jszip/lib/crc32.js","../node_modules/jszip/lib/stream/Crc32Probe.js","../node_modules/jszip/lib/compressedObject.js","../node_modules/jszip/lib/zipObject.js","../node_modules/pako/lib/utils/common.js","../node_modules/pako/lib/zlib/trees.js","../node_modules/pako/lib/zlib/adler32.js","../node_modules/pako/lib/zlib/crc32.js","../node_modules/pako/lib/zlib/messages.js","../node_modules/pako/lib/zlib/deflate.js","../node_modules/pako/lib/utils/strings.js","../node_modules/pako/lib/zlib/zstream.js","../node_modules/pako/lib/deflate.js","../node_modules/pako/lib/zlib/inffast.js","../node_modules/pako/lib/zlib/inftrees.js","../node_modules/pako/lib/zlib/inflate.js","../node_modules/pako/lib/zlib/constants.js","../node_modules/pako/lib/zlib/gzheader.js","../node_modules/pako/lib/inflate.js","../node_modules/pako/index.js","../node_modules/jszip/lib/flate.js","../node_modules/jszip/lib/compressions.js","../node_modules/jszip/lib/signature.js","../node_modules/jszip/lib/generate/ZipFileWorker.js","../node_modules/jszip/lib/generate/index.js","../node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js","../node_modules/jszip/lib/object.js","../node_modules/jszip/lib/reader/DataReader.js","../node_modules/jszip/lib/reader/ArrayReader.js","../node_modules/jszip/lib/reader/StringReader.js","../node_modules/jszip/lib/reader/Uint8ArrayReader.js","../node_modules/jszip/lib/reader/NodeBufferReader.js","../node_modules/jszip/lib/reader/readerFor.js","../node_modules/jszip/lib/zipEntry.js","../node_modules/jszip/lib/zipEntries.js","../node_modules/jszip/lib/load.js","../node_modules/jszip/lib/index.js","../node_modules/js-yaml/lib/js-yaml/common.js","../node_modules/js-yaml/lib/js-yaml/exception.js","../node_modules/js-yaml/lib/js-yaml/mark.js","../node_modules/js-yaml/lib/js-yaml/type.js","../node_modules/js-yaml/lib/js-yaml/schema.js","../node_modules/js-yaml/lib/js-yaml/type/str.js","../node_modules/js-yaml/lib/js-yaml/type/seq.js","../node_modules/js-yaml/lib/js-yaml/type/map.js","../node_modules/js-yaml/lib/js-yaml/schema/failsafe.js","../node_modules/js-yaml/lib/js-yaml/type/null.js","../node_modules/js-yaml/lib/js-yaml/type/bool.js","../node_modules/js-yaml/lib/js-yaml/type/int.js","../node_modules/js-yaml/lib/js-yaml/type/float.js","../node_modules/js-yaml/lib/js-yaml/schema/json.js","../node_modules/js-yaml/lib/js-yaml/schema/core.js","../node_modules/js-yaml/lib/js-yaml/type/timestamp.js","../node_modules/js-yaml/lib/js-yaml/type/merge.js","../node_modules/rollup-plugin-node-resolve/src/empty.js","../node_modules/js-yaml/lib/js-yaml/type/binary.js","../node_modules/js-yaml/lib/js-yaml/type/omap.js","../node_modules/js-yaml/lib/js-yaml/type/pairs.js","../node_modules/js-yaml/lib/js-yaml/type/set.js","../node_modules/js-yaml/lib/js-yaml/schema/default_safe.js","../node_modules/js-yaml/lib/js-yaml/type/js/undefined.js","../node_modules/js-yaml/lib/js-yaml/type/js/regexp.js","../node_modules/js-yaml/lib/js-yaml/type/js/function.js","../node_modules/js-yaml/lib/js-yaml/schema/default_full.js","../node_modules/js-yaml/lib/js-yaml/loader.js","../node_modules/js-yaml/lib/js-yaml.js","../node_modules/js-yaml/index.js","../src/scene/scene_bundle.js","../src/scene/scene_loader.js","../src/tile/tile_pyramid.js","../src/labels/main_pass.js","../src/tile/tile_manager.js","../src/gl/render_state.js","../node_modules/core-js/modules/es6.typed.uint8-clamped-array.js","../src/utils/media_capture.js","../src/scene/scene_debug.js","../src/scene/scene.js","../src/utils/debounce.js","../src/leaflet_layer.js","../src/index.js","../build/bundle.js"],"sourcesContent":["var core = module.exports = { version: '2.6.3' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self\n // eslint-disable-next-line no-new-func\n : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n","module.exports = false;\n","var core = require('./_core');\nvar global = require('./_global');\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: core.version,\n mode: require('./_library') ? 'pure' : 'global',\n copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n});\n","var id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n","var store = require('./_shared')('wks');\nvar uid = require('./_uid');\nvar Symbol = require('./_global').Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n","module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n","var isObject = require('./_is-object');\nmodule.exports = function (it) {\n if (!isObject(it)) throw TypeError(it + ' is not an object!');\n return it;\n};\n","module.exports = function (exec) {\n try {\n return !!exec();\n } catch (e) {\n return true;\n }\n};\n","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function () {\n return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n","var isObject = require('./_is-object');\nvar document = require('./_global').document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n return is ? document.createElement(it) : {};\n};\n","module.exports = !require('./_descriptors') && !require('./_fails')(function () {\n return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n if (!isObject(it)) return it;\n var fn, val;\n if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n","var anObject = require('./_an-object');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar toPrimitive = require('./_to-primitive');\nvar dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return dP(O, P, Attributes);\n } catch (e) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","var dP = require('./_object-dp');\nvar createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function (object, key, value) {\n return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","// 22.1.3.31 Array.prototype[@@unscopables]\nvar UNSCOPABLES = require('./_wks')('unscopables');\nvar ArrayProto = Array.prototype;\nif (ArrayProto[UNSCOPABLES] == undefined) require('./_hide')(ArrayProto, UNSCOPABLES, {});\nmodule.exports = function (key) {\n ArrayProto[UNSCOPABLES][key] = true;\n};\n","module.exports = function (done, value) {\n return { value: value, done: !!done };\n};\n","module.exports = {};\n","var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject');\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return IObject(defined(it));\n};\n","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n","var global = require('./_global');\nvar hide = require('./_hide');\nvar has = require('./_has');\nvar SRC = require('./_uid')('src');\nvar TO_STRING = 'toString';\nvar $toString = Function[TO_STRING];\nvar TPL = ('' + $toString).split(TO_STRING);\n\nrequire('./_core').inspectSource = function (it) {\n return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n var isFunction = typeof val == 'function';\n if (isFunction) has(val, 'name') || hide(val, 'name', key);\n if (O[key] === val) return;\n if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n if (O === global) {\n O[key] = val;\n } else if (!safe) {\n delete O[key];\n hide(O, key, val);\n } else if (O[key]) {\n O[key] = val;\n } else {\n hide(O, key, val);\n }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n","module.exports = function (it) {\n if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n return it;\n};\n","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n","var global = require('./_global');\nvar core = require('./_core');\nvar hide = require('./_hide');\nvar redefine = require('./_redefine');\nvar ctx = require('./_ctx');\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n var IS_FORCED = type & $export.F;\n var IS_GLOBAL = type & $export.G;\n var IS_STATIC = type & $export.S;\n var IS_PROTO = type & $export.P;\n var IS_BIND = type & $export.B;\n var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n var key, own, out, exp;\n if (IS_GLOBAL) source = name;\n for (key in source) {\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n // export native or passed\n out = (own ? target : source)[key];\n // bind timers to global for call from export context\n exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // extend global\n if (target) redefine(target, key, out, type & $export.U);\n // export\n if (exports[key] != out) hide(exports, key, exp);\n if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n","// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer');\nvar min = Math.min;\nmodule.exports = function (it) {\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n","var toInteger = require('./_to-integer');\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject');\nvar toLength = require('./_to-length');\nvar toAbsoluteIndex = require('./_to-absolute-index');\nmodule.exports = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIObject($this);\n var length = toLength(O.length);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n if (O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n","var shared = require('./_shared')('keys');\nvar uid = require('./_uid');\nmodule.exports = function (key) {\n return shared[key] || (shared[key] = uid(key));\n};\n","var has = require('./_has');\nvar toIObject = require('./_to-iobject');\nvar arrayIndexOf = require('./_array-includes')(false);\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function (object, names) {\n var O = toIObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (has(O, key = names[i++])) {\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n","// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal');\nvar enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O) {\n return $keys(O, enumBugKeys);\n};\n","var dP = require('./_object-dp');\nvar anObject = require('./_an-object');\nvar getKeys = require('./_object-keys');\n\nmodule.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties) {\n anObject(O);\n var keys = getKeys(Properties);\n var length = keys.length;\n var i = 0;\n var P;\n while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n return O;\n};\n","var document = require('./_global').document;\nmodule.exports = document && document.documentElement;\n","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object');\nvar dPs = require('./_object-dps');\nvar enumBugKeys = require('./_enum-bug-keys');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe');\n var i = enumBugKeys.length;\n var lt = '<';\n var gt = '>';\n var iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty();\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n","var def = require('./_object-dp').f;\nvar has = require('./_has');\nvar TAG = require('./_wks')('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n","'use strict';\nvar create = require('./_object-create');\nvar descriptor = require('./_property-desc');\nvar setToStringTag = require('./_set-to-string-tag');\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n setToStringTag(Constructor, NAME + ' Iterator');\n};\n","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return Object(defined(it));\n};\n","// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = require('./_has');\nvar toObject = require('./_to-object');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n O = toObject(O);\n if (has(O, IE_PROTO)) return O[IE_PROTO];\n if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectProto : null;\n};\n","'use strict';\nvar LIBRARY = require('./_library');\nvar $export = require('./_export');\nvar redefine = require('./_redefine');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar $iterCreate = require('./_iter-create');\nvar setToStringTag = require('./_set-to-string-tag');\nvar getPrototypeOf = require('./_object-gpo');\nvar ITERATOR = require('./_wks')('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n $iterCreate(Constructor, NAME, next);\n var getMethod = function (kind) {\n if (!BUGGY && kind in proto) return proto[kind];\n switch (kind) {\n case KEYS: return function keys() { return new Constructor(this, kind); };\n case VALUES: return function values() { return new Constructor(this, kind); };\n } return function entries() { return new Constructor(this, kind); };\n };\n var TAG = NAME + ' Iterator';\n var DEF_VALUES = DEFAULT == VALUES;\n var VALUES_BUG = false;\n var proto = Base.prototype;\n var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n var $default = $native || getMethod(DEFAULT);\n var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n var methods, key, IteratorPrototype;\n // Fix native\n if ($anyNative) {\n IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n // Set @@toStringTag to native iterators\n setToStringTag(IteratorPrototype, TAG, true);\n // fix for some old engines\n if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n }\n }\n // fix Array#{values, @@iterator}.name in V8 / FF\n if (DEF_VALUES && $native && $native.name !== VALUES) {\n VALUES_BUG = true;\n $default = function values() { return $native.call(this); };\n }\n // Define iterator\n if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n hide(proto, ITERATOR, $default);\n }\n // Plug for library\n Iterators[NAME] = $default;\n Iterators[TAG] = returnThis;\n if (DEFAULT) {\n methods = {\n values: DEF_VALUES ? $default : getMethod(VALUES),\n keys: IS_SET ? $default : getMethod(KEYS),\n entries: $entries\n };\n if (FORCED) for (key in methods) {\n if (!(key in proto)) redefine(proto, key, methods[key]);\n } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n }\n return methods;\n};\n","'use strict';\nvar addToUnscopables = require('./_add-to-unscopables');\nvar step = require('./_iter-step');\nvar Iterators = require('./_iterators');\nvar toIObject = require('./_to-iobject');\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = require('./_iter-define')(Array, 'Array', function (iterated, kind) {\n this._t = toIObject(iterated); // target\n this._i = 0; // next index\n this._k = kind; // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var kind = this._k;\n var index = this._i++;\n if (!O || index >= O.length) {\n this._t = undefined;\n return step(1);\n }\n if (kind == 'keys') return step(0, index);\n if (kind == 'values') return step(0, O[index]);\n return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n","var $iterators = require('./es6.array.iterator');\nvar getKeys = require('./_object-keys');\nvar redefine = require('./_redefine');\nvar global = require('./_global');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar wks = require('./_wks');\nvar ITERATOR = wks('iterator');\nvar TO_STRING_TAG = wks('toStringTag');\nvar ArrayValues = Iterators.Array;\n\nvar DOMIterables = {\n CSSRuleList: true, // TODO: Not spec compliant, should be false.\n CSSStyleDeclaration: false,\n CSSValueList: false,\n ClientRectList: false,\n DOMRectList: false,\n DOMStringList: false,\n DOMTokenList: true,\n DataTransferItemList: false,\n FileList: false,\n HTMLAllCollection: false,\n HTMLCollection: false,\n HTMLFormElement: false,\n HTMLSelectElement: false,\n MediaList: true, // TODO: Not spec compliant, should be false.\n MimeTypeArray: false,\n NamedNodeMap: false,\n NodeList: true,\n PaintRequestList: false,\n Plugin: false,\n PluginArray: false,\n SVGLengthList: false,\n SVGNumberList: false,\n SVGPathSegList: false,\n SVGPointList: false,\n SVGStringList: false,\n SVGTransformList: false,\n SourceBufferList: false,\n StyleSheetList: true, // TODO: Not spec compliant, should be false.\n TextTrackCueList: false,\n TextTrackList: false,\n TouchList: false\n};\n\nfor (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {\n var NAME = collections[i];\n var explicit = DOMIterables[NAME];\n var Collection = global[NAME];\n var proto = Collection && Collection.prototype;\n var key;\n if (proto) {\n if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);\n if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n Iterators[NAME] = ArrayValues;\n if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);\n }\n}\n","exports.f = Object.getOwnPropertySymbols;\n","exports.f = {}.propertyIsEnumerable;\n","'use strict';\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = require('./_object-keys');\nvar gOPS = require('./_object-gops');\nvar pIE = require('./_object-pie');\nvar toObject = require('./_to-object');\nvar IObject = require('./_iobject');\nvar $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || require('./_fails')(function () {\n var A = {};\n var B = {};\n // eslint-disable-next-line no-undef\n var S = Symbol();\n var K = 'abcdefghijklmnopqrst';\n A[S] = 7;\n K.split('').forEach(function (k) { B[k] = k; });\n return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source) { // eslint-disable-line no-unused-vars\n var T = toObject(target);\n var aLen = arguments.length;\n var index = 1;\n var getSymbols = gOPS.f;\n var isEnum = pIE.f;\n while (aLen > index) {\n var S = IObject(arguments[index++]);\n var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);\n var length = keys.length;\n var j = 0;\n var key;\n while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];\n } return T;\n} : $assign;\n","// 19.1.3.1 Object.assign(target, source)\nvar $export = require('./_export');\n\n$export($export.S + $export.F, 'Object', { assign: require('./_object-assign') });\n","/*jshint worker: true*/\n\n// Mark thread as main or worker\nconst Thread = {};\n\ntry {\n if (window instanceof Window && window.document instanceof HTMLDocument) { // jshint ignore:line\n Thread.is_worker = false;\n Thread.is_main = true;\n }\n}\ncatch(e) {\n Thread.is_worker = true;\n Thread.is_main = false;\n\n // Patch for 3rd party libs that require these globals to be present. Specifically, FontFaceObserver.\n // Brittle solution but allows that library to load on worker threads.\n self.window = { document: {} };\n self.document = self.window.document;\n}\n\nexport default Thread;\n","var toInteger = require('./_to-integer');\nvar defined = require('./_defined');\n// true -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n return function (that, pos) {\n var s = String(defined(that));\n var i = toInteger(pos);\n var l = s.length;\n var a, b;\n if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n a = s.charCodeAt(i);\n return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n ? TO_STRING ? s.charAt(i) : a\n : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n };\n};\n","'use strict';\nvar at = require('./_string-at')(true);\n\n // `AdvanceStringIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-advancestringindex\nmodule.exports = function (S, index, unicode) {\n return index + (unicode ? at(S, index).length : 1);\n};\n","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof');\nvar TAG = require('./_wks')('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n","'use strict';\n\nvar classof = require('./_classof');\nvar builtinExec = RegExp.prototype.exec;\n\n // `RegExpExec` abstract operation\n// https://tc39.github.io/ecma262/#sec-regexpexec\nmodule.exports = function (R, S) {\n var exec = R.exec;\n if (typeof exec === 'function') {\n var result = exec.call(R, S);\n if (typeof result !== 'object') {\n throw new TypeError('RegExp exec method returned something other than an Object or null');\n }\n return result;\n }\n if (classof(R) !== 'RegExp') {\n throw new TypeError('RegExp#exec called on incompatible receiver');\n }\n return builtinExec.call(R, S);\n};\n","'use strict';\n// 21.2.5.3 get RegExp.prototype.flags\nvar anObject = require('./_an-object');\nmodule.exports = function () {\n var that = anObject(this);\n var result = '';\n if (that.global) result += 'g';\n if (that.ignoreCase) result += 'i';\n if (that.multiline) result += 'm';\n if (that.unicode) result += 'u';\n if (that.sticky) result += 'y';\n return result;\n};\n","'use strict';\n\nvar regexpFlags = require('./_flags');\n\nvar nativeExec = RegExp.prototype.exec;\n// This always refers to the native implementation, because the\n// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,\n// which loads this file before patching the method.\nvar nativeReplace = String.prototype.replace;\n\nvar patchedExec = nativeExec;\n\nvar LAST_INDEX = 'lastIndex';\n\nvar UPDATES_LAST_INDEX_WRONG = (function () {\n var re1 = /a/,\n re2 = /b*/g;\n nativeExec.call(re1, 'a');\n nativeExec.call(re2, 'a');\n return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;\n})();\n\n// nonparticipating capturing group, copied from es5-shim's String#split patch.\nvar NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;\n\nvar PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;\n\nif (PATCH) {\n patchedExec = function exec(str) {\n var re = this;\n var lastIndex, reCopy, match, i;\n\n if (NPCG_INCLUDED) {\n reCopy = new RegExp('^' + re.source + '$(?!\\\\s)', regexpFlags.call(re));\n }\n if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];\n\n match = nativeExec.call(re, str);\n\n if (UPDATES_LAST_INDEX_WRONG && match) {\n re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;\n }\n if (NPCG_INCLUDED && match && match.length > 1) {\n // Fix browsers whose `exec` methods don't consistently return `undefined`\n // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/\n // eslint-disable-next-line no-loop-func\n nativeReplace.call(match[0], reCopy, function () {\n for (i = 1; i < arguments.length - 2; i++) {\n if (arguments[i] === undefined) match[i] = undefined;\n }\n });\n }\n\n return match;\n };\n}\n\nmodule.exports = patchedExec;\n","'use strict';\nvar regexpExec = require('./_regexp-exec');\nrequire('./_export')({\n target: 'RegExp',\n proto: true,\n forced: regexpExec !== /./.exec\n}, {\n exec: regexpExec\n});\n","'use strict';\nrequire('./es6.regexp.exec');\nvar redefine = require('./_redefine');\nvar hide = require('./_hide');\nvar fails = require('./_fails');\nvar defined = require('./_defined');\nvar wks = require('./_wks');\nvar regexpExec = require('./_regexp-exec');\n\nvar SPECIES = wks('species');\n\nvar REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {\n // #replace needs built-in support for named groups.\n // #match works fine because it just return the exec results, even if it has\n // a \"grops\" property.\n var re = /./;\n re.exec = function () {\n var result = [];\n result.groups = { a: '7' };\n return result;\n };\n return ''.replace(re, '$') !== '7';\n});\n\nvar SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () {\n // Chrome 51 has a buggy \"split\" implementation when RegExp#exec !== nativeExec\n var re = /(?:)/;\n var originalExec = re.exec;\n re.exec = function () { return originalExec.apply(this, arguments); };\n var result = 'ab'.split(re);\n return result.length === 2 && result[0] === 'a' && result[1] === 'b';\n})();\n\nmodule.exports = function (KEY, length, exec) {\n var SYMBOL = wks(KEY);\n\n var DELEGATES_TO_SYMBOL = !fails(function () {\n // String methods call symbol-named RegEp methods\n var O = {};\n O[SYMBOL] = function () { return 7; };\n return ''[KEY](O) != 7;\n });\n\n var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !fails(function () {\n // Symbol-named RegExp methods call .exec\n var execCalled = false;\n var re = /a/;\n re.exec = function () { execCalled = true; return null; };\n if (KEY === 'split') {\n // RegExp[@@split] doesn't call the regex's exec method, but first creates\n // a new one. We need to return the patched regex when creating the new one.\n re.constructor = {};\n re.constructor[SPECIES] = function () { return re; };\n }\n re[SYMBOL]('');\n return !execCalled;\n }) : undefined;\n\n if (\n !DELEGATES_TO_SYMBOL ||\n !DELEGATES_TO_EXEC ||\n (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||\n (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)\n ) {\n var nativeRegExpMethod = /./[SYMBOL];\n var fns = exec(\n defined,\n SYMBOL,\n ''[KEY],\n function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {\n if (regexp.exec === regexpExec) {\n if (DELEGATES_TO_SYMBOL && !forceStringMethod) {\n // The native String method already delegates to @@method (this\n // polyfilled function), leasing to infinite recursion.\n // We avoid it by directly calling the native @@method method.\n return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };\n }\n return { done: true, value: nativeMethod.call(str, regexp, arg2) };\n }\n return { done: false };\n }\n );\n var strfn = fns[0];\n var rxfn = fns[1];\n\n redefine(String.prototype, KEY, strfn);\n hide(RegExp.prototype, SYMBOL, length == 2\n // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n ? function (string, arg) { return rxfn.call(string, this, arg); }\n // 21.2.5.6 RegExp.prototype[@@match](string)\n // 21.2.5.9 RegExp.prototype[@@search](string)\n : function (string) { return rxfn.call(string, this); }\n );\n }\n};\n","'use strict';\n\nvar anObject = require('./_an-object');\nvar toObject = require('./_to-object');\nvar toLength = require('./_to-length');\nvar toInteger = require('./_to-integer');\nvar advanceStringIndex = require('./_advance-string-index');\nvar regExpExec = require('./_regexp-exec-abstract');\nvar max = Math.max;\nvar min = Math.min;\nvar floor = Math.floor;\nvar SUBSTITUTION_SYMBOLS = /\\$([$&`']|\\d\\d?|<[^>]*>)/g;\nvar SUBSTITUTION_SYMBOLS_NO_NAMED = /\\$([$&`']|\\d\\d?)/g;\n\nvar maybeToString = function (it) {\n return it === undefined ? it : String(it);\n};\n\n// @@replace logic\nrequire('./_fix-re-wks')('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {\n return [\n // `String.prototype.replace` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.replace\n function replace(searchValue, replaceValue) {\n var O = defined(this);\n var fn = searchValue == undefined ? undefined : searchValue[REPLACE];\n return fn !== undefined\n ? fn.call(searchValue, O, replaceValue)\n : $replace.call(String(O), searchValue, replaceValue);\n },\n // `RegExp.prototype[@@replace]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace\n function (regexp, replaceValue) {\n var res = maybeCallNative($replace, regexp, this, replaceValue);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n var functionalReplace = typeof replaceValue === 'function';\n if (!functionalReplace) replaceValue = String(replaceValue);\n var global = rx.global;\n if (global) {\n var fullUnicode = rx.unicode;\n rx.lastIndex = 0;\n }\n var results = [];\n while (true) {\n var result = regExpExec(rx, S);\n if (result === null) break;\n results.push(result);\n if (!global) break;\n var matchStr = String(result[0]);\n if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n }\n var accumulatedResult = '';\n var nextSourcePosition = 0;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n var matched = String(result[0]);\n var position = max(min(toInteger(result.index), S.length), 0);\n var captures = [];\n // NOTE: This is equivalent to\n // captures = result.slice(1).map(maybeToString)\n // but for some reason `nativeSlice.call(result, 1, result.length)` (called in\n // the slice polyfill when slicing native arrays) \"doesn't work\" in safari 9 and\n // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.\n for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));\n var namedCaptures = result.groups;\n if (functionalReplace) {\n var replacerArgs = [matched].concat(captures, position, S);\n if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);\n var replacement = String(replaceValue.apply(undefined, replacerArgs));\n } else {\n replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);\n }\n if (position >= nextSourcePosition) {\n accumulatedResult += S.slice(nextSourcePosition, position) + replacement;\n nextSourcePosition = position + matched.length;\n }\n }\n return accumulatedResult + S.slice(nextSourcePosition);\n }\n ];\n\n // https://tc39.github.io/ecma262/#sec-getsubstitution\n function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {\n var tailPos = position + matched.length;\n var m = captures.length;\n var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;\n if (namedCaptures !== undefined) {\n namedCaptures = toObject(namedCaptures);\n symbols = SUBSTITUTION_SYMBOLS;\n }\n return $replace.call(replacement, symbols, function (match, ch) {\n var capture;\n switch (ch.charAt(0)) {\n case '$': return '$';\n case '&': return matched;\n case '`': return str.slice(0, position);\n case \"'\": return str.slice(tailPos);\n case '<':\n capture = namedCaptures[ch.slice(1, -1)];\n break;\n default: // \\d\\d?\n var n = +ch;\n if (n === 0) return match;\n if (n > m) {\n var f = floor(n / 10);\n if (f === 0) return match;\n if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);\n return match;\n }\n capture = captures[n - 1];\n }\n return capture === undefined ? '' : capture;\n });\n }\n});\n","'use strict';\nvar fails = require('./_fails');\n\nmodule.exports = function (method, arg) {\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call\n arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);\n });\n};\n","'use strict';\nvar $export = require('./_export');\nvar aFunction = require('./_a-function');\nvar toObject = require('./_to-object');\nvar fails = require('./_fails');\nvar $sort = [].sort;\nvar test = [1, 2, 3];\n\n$export($export.P + $export.F * (fails(function () {\n // IE8-\n test.sort(undefined);\n}) || !fails(function () {\n // V8 bug\n test.sort(null);\n // Old WebKit\n}) || !require('./_strict-method')($sort)), 'Array', {\n // 22.1.3.25 Array.prototype.sort(comparefn)\n sort: function sort(comparefn) {\n return comparefn === undefined\n ? $sort.call(toObject(this))\n : $sort.call(toObject(this), aFunction(comparefn));\n }\n});\n","var META = require('./_uid')('meta');\nvar isObject = require('./_is-object');\nvar has = require('./_has');\nvar setDesc = require('./_object-dp').f;\nvar id = 0;\nvar isExtensible = Object.isExtensible || function () {\n return true;\n};\nvar FREEZE = !require('./_fails')(function () {\n return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function (it) {\n setDesc(it, META, { value: {\n i: 'O' + ++id, // object ID\n w: {} // weak collections IDs\n } });\n};\nvar fastKey = function (it, create) {\n // return primitive with prefix\n if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n if (!has(it, META)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return 'F';\n // not necessary to add metadata\n if (!create) return 'E';\n // add missing metadata\n setMeta(it);\n // return object ID\n } return it[META].i;\n};\nvar getWeak = function (it, create) {\n if (!has(it, META)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return true;\n // not necessary to add metadata\n if (!create) return false;\n // add missing metadata\n setMeta(it);\n // return hash weak collections IDs\n } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function (it) {\n if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);\n return it;\n};\nvar meta = module.exports = {\n KEY: META,\n NEED: false,\n fastKey: fastKey,\n getWeak: getWeak,\n onFreeze: onFreeze\n};\n","// 7.2.2 IsArray(argument)\nvar cof = require('./_cof');\nmodule.exports = Array.isArray || function isArray(arg) {\n return cof(arg) == 'Array';\n};\n","// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = require('./_object-keys-internal');\nvar hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return $keys(O, hiddenKeys);\n};\n","var pIE = require('./_object-pie');\nvar createDesc = require('./_property-desc');\nvar toIObject = require('./_to-iobject');\nvar toPrimitive = require('./_to-primitive');\nvar has = require('./_has');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P) {\n O = toIObject(O);\n P = toPrimitive(P, true);\n if (IE8_DOM_DEFINE) try {\n return gOPD(O, P);\n } catch (e) { /* empty */ }\n if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);\n};\n","'use strict';\nvar $at = require('./_string-at')(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\nrequire('./_iter-define')(String, 'String', function (iterated) {\n this._t = String(iterated); // target\n this._i = 0; // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var index = this._i;\n var point;\n if (index >= O.length) return { value: undefined, done: true };\n point = $at(O, index);\n this._i += point.length;\n return { value: point, done: false };\n});\n","module.exports = function (it, Constructor, name, forbiddenField) {\n if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {\n throw TypeError(name + ': incorrect invocation!');\n } return it;\n};\n","// call something on iterator step with safe closing on error\nvar anObject = require('./_an-object');\nmodule.exports = function (iterator, fn, value, entries) {\n try {\n return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch (e) {\n var ret = iterator['return'];\n if (ret !== undefined) anObject(ret.call(iterator));\n throw e;\n }\n};\n","// check on default Array iterator\nvar Iterators = require('./_iterators');\nvar ITERATOR = require('./_wks')('iterator');\nvar ArrayProto = Array.prototype;\n\nmodule.exports = function (it) {\n return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n","var classof = require('./_classof');\nvar ITERATOR = require('./_wks')('iterator');\nvar Iterators = require('./_iterators');\nmodule.exports = require('./_core').getIteratorMethod = function (it) {\n if (it != undefined) return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n","var ctx = require('./_ctx');\nvar call = require('./_iter-call');\nvar isArrayIter = require('./_is-array-iter');\nvar anObject = require('./_an-object');\nvar toLength = require('./_to-length');\nvar getIterFn = require('./core.get-iterator-method');\nvar BREAK = {};\nvar RETURN = {};\nvar exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {\n var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);\n var f = ctx(fn, that, entries ? 2 : 1);\n var index = 0;\n var length, step, iterator, result;\n if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');\n // fast case for arrays with default iterator\n if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {\n result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n if (result === BREAK || result === RETURN) return result;\n } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {\n result = call(iterator, f, step.value, entries);\n if (result === BREAK || result === RETURN) return result;\n }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n","// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = require('./_an-object');\nvar aFunction = require('./_a-function');\nvar SPECIES = require('./_wks')('species');\nmodule.exports = function (O, D) {\n var C = anObject(O).constructor;\n var S;\n return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n","// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function (fn, args, that) {\n var un = that === undefined;\n switch (args.length) {\n case 0: return un ? fn()\n : fn.call(that);\n case 1: return un ? fn(args[0])\n : fn.call(that, args[0]);\n case 2: return un ? fn(args[0], args[1])\n : fn.call(that, args[0], args[1]);\n case 3: return un ? fn(args[0], args[1], args[2])\n : fn.call(that, args[0], args[1], args[2]);\n case 4: return un ? fn(args[0], args[1], args[2], args[3])\n : fn.call(that, args[0], args[1], args[2], args[3]);\n } return fn.apply(that, args);\n};\n","var ctx = require('./_ctx');\nvar invoke = require('./_invoke');\nvar html = require('./_html');\nvar cel = require('./_dom-create');\nvar global = require('./_global');\nvar process = global.process;\nvar setTask = global.setImmediate;\nvar clearTask = global.clearImmediate;\nvar MessageChannel = global.MessageChannel;\nvar Dispatch = global.Dispatch;\nvar counter = 0;\nvar queue = {};\nvar ONREADYSTATECHANGE = 'onreadystatechange';\nvar defer, channel, port;\nvar run = function () {\n var id = +this;\n // eslint-disable-next-line no-prototype-builtins\n if (queue.hasOwnProperty(id)) {\n var fn = queue[id];\n delete queue[id];\n fn();\n }\n};\nvar listener = function (event) {\n run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif (!setTask || !clearTask) {\n setTask = function setImmediate(fn) {\n var args = [];\n var i = 1;\n while (arguments.length > i) args.push(arguments[i++]);\n queue[++counter] = function () {\n // eslint-disable-next-line no-new-func\n invoke(typeof fn == 'function' ? fn : Function(fn), args);\n };\n defer(counter);\n return counter;\n };\n clearTask = function clearImmediate(id) {\n delete queue[id];\n };\n // Node.js 0.8-\n if (require('./_cof')(process) == 'process') {\n defer = function (id) {\n process.nextTick(ctx(run, id, 1));\n };\n // Sphere (JS game engine) Dispatch API\n } else if (Dispatch && Dispatch.now) {\n defer = function (id) {\n Dispatch.now(ctx(run, id, 1));\n };\n // Browsers with MessageChannel, includes WebWorkers\n } else if (MessageChannel) {\n channel = new MessageChannel();\n port = channel.port2;\n channel.port1.onmessage = listener;\n defer = ctx(port.postMessage, port, 1);\n // Browsers with postMessage, skip WebWorkers\n // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {\n defer = function (id) {\n global.postMessage(id + '', '*');\n };\n global.addEventListener('message', listener, false);\n // IE8-\n } else if (ONREADYSTATECHANGE in cel('script')) {\n defer = function (id) {\n html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {\n html.removeChild(this);\n run.call(id);\n };\n };\n // Rest old browsers\n } else {\n defer = function (id) {\n setTimeout(ctx(run, id, 1), 0);\n };\n }\n}\nmodule.exports = {\n set: setTask,\n clear: clearTask\n};\n","var global = require('./_global');\nvar macrotask = require('./_task').set;\nvar Observer = global.MutationObserver || global.WebKitMutationObserver;\nvar process = global.process;\nvar Promise = global.Promise;\nvar isNode = require('./_cof')(process) == 'process';\n\nmodule.exports = function () {\n var head, last, notify;\n\n var flush = function () {\n var parent, fn;\n if (isNode && (parent = process.domain)) parent.exit();\n while (head) {\n fn = head.fn;\n head = head.next;\n try {\n fn();\n } catch (e) {\n if (head) notify();\n else last = undefined;\n throw e;\n }\n } last = undefined;\n if (parent) parent.enter();\n };\n\n // Node.js\n if (isNode) {\n notify = function () {\n process.nextTick(flush);\n };\n // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339\n } else if (Observer && !(global.navigator && global.navigator.standalone)) {\n var toggle = true;\n var node = document.createTextNode('');\n new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new\n notify = function () {\n node.data = toggle = !toggle;\n };\n // environments with maybe non-completely correct, but existent Promise\n } else if (Promise && Promise.resolve) {\n // Promise.resolve without an argument throws an error in LG WebOS 2\n var promise = Promise.resolve(undefined);\n notify = function () {\n promise.then(flush);\n };\n // for other environments - macrotask based on:\n // - setImmediate\n // - MessageChannel\n // - window.postMessag\n // - onreadystatechange\n // - setTimeout\n } else {\n notify = function () {\n // strange IE + webpack dev server bug - use .call(global)\n macrotask.call(global, flush);\n };\n }\n\n return function (fn) {\n var task = { fn: fn, next: undefined };\n if (last) last.next = task;\n if (!head) {\n head = task;\n notify();\n } last = task;\n };\n};\n","'use strict';\n// 25.4.1.5 NewPromiseCapability(C)\nvar aFunction = require('./_a-function');\n\nfunction PromiseCapability(C) {\n var resolve, reject;\n this.promise = new C(function ($$resolve, $$reject) {\n if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n resolve = $$resolve;\n reject = $$reject;\n });\n this.resolve = aFunction(resolve);\n this.reject = aFunction(reject);\n}\n\nmodule.exports.f = function (C) {\n return new PromiseCapability(C);\n};\n","module.exports = function (exec) {\n try {\n return { e: false, v: exec() };\n } catch (e) {\n return { e: true, v: e };\n }\n};\n","var global = require('./_global');\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n","var anObject = require('./_an-object');\nvar isObject = require('./_is-object');\nvar newPromiseCapability = require('./_new-promise-capability');\n\nmodule.exports = function (C, x) {\n anObject(C);\n if (isObject(x) && x.constructor === C) return x;\n var promiseCapability = newPromiseCapability.f(C);\n var resolve = promiseCapability.resolve;\n resolve(x);\n return promiseCapability.promise;\n};\n","var redefine = require('./_redefine');\nmodule.exports = function (target, src, safe) {\n for (var key in src) redefine(target, key, src[key], safe);\n return target;\n};\n","'use strict';\nvar global = require('./_global');\nvar dP = require('./_object-dp');\nvar DESCRIPTORS = require('./_descriptors');\nvar SPECIES = require('./_wks')('species');\n\nmodule.exports = function (KEY) {\n var C = global[KEY];\n if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {\n configurable: true,\n get: function () { return this; }\n });\n};\n","var ITERATOR = require('./_wks')('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n var riter = [7][ITERATOR]();\n riter['return'] = function () { SAFE_CLOSING = true; };\n // eslint-disable-next-line no-throw-literal\n Array.from(riter, function () { throw 2; });\n} catch (e) { /* empty */ }\n\nmodule.exports = function (exec, skipClosing) {\n if (!skipClosing && !SAFE_CLOSING) return false;\n var safe = false;\n try {\n var arr = [7];\n var iter = arr[ITERATOR]();\n iter.next = function () { return { done: safe = true }; };\n arr[ITERATOR] = function () { return iter; };\n exec(arr);\n } catch (e) { /* empty */ }\n return safe;\n};\n","'use strict';\nvar LIBRARY = require('./_library');\nvar global = require('./_global');\nvar ctx = require('./_ctx');\nvar classof = require('./_classof');\nvar $export = require('./_export');\nvar isObject = require('./_is-object');\nvar aFunction = require('./_a-function');\nvar anInstance = require('./_an-instance');\nvar forOf = require('./_for-of');\nvar speciesConstructor = require('./_species-constructor');\nvar task = require('./_task').set;\nvar microtask = require('./_microtask')();\nvar newPromiseCapabilityModule = require('./_new-promise-capability');\nvar perform = require('./_perform');\nvar userAgent = require('./_user-agent');\nvar promiseResolve = require('./_promise-resolve');\nvar PROMISE = 'Promise';\nvar TypeError = global.TypeError;\nvar process = global.process;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8 || '';\nvar $Promise = global[PROMISE];\nvar isNode = classof(process) == 'process';\nvar empty = function () { /* empty */ };\nvar Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;\nvar newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;\n\nvar USE_NATIVE = !!function () {\n try {\n // correct subclassing with @@species support\n var promise = $Promise.resolve(1);\n var FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function (exec) {\n exec(empty, empty);\n };\n // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n return (isNode || typeof PromiseRejectionEvent == 'function')\n && promise.then(empty) instanceof FakePromise\n // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables\n // https://bugs.chromium.org/p/chromium/issues/detail?id=830565\n // we can't detect it synchronously, so just check versions\n && v8.indexOf('6.6') !== 0\n && userAgent.indexOf('Chrome/66') === -1;\n } catch (e) { /* empty */ }\n}();\n\n// helpers\nvar isThenable = function (it) {\n var then;\n return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar notify = function (promise, isReject) {\n if (promise._n) return;\n promise._n = true;\n var chain = promise._c;\n microtask(function () {\n var value = promise._v;\n var ok = promise._s == 1;\n var i = 0;\n var run = function (reaction) {\n var handler = ok ? reaction.ok : reaction.fail;\n var resolve = reaction.resolve;\n var reject = reaction.reject;\n var domain = reaction.domain;\n var result, then, exited;\n try {\n if (handler) {\n if (!ok) {\n if (promise._h == 2) onHandleUnhandled(promise);\n promise._h = 1;\n }\n if (handler === true) result = value;\n else {\n if (domain) domain.enter();\n result = handler(value); // may throw\n if (domain) {\n domain.exit();\n exited = true;\n }\n }\n if (result === reaction.promise) {\n reject(TypeError('Promise-chain cycle'));\n } else if (then = isThenable(result)) {\n then.call(result, resolve, reject);\n } else resolve(result);\n } else reject(value);\n } catch (e) {\n if (domain && !exited) domain.exit();\n reject(e);\n }\n };\n while (chain.length > i) run(chain[i++]); // variable length - can't use forEach\n promise._c = [];\n promise._n = false;\n if (isReject && !promise._h) onUnhandled(promise);\n });\n};\nvar onUnhandled = function (promise) {\n task.call(global, function () {\n var value = promise._v;\n var unhandled = isUnhandled(promise);\n var result, handler, console;\n if (unhandled) {\n result = perform(function () {\n if (isNode) {\n process.emit('unhandledRejection', value, promise);\n } else if (handler = global.onunhandledrejection) {\n handler({ promise: promise, reason: value });\n } else if ((console = global.console) && console.error) {\n console.error('Unhandled promise rejection', value);\n }\n });\n // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n } promise._a = undefined;\n if (unhandled && result.e) throw result.v;\n });\n};\nvar isUnhandled = function (promise) {\n return promise._h !== 1 && (promise._a || promise._c).length === 0;\n};\nvar onHandleUnhandled = function (promise) {\n task.call(global, function () {\n var handler;\n if (isNode) {\n process.emit('rejectionHandled', promise);\n } else if (handler = global.onrejectionhandled) {\n handler({ promise: promise, reason: promise._v });\n }\n });\n};\nvar $reject = function (value) {\n var promise = this;\n if (promise._d) return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n promise._v = value;\n promise._s = 2;\n if (!promise._a) promise._a = promise._c.slice();\n notify(promise, true);\n};\nvar $resolve = function (value) {\n var promise = this;\n var then;\n if (promise._d) return;\n promise._d = true;\n promise = promise._w || promise; // unwrap\n try {\n if (promise === value) throw TypeError(\"Promise can't be resolved itself\");\n if (then = isThenable(value)) {\n microtask(function () {\n var wrapper = { _w: promise, _d: false }; // wrap\n try {\n then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n } catch (e) {\n $reject.call(wrapper, e);\n }\n });\n } else {\n promise._v = value;\n promise._s = 1;\n notify(promise, false);\n }\n } catch (e) {\n $reject.call({ _w: promise, _d: false }, e); // wrap\n }\n};\n\n// constructor polyfill\nif (!USE_NATIVE) {\n // 25.4.3.1 Promise(executor)\n $Promise = function Promise(executor) {\n anInstance(this, $Promise, PROMISE, '_h');\n aFunction(executor);\n Internal.call(this);\n try {\n executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n } catch (err) {\n $reject.call(this, err);\n }\n };\n // eslint-disable-next-line no-unused-vars\n Internal = function Promise(executor) {\n this._c = []; // <- awaiting reactions\n this._a = undefined; // <- checked in isUnhandled reactions\n this._s = 0; // <- state\n this._d = false; // <- done\n this._v = undefined; // <- value\n this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n this._n = false; // <- notify\n };\n Internal.prototype = require('./_redefine-all')($Promise.prototype, {\n // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n then: function then(onFulfilled, onRejected) {\n var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n reaction.fail = typeof onRejected == 'function' && onRejected;\n reaction.domain = isNode ? process.domain : undefined;\n this._c.push(reaction);\n if (this._a) this._a.push(reaction);\n if (this._s) notify(this, false);\n return reaction.promise;\n },\n // 25.4.5.1 Promise.prototype.catch(onRejected)\n 'catch': function (onRejected) {\n return this.then(undefined, onRejected);\n }\n });\n OwnPromiseCapability = function () {\n var promise = new Internal();\n this.promise = promise;\n this.resolve = ctx($resolve, promise, 1);\n this.reject = ctx($reject, promise, 1);\n };\n newPromiseCapabilityModule.f = newPromiseCapability = function (C) {\n return C === $Promise || C === Wrapper\n ? new OwnPromiseCapability(C)\n : newGenericPromiseCapability(C);\n };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });\nrequire('./_set-to-string-tag')($Promise, PROMISE);\nrequire('./_set-species')(PROMISE);\nWrapper = require('./_core')[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n // 25.4.4.5 Promise.reject(r)\n reject: function reject(r) {\n var capability = newPromiseCapability(this);\n var $$reject = capability.reject;\n $$reject(r);\n return capability.promise;\n }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n // 25.4.4.6 Promise.resolve(x)\n resolve: function resolve(x) {\n return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);\n }\n});\n$export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(function (iter) {\n $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n // 25.4.4.1 Promise.all(iterable)\n all: function all(iterable) {\n var C = this;\n var capability = newPromiseCapability(C);\n var resolve = capability.resolve;\n var reject = capability.reject;\n var result = perform(function () {\n var values = [];\n var index = 0;\n var remaining = 1;\n forOf(iterable, false, function (promise) {\n var $index = index++;\n var alreadyCalled = false;\n values.push(undefined);\n remaining++;\n C.resolve(promise).then(function (value) {\n if (alreadyCalled) return;\n alreadyCalled = true;\n values[$index] = value;\n --remaining || resolve(values);\n }, reject);\n });\n --remaining || resolve(values);\n });\n if (result.e) reject(result.v);\n return capability.promise;\n },\n // 25.4.4.4 Promise.race(iterable)\n race: function race(iterable) {\n var C = this;\n var capability = newPromiseCapability(C);\n var reject = capability.reject;\n var result = perform(function () {\n forOf(iterable, false, function (promise) {\n C.resolve(promise).then(capability.resolve, reject);\n });\n });\n if (result.e) reject(result.v);\n return capability.promise;\n }\n});\n","var dP = require('./_object-dp').f;\nvar FProto = Function.prototype;\nvar nameRE = /^\\s*function ([^ (]*)/;\nvar NAME = 'name';\n\n// 19.2.4.2 name\nNAME in FProto || require('./_descriptors') && dP(FProto, NAME, {\n configurable: true,\n get: function () {\n try {\n return ('' + this).match(nameRE)[1];\n } catch (e) {\n return '';\n }\n }\n});\n","// most Object methods by ES6 should accept primitives\nvar $export = require('./_export');\nvar core = require('./_core');\nvar fails = require('./_fails');\nmodule.exports = function (KEY, exec) {\n var fn = (core.Object || {})[KEY] || Object[KEY];\n var exp = {};\n exp[KEY] = exec(fn);\n $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp);\n};\n","// 19.1.2.14 Object.keys(O)\nvar toObject = require('./_to-object');\nvar $keys = require('./_object-keys');\n\nrequire('./_object-sap')('keys', function () {\n return function keys(it) {\n return $keys(toObject(it));\n };\n});\n","import {version} from '../../package.json';\n\nexport default 'v' + version;\n","// 7.2.8 IsRegExp(argument)\nvar isObject = require('./_is-object');\nvar cof = require('./_cof');\nvar MATCH = require('./_wks')('match');\nmodule.exports = function (it) {\n var isRegExp;\n return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');\n};\n","'use strict';\n\nvar isRegExp = require('./_is-regexp');\nvar anObject = require('./_an-object');\nvar speciesConstructor = require('./_species-constructor');\nvar advanceStringIndex = require('./_advance-string-index');\nvar toLength = require('./_to-length');\nvar callRegExpExec = require('./_regexp-exec-abstract');\nvar regexpExec = require('./_regexp-exec');\nvar fails = require('./_fails');\nvar $min = Math.min;\nvar $push = [].push;\nvar $SPLIT = 'split';\nvar LENGTH = 'length';\nvar LAST_INDEX = 'lastIndex';\nvar MAX_UINT32 = 0xffffffff;\n\n// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError\nvar SUPPORTS_Y = !fails(function () { RegExp(MAX_UINT32, 'y'); });\n\n// @@split logic\nrequire('./_fix-re-wks')('split', 2, function (defined, SPLIT, $split, maybeCallNative) {\n var internalSplit;\n if (\n 'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||\n 'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||\n 'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||\n '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||\n '.'[$SPLIT](/()()/)[LENGTH] > 1 ||\n ''[$SPLIT](/.?/)[LENGTH]\n ) {\n // based on es5-shim implementation, need to rework it\n internalSplit = function (separator, limit) {\n var string = String(this);\n if (separator === undefined && limit === 0) return [];\n // If `separator` is not a regex, use native split\n if (!isRegExp(separator)) return $split.call(string, separator, limit);\n var output = [];\n var flags = (separator.ignoreCase ? 'i' : '') +\n (separator.multiline ? 'm' : '') +\n (separator.unicode ? 'u' : '') +\n (separator.sticky ? 'y' : '');\n var lastLastIndex = 0;\n var splitLimit = limit === undefined ? MAX_UINT32 : limit >>> 0;\n // Make `global` and avoid `lastIndex` issues by working with a copy\n var separatorCopy = new RegExp(separator.source, flags + 'g');\n var match, lastIndex, lastLength;\n while (match = regexpExec.call(separatorCopy, string)) {\n lastIndex = separatorCopy[LAST_INDEX];\n if (lastIndex > lastLastIndex) {\n output.push(string.slice(lastLastIndex, match.index));\n if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));\n lastLength = match[0][LENGTH];\n lastLastIndex = lastIndex;\n if (output[LENGTH] >= splitLimit) break;\n }\n if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop\n }\n if (lastLastIndex === string[LENGTH]) {\n if (lastLength || !separatorCopy.test('')) output.push('');\n } else output.push(string.slice(lastLastIndex));\n return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;\n };\n // Chakra, V8\n } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {\n internalSplit = function (separator, limit) {\n return separator === undefined && limit === 0 ? [] : $split.call(this, separator, limit);\n };\n } else {\n internalSplit = $split;\n }\n\n return [\n // `String.prototype.split` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.split\n function split(separator, limit) {\n var O = defined(this);\n var splitter = separator == undefined ? undefined : separator[SPLIT];\n return splitter !== undefined\n ? splitter.call(separator, O, limit)\n : internalSplit.call(String(O), separator, limit);\n },\n // `RegExp.prototype[@@split]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split\n //\n // NOTE: This cannot be properly polyfilled in engines that don't support\n // the 'y' flag.\n function (regexp, limit) {\n var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== $split);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n var C = speciesConstructor(rx, RegExp);\n\n var unicodeMatching = rx.unicode;\n var flags = (rx.ignoreCase ? 'i' : '') +\n (rx.multiline ? 'm' : '') +\n (rx.unicode ? 'u' : '') +\n (SUPPORTS_Y ? 'y' : 'g');\n\n // ^(? + rx + ) is needed, in combination with some S slicing, to\n // simulate the 'y' flag.\n var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);\n var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n if (lim === 0) return [];\n if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];\n var p = 0;\n var q = 0;\n var A = [];\n while (q < S.length) {\n splitter.lastIndex = SUPPORTS_Y ? q : 0;\n var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));\n var e;\n if (\n z === null ||\n (e = $min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p\n ) {\n q = advanceStringIndex(S, q, unicodeMatching);\n } else {\n A.push(S.slice(p, q));\n if (A.length === lim) return A;\n for (var i = 1; i <= z.length - 1; i++) {\n A.push(z[i]);\n if (A.length === lim) return A;\n }\n q = p = e;\n }\n }\n A.push(S.slice(p));\n return A;\n }\n ];\n});\n","/*jshint worker: true*/\n\n// WorkerBroker routes messages between web workers and the main thread, allowing for simpler\n// async code via promises. Example usage:\n//\n// In web worker, register self as a callable \"target\", and define a method:\n//\n// WorkerBroker.addTarget('self', self);\n//\n// self.square = function (x) {\n// return x * x;\n// };\n//\n// In main thread, invoke that method and receive the result (if any) as a promise.\n//\n// worker = new Worker(...);\n// WorkerBroker.addWorker(worker);\n//\n// WorkerBroker.postMessage(worker, 'self.square', 5).then(function(y) {\n// console.log(y);\n// });\n//\n// -> prints 25\n//\n// Async code:\n//\n// For synchronous code that must pass a return value to the main thread, the function can simply\n// return an immediate value (see example above). For cases where the worker method needs to run\n// asynchronous code, the function can return a promise, and the resolved or rejected value will\n// be sent back to the main thread when the promise is fulfilled.\n//\n// Error handling:\n//\n// If the worker method either throws an error, or returns a promise that is rejected, it will be\n// sent back to the main thread as a promise rejection. These two examples are equivalent:\n//\n// In worker, throwing an error:\n//\n// self.broken = function () {\n// throw new Error('error in worker!');\n// };\n//\n// In worker, returning a rejected promise:\n//\n// self.broken = function () {\n// return Promise.reject(new Error('error in worker!'));\n// };\n//\n// In main thread, both errors are received as a promise rejection:\n//\n// WorkerBroker.postMessage(worker, 'self.broken').then(\n// // Promise resolved\n// function() {\n// console.log('success!');\n// },\n// // Promise rejected\n// function(error) {\n// console.log('error!', error);\n// });\n//\n// -> prints 'error! error in worker'\n//\n// Calling from worker to main thread:\n//\n// The same style of calls can be made *from* a web worker, to the main thread. The API is the same\n// with the exception that the first argument, 'worker', is not needed for WorkerBroker.postMessage(),\n// since the main thread is the implicit target.\n//\n// In main thread, define a method and register it:\n//\n// var geometry = {\n// length: function(x, y) {\n// return Math.sqrt(x * x + y * y);\n// }\n// };\n//\n// WorkerBroker.addTarget('geometry', geometry);\n//\n// In worker thread):\n//\n// WorkerBroker.postMessage('geometry.length', 3, 4).then(function(d) {\n// console.log(d);\n// });\n//\n// -> prints 5\n//\n\nimport Thread from './thread';\nimport log from './log';\n\nvar WorkerBroker;\nexport default WorkerBroker = {};\n\n// Global list of all worker messages\n// Uniquely tracks every call made between main thread and a worker\nvar message_id = 0;\nvar messages = {};\n\n// Register an object to receive calls from other thread\nWorkerBroker.targets = {};\nWorkerBroker.addTarget = function (name, target) {\n WorkerBroker.targets[name] = target;\n};\n\nWorkerBroker.removeTarget = function (name) {\n if (name) {\n delete WorkerBroker.targets[name];\n }\n};\n\n// Given a dot-notation-style method name, e.g. 'Object.object.method',\n// find the object to call the method on from the list of registered targets\nfunction findTarget (method) {\n var chain = [];\n if (typeof method === 'string') {\n chain = method.split('.');\n method = chain.pop();\n }\n\n var target = WorkerBroker.targets;\n\n for (let m=0; m < chain.length; m++) {\n if (target[chain[m]]) {\n target = target[chain[m]];\n }\n else {\n return [];\n }\n }\n\n return [method, target];\n}\n\n// Main thread:\n// - Send messages to workers, and optionally receive an async response as a promise\n// - Receive messages from workers, and optionally send an async response back as a promise\nfunction setupMainThread () {\n\n // Send a message to a worker, and optionally get an async response\n // Arguments:\n // - worker: one or more web worker instances to send the message to (single value or array)\n // - method: the method with this name, specified with dot-notation, will be invoked in the worker\n // - message: spread of arguments to call the method with\n // Returns:\n // - a promise that will be fulfilled if the worker method returns a value (could be immediately, or async)\n //\n WorkerBroker.postMessage = function (worker, method, ...message) {\n // If more than one worker specified, post to multiple\n if (Array.isArray(worker)) {\n return Promise.all(\n worker.map(w => WorkerBroker.postMessage(w, method, ...message))\n );\n }\n\n // Parse options\n let options = {};\n if (typeof method === 'object') {\n options = method;\n method = method.method;\n }\n\n // Track state of this message\n var promise = new Promise((resolve, reject) => {\n messages[message_id] = { method, message, resolve, reject };\n });\n\n\n let payload, transferables = [];\n\n if (message && message.length === 1 && message[0] instanceof WorkerBroker.withTransferables) {\n transferables = message[0].transferables;\n message = message[0].value;\n }\n\n payload = {\n type: 'main_send', // mark message as method invocation from main thread\n message_id, // unique id for this message, for life of program\n method, // will dispatch to a function of this name within the worker\n message // message payload\n };\n\n if (options.stringify) {\n payload = JSON.stringify(payload);\n }\n\n worker.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method}' transferred ${transferables.length} objects to worker thread`);\n }\n\n message_id++;\n return promise;\n };\n\n // Add a worker to communicate with - each worker must be registered from the main thread\n WorkerBroker.addWorker = function (worker) {\n if (!(worker instanceof Worker)) {\n throw Error('Worker broker could not add non-Worker object', worker);\n }\n\n worker.addEventListener('message', function WorkerBrokerMainThreadHandler(event) {\n let data = ((typeof event.data === 'string') ? JSON.parse(event.data) : event.data);\n let id = data.message_id;\n\n // Listen for messages coming back from the worker, and fulfill that message's promise\n if (data.type === 'worker_reply') {\n // Pass the result to the promise\n if (messages[id]) {\n if (data.error) {\n messages[id].reject(data.error);\n }\n else {\n messages[id].resolve(data.message);\n }\n delete messages[id];\n }\n }\n // Listen for messages initiating a call from the worker, dispatch them,\n // and send any return value back to the worker\n // Unique id for this message & return call to main thread\n else if (data.type === 'worker_send' && id != null) {\n // Call the requested method and save the return value\n let result, error, target, method_name, method;\n try {\n [method_name, target] = findTarget(data.method);\n if (!target) {\n throw Error(`Worker broker could not dispatch message type ${data.method} on target ${data.target} because no object with that name is registered on main thread`);\n }\n\n method = (typeof target[method_name] === 'function') && target[method_name];\n if (!method) {\n throw Error(`Worker broker could not dispatch message type ${data.method} on target ${data.target} because object has no method with that name`);\n }\n\n result = method.apply(target, data.message);\n }\n catch(e) {\n // Thrown errors will be passed back (in string form) to worker\n error = e;\n\n }\n // Send return value to worker\n let payload, transferables = [];\n\n // Async result\n if (result instanceof Promise) {\n result.then((value) => {\n if (value instanceof WorkerBroker.withTransferables) {\n transferables = value.transferables;\n value = value.value[0];\n }\n\n payload = {\n type: 'main_reply',\n message_id: id,\n message: value\n };\n worker.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to worker thread`);\n }\n\n }, (error) => {\n worker.postMessage({\n type: 'main_reply',\n message_id: id,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n });\n });\n }\n // Immediate result\n else {\n if (result instanceof WorkerBroker.withTransferables) {\n transferables = result.transferables;\n result = result.value[0];\n }\n\n payload = {\n type: 'main_reply',\n message_id: id,\n message: result,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n };\n worker.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to worker thread`);\n }\n }\n }\n });\n\n };\n\n // Expose for debugging\n WorkerBroker.getMessages = function () {\n return messages;\n };\n\n WorkerBroker.getMessageId = function () {\n return message_id;\n };\n\n}\n\n// Worker threads:\n// - Receive messages from main thread, and optionally send an async response back as a promise\n// - Send messages to main thread, and optionally receive an async response as a promise\nfunction setupWorkerThread () {\n\n // Send a message to the main thread, and optionally get an async response as a promise\n // Arguments:\n // - method: the method with this name, specified with dot-notation, will be invoked on the main thread\n // - message: array of arguments to call the method with\n // Returns:\n // - a promise that will be fulfilled if the main thread method returns a value (could be immediately, or async)\n //\n WorkerBroker.postMessage = function (method, ...message) {\n // Parse options\n let options = {};\n if (typeof method === 'object') {\n options = method;\n method = method.method;\n }\n\n // Track state of this message\n var promise = new Promise((resolve, reject) => {\n messages[message_id] = { method, message, resolve, reject };\n });\n\n let payload, transferables = [];\n\n if (message && message.length === 1 && message[0] instanceof WorkerBroker.withTransferables) {\n transferables = message[0].transferables;\n message = message[0].value;\n }\n\n payload = {\n type: 'worker_send', // mark message as method invocation from worker\n message_id, // unique id for this message, for life of program\n method, // will dispatch to a method of this name on the main thread\n message // message payload\n };\n\n if (options.stringify) {\n payload = JSON.stringify(payload);\n }\n\n self.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method}' transferred ${transferables.length} objects to main thread`);\n }\n\n message_id++;\n return promise;\n };\n\n self.addEventListener('message', function WorkerBrokerWorkerThreadHandler(event) {\n let data = ((typeof event.data === 'string') ? JSON.parse(event.data) : event.data);\n let id = data.message_id;\n\n // Listen for messages coming back from the main thread, and fulfill that message's promise\n if (data.type === 'main_reply') {\n // Pass the result to the promise\n if (messages[id]) {\n if (data.error) {\n messages[id].reject(data.error);\n }\n else {\n messages[id].resolve(data.message);\n }\n delete messages[id];\n }\n }\n // Receive messages from main thread, dispatch them, and send back a reply\n // Unique id for this message & return call to main thread\n else if (data.type === 'main_send' && id != null) {\n // Call the requested worker method and save the return value\n let result, error, target, method_name, method;\n try {\n [method_name, target] = findTarget(data.method);\n if (!target) {\n throw Error(`Worker broker could not dispatch message type ${data.method} on target ${data.target} because no object with that name is registered on main thread`);\n }\n\n method = (typeof target[method_name] === 'function') && target[method_name];\n\n if (!method) {\n throw Error(`Worker broker could not dispatch message type ${data.method} because worker has no method with that name`);\n }\n\n result = method.apply(target, data.message);\n }\n catch(e) {\n // Thrown errors will be passed back (in string form) to main thread\n error = e;\n }\n\n // Send return value to main thread\n let payload, transferables = [];\n\n // Async result\n if (result instanceof Promise) {\n result.then((value) => {\n if (value instanceof WorkerBroker.withTransferables) {\n transferables = value.transferables;\n value = value.value[0];\n }\n\n payload = {\n type: 'worker_reply',\n message_id: id,\n message: value\n };\n self.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to main thread`);\n }\n }, (error) => {\n self.postMessage({\n type: 'worker_reply',\n message_id: id,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n });\n });\n }\n // Immediate result\n else {\n if (result instanceof WorkerBroker.withTransferables) {\n transferables = result.transferables;\n result = result.value[0];\n }\n\n payload = {\n type: 'worker_reply',\n message_id: id,\n message: result,\n error: (error instanceof Error ? `${error.message}: ${error.stack}` : error)\n };\n self.postMessage(payload, transferables.map(t => t.object));\n freeTransferables(transferables);\n if (transferables.length > 0) {\n log('trace', `'${method_name}' transferred ${transferables.length} objects to main thread`);\n }\n }\n }\n });\n\n}\n\n// Special value wrapper, to indicate that we want to find and include transferable objects in the message\nWorkerBroker.withTransferables = function (...value) {\n if (!(this instanceof WorkerBroker.withTransferables)) {\n return new WorkerBroker.withTransferables(...value);\n }\n\n this.value = value;\n this.transferables = findTransferables(this.value);\n};\n\n// Build a list of transferable objects from a source object\n// Returns a list of info about each transferable:\n// - object: the actual transferable object\n// - parent: the parent object that the transferable is a property of (if any)\n// - property: the property name of the transferable on the parent object (if any)\n// TODO: add option in case you DON'T want to transfer objects\nfunction findTransferables(source, parent = null, property = null, list = []) {\n if (!source) {\n return list;\n }\n\n if (Array.isArray(source)) {\n // Check each array element\n source.forEach((x, i) => findTransferables(x, source, i, list));\n }\n else if (typeof source === 'object') {\n // Is the object a transferable array buffer?\n if (source instanceof ArrayBuffer) {\n list.push({ object: source, parent, property });\n }\n // Or looks like a typed array (has an array buffer property)?\n else if (source.buffer instanceof ArrayBuffer) {\n list.push({ object: source.buffer, parent, property });\n }\n // Otherwise check each property\n else {\n for (let prop in source) {\n findTransferables(source[prop], source, prop, list);\n }\n }\n }\n return list;\n}\n\n// Remove neutered transferables from parent objects, as they should no longer be accessed after transfer\nfunction freeTransferables(transferables) {\n if (!Array.isArray(transferables)) {\n return;\n }\n transferables.filter(t => t.parent && t.property).forEach(t => delete t.parent[t.property]);\n}\n\n// Setup this thread as appropriate\nif (Thread.is_main) {\n setupMainThread();\n}\n\nif (Thread.is_worker) {\n setupWorkerThread();\n}\n","import version from './version';\nimport Thread from './thread';\nimport WorkerBroker from './worker_broker';\n\nconst LEVELS = {\n silent: -1,\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4\n};\n\nconst methods = {};\nlet logged_once = {};\n\nfunction methodForLevel (level) {\n if (Thread.is_main) {\n methods[level] = methods[level] || (console[level] ? console[level] : console.log).bind(console); // eslint-disable-line no-console\n return methods[level];\n }\n}\n\n// Logs message, proxying any log requests from worker threads back to the main thread.\n// Returns (asynchronously, due to proxying) a boolean indicating if the message was logged.\n// Option `once: true` can be used to only log each unique log message once (e.g. for warnings\n// that would otherwise be repetitive or possibly logged thousands of times, such as per feature).\nexport default function log (opts, ...msg) {\n let level = (typeof opts === 'object') ? opts.level : opts;\n if (LEVELS[level] <= LEVELS[log.level]) {\n if (Thread.is_worker) {\n // Proxy to main thread\n return WorkerBroker.postMessage({ method: '_logProxy', stringify: true }, opts, ...msg);\n }\n else {\n // Only log message once?\n if (typeof opts === 'object' && opts.once === true) {\n if (logged_once[JSON.stringify(msg)]) {\n return Promise.resolve(false);\n }\n logged_once[JSON.stringify(msg)] = true;\n }\n\n // Write to console (on main thread)\n let logger = methodForLevel(level);\n if (msg.length > 1) {\n logger(`Tangram ${version} [${level}]: ${msg[0]}`, ...msg.slice(1));\n }\n else {\n logger(`Tangram ${version} [${level}]: ${msg[0]}`);\n }\n }\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n}\n\nlog.level = 'info';\nlog.workers = null;\n\nlog.setLevel = function (level) {\n log.level = level;\n\n if (Thread.is_main && Array.isArray(log.workers)) {\n WorkerBroker.postMessage(log.workers, '_logSetLevelProxy', level);\n }\n};\n\nif (Thread.is_main) {\n log.setWorkers = function (workers) {\n log.workers = workers;\n };\n\n log.reset = function () {\n logged_once = {};\n };\n}\n\nWorkerBroker.addTarget('_logProxy', log); // proxy log messages from worker to main thread\nWorkerBroker.addTarget('_logSetLevelProxy', log.setLevel); // proxy log level setting from main to worker thread\n","// 21.2.5.3 get RegExp.prototype.flags()\nif (require('./_descriptors') && /./g.flags != 'g') require('./_object-dp').f(RegExp.prototype, 'flags', {\n configurable: true,\n get: require('./_flags')\n});\n","'use strict';\nrequire('./es6.regexp.flags');\nvar anObject = require('./_an-object');\nvar $flags = require('./_flags');\nvar DESCRIPTORS = require('./_descriptors');\nvar TO_STRING = 'toString';\nvar $toString = /./[TO_STRING];\n\nvar define = function (fn) {\n require('./_redefine')(RegExp.prototype, TO_STRING, fn, true);\n};\n\n// 21.2.5.14 RegExp.prototype.toString()\nif (require('./_fails')(function () { return $toString.call({ source: 'a', flags: 'b' }) != '/a/b'; })) {\n define(function toString() {\n var R = anObject(this);\n return '/'.concat(R.source, '/',\n 'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);\n });\n// FF44- RegExp#toString has a wrong name\n} else if ($toString.name != TO_STRING) {\n define(function toString() {\n return $toString.call(this);\n });\n}\n","// Miscellaneous geo functions\n\nvar Geo;\nexport default Geo = {};\n\n// Projection constants\nGeo.default_source_max_zoom = 18;\nGeo.default_view_max_zoom = 20;\nGeo.max_style_zoom = 25; // max zoom at which styles will be evaluated\nGeo.tile_size = 256;\nGeo.half_circumference_meters = 20037508.342789244;\nGeo.circumference_meters = Geo.half_circumference_meters * 2;\nGeo.min_zoom_meters_per_pixel = Geo.circumference_meters / Geo.tile_size; // min zoom draws world as 2 tiles wide\n\nlet meters_per_pixel = [];\nGeo.metersPerPixel = function (z) {\n meters_per_pixel[z] = meters_per_pixel[z] || Geo.min_zoom_meters_per_pixel / Math.pow(2, z);\n return meters_per_pixel[z];\n};\n\nlet meters_per_tile = [];\nGeo.metersPerTile = function (z) {\n meters_per_tile[z] = meters_per_tile[z] || Geo.circumference_meters / Math.pow(2, z);\n return meters_per_tile[z];\n};\n\n// Conversion functions based on an defined tile scale\nGeo.tile_scale = 4096; // coordinates are locally scaled to the range [0, tile_scale]\nGeo.units_per_pixel = Geo.tile_scale / Geo.tile_size;\nGeo.height_scale = 16; // provides sub-meter precision for height values (16ths of a meters)\n\nlet units_per_meter = [];\nGeo.unitsPerMeter = function (z) {\n units_per_meter[z] = units_per_meter[z] || Geo.tile_scale / (Geo.tile_size * Geo.metersPerPixel(z));\n return units_per_meter[z];\n};\n\n// Convert tile location to mercator meters - multiply by pixels per tile, then by meters per pixel, adjust for map origin\nGeo.metersForTile = function (tile) {\n return {\n x: tile.x * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters,\n y: -(tile.y * Geo.circumference_meters / Math.pow(2, tile.z) - Geo.half_circumference_meters)\n };\n};\n\n/**\n Given a point in mercator meters and a zoom level, return the tile X/Y/Z that the point lies in\n*/\nGeo.tileForMeters = function ([x, y], zoom) {\n return {\n x: Math.floor((x + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))),\n y: Math.floor((-y + Geo.half_circumference_meters) / (Geo.circumference_meters / Math.pow(2, zoom))),\n z: zoom\n };\n};\n\n// Wrap a tile to positive #s for zoom\n// Optionally specify the axes to wrap\nGeo.wrapTile = function({ x, y, z }, mask = { x: true, y: false }) {\n var m = (1 << z) - 1;\n if (mask.x) {\n x = x & m;\n }\n if (mask.y) {\n y = y & m;\n }\n return { x, y, z };\n};\n\n/**\n Convert mercator meters to lat-lng\n*/\nGeo.metersToLatLng = function ([x, y]) {\n\n x /= Geo.half_circumference_meters;\n y /= Geo.half_circumference_meters;\n\n y = (2 * Math.atan(Math.exp(y * Math.PI)) - (Math.PI / 2)) / Math.PI;\n\n x *= 180;\n y *= 180;\n\n return [x, y];\n};\n\n/**\n Convert lat-lng to mercator meters\n*/\nGeo.latLngToMeters = function([x, y]) {\n\n // Latitude\n y = Math.log(Math.tan(y*Math.PI/360 + Math.PI/4)) / Math.PI;\n y *= Geo.half_circumference_meters;\n\n // Longitude\n x *= Geo.half_circumference_meters / 180;\n\n return [x, y];\n};\n\n// Transform from local tile coordinats to lat lng\nGeo.tileSpaceToLatlng = function (geometry, z, min) {\n const units_per_meter = Geo.unitsPerMeter(z);\n Geo.transformGeometry(geometry, coord => {\n coord[0] = (coord[0] / units_per_meter) + min.x;\n coord[1] = (coord[1] / units_per_meter) + min.y;\n\n let [x, y] = Geo.metersToLatLng(coord);\n coord[0] = x;\n coord[1] = y;\n });\n return geometry;\n};\n\n// Copy GeoJSON geometry\nGeo.copyGeometry = function (geometry) {\n if (geometry == null) {\n return; // skip if missing geometry (valid GeoJSON)\n }\n\n let copy = { type: geometry.type };\n\n if (geometry.type === 'Point') {\n copy.coordinates = [geometry.coordinates[0], geometry.coordinates[1]];\n }\n else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') {\n copy.coordinates = geometry.coordinates.map(c => [c[0], c[1]]);\n }\n else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') {\n copy.coordinates = geometry.coordinates.map(ring => ring.map(c => [c[0], c[1]]));\n }\n else if (geometry.type === 'MultiPolygon') {\n copy.coordinates = geometry.coordinates.map(polygon => {\n return polygon.map(ring => ring.map(c => [c[0], c[1]]));\n });\n }\n // TODO: support GeometryCollection\n return copy;\n};\n\n// Run an in-place transform function on each cooordinate in a GeoJSON geometry\nGeo.transformGeometry = function (geometry, transform) {\n if (geometry == null) {\n return; // skip if missing geometry (valid GeoJSON)\n }\n\n if (geometry.type === 'Point') {\n transform(geometry.coordinates);\n }\n else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') {\n geometry.coordinates.forEach(transform);\n }\n else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') {\n geometry.coordinates.forEach(ring => ring.forEach(transform));\n }\n else if (geometry.type === 'MultiPolygon') {\n geometry.coordinates.forEach(polygon => {\n polygon.forEach(ring => ring.forEach(transform));\n });\n }\n // TODO: support GeometryCollection\n};\n\nGeo.boxIntersect = function (b1, b2) {\n return !(\n b2.sw.x > b1.ne.x ||\n b2.ne.x < b1.sw.x ||\n b2.sw.y > b1.ne.y ||\n b2.ne.y < b1.sw.y\n );\n};\n\n// Finds the axis-aligned bounding box for a polygon\nGeo.findBoundingBox = function (polygon) {\n var min_x = Infinity,\n max_x = -Infinity,\n min_y = Infinity,\n max_y = -Infinity;\n\n // Only need to examine outer ring (polygon[0])\n var num_coords = polygon[0].length;\n for (var c=0; c < num_coords; c++) {\n var coord = polygon[0][c];\n\n if (coord[0] < min_x) {\n min_x = coord[0];\n }\n if (coord[1] < min_y) {\n min_y = coord[1];\n }\n if (coord[0] > max_x) {\n max_x = coord[0];\n }\n if (coord[1] > max_y) {\n max_y = coord[1];\n }\n }\n\n return [min_x, min_y, max_x, max_y];\n};\n\n// Convert geometry type to one of: 'point', 'line', 'polygon'\nGeo.geometryType = function(type) {\n if (type === 'Polygon' || type === 'MultiPolygon') {\n return 'polygon';\n }\n else if (type === 'LineString' || type === 'MultiLineString') {\n return 'line';\n }\n if (type === 'Point' || type === 'MultiPoint') {\n return 'point';\n }\n};\n\n// Geometric / weighted centroid of polygon\n// Adapted from https://github.com/Leaflet/Leaflet/blob/c10f405a112142b19785967ce0e142132a6095ad/src/layer/vector/Polygon.js#L57\nGeo.centroid = function (polygon, relative = true) {\n if (!polygon || polygon.length === 0) {\n return;\n }\n\n let x = 0, y = 0, area = 0;\n let ring = polygon[0]; // only use first ring for now\n let len = ring.length;\n\n // optionally calculate relative to first coordinate to avoid precision issues w/small polygons\n let origin;\n if (relative) {\n origin = ring[0];\n ring = ring.map(v => [v[0] - origin[0], v[1] - origin[1]]);\n }\n\n for (let i = 0, j = len - 1; i < len; j = i, i++) {\n let p0 = ring[i];\n let p1 = ring[j];\n let f = p0[1] * p1[0] - p1[1] * p0[0];\n\n x += (p0[0] + p1[0]) * f;\n y += (p0[1] + p1[1]) * f;\n area += f * 3;\n }\n\n if (!area) {\n return; // skip degenerate polygons\n }\n\n let c = [x / area, y / area];\n if (relative) {\n c[0] += origin[0];\n c[1] += origin[1];\n }\n return c;\n};\n\nGeo.multiCentroid = function (polygons) {\n let n = 0;\n let centroid = null;\n\n for (let p=0; p < polygons.length; p++) {\n let c = Geo.centroid(polygons[p]);\n if (c) { // skip degenerate polygons\n centroid = centroid || [0, 0];\n centroid[0] += c[0];\n centroid[1] += c[1];\n n++;\n }\n }\n\n if (n > 0) {\n centroid[0] /= n;\n centroid[1] /= n;\n }\n\n return centroid; // will return null if all polygons were degenerate\n};\n\nGeo.signedPolygonRingAreaSum = function (ring) {\n let area = 0;\n let n = ring.length;\n\n for (let i = 0; i < n - 1; i++) {\n let p0 = ring[i];\n let p1 = ring[i+1];\n\n area += p0[0] * p1[1] - p1[0] * p0[1];\n }\n\n area += ring[n - 1][0] * ring[0][1] - ring[0][0] * ring[n - 1][1];\n return area;\n};\n\nGeo.polygonRingArea = function (ring) {\n return Math.abs(Geo.signedPolygonRingAreaSum(ring)) / 2;\n};\n\n// TODO: subtract inner rings\nGeo.polygonArea = function (polygon) {\n if (!polygon) {\n return;\n }\n return Geo.polygonRingArea(polygon[0]);\n};\n\nGeo.multiPolygonArea = function (polygons) {\n let area = 0;\n\n for (let p=0; p < polygons.length; p++) {\n area += Geo.polygonArea(polygons[p]);\n }\n\n return area;\n};\n\nGeo.ringWinding = function (ring) {\n let area = Geo.signedPolygonRingAreaSum(ring);\n if (area > 0) {\n return 'CW';\n }\n else if (area < 0) {\n return 'CCW';\n }\n // return undefined on zero area polygon\n};\n","// Miscellaneous utilities\n/*jshint worker: true*/\n\nimport log from './log';\nimport Thread from './thread';\nimport WorkerBroker from './worker_broker';\nimport Geo from './geo';\n\nexport default Utils;\n\nconst Utils = {};\n\nWorkerBroker.addTarget('Utils', Utils);\n\n// Basic Safari detection\n// http://stackoverflow.com/questions/7944460/detect-safari-browser\nUtils.isSafari = function () {\n return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n};\n\n// Basic IE11 or Edge detection\nUtils.isMicrosoft = function () {\n return /(Trident\\/7.0|Edge[ /](\\d+[.\\d]+))/i.test(navigator.userAgent);\n};\n\nUtils._requests = {}; // XHR requests on current thread\nUtils._proxy_requests = {}; // XHR requests proxied to main thread\n\n// `request_key` is a user-provided key that can be later used to cancel the request\nUtils.io = function (url, timeout = 60000, responseType = 'text', method = 'GET', headers = {}, request_key = null, proxy = false) {\n if (Thread.is_worker && Utils.isMicrosoft()) {\n // Some versions of IE11 and Edge will hang web workers when performing XHR requests\n // These requests can be proxied through the main thread\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9545866/\n log('debug', 'Proxying request for URL to worker', url);\n\n if (request_key) {\n Utils._proxy_requests[request_key] = true; // mark as proxied\n }\n return WorkerBroker.postMessage('Utils.io', url, timeout, responseType, method, headers, request_key, true);\n }\n else {\n var request = new XMLHttpRequest();\n var promise = new Promise((resolve, reject) => {\n request.open(method, url, true);\n request.timeout = timeout;\n request.responseType = responseType;\n\n // Attach optional request headers\n if (headers && typeof headers === 'object') {\n for (let key in headers) {\n request.setRequestHeader(key, headers[key]);\n }\n }\n\n request.onload = () => {\n if (request.status === 200) {\n if (['text', 'json'].indexOf(request.responseType) > -1) {\n resolve(request.responseText);\n }\n else {\n resolve(request.response);\n }\n } else {\n reject(Error('Request error with a status of ' + request.statusText));\n }\n };\n request.onerror = (evt) => {\n reject(Error('There was a network error' + evt.toString()));\n };\n request.ontimeout = (evt) => {\n reject(Error('timeout '+ evt.toString()));\n };\n request.send();\n });\n\n promise = promise.then(response => {\n if (request_key) {\n delete Utils._requests[request_key];\n }\n\n if (proxy) {\n return WorkerBroker.withTransferables(response);\n }\n return response;\n });\n\n if (request_key) {\n Utils._requests[request_key] = request;\n }\n\n return promise;\n }\n};\n\n// Çancel a pending network request by user-provided request key\nUtils.cancelRequest = function (key) {\n // Check for a request that was proxied to the main thread\n if (Thread.is_worker && Utils._proxy_requests[key]) {\n return WorkerBroker.postMessage('Utils.cancelRequest', key); // forward to main thread\n }\n\n let req = Utils._requests[key];\n if (req) {\n log('trace', `Cancelling network request key '${key}'`);\n Utils._requests[key].abort();\n delete Utils._requests[key];\n }\n else {\n log('trace', `Could not find network request key '${key}'`);\n }\n};\n\n// Stringify an object into JSON, but convert functions to strings\nUtils.serializeWithFunctions = function (obj) {\n if (typeof obj === 'function') {\n return obj.toString();\n }\n\n let serialized = JSON.stringify(obj, function(k, v) {\n // Convert functions to strings\n if (typeof v === 'function') {\n return v.toString();\n }\n return v;\n });\n\n return serialized;\n};\n\n// Default to allowing high pixel density\n// Returns true if display density changed\nUtils.use_high_density_display = true;\nUtils.updateDevicePixelRatio = function () {\n let prev = Utils.device_pixel_ratio;\n Utils.device_pixel_ratio = (Utils.use_high_density_display && window.devicePixelRatio) || 1;\n return Utils.device_pixel_ratio !== prev;\n};\n\nif (Thread.is_main) {\n Utils.updateDevicePixelRatio();\n}\n\n// Used for differentiating between power-of-2 and non-power-of-2 textures\n// Via: http://stackoverflow.com/questions/19722247/webgl-wait-for-texture-to-load\nUtils.isPowerOf2 = function(value) {\n return (value & (value - 1)) === 0;\n};\n\n// Interpolate 'x' along a series of control points\n// 'points' is an array of control points in the form [x, y]\n//\n// Example:\n// Control points:\n// [0, 5]: when x=0, y=5\n// [4, 10]: when x=4, y=10\n//\n// Utils.interpolate(2, [[0, 5], [4, 10]]);\n// -> computes x=2, halfway between x=0 and x=4: (10 - 5) / 2 +5\n// -> returns 7.5\n//\n// TODO: add other interpolation methods besides linear\n//\nUtils.interpolate = function(x, points, transform) {\n // If this doesn't resemble a list of control points, just return the original value\n if (!Array.isArray(points) || !Array.isArray(points[0])) {\n return points;\n }\n else if (points.length < 1) {\n return points;\n }\n\n var x1, x2, d, y, y1, y2;\n\n // Min bounds\n if (x <= points[0][0]) {\n y = points[0][1];\n if (typeof transform === 'function') {\n y = transform(y);\n }\n }\n // Max bounds\n else if (x >= points[points.length-1][0]) {\n y = points[points.length-1][1];\n if (typeof transform === 'function') {\n y = transform(y);\n }\n }\n // Find which control points x is between\n else {\n for (var i=0; i < points.length - 1; i++) {\n if (x >= points[i][0] && x < points[i+1][0]) {\n // Linear interpolation\n x1 = points[i][0];\n x2 = points[i+1][0];\n\n // Multiple values\n if (Array.isArray(points[i][1])) {\n y = [];\n for (var c=0; c < points[i][1].length; c++) {\n if (typeof transform === 'function') {\n y1 = transform(points[i][1][c]);\n y2 = transform(points[i+1][1][c]);\n d = y2 - y1;\n y[c] = d * (x - x1) / (x2 - x1) + y1;\n }\n else {\n d = points[i+1][1][c] - points[i][1][c];\n y[c] = d * (x - x1) / (x2 - x1) + points[i][1][c];\n }\n }\n }\n // Single value\n else {\n if (typeof transform === 'function') {\n y1 = transform(points[i][1]);\n y2 = transform(points[i+1][1]);\n d = y2 - y1;\n y = d * (x - x1) / (x2 - x1) + y1;\n }\n else {\n d = points[i+1][1] - points[i][1];\n y = d * (x - x1) / (x2 - x1) + points[i][1];\n }\n }\n break;\n }\n }\n }\n return y;\n};\n\nUtils.toCSSColor = function (color) {\n if (color[3] === 1) { // full opacity\n return `rgb(${color.slice(0, 3).map(c => Math.round(c * 255)).join(', ')})`;\n }\n // RGB is between [0, 255] opacity is between [0, 1]\n return `rgba(${color.map((c, i) => (i < 3 && Math.round(c * 255)) || c).join(', ')})`;\n};\n\nUtils.pointInTile = function (point) {\n return point[0] >= 0 && point[1] > -Geo.tile_scale && point[0] < Geo.tile_scale && point[1] <= 0;\n};\n","let debugSettings;\n\nexport default debugSettings = {\n // draws a blue rectangle border around the collision box of a label\n draw_label_collision_boxes: false,\n\n // draws a green rectangle border within the texture box of a label\n draw_label_texture_boxes: false,\n\n // suppreses fade-in of labels\n suppress_label_fade_in: false,\n\n // suppress animaton of label snap to pixel grid\n suppress_label_snap_animation: false,\n\n // show hidden labels for debugging\n show_hidden_labels: false,\n\n // collect feature/geometry stats on styling layers\n layer_stats: false\n};\n\nexport function mergeDebugSettings (settings) {\n Object.assign(debugSettings, settings);\n}\n","// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nvar isObject = require('./_is-object');\nvar anObject = require('./_an-object');\nvar check = function (O, proto) {\n anObject(O);\n if (!isObject(proto) && proto !== null) throw TypeError(proto + \": can't set as prototype!\");\n};\nmodule.exports = {\n set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line\n function (test, buggy, set) {\n try {\n set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);\n set(test, []);\n buggy = !(test instanceof Array);\n } catch (e) { buggy = true; }\n return function setPrototypeOf(O, proto) {\n check(O, proto);\n if (buggy) O.__proto__ = proto;\n else set(O, proto);\n return O;\n };\n }({}, false) : undefined),\n check: check\n};\n","var isObject = require('./_is-object');\nvar setPrototypeOf = require('./_set-proto').set;\nmodule.exports = function (that, target, C) {\n var S = target.constructor;\n var P;\n if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {\n setPrototypeOf(that, P);\n } return that;\n};\n","var global = require('./_global');\nvar inheritIfRequired = require('./_inherit-if-required');\nvar dP = require('./_object-dp').f;\nvar gOPN = require('./_object-gopn').f;\nvar isRegExp = require('./_is-regexp');\nvar $flags = require('./_flags');\nvar $RegExp = global.RegExp;\nvar Base = $RegExp;\nvar proto = $RegExp.prototype;\nvar re1 = /a/g;\nvar re2 = /a/g;\n// \"new\" creates a new object, old webkit buggy here\nvar CORRECT_NEW = new $RegExp(re1) !== re1;\n\nif (require('./_descriptors') && (!CORRECT_NEW || require('./_fails')(function () {\n re2[require('./_wks')('match')] = false;\n // RegExp constructor can alter flags and IsRegExp works correct with @@match\n return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';\n}))) {\n $RegExp = function RegExp(p, f) {\n var tiRE = this instanceof $RegExp;\n var piRE = isRegExp(p);\n var fiU = f === undefined;\n return !tiRE && piRE && p.constructor === $RegExp && fiU ? p\n : inheritIfRequired(CORRECT_NEW\n ? new Base(piRE && !fiU ? p.source : p, f)\n : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)\n , tiRE ? this : proto, $RegExp);\n };\n var proxy = function (key) {\n key in $RegExp || dP($RegExp, key, {\n configurable: true,\n get: function () { return Base[key]; },\n set: function (it) { Base[key] = it; }\n });\n };\n for (var keys = gOPN(Base), i = 0; keys.length > i;) proxy(keys[i++]);\n proto.constructor = $RegExp;\n $RegExp.prototype = proto;\n require('./_redefine')(global, 'RegExp', $RegExp);\n}\n\nrequire('./_set-species')('RegExp');\n","// 7.2.9 SameValue(x, y)\nmodule.exports = Object.is || function is(x, y) {\n // eslint-disable-next-line no-self-compare\n return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;\n};\n","'use strict';\n\nvar anObject = require('./_an-object');\nvar sameValue = require('./_same-value');\nvar regExpExec = require('./_regexp-exec-abstract');\n\n// @@search logic\nrequire('./_fix-re-wks')('search', 1, function (defined, SEARCH, $search, maybeCallNative) {\n return [\n // `String.prototype.search` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.search\n function search(regexp) {\n var O = defined(this);\n var fn = regexp == undefined ? undefined : regexp[SEARCH];\n return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));\n },\n // `RegExp.prototype[@@search]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search\n function (regexp) {\n var res = maybeCallNative($search, regexp, this);\n if (res.done) return res.value;\n var rx = anObject(regexp);\n var S = String(this);\n var previousLastIndex = rx.lastIndex;\n if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0;\n var result = regExpExec(rx, S);\n if (!sameValue(rx.lastIndex, previousLastIndex)) rx.lastIndex = previousLastIndex;\n return result === null ? -1 : result.index;\n }\n ];\n});\n","import log from './log';\n\n// Adds a base origin to relative URLs\nexport function addBaseURL (url, base) {\n if (!url || !isRelativeURL(url)) {\n return url;\n }\n\n var relative_path = (url[0] !== '/');\n var base_info;\n if (base) {\n base_info = document.createElement('a'); // use a temporary element to parse URL\n base_info.href = base;\n }\n else {\n base_info = window.location;\n }\n\n if (relative_path) {\n let path = pathForURL(base_info.href);\n url = path + url;\n }\n else {\n let origin = base_info.origin;\n if (!origin) {\n origin = base_info.protocol + '//' + base_info.host; // IE11 doesn't have origin property\n }\n url = origin + url;\n }\n\n return url;\n}\n\nexport function pathForURL (url) {\n if (typeof url === 'string' && url.search(/^(data|blob):/) === -1) {\n let qs = url.indexOf('?');\n if (qs > -1) {\n url = url.substr(0, qs);\n }\n\n let hash = url.indexOf('#');\n if (hash > -1) {\n url = url.substr(0, hash);\n }\n\n return url.substr(0, url.lastIndexOf('/') + 1) || '';\n }\n return '';\n}\n\nexport function extensionForURL (url) {\n url = url.split('/').pop();\n let last_dot = url.lastIndexOf('.');\n if (last_dot > -1) {\n return url.substring(last_dot + 1);\n }\n}\n\nexport function isLocalURL (url) {\n if (typeof url !== 'string') {\n return;\n }\n return (url.search(/^(data|blob):/) > -1);\n}\n\nexport function isRelativeURL (url) {\n if (typeof url !== 'string') {\n return;\n }\n return !(url.search(/^(http|https|data|blob):/) > -1 || url.substr(0, 2) === '//');\n}\n\n// Resolves './' and '../' components from relative path, to get a \"flattened\" path\nexport function flattenRelativeURL (url) {\n let dirs = (url || '').split('/');\n for (let d = 1; d < dirs.length; d++) {\n if (dirs[d] === '.') {\n dirs.splice(d, 1);\n d--;\n }\n else if (dirs[d] === '..') {\n d = d + 0;\n dirs.splice(d-1, 2);\n d--;\n }\n }\n return dirs.join('/');\n}\n\n// Add a set of query string params to a URL\n// params: hash of key/value pairs of query string parameters\n// returns array of: [modified URL, array of duplicate param name and values]\nexport function addParamsToURL (url, params) {\n if (!params || Object.keys(params).length === 0) {\n return [url, []];\n }\n\n var qs_index = url.indexOf('?');\n var hash_index = url.indexOf('#');\n\n // Save and trim hash\n var hash = '';\n if (hash_index > -1) {\n hash = url.slice(hash_index);\n url = url.slice(0, hash_index);\n }\n\n // Start query string\n if (qs_index === -1) {\n qs_index = url.length;\n url += '?';\n }\n qs_index++; // advanced past '?'\n\n // Build query string params\n var url_params = '';\n var dupes = [];\n for (var p in params) {\n if (getURLParameter(p, url) !== '') {\n dupes.push([p, params[p]]);\n continue;\n }\n url_params += `${p}=${params[p]}&`;\n }\n\n // Insert new query string params and restore hash\n url = url.slice(0, qs_index) + url_params + url.slice(qs_index) + hash;\n\n return [url, dupes];\n}\n\n// Polyfill (for Safari compatibility)\nlet _createObjectURL;\nexport function createObjectURL (url) {\n if (_createObjectURL === undefined) {\n _createObjectURL = (window.URL && window.URL.createObjectURL) || (window.webkitURL && window.webkitURL.createObjectURL);\n\n if (typeof _createObjectURL !== 'function') {\n _createObjectURL = null;\n log('warn', 'window.URL.createObjectURL (or vendor prefix) not found, unable to create local blob URLs');\n }\n }\n\n if (_createObjectURL) {\n return _createObjectURL(url);\n }\n else {\n return url;\n }\n}\n\nlet _revokeObjectURL;\nexport function revokeObjectURL (url) {\n if (_revokeObjectURL === undefined) {\n _revokeObjectURL = (window.URL && window.URL.revokeObjectURL) || (window.webkitURL && window.webkitURL.revokeObjectURL);\n\n if (typeof _revokeObjectURL !== 'function') {\n _revokeObjectURL = null;\n log('warn', 'window.URL.revokeObjectURL (or vendor prefix) not found, unable to create local blob URLs');\n }\n }\n\n if (_revokeObjectURL) {\n return _revokeObjectURL(url);\n }\n else {\n return url;\n }\n}\n\n// Get URL that the current script was loaded from\n// If currentScript is not available, loops through