├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── cmd.js ├── index.html ├── index.js ├── lewis.png ├── lib ├── limit_stream.js ├── map_image_stream.js ├── map_mosaic_stream.js ├── scale.js └── viewport.js ├── main.js ├── package-lock.json ├── package.json ├── renderer.js └── usage.txt /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | test 7 | test.js 8 | demo/ 9 | .npmignore 10 | LICENSE.md -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 6 | 7 | ## [2.2.0] - 2017-07-06 8 | ### Changed 9 | - Switch from using [jam3/devtool](https://github.com/Jam3/devtool) to directly spawning electron 10 | 11 | ### Added 12 | - Log progress to a single line 13 | 14 | ### Fixed 15 | - Ensure tiles are loaded before exporting map 16 | 17 | ### Known Issues 18 | - Export to stdout does not exit process on completion (need to Ctrl-C to exit) 19 | 20 | [2.2.0]: https://github.com/digidem/mapbox-map-image-export/compare/v2.1.0...v2.2.0 21 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Digital Democracy / Gregor MacLennan 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 20 | OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mapbox-map-image-export 2 | 3 | A command-line tool to export a [Mapbox vector map][1], such as one created with [Mapbox Studio][2], to a high-resolution image for printing etc. 4 | 5 | Mapbox has a [Maps static API][3] for exporting images, but it is limited to `1280px`, and exports as jpeg, with visible compression artifacts. `mapbox-map-image-export` renders the map in a headless browser and exports by default to uncompressed png. You can adjust the dpi setting for high-quality printing. `192dpi` (the default) is good enough for most print applications, but if you want better quality try `288dpi`. Icons will be 192dpi (retina) due to the way sprites are handled by `mapbox-gl-js`. 6 | 7 | The Mapbox [wmts service][4] is another option for creating maps for printing in QGIS or ArcMap, but it does not currently support retina maps, so is limited to printing at around 72dpi, and is also only jpeg right now. 8 | 9 | [1]: https://www.mapbox.com/maps/ 10 | [2]: https://www.mapbox.com/mapbox-studio/ 11 | [3]: https://www.mapbox.com/api-documentation/#static 12 | [4]: https://www.mapbox.com/help/mapbox-arcgis-qgis/ 13 | 14 | ```sh 15 | export MAPBOX_TOKEN=YOUR_MAPBOX_API_PUBLIC_TOKEN 16 | 17 | export-map mapbox://styles/mapbox/streets-v9 -w=11in -h=8.5in \ 18 | -b=-7.1354,57.9095,-6.1357,58.516 -t=$MAPBOX_TOKEN -o=lewis.png 19 | ``` 20 | 21 | ![lewis](lewis.png) 22 | 23 | ## Terms of Use 24 | 25 | If you use this tool to export images from maps which include data from Mapbox, then you must follow the [Mapbox terms of service](https://www.mapbox.com/tos/): 26 | 27 | - Exported images must only be used for non-commercial, non-profit or educational use. 28 | - You must add attribution and the [Mapbox logo](https://www.mapbox.com/about/press/brand-guidelines/) to the printed map according to the Mapbox [attribution guidelines for static print](https://docs.mapbox.com/help/how-mapbox-works/attribution/#static--print). 29 | - To secure permission to print images of a Mapbox style for a commercial project, please [contact Mapbox](https://www.mapbox.com/contact/sales/). 30 | 31 | ## Install 32 | 33 | This tool uses Electron to render the map using [mapbox-gl-js][3], so it is fairly heavy (~100mb). Install with latest [npm](https://www.npmjs.com/). 34 | 35 | [5]: https://www.mapbox.com/mapbox-gl-js/api/ 36 | 37 | ```sh 38 | npm install mapbox-map-image-export -g 39 | ``` 40 | 41 | ## Usage 42 | 43 | ```txt 44 | Usage: 45 | export-map mapboxStyleUrl 46 | 47 | Options: 48 | --bounds, -b comma-separated bounding box [required] 'minLon,minLat maxLon,maxLat' eg. '-7.1354,57.9095,-6.1357,58.516' 49 | --token, -t Mapbox API token [required]: 50 | https://www.mapbox.com/studio/account/tokens/ 51 | --output, -o image output path, optional, defaults to std.out 52 | --dpi, -d dpi of output image, default 192dpi (equivalent to how the map renders on a retina screen) 53 | --format, -f output format, "jpg", "webp" or "png" (default) 54 | --quality, -q encoding quality for jpg and webp, default 0.9 55 | --width, -w output width for printing e.g. 11in or 297mm 56 | --height, -h output height for printing 57 | --help show this help 58 | --version, -v show version 59 | --debug renders bounding box and (print) tile boundaries and opens the developer tools console 60 | ``` 61 | 62 | Exports a map for a given mapbox style url for the specified bounding box. 63 | 64 | If no `--output` is given, the PNG is written to stdout. 65 | 66 | ## What does 'dpi' mean? 67 | 68 | Mapbox Studio and Mapbox GL maps are designed for the screen, as such 'dpi' (dots per inch), a print term, does not have any real meaning. However, the standard screen resolution is equivalent to between 72 and 96dpi (e.g. 96 screen pixels will measure approximately 1 inch on a standard screen). Mapbox GL maps are designed by zoom level, and this tool assumes you want maps to look on paper roughly the same as they look on screen at the same size. `mapbox-map-image-export` assumes a standard resolution mapbox map is 96dpi, and a retina (@2x) map is 192dpi. You can set 288dpi if you like, and this will render as if to an ultra-retina screen with a devicePixelRatio=3. Keep dpi to a multiple of `96` if you want icons to look good. 69 | 70 | ## Acknowledgements 71 | 72 | This is inspired by [extract-streetview](https://github.com/Jam3/extract-streetview) by [mattdesl](https://github.com/mattdesl). It uses [Electron](https://electron.atom.io/) to render the map in a headless version of Chrome. 73 | 74 | ## License 75 | 76 | MIT 77 | -------------------------------------------------------------------------------- /cmd.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var electron = require('electron') 3 | var proc = require('child_process') 4 | var assert = require('assert') 5 | var fs = require('fs') 6 | var path = require('path') 7 | 8 | var mainProcessScript = require.resolve('./main.js') 9 | 10 | var args = [mainProcessScript].concat(process.argv.slice(2)) 11 | 12 | var argv = require('minimist')(process.argv.slice(2), { 13 | alias: { 14 | bbox: 'b', 15 | width: 'w', 16 | height: 'h', 17 | dpi: 'd', 18 | format: 'f', 19 | output: 'o', 20 | quality: 'q', 21 | token: 't', 22 | version: 'v' 23 | }, 24 | default: { 25 | format: 'image/png', 26 | quality: 0.9, 27 | dpi: 192, 28 | width: '11in', 29 | height: '8.5in' 30 | }, 31 | string: ['bbox', 'width', 'height', 'format', 'output', 'token'] 32 | }) 33 | 34 | if (argv.version) { 35 | console.log(require('./package.json').version) 36 | process.exit() 37 | } 38 | 39 | if (argv.help) { 40 | console.log(fs.readFileSync(path.join(__dirname, 'usage.txt'), 'utf8')) 41 | process.exit() 42 | } 43 | 44 | validateBbox(argv.bbox) 45 | assert(argv.quality > 0 && argv.quality <= 1, '--quality must be a number between 0 and 1') 46 | assert(typeof argv.dpi === 'number', '--dpi must be a number') 47 | assert(typeof argv.token === 'string', 'Missing --token (must pass a valid Mapbox API token)') 48 | 49 | var child = proc.spawn(electron, args, {stdio: 'inherit'}) 50 | child.on('close', function (code) { 51 | process.exit(code) 52 | }) 53 | 54 | function validateBbox (arg) { 55 | assert(typeof arg === 'string', 'Must pass a bounding box --bbox option') 56 | var b = arg.split(/,|\s/).map(parseFloat) 57 | assert(b.length === 4, "--bbox argument must be 4 numbers, separated by ',' or ' '") 58 | assert(b[0] < b[2] && b[1] < b[3], 'invalid bounding box, check coordinates are WSEN (west, south, east north)') 59 | assert(b[0] >= -180 && b[2] <= 180 && b[1] >= -90 && b[3] <= 90, 'Invalid bounding box, bounds are outside world bounds') 60 | } 61 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mapbox-gl-js image export 6 | 7 | 8 | 11 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/map_mosaic_stream') 2 | -------------------------------------------------------------------------------- /lewis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/digidem/mapbox-map-image-export/6c5cee8083c6b5b5bcf363b5359ce9a1f479e07b/lewis.png -------------------------------------------------------------------------------- /lib/limit_stream.js: -------------------------------------------------------------------------------- 1 | var through = require('through2') 2 | var once = require('once') 3 | 4 | // color space component counts 5 | var COMPONENTS = { 6 | rgb: 3, 7 | rgba: 4, 8 | cmyk: 4, 9 | gray: 1, 10 | graya: 2, 11 | indexed: 1 12 | } 13 | 14 | var DEFAULTS = { 15 | width: 0, 16 | height: 0, 17 | colorSpace: 'rgba' 18 | } 19 | 20 | /** 21 | * Limit a stream to a fixed number of bytes based on 22 | * width, height and colorSpace 23 | * @param {object} opts 24 | * @param {number} opts.width Image width 25 | * @param {number} opts.height Image height 26 | * @param {string} opts.colorSpace One of `rgb|rgba|cmyk|gray|graya|indexed` 27 | * @return {Stream} Transform Stream 28 | */ 29 | module.exports = function (opts) { 30 | var format = Object.assign({}, DEFAULTS, opts) 31 | var limit = format.width * format.height * COMPONENTS[format.colorSpace] 32 | var consumed = 0 33 | var stream = through(function (chunk, enc, next) { 34 | emitFormat() 35 | if (consumed >= limit) return next(null, null) 36 | consumed += chunk.length 37 | // console.log(chunk.slice(0, limit - consumed + chunk.length).length) 38 | next(null, chunk.slice(0, limit - consumed + chunk.length)) 39 | }).once('pipe', function (src) { 40 | src.on('format', function (srcFormat) { 41 | Object.assign(format, srcFormat) 42 | }) 43 | }) 44 | var emitFormat = once(function () { 45 | stream.emit('format', Object.assign({}, format)) 46 | }) 47 | return stream 48 | } 49 | -------------------------------------------------------------------------------- /lib/map_image_stream.js: -------------------------------------------------------------------------------- 1 | var createFBO = require('gl-fbo') 2 | var createGlPixelStream = require('gl-pixel-stream') 3 | var pumpify = require('pumpify') 4 | var bboxPolygon = require('@turf/bbox-polygon').default 5 | var calcViewport = require('./viewport') 6 | var limit = require('./limit_stream') 7 | 8 | module.exports = mapImageStream 9 | 10 | const tileBboxLayer = { 11 | 'id': 'tile-bbox', 12 | 'type': 'line', 13 | 'source': 'bbox', 14 | 'filter': ['==', '$id', 0], 15 | 'layout': { 16 | 'line-join': 'miter' 17 | }, 18 | 'paint': { 19 | 'line-color': 'rgb(255, 255, 0)', 20 | 'line-width': 4 21 | } 22 | } 23 | 24 | const origBboxLayer = { 25 | 'id': 'orig-bbox', 26 | 'type': 'line', 27 | 'source': 'bbox', 28 | 'filter': ['==', '$id', 1], 29 | 'layout': { 30 | 'line-join': 'miter' 31 | }, 32 | 'paint': { 33 | 'line-color': 'rgb(255, 0, 0)', 34 | 'line-opacity': 0.8, 35 | 'line-width': 8, 36 | 'line-dasharray': [1.5, 1.5] 37 | } 38 | } 39 | 40 | /** 41 | * Returns a stream of raw image data from a specific map area 42 | * @param {mapboxgl.Map} map A mapbox-gl-js map instance (already rendered to the DOM) 43 | * @param {Array(2)} dim Dimensions of the map in display pixels `[x, y]` 44 | * @param {Array(4)} bbox Bbox of area to include in the map in decimal degrees `[W, S, E, N]` 45 | * @return {ReadableStream} ReadableStream of raw pixel data from the rendered map 46 | */ 47 | function mapImageStream (map, dim, bbox, origBbox, debug) { 48 | if (debug) { 49 | const geojson = { 50 | type: 'FeatureCollection', 51 | features: [ 52 | bboxPolygon(bbox, { id: 0 }), 53 | bboxPolygon(origBbox, { id: 1 }) 54 | ] 55 | } 56 | try { 57 | map.addSource('bbox', { type: 'geojson', data: geojson }) 58 | } catch (e) { 59 | map.getSource('bbox').setData(geojson) 60 | } 61 | 62 | if (!map.getLayer('orig-bbox')) { 63 | map.addLayer(origBboxLayer).addLayer(tileBboxLayer) 64 | } 65 | } 66 | 67 | if (map.__mmie_processing) throw Error('map instance is currently processing') 68 | map.__mmie_processing = true 69 | var inprogress = false 70 | var gl = map.painter.context.gl 71 | // Dimensions in absolute pixels (vs. display pixels) 72 | var pixelDim = dim.map(function (d) { return d * window.devicePixelRatio }) 73 | 74 | if (sizeTooBig(gl, pixelDim)) throw Error('map size is too big') 75 | 76 | var stream = pumpify() 77 | 78 | var mapDiv = map.getContainer() 79 | mapDiv.style.width = dim[0] + 'px' 80 | mapDiv.style.height = dim[1] + 'px' 81 | map.resize()._update() 82 | var viewport = calcViewport.fitDim(map, dim, bbox) 83 | var fbo = createFBO(gl, pixelDim, { stencil: true }) 84 | fbo.bind() 85 | 86 | map.once('moveend', function () { 87 | onMapRenderComplete(map, streamCanvas) 88 | }) 89 | 90 | map.jumpTo({ 91 | center: viewport.center, 92 | zoom: viewport.zoom, 93 | bearing: 0, 94 | pitch: 0 95 | }) 96 | 97 | return stream 98 | 99 | function onMapRenderComplete (map, fn) { 100 | process.nextTick(() => { 101 | if (inprogress) return 102 | if (map.areTilesLoaded() && map.isStyleLoaded() && map.loaded()) { 103 | var timeout = setTimeout(fn, 2000) 104 | map.once('render', () => { 105 | clearTimeout(timeout) 106 | onMapRenderComplete(map, fn) 107 | }) 108 | } else { 109 | map.once('render', () => onMapRenderComplete(map, fn)) 110 | } 111 | }) 112 | } 113 | 114 | function streamCanvas () { 115 | if (!inprogress) inprogress = true 116 | var glStream = createGlPixelStream(gl, fbo.handle, fbo.shape, { flipY: true }) 117 | glStream.on('end', () => { 118 | gl.bindFramebuffer(gl.FRAMEBUFFER, null) 119 | inprogress = false 120 | map.__mmie_processing = false 121 | fbo.dispose() 122 | map.remove() 123 | }) 124 | var format = stream.format = { width: pixelDim[0], height: pixelDim[1], colorSpace: 'rgba' } 125 | stream.emit('format', format) 126 | stream.setPipeline(glStream, limit(format)) 127 | } 128 | } 129 | 130 | function sizeTooBig (gl, dim) { 131 | var maxDim = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) / 2 132 | return dim.filter(function (d) { return d > maxDim }).length 133 | } 134 | -------------------------------------------------------------------------------- /lib/map_mosaic_stream.js: -------------------------------------------------------------------------------- 1 | var Qty = require('js-quantities') 2 | var PNGEncoder = require('png-stream/encoder') 3 | var pumpify = require('pumpify') 4 | var mapboxgl = require('mapbox-gl/dist/mapbox-gl-dev.js') 5 | var mosaic = require('mosaic-image-stream') 6 | var spy = require('through2-spy') 7 | 8 | var calcViewport = require('./viewport') 9 | var mapImageStream = require('./map_image_stream') 10 | var getScale = require('./scale') 11 | 12 | var DEFAULTS = { 13 | format: 'image/png', 14 | quality: 0.9, 15 | dpi: 192, 16 | width: '11in', 17 | height: '8.5in' 18 | } 19 | 20 | module.exports = mapMosaicStream 21 | 22 | function mapMosaicStream (style, mapDiv, opts) { 23 | opts = Object.assign({}, DEFAULTS, opts) 24 | var bbox = parseBboxArg(opts.bbox) 25 | 26 | var token = mapboxgl.accessToken = opts.token 27 | if (!token) { 28 | throw new Error('you must pass a valid Mapbox public token: https://www.mapbox.com/studio/account/tokens/') 29 | } 30 | 31 | var pixelRatio = window.devicePixelRatio = opts.dpi / 96 32 | // Dimensions in absolute pixels 33 | var pixelDim = [opts.width, opts.height] 34 | .map(function (d) { return Math.ceil(parseLengthToPixels(d, opts.dpi) / pixelRatio) * pixelRatio }) 35 | // Dimensions in display pixels 36 | var dpDim = pixelDim.map(function (d) { return d / pixelRatio }) 37 | 38 | var map = new mapboxgl.Map({ 39 | container: mapDiv, 40 | bearing: 0, 41 | pitch: 0, 42 | style: style 43 | }) 44 | 45 | var viewport = calcViewport.fitDim(map, dpDim, bbox) 46 | 47 | map.jumpTo({ 48 | center: viewport.center, 49 | zoom: viewport.zoom, 50 | bearing: 0, 51 | pitch: 0 52 | }) 53 | 54 | var scale = getScale(map, dpDim[0], parseLengthToMeters(opts.width)) 55 | console.error('SCALE: 1:%d', scale) 56 | console.error('ZOOM: %d', viewport.zoom) 57 | var gl = map.painter.context.gl 58 | var maxRenderBuf = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) 59 | // Above a certain screen pixel size the map does not render correctly 60 | var maxTileDim = Array(2).fill(Math.min(Infinity, Math.floor(maxRenderBuf / 2 / pixelRatio))) 61 | map.remove() 62 | 63 | var tiles = getTileStreams(viewport, dpDim, maxTileDim, style, bbox, opts.debug) 64 | 65 | var mapMosaic = mosaic(tiles, pixelDim[1]) 66 | 67 | var pngStream = new PNGEncoder({ 68 | width: pixelDim[0], 69 | height: pixelDim[1], 70 | colorSpace: 'rgba' 71 | }) 72 | var total = pixelDim[0] * pixelDim[1] * 4 73 | var complete = 0 74 | var out = pumpify(mapMosaic, spy(onChunk), pngStream) 75 | pngStream.on('format', function (f) { 76 | out.emit('format', f) 77 | }) 78 | function onChunk (chunk) { 79 | complete += chunk.length 80 | out.emit('progress', complete / total, total) 81 | } 82 | return out 83 | } 84 | 85 | function getTileStreams (viewport, dim, maxTileDim, style, origBbox, debug) { 86 | var ne = viewport.bounds.getNorthEast() 87 | var sw = viewport.bounds.getSouthWest() 88 | var pixels2lng = dim[0] / (ne.lng - sw.lng) 89 | var pixels2lat = dim[1] / (ne.lat - sw.lat) 90 | var maxTileDimDeg = [maxTileDim[0] / pixels2lng, maxTileDim[1] / pixels2lat] 91 | 92 | var cols = Math.ceil(dim[0] / maxTileDim[0]) 93 | var rows = Math.ceil(dim[1] / maxTileDim[1]) 94 | 95 | return Array(cols).fill(1).map(function (_, i) { 96 | var row = 0 97 | var mapDiv = document.createElement('div') 98 | mapDiv.className = 'map' 99 | document.body.appendChild(mapDiv) 100 | return function createStream (cb) { 101 | if (row >= rows) return cb(null, null) 102 | var map = window['map' + i] = new mapboxgl.Map({ 103 | container: mapDiv, 104 | bearing: 0, 105 | pitch: 0, 106 | style: style, 107 | preserveDrawingBuffer: true 108 | }) 109 | var w = sw.lng + (i * maxTileDimDeg[0]) 110 | var s = Math.max(sw.lat, ne.lat - ((row + 1) * maxTileDimDeg[1])) 111 | var e = Math.min(ne.lng, sw.lng + ((i + 1) * maxTileDimDeg[0])) 112 | var n = ne.lat - (row * maxTileDimDeg[1]) 113 | var width = (i + 1) * maxTileDim[0] <= dim[0] ? maxTileDim[0] : dim[0] % maxTileDim[0] 114 | var height = (row + 1) * maxTileDim[1] <= dim[1] ? maxTileDim[1] : dim[1] % maxTileDim[1] 115 | row++ 116 | if (map.loaded()) { 117 | cb(null, mapImageStream(map, [width, height], [w, s, e, n], origBbox, debug)) 118 | } else { 119 | map.on('load', function () { 120 | cb(null, mapImageStream(map, [width, height], [w, s, e, n], origBbox, debug)) 121 | }) 122 | } 123 | } 124 | }) 125 | } 126 | 127 | function parseBboxArg (str) { 128 | var b = str.split(/,|\s/).map(parseFloat) 129 | var invalid = b.length !== 4 || 130 | b[0] >= b[2] || 131 | b[1] >= b[3] || 132 | b[0] < -180 || 133 | b[2] > 180 || 134 | b[1] < -90 || 135 | b[3] > 90 136 | if (invalid) throw new Error('Must pass a valid bounding box') 137 | return b 138 | } 139 | 140 | function parseLengthToMeters (length) { 141 | var qty = new Qty(length) 142 | // TODO: This should assume pixels and 96 dpi? 143 | // as it is this will give a meaningless scale for unitless map sizes 144 | if (qty.isUnitless()) return length 145 | return parseFloat(qty.to('meters').toString()) 146 | } 147 | 148 | function parseLengthToPixels (length, dpi) { 149 | dpi = dpi || 96 150 | var qty = new Qty(length) 151 | if (qty.isUnitless()) return length 152 | if (qty.kind() !== 'length') throw new Error('Invalid units') 153 | // Yikes, can't find method to get a unitless number back! 154 | // TODO: Use a better unit conversion library 155 | return Math.ceil(parseFloat(qty.to('in').toString()) * dpi) 156 | } 157 | 158 | // function parseFormat (format) { 159 | // switch (format) { 160 | // case 'jpg': 161 | // case 'jpeg': 162 | // case 'image/jpg': 163 | // case 'image/jpeg': 164 | // return 'image/jpeg' 165 | // case 'webp': 166 | // case 'image/webp': 167 | // return 'image/webp' 168 | // default: 169 | // return 'image/png' 170 | // } 171 | // } 172 | -------------------------------------------------------------------------------- /lib/scale.js: -------------------------------------------------------------------------------- 1 | // Largely copied from https://github.com/mapbox/mapbox-gl-js/blob/master/js/ui/control/scale_control.js 2 | // License: BSD-3-Clause 3 | 4 | module.exports = getScale 5 | 6 | function getScale (map, mapWidthDisplayPixels, outputWidthMeters) { 7 | // A horizontal scale is imagined to be present at center of the map 8 | // container with maximum length (Default) as 100px. 9 | // Using spherical law of cosines approximation, the real distance is 10 | // found between the two coordinates. 11 | var maxWidth = 100 12 | 13 | var y = map._container.clientHeight / 2 14 | var width100pxMeters = getDistance(map.unproject([0, y]), map.unproject([maxWidth, y])) 15 | var mapRealWidthMeters = width100pxMeters * mapWidthDisplayPixels / maxWidth 16 | return mapRealWidthMeters / outputWidthMeters 17 | } 18 | 19 | function getDistance (latlng1, latlng2) { 20 | // Uses spherical law of cosines approximation. 21 | var R = 6371000 22 | 23 | var rad = Math.PI / 180 24 | var lat1 = latlng1.lat * rad 25 | var lat2 = latlng2.lat * rad 26 | var a = Math.sin(lat1) * Math.sin(lat2) + 27 | Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlng2.lng - latlng1.lng) * rad) 28 | 29 | var maxMeters = R * Math.acos(Math.min(a, 1)) 30 | return maxMeters 31 | } 32 | -------------------------------------------------------------------------------- /lib/viewport.js: -------------------------------------------------------------------------------- 1 | var mapboxgl = require('mapbox-gl/dist/mapbox-gl-dev.js') 2 | var Decimal = require('decimal.js') 3 | 4 | var LngLatBounds = mapboxgl.LngLatBounds 5 | var Point = mapboxgl.Point 6 | 7 | module.exports = { 8 | fitDim: fitDim, 9 | fitZoom: fitZoom 10 | } 11 | 12 | /** 13 | * Fit a bounding box into a given pixel dimensions (display pixels, not device pixels) 14 | * and return the zoom, center, and new bounding box for the map view that includes 15 | * the original bbox, but fills the input dimensions. 16 | * We use `decimal.js` to reduce floating point rounding errors with all the projection math 17 | * - the math needs to be accurate because tiles need to line up precisely 18 | * @param {mapboxgl.Map} map A mapbox-gl-js map instance - we use this for the projection math, but we do set the zoom on the map, so the map view will change 19 | * @param {Array(2)} dim Display pixel dimensions of the desired output 20 | * @param {Array(4)} bbox Bounding box of the area to be fitted in the output map, `[w, s, e, n]` 21 | * @return {Object} Returns an object with the map center and zoom, and the bounds of the view to fit the input pixel dimensions 22 | */ 23 | function fitDim (map, dim, bbox) { 24 | // The closer the map zoom is to the output zoom, the fewer rounding errors 25 | // TODO? Once the zoom is calculated, re-run this calculation for higher precision? 26 | map.setZoom(15) 27 | map.setBearing(0) 28 | map.setPitch(0) 29 | var llb = bboxToBounds(bbox) 30 | var pt = new Point(dim[0], dim[1]) 31 | // NB: Points (in pixels) are measured from the top-left (nw) of the map, 32 | // whereas LatLng is measured from the bottom-left (sw) 33 | // took a lot of head scratching before I figured that one out. 34 | var nw = map.project(llb.getNorthWest()) 35 | var se = map.project(llb.getSouthEast()) 36 | var size = {x: Decimal.sub(se.x, nw.x), y: Decimal.sub(se.y, nw.y)} 37 | var scaleX = Decimal.div(pt.x, size.x) 38 | var scaleY = Decimal.div(pt.y, size.y) 39 | var tr = map.transform 40 | var zoom = tr.scaleZoom(tr.scale * +Decimal.min(scaleX, scaleY)) 41 | var center = map.unproject(nw.add(se).div(2)) 42 | // Aspect ratio of the input bounding box 43 | var boundRatio = Decimal.div(size.x, size.y) 44 | // Aspect ratio of the desired output pixel dimensions 45 | var areaRatio = Decimal.div(pt.x, pt.y) 46 | // Calculate how much we need to pad the bounding box by to fill the pixel dimensions 47 | var padX = areaRatio.greaterThan(boundRatio) ? areaRatio.times(size.y).minus(size.x).div(2) : 0 48 | var padY = areaRatio.lessThan(boundRatio) ? size.x.div(areaRatio).minus(size.y).div(2) : 0 49 | var paddedNw = new Point(+Decimal.sub(nw.x, padX), +Decimal.sub(nw.y, padY)) 50 | var paddedSe = new Point(+Decimal.add(se.x, padX), +Decimal.add(se.y, padY)) 51 | var paddedllnw = map.unproject(paddedNw) 52 | var paddedllse = map.unproject(paddedSe) 53 | var paddedBounds = new LngLatBounds([ 54 | [paddedllnw.lng, paddedllse.lat], 55 | [paddedllse.lng, paddedllnw.lat] 56 | ]) 57 | 58 | var viewport = { 59 | center: center, 60 | zoom: zoom, 61 | bearing: 0, 62 | pitch: 0, 63 | bounds: paddedBounds 64 | } 65 | return viewport 66 | } 67 | 68 | function fitZoom (map, zoom, bbox) { 69 | map.setZoom(zoom) 70 | var llb = bboxToBounds(bbox) 71 | // NB: Points (in pixels) are measured from the top-left (nw) of the map, 72 | // whereas LatLng is measured from the bottom-left (sw) 73 | // took a lot of head scratching before I figured that one out. 74 | var nw = map.project(llb.getNorthWest()) 75 | var se = map.project(llb.getSouthEast()) 76 | var center = map.unproject(nw.add(se).div(2)) 77 | var ratio = window.devicePixelRatio 78 | var size = se.sub(nw) 79 | var pixelDim = [size.x * ratio, size.y * ratio] 80 | var viewport = { 81 | center: center, 82 | zoom: zoom, 83 | bearing: 0, 84 | pitch: 0, 85 | bounds: llb, 86 | pixelDim: pixelDim 87 | } 88 | return viewport 89 | } 90 | 91 | function bboxToBounds (bbox) { 92 | return LngLatBounds.convert([[bbox[0], bbox[1]], [bbox[2], bbox[3]]]) 93 | } 94 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const { app, BrowserWindow } = require('electron') 2 | const path = require('path') 3 | const url = require('url') 4 | 5 | const argv = module.exports.argv = require('yargs-parser')(process.argv.slice(2), { 6 | alias: { 7 | bbox: 'b', 8 | width: 'w', 9 | height: 'h', 10 | dpi: 'd', 11 | format: 'f', 12 | output: 'o', 13 | quality: 'q', 14 | token: 't', 15 | version: 'v' 16 | }, 17 | boolean: ['debug'], 18 | string: ['bbox', 'width', 'height', 'format', 'output', 'token'], 19 | default: { 20 | token: process.env.MAPBOX_TOKEN 21 | } 22 | }) 23 | 24 | module.exports.console = console 25 | 26 | // Keep a global reference of the window object, if you don't, the window will 27 | // be closed automatically when the JavaScript object is garbage collected. 28 | let win 29 | 30 | function createWindow () { 31 | // Create the browser window. 32 | win = new BrowserWindow({ show: !!argv.debug }) 33 | if (argv.debug) win.webContents.openDevTools() 34 | // win.webContents.openDevTools() 35 | // and load the index.html of the app. 36 | win.loadURL(url.format({ 37 | pathname: path.join(__dirname, 'index.html'), 38 | protocol: 'file:', 39 | slashes: true 40 | })) 41 | 42 | // Emitted when the window is closed. 43 | win.on('closed', () => { 44 | // Dereference the window object, usually you would store windows 45 | // in an array if your app supports multi windows, this is the time 46 | // when you should delete the corresponding element. 47 | win = null 48 | }) 49 | } 50 | 51 | // This method will be called when Electron has finished 52 | // initialization and is ready to create browser windows. 53 | // Some APIs can only be used after this event occurs. 54 | app.on('ready', createWindow) 55 | 56 | // Quit when all windows are closed. 57 | app.on('window-all-closed', () => { 58 | app.quit() 59 | }) 60 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mapbox-map-image-export", 3 | "version": "2.4.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@mapbox/geojson-area": { 8 | "version": "0.2.2", 9 | "resolved": "https://registry.npmjs.org/@mapbox/geojson-area/-/geojson-area-0.2.2.tgz", 10 | "integrity": "sha1-GNeBSqNr8j+7zDefjiaiKSfevxA=", 11 | "requires": { 12 | "wgs84": "0.0.0" 13 | } 14 | }, 15 | "@mapbox/geojson-types": { 16 | "version": "1.0.2", 17 | "resolved": "https://registry.npmjs.org/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz", 18 | "integrity": "sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw==" 19 | }, 20 | "@mapbox/jsonlint-lines-primitives": { 21 | "version": "2.0.2", 22 | "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", 23 | "integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ=" 24 | }, 25 | "@mapbox/mapbox-gl-supported": { 26 | "version": "1.4.0", 27 | "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.4.0.tgz", 28 | "integrity": "sha512-ZD0Io4XK+/vU/4zpANjOtdWfVszAgnaMPsGR6LKsWh4kLIEv9qoobTVmJPPuwuM+ZI2b3BlZ6DYw1XHVmv6YTA==" 29 | }, 30 | "@mapbox/point-geometry": { 31 | "version": "0.1.0", 32 | "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", 33 | "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" 34 | }, 35 | "@mapbox/tiny-sdf": { 36 | "version": "1.1.0", 37 | "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.1.0.tgz", 38 | "integrity": "sha512-dnhyk8X2BkDRWImgHILYAGgo+kuciNYX30CUKj/Qd5eNjh54OWM/mdOS/PWsPeN+3abtN+QDGYM4G220ynVJKA==" 39 | }, 40 | "@mapbox/unitbezier": { 41 | "version": "0.0.0", 42 | "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz", 43 | "integrity": "sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4=" 44 | }, 45 | "@mapbox/vector-tile": { 46 | "version": "1.3.1", 47 | "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", 48 | "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", 49 | "requires": { 50 | "@mapbox/point-geometry": "~0.1.0" 51 | } 52 | }, 53 | "@mapbox/whoots-js": { 54 | "version": "3.1.0", 55 | "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", 56 | "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==" 57 | }, 58 | "@turf/bbox-polygon": { 59 | "version": "6.0.1", 60 | "resolved": "https://registry.npmjs.org/@turf/bbox-polygon/-/bbox-polygon-6.0.1.tgz", 61 | "integrity": "sha512-f6BK6GOzUNjmJeOYHklk/5LNcQMQbo51gvAM10dTM5IqzKP01KM5bgV88uOKfSZB0HRQVpaRV1tgXk2bg5cPRg==", 62 | "requires": { 63 | "@turf/helpers": "6.x" 64 | } 65 | }, 66 | "@turf/helpers": { 67 | "version": "6.1.4", 68 | "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.1.4.tgz", 69 | "integrity": "sha512-vJvrdOZy1ngC7r3MDA7zIGSoIgyrkWcGnNIEaqn/APmw+bVLF2gAW7HIsdTxd12s5wQMqEpqIQrmrbRRZ0xC7g==" 70 | }, 71 | "@types/node": { 72 | "version": "8.10.37", 73 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.37.tgz", 74 | "integrity": "sha512-Jp39foY8Euv/PG4OGPyzxis82mnjcUtXLEMA8oFMCE4ilmuJgZPdV2nZNV1moz+99EJTtcpOSgDCgATUwABKig==" 75 | }, 76 | "acorn": { 77 | "version": "5.7.3", 78 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", 79 | "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" 80 | }, 81 | "ajv": { 82 | "version": "5.5.2", 83 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 84 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 85 | "requires": { 86 | "co": "^4.6.0", 87 | "fast-deep-equal": "^1.0.0", 88 | "fast-json-stable-stringify": "^2.0.0", 89 | "json-schema-traverse": "^0.3.0" 90 | } 91 | }, 92 | "ansi-regex": { 93 | "version": "2.1.1", 94 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 95 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 96 | }, 97 | "ansicolors": { 98 | "version": "0.2.1", 99 | "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz", 100 | "integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8=" 101 | }, 102 | "array-find-index": { 103 | "version": "1.0.2", 104 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", 105 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" 106 | }, 107 | "asn1": { 108 | "version": "0.2.4", 109 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 110 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 111 | "requires": { 112 | "safer-buffer": "~2.1.0" 113 | } 114 | }, 115 | "assert-plus": { 116 | "version": "1.0.0", 117 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 118 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 119 | }, 120 | "asynckit": { 121 | "version": "0.4.0", 122 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 123 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 124 | }, 125 | "aws-sign2": { 126 | "version": "0.7.0", 127 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 128 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 129 | }, 130 | "aws4": { 131 | "version": "1.8.0", 132 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 133 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" 134 | }, 135 | "bcrypt-pbkdf": { 136 | "version": "1.0.2", 137 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 138 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 139 | "requires": { 140 | "tweetnacl": "^0.14.3" 141 | } 142 | }, 143 | "bit-twiddle": { 144 | "version": "1.0.2", 145 | "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", 146 | "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4=" 147 | }, 148 | "bl": { 149 | "version": "0.9.5", 150 | "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", 151 | "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", 152 | "requires": { 153 | "readable-stream": "~1.0.26" 154 | }, 155 | "dependencies": { 156 | "readable-stream": { 157 | "version": "1.0.34", 158 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", 159 | "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", 160 | "requires": { 161 | "core-util-is": "~1.0.0", 162 | "inherits": "~2.0.1", 163 | "isarray": "0.0.1", 164 | "string_decoder": "~0.10.x" 165 | } 166 | } 167 | } 168 | }, 169 | "block-stream2": { 170 | "version": "1.1.0", 171 | "resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-1.1.0.tgz", 172 | "integrity": "sha1-xzjjqRupd+u14f70MeE8oR2GOeI=", 173 | "requires": { 174 | "defined": "^1.0.0", 175 | "inherits": "^2.0.1", 176 | "readable-stream": "^2.0.4" 177 | }, 178 | "dependencies": { 179 | "isarray": { 180 | "version": "1.0.0", 181 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 182 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 183 | }, 184 | "readable-stream": { 185 | "version": "2.3.3", 186 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 187 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 188 | "requires": { 189 | "core-util-is": "~1.0.0", 190 | "inherits": "~2.0.3", 191 | "isarray": "~1.0.0", 192 | "process-nextick-args": "~1.0.6", 193 | "safe-buffer": "~5.1.1", 194 | "string_decoder": "~1.0.3", 195 | "util-deprecate": "~1.0.1" 196 | } 197 | }, 198 | "string_decoder": { 199 | "version": "1.0.3", 200 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 201 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 202 | "requires": { 203 | "safe-buffer": "~5.1.0" 204 | } 205 | } 206 | } 207 | }, 208 | "brfs": { 209 | "version": "1.6.1", 210 | "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", 211 | "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", 212 | "requires": { 213 | "quote-stream": "^1.0.1", 214 | "resolve": "^1.1.5", 215 | "static-module": "^2.2.0", 216 | "through2": "^2.0.0" 217 | } 218 | }, 219 | "buffer-crc32": { 220 | "version": "0.2.13", 221 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 222 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" 223 | }, 224 | "buffer-equal": { 225 | "version": "0.0.1", 226 | "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", 227 | "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" 228 | }, 229 | "buffer-from": { 230 | "version": "1.1.1", 231 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 232 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 233 | }, 234 | "buffer-peek-stream": { 235 | "version": "1.0.1", 236 | "resolved": "https://registry.npmjs.org/buffer-peek-stream/-/buffer-peek-stream-1.0.1.tgz", 237 | "integrity": "sha1-U7R1cKE0d4fFutTKLKMCH52LPP0=" 238 | }, 239 | "builtin-modules": { 240 | "version": "1.1.1", 241 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 242 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 243 | }, 244 | "camelcase": { 245 | "version": "2.1.1", 246 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", 247 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" 248 | }, 249 | "camelcase-keys": { 250 | "version": "2.1.0", 251 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", 252 | "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", 253 | "requires": { 254 | "camelcase": "^2.0.0", 255 | "map-obj": "^1.0.0" 256 | } 257 | }, 258 | "cardinal": { 259 | "version": "0.4.4", 260 | "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz", 261 | "integrity": "sha1-ylu2iltRG5D+k7ms6km97lwyv+I=", 262 | "requires": { 263 | "ansicolors": "~0.2.1", 264 | "redeyed": "~0.4.0" 265 | } 266 | }, 267 | "caseless": { 268 | "version": "0.12.0", 269 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 270 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 271 | }, 272 | "co": { 273 | "version": "4.6.0", 274 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 275 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 276 | }, 277 | "code-point-at": { 278 | "version": "1.1.0", 279 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 280 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 281 | }, 282 | "combined-stream": { 283 | "version": "1.0.7", 284 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", 285 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", 286 | "requires": { 287 | "delayed-stream": "~1.0.0" 288 | } 289 | }, 290 | "concat-stream": { 291 | "version": "1.6.2", 292 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 293 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 294 | "requires": { 295 | "buffer-from": "^1.0.0", 296 | "inherits": "^2.0.3", 297 | "readable-stream": "^2.2.2", 298 | "typedarray": "^0.0.6" 299 | }, 300 | "dependencies": { 301 | "isarray": { 302 | "version": "1.0.0", 303 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 304 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 305 | }, 306 | "process-nextick-args": { 307 | "version": "2.0.0", 308 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 309 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 310 | }, 311 | "readable-stream": { 312 | "version": "2.3.6", 313 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 314 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 315 | "requires": { 316 | "core-util-is": "~1.0.0", 317 | "inherits": "~2.0.3", 318 | "isarray": "~1.0.0", 319 | "process-nextick-args": "~2.0.0", 320 | "safe-buffer": "~5.1.1", 321 | "string_decoder": "~1.1.1", 322 | "util-deprecate": "~1.0.1" 323 | } 324 | }, 325 | "string_decoder": { 326 | "version": "1.1.1", 327 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 328 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 329 | "requires": { 330 | "safe-buffer": "~5.1.0" 331 | } 332 | } 333 | } 334 | }, 335 | "convert-source-map": { 336 | "version": "1.6.0", 337 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", 338 | "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", 339 | "requires": { 340 | "safe-buffer": "~5.1.1" 341 | } 342 | }, 343 | "core-util-is": { 344 | "version": "1.0.2", 345 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 346 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 347 | }, 348 | "csscolorparser": { 349 | "version": "1.0.3", 350 | "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", 351 | "integrity": "sha1-s085HupNqPPpgjHizNjfnAQfFxs=" 352 | }, 353 | "currently-unhandled": { 354 | "version": "0.4.1", 355 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", 356 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", 357 | "requires": { 358 | "array-find-index": "^1.0.1" 359 | } 360 | }, 361 | "cwise-compiler": { 362 | "version": "1.1.3", 363 | "resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz", 364 | "integrity": "sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU=", 365 | "requires": { 366 | "uniq": "^1.0.0" 367 | } 368 | }, 369 | "dashdash": { 370 | "version": "1.14.1", 371 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 372 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 373 | "requires": { 374 | "assert-plus": "^1.0.0" 375 | } 376 | }, 377 | "debug": { 378 | "version": "3.2.6", 379 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 380 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 381 | "requires": { 382 | "ms": "^2.1.1" 383 | } 384 | }, 385 | "decamelize": { 386 | "version": "1.2.0", 387 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 388 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 389 | }, 390 | "decimal.js": { 391 | "version": "10.0.1", 392 | "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.0.1.tgz", 393 | "integrity": "sha512-vklWB5C4Cj423xnaOtsUmAv0/7GqlXIgDv2ZKDyR64OV3OSzGHNx2mk4p/1EKnB5s70k73cIOOEcG9YzF0q4Lw==" 394 | }, 395 | "deep-extend": { 396 | "version": "0.6.0", 397 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 398 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 399 | }, 400 | "deep-is": { 401 | "version": "0.1.3", 402 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 403 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" 404 | }, 405 | "defined": { 406 | "version": "1.0.0", 407 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", 408 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" 409 | }, 410 | "delayed-stream": { 411 | "version": "1.0.0", 412 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 413 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 414 | }, 415 | "dup": { 416 | "version": "1.0.0", 417 | "resolved": "https://registry.npmjs.org/dup/-/dup-1.0.0.tgz", 418 | "integrity": "sha1-UfxaxoX4GWRp3wuQXpNLIK9bQCk=" 419 | }, 420 | "duplexer2": { 421 | "version": "0.1.4", 422 | "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", 423 | "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", 424 | "requires": { 425 | "readable-stream": "^2.0.2" 426 | }, 427 | "dependencies": { 428 | "isarray": { 429 | "version": "1.0.0", 430 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 431 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 432 | }, 433 | "process-nextick-args": { 434 | "version": "2.0.0", 435 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 436 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 437 | }, 438 | "readable-stream": { 439 | "version": "2.3.6", 440 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 441 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 442 | "requires": { 443 | "core-util-is": "~1.0.0", 444 | "inherits": "~2.0.3", 445 | "isarray": "~1.0.0", 446 | "process-nextick-args": "~2.0.0", 447 | "safe-buffer": "~5.1.1", 448 | "string_decoder": "~1.1.1", 449 | "util-deprecate": "~1.0.1" 450 | } 451 | }, 452 | "string_decoder": { 453 | "version": "1.1.1", 454 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 455 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 456 | "requires": { 457 | "safe-buffer": "~5.1.0" 458 | } 459 | } 460 | } 461 | }, 462 | "duplexify": { 463 | "version": "3.6.1", 464 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", 465 | "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", 466 | "requires": { 467 | "end-of-stream": "^1.0.0", 468 | "inherits": "^2.0.1", 469 | "readable-stream": "^2.0.0", 470 | "stream-shift": "^1.0.0" 471 | }, 472 | "dependencies": { 473 | "isarray": { 474 | "version": "1.0.0", 475 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 476 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 477 | }, 478 | "process-nextick-args": { 479 | "version": "2.0.0", 480 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 481 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 482 | }, 483 | "readable-stream": { 484 | "version": "2.3.6", 485 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 486 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 487 | "requires": { 488 | "core-util-is": "~1.0.0", 489 | "inherits": "~2.0.3", 490 | "isarray": "~1.0.0", 491 | "process-nextick-args": "~2.0.0", 492 | "safe-buffer": "~5.1.1", 493 | "string_decoder": "~1.1.1", 494 | "util-deprecate": "~1.0.1" 495 | } 496 | }, 497 | "string_decoder": { 498 | "version": "1.1.1", 499 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 500 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 501 | "requires": { 502 | "safe-buffer": "~5.1.0" 503 | } 504 | } 505 | } 506 | }, 507 | "earcut": { 508 | "version": "2.1.3", 509 | "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.1.3.tgz", 510 | "integrity": "sha512-AxdCdWUk1zzK/NuZ7e1ljj6IGC+VAdC3Qb7QQDsXpfNrc5IM8tL9nNXUmEGE6jRHTfZ10zhzRhtDmWVsR5pd3A==" 511 | }, 512 | "ecc-jsbn": { 513 | "version": "0.1.2", 514 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 515 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 516 | "requires": { 517 | "jsbn": "~0.1.0", 518 | "safer-buffer": "^2.1.0" 519 | } 520 | }, 521 | "electron": { 522 | "version": "3.0.7", 523 | "resolved": "https://registry.npmjs.org/electron/-/electron-3.0.7.tgz", 524 | "integrity": "sha512-c/pww23/oPm3wt/wPshuAQCH4ooysS29a9fahxpvYP3ghFZ0zFHN3BWR/WHIEIqPGXWMTD4XbsD7lUtRZEZB+g==", 525 | "requires": { 526 | "@types/node": "^8.0.24", 527 | "electron-download": "^4.1.0", 528 | "extract-zip": "^1.0.3" 529 | } 530 | }, 531 | "electron-download": { 532 | "version": "4.1.1", 533 | "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz", 534 | "integrity": "sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==", 535 | "requires": { 536 | "debug": "^3.0.0", 537 | "env-paths": "^1.0.0", 538 | "fs-extra": "^4.0.1", 539 | "minimist": "^1.2.0", 540 | "nugget": "^2.0.1", 541 | "path-exists": "^3.0.0", 542 | "rc": "^1.2.1", 543 | "semver": "^5.4.1", 544 | "sumchecker": "^2.0.2" 545 | } 546 | }, 547 | "end-of-stream": { 548 | "version": "1.4.1", 549 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", 550 | "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 551 | "requires": { 552 | "once": "^1.4.0" 553 | } 554 | }, 555 | "env-paths": { 556 | "version": "1.0.0", 557 | "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz", 558 | "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=" 559 | }, 560 | "error-ex": { 561 | "version": "1.3.2", 562 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 563 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 564 | "requires": { 565 | "is-arrayish": "^0.2.1" 566 | } 567 | }, 568 | "escodegen": { 569 | "version": "1.9.1", 570 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", 571 | "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", 572 | "requires": { 573 | "esprima": "^3.1.3", 574 | "estraverse": "^4.2.0", 575 | "esutils": "^2.0.2", 576 | "optionator": "^0.8.1", 577 | "source-map": "~0.6.1" 578 | } 579 | }, 580 | "esprima": { 581 | "version": "3.1.3", 582 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 583 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" 584 | }, 585 | "estraverse": { 586 | "version": "4.2.0", 587 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 588 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" 589 | }, 590 | "esutils": { 591 | "version": "2.0.2", 592 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 593 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" 594 | }, 595 | "expect.js": { 596 | "version": "0.2.0", 597 | "resolved": "https://registry.npmjs.org/expect.js/-/expect.js-0.2.0.tgz", 598 | "integrity": "sha1-EChTPSwcNj90pnlv9X7AUg3tK+E=" 599 | }, 600 | "extend": { 601 | "version": "3.0.2", 602 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 603 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 604 | }, 605 | "extract-zip": { 606 | "version": "1.6.7", 607 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", 608 | "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", 609 | "requires": { 610 | "concat-stream": "1.6.2", 611 | "debug": "2.6.9", 612 | "mkdirp": "0.5.1", 613 | "yauzl": "2.4.1" 614 | }, 615 | "dependencies": { 616 | "debug": { 617 | "version": "2.6.9", 618 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 619 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 620 | "requires": { 621 | "ms": "2.0.0" 622 | } 623 | }, 624 | "ms": { 625 | "version": "2.0.0", 626 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 627 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 628 | } 629 | } 630 | }, 631 | "extsprintf": { 632 | "version": "1.3.0", 633 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 634 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 635 | }, 636 | "falafel": { 637 | "version": "2.1.0", 638 | "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz", 639 | "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", 640 | "requires": { 641 | "acorn": "^5.0.0", 642 | "foreach": "^2.0.5", 643 | "isarray": "0.0.1", 644 | "object-keys": "^1.0.6" 645 | }, 646 | "dependencies": { 647 | "object-keys": { 648 | "version": "1.0.12", 649 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", 650 | "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" 651 | } 652 | } 653 | }, 654 | "fast-deep-equal": { 655 | "version": "1.1.0", 656 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 657 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 658 | }, 659 | "fast-json-stable-stringify": { 660 | "version": "2.0.0", 661 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 662 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 663 | }, 664 | "fast-levenshtein": { 665 | "version": "2.0.6", 666 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 667 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 668 | }, 669 | "fd-slicer": { 670 | "version": "1.0.1", 671 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", 672 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", 673 | "requires": { 674 | "pend": "~1.2.0" 675 | } 676 | }, 677 | "find-up": { 678 | "version": "1.1.2", 679 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 680 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 681 | "requires": { 682 | "path-exists": "^2.0.0", 683 | "pinkie-promise": "^2.0.0" 684 | }, 685 | "dependencies": { 686 | "path-exists": { 687 | "version": "2.1.0", 688 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 689 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 690 | "requires": { 691 | "pinkie-promise": "^2.0.0" 692 | } 693 | } 694 | } 695 | }, 696 | "flush-write-stream": { 697 | "version": "1.0.2", 698 | "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz", 699 | "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=", 700 | "requires": { 701 | "inherits": "^2.0.1", 702 | "readable-stream": "^2.0.4" 703 | }, 704 | "dependencies": { 705 | "isarray": { 706 | "version": "1.0.0", 707 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 708 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 709 | }, 710 | "readable-stream": { 711 | "version": "2.3.3", 712 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 713 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 714 | "requires": { 715 | "core-util-is": "~1.0.0", 716 | "inherits": "~2.0.3", 717 | "isarray": "~1.0.0", 718 | "process-nextick-args": "~1.0.6", 719 | "safe-buffer": "~5.1.1", 720 | "string_decoder": "~1.0.3", 721 | "util-deprecate": "~1.0.1" 722 | } 723 | }, 724 | "string_decoder": { 725 | "version": "1.0.3", 726 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 727 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 728 | "requires": { 729 | "safe-buffer": "~5.1.0" 730 | } 731 | } 732 | } 733 | }, 734 | "foreach": { 735 | "version": "2.0.5", 736 | "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", 737 | "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" 738 | }, 739 | "forever-agent": { 740 | "version": "0.6.1", 741 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 742 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 743 | }, 744 | "form-data": { 745 | "version": "2.3.3", 746 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 747 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 748 | "requires": { 749 | "asynckit": "^0.4.0", 750 | "combined-stream": "^1.0.6", 751 | "mime-types": "^2.1.12" 752 | } 753 | }, 754 | "from2": { 755 | "version": "2.3.0", 756 | "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", 757 | "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", 758 | "requires": { 759 | "inherits": "^2.0.1", 760 | "readable-stream": "^2.0.0" 761 | }, 762 | "dependencies": { 763 | "isarray": { 764 | "version": "1.0.0", 765 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 766 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 767 | }, 768 | "readable-stream": { 769 | "version": "2.3.3", 770 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 771 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 772 | "requires": { 773 | "core-util-is": "~1.0.0", 774 | "inherits": "~2.0.3", 775 | "isarray": "~1.0.0", 776 | "process-nextick-args": "~1.0.6", 777 | "safe-buffer": "~5.1.1", 778 | "string_decoder": "~1.0.3", 779 | "util-deprecate": "~1.0.1" 780 | } 781 | }, 782 | "string_decoder": { 783 | "version": "1.0.3", 784 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 785 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 786 | "requires": { 787 | "safe-buffer": "~5.1.0" 788 | } 789 | } 790 | } 791 | }, 792 | "fs-extra": { 793 | "version": "4.0.3", 794 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", 795 | "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", 796 | "requires": { 797 | "graceful-fs": "^4.1.2", 798 | "jsonfile": "^4.0.0", 799 | "universalify": "^0.1.0" 800 | } 801 | }, 802 | "function-bind": { 803 | "version": "1.1.1", 804 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 805 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 806 | }, 807 | "geojson-rewind": { 808 | "version": "0.3.1", 809 | "resolved": "https://registry.npmjs.org/geojson-rewind/-/geojson-rewind-0.3.1.tgz", 810 | "integrity": "sha1-IiQHl8hHzC8MHTE+SqDJFa+n8p0=", 811 | "requires": { 812 | "@mapbox/geojson-area": "0.2.2", 813 | "concat-stream": "~1.6.0", 814 | "minimist": "1.2.0", 815 | "sharkdown": "^0.1.0" 816 | } 817 | }, 818 | "geojson-vt": { 819 | "version": "3.2.1", 820 | "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", 821 | "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==" 822 | }, 823 | "get-stdin": { 824 | "version": "4.0.1", 825 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", 826 | "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" 827 | }, 828 | "getpass": { 829 | "version": "0.1.7", 830 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 831 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 832 | "requires": { 833 | "assert-plus": "^1.0.0" 834 | } 835 | }, 836 | "gl-fbo": { 837 | "version": "2.0.5", 838 | "resolved": "https://registry.npmjs.org/gl-fbo/-/gl-fbo-2.0.5.tgz", 839 | "integrity": "sha1-D6daSXz3h2lVMGkcjwSrtvtV+iI=", 840 | "requires": { 841 | "gl-texture2d": "^2.0.0" 842 | } 843 | }, 844 | "gl-matrix": { 845 | "version": "2.8.1", 846 | "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-2.8.1.tgz", 847 | "integrity": "sha512-0YCjVpE3pS5XWlN3J4X7AiAx65+nqAI54LndtVFnQZB6G/FVLkZH8y8V6R3cIoOQR4pUdfwQGd1iwyoXHJ4Qfw==" 848 | }, 849 | "gl-pixel-stream": { 850 | "version": "1.2.0", 851 | "resolved": "https://registry.npmjs.org/gl-pixel-stream/-/gl-pixel-stream-1.2.0.tgz", 852 | "integrity": "sha1-9HsVG7n7ZWJ4CRDEnjssXFSISh8=", 853 | "requires": { 854 | "readable-stream": "^2.0.3" 855 | }, 856 | "dependencies": { 857 | "isarray": { 858 | "version": "1.0.0", 859 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 860 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 861 | }, 862 | "readable-stream": { 863 | "version": "2.3.3", 864 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 865 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 866 | "requires": { 867 | "core-util-is": "~1.0.0", 868 | "inherits": "~2.0.3", 869 | "isarray": "~1.0.0", 870 | "process-nextick-args": "~1.0.6", 871 | "safe-buffer": "~5.1.1", 872 | "string_decoder": "~1.0.3", 873 | "util-deprecate": "~1.0.1" 874 | } 875 | }, 876 | "string_decoder": { 877 | "version": "1.0.3", 878 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 879 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 880 | "requires": { 881 | "safe-buffer": "~5.1.0" 882 | } 883 | } 884 | } 885 | }, 886 | "gl-texture2d": { 887 | "version": "2.1.0", 888 | "resolved": "https://registry.npmjs.org/gl-texture2d/-/gl-texture2d-2.1.0.tgz", 889 | "integrity": "sha1-/2gk5+fDGoum/c2+nlxpXX4hh8c=", 890 | "requires": { 891 | "ndarray": "^1.0.15", 892 | "ndarray-ops": "^1.2.2", 893 | "typedarray-pool": "^1.1.0" 894 | } 895 | }, 896 | "graceful-fs": { 897 | "version": "4.1.14", 898 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.14.tgz", 899 | "integrity": "sha512-ns/IGcSmmGNPP085JCheg0Nombh1QPvSCnlx+2V+byQWRQEIL4ZB5jXJMNIHOFVS1roi85HIi5Ka0h43iWXfcQ==" 900 | }, 901 | "grid-index": { 902 | "version": "1.0.0", 903 | "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.0.0.tgz", 904 | "integrity": "sha1-rSxdVM5bNUN/r/HXCprrPR0mERA=" 905 | }, 906 | "har-schema": { 907 | "version": "2.0.0", 908 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 909 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 910 | }, 911 | "har-validator": { 912 | "version": "5.1.0", 913 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", 914 | "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", 915 | "requires": { 916 | "ajv": "^5.3.0", 917 | "har-schema": "^2.0.0" 918 | } 919 | }, 920 | "has": { 921 | "version": "1.0.3", 922 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 923 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 924 | "requires": { 925 | "function-bind": "^1.1.1" 926 | } 927 | }, 928 | "hosted-git-info": { 929 | "version": "2.7.1", 930 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", 931 | "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" 932 | }, 933 | "http-signature": { 934 | "version": "1.2.0", 935 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 936 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 937 | "requires": { 938 | "assert-plus": "^1.0.0", 939 | "jsprim": "^1.2.2", 940 | "sshpk": "^1.7.0" 941 | } 942 | }, 943 | "ieee754": { 944 | "version": "1.1.12", 945 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", 946 | "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" 947 | }, 948 | "indent-string": { 949 | "version": "2.1.0", 950 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", 951 | "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", 952 | "requires": { 953 | "repeating": "^2.0.0" 954 | } 955 | }, 956 | "inherits": { 957 | "version": "2.0.3", 958 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 959 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 960 | }, 961 | "ini": { 962 | "version": "1.3.5", 963 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 964 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 965 | }, 966 | "interleave-stream": { 967 | "version": "1.0.2", 968 | "resolved": "https://registry.npmjs.org/interleave-stream/-/interleave-stream-1.0.2.tgz", 969 | "integrity": "sha1-WEEWBJvwvIoz3U/RX2+++h4TvEg=", 970 | "requires": { 971 | "flush-write-stream": "^1.0.2", 972 | "from2": "^2.3.0", 973 | "once": "^1.4.0" 974 | } 975 | }, 976 | "iota-array": { 977 | "version": "1.0.0", 978 | "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", 979 | "integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" 980 | }, 981 | "is-arrayish": { 982 | "version": "0.2.1", 983 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 984 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" 985 | }, 986 | "is-buffer": { 987 | "version": "1.1.5", 988 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", 989 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" 990 | }, 991 | "is-builtin-module": { 992 | "version": "1.0.0", 993 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 994 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 995 | "requires": { 996 | "builtin-modules": "^1.0.0" 997 | } 998 | }, 999 | "is-finite": { 1000 | "version": "1.0.2", 1001 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 1002 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 1003 | "requires": { 1004 | "number-is-nan": "^1.0.0" 1005 | } 1006 | }, 1007 | "is-fullwidth-code-point": { 1008 | "version": "1.0.0", 1009 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 1010 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 1011 | "requires": { 1012 | "number-is-nan": "^1.0.0" 1013 | } 1014 | }, 1015 | "is-typedarray": { 1016 | "version": "1.0.0", 1017 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1018 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 1019 | }, 1020 | "is-utf8": { 1021 | "version": "0.2.1", 1022 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 1023 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" 1024 | }, 1025 | "isarray": { 1026 | "version": "0.0.1", 1027 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 1028 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 1029 | }, 1030 | "isstream": { 1031 | "version": "0.1.2", 1032 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 1033 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 1034 | }, 1035 | "js-quantities": { 1036 | "version": "1.7.2", 1037 | "resolved": "https://registry.npmjs.org/js-quantities/-/js-quantities-1.7.2.tgz", 1038 | "integrity": "sha512-bnvOFPJ38cQT4bn3M7xwoaEM0ki+w1mVTH3LNFvkphmZLxoKIihjHZbAvI9Ep1eCMVZ5aHFDVxfCQ/t80sI28w==" 1039 | }, 1040 | "jsbn": { 1041 | "version": "0.1.1", 1042 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 1043 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 1044 | }, 1045 | "json-schema": { 1046 | "version": "0.2.3", 1047 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 1048 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 1049 | }, 1050 | "json-schema-traverse": { 1051 | "version": "0.3.1", 1052 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 1053 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 1054 | }, 1055 | "json-stringify-safe": { 1056 | "version": "5.0.1", 1057 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 1058 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 1059 | }, 1060 | "jsonfile": { 1061 | "version": "4.0.0", 1062 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 1063 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 1064 | "requires": { 1065 | "graceful-fs": "^4.1.6" 1066 | } 1067 | }, 1068 | "jsprim": { 1069 | "version": "1.4.1", 1070 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 1071 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 1072 | "requires": { 1073 | "assert-plus": "1.0.0", 1074 | "extsprintf": "1.3.0", 1075 | "json-schema": "0.2.3", 1076 | "verror": "1.10.0" 1077 | } 1078 | }, 1079 | "kdbush": { 1080 | "version": "2.0.1", 1081 | "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-2.0.1.tgz", 1082 | "integrity": "sha512-9KqSdmWCkBIisFIGclT0FRagKhI7IVbMyUjsxCFG0Ly1Dg6whlxJ7b9lrq8ifk3X/fGeJzok1R75LQfZTfA5zQ==" 1083 | }, 1084 | "levn": { 1085 | "version": "0.3.0", 1086 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1087 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1088 | "requires": { 1089 | "prelude-ls": "~1.1.2", 1090 | "type-check": "~0.3.2" 1091 | } 1092 | }, 1093 | "load-json-file": { 1094 | "version": "1.1.0", 1095 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", 1096 | "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", 1097 | "requires": { 1098 | "graceful-fs": "^4.1.2", 1099 | "parse-json": "^2.2.0", 1100 | "pify": "^2.0.0", 1101 | "pinkie-promise": "^2.0.0", 1102 | "strip-bom": "^2.0.0" 1103 | } 1104 | }, 1105 | "loud-rejection": { 1106 | "version": "1.6.0", 1107 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", 1108 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", 1109 | "requires": { 1110 | "currently-unhandled": "^0.4.1", 1111 | "signal-exit": "^3.0.0" 1112 | } 1113 | }, 1114 | "magic-string": { 1115 | "version": "0.22.5", 1116 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", 1117 | "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", 1118 | "requires": { 1119 | "vlq": "^0.2.2" 1120 | } 1121 | }, 1122 | "map-obj": { 1123 | "version": "1.0.1", 1124 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", 1125 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" 1126 | }, 1127 | "mapbox-gl": { 1128 | "version": "0.49.0", 1129 | "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-0.49.0.tgz", 1130 | "integrity": "sha512-2gbKNosaIQjHp6xgCcOLYAC+vnmgYQ89qiOtip5L8tQLPhsJ3vNwU7pXRaCm4sFU1i8JakvF13vu8Xnsi5/ssA==", 1131 | "requires": { 1132 | "@mapbox/geojson-types": "^1.0.2", 1133 | "@mapbox/jsonlint-lines-primitives": "^2.0.2", 1134 | "@mapbox/mapbox-gl-supported": "^1.4.0", 1135 | "@mapbox/point-geometry": "^0.1.0", 1136 | "@mapbox/tiny-sdf": "^1.1.0", 1137 | "@mapbox/unitbezier": "^0.0.0", 1138 | "@mapbox/vector-tile": "^1.3.1", 1139 | "@mapbox/whoots-js": "^3.1.0", 1140 | "brfs": "^1.4.4", 1141 | "csscolorparser": "~1.0.2", 1142 | "earcut": "^2.1.3", 1143 | "geojson-rewind": "^0.3.0", 1144 | "geojson-vt": "^3.2.0", 1145 | "gl-matrix": "^2.6.1", 1146 | "grid-index": "^1.0.0", 1147 | "minimist": "0.0.8", 1148 | "murmurhash-js": "^1.0.0", 1149 | "pbf": "^3.0.5", 1150 | "potpack": "^1.0.1", 1151 | "quickselect": "^1.0.0", 1152 | "rw": "^1.3.3", 1153 | "supercluster": "^4.1.1", 1154 | "tinyqueue": "^1.1.0", 1155 | "vt-pbf": "^3.0.1" 1156 | }, 1157 | "dependencies": { 1158 | "minimist": { 1159 | "version": "0.0.8", 1160 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1161 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 1162 | } 1163 | } 1164 | }, 1165 | "meow": { 1166 | "version": "3.7.0", 1167 | "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", 1168 | "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", 1169 | "requires": { 1170 | "camelcase-keys": "^2.0.0", 1171 | "decamelize": "^1.1.2", 1172 | "loud-rejection": "^1.0.0", 1173 | "map-obj": "^1.0.1", 1174 | "minimist": "^1.1.3", 1175 | "normalize-package-data": "^2.3.4", 1176 | "object-assign": "^4.0.1", 1177 | "read-pkg-up": "^1.0.1", 1178 | "redent": "^1.0.0", 1179 | "trim-newlines": "^1.0.0" 1180 | } 1181 | }, 1182 | "merge-source-map": { 1183 | "version": "1.0.4", 1184 | "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", 1185 | "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", 1186 | "requires": { 1187 | "source-map": "^0.5.6" 1188 | }, 1189 | "dependencies": { 1190 | "source-map": { 1191 | "version": "0.5.7", 1192 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1193 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" 1194 | } 1195 | } 1196 | }, 1197 | "mime-db": { 1198 | "version": "1.37.0", 1199 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", 1200 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" 1201 | }, 1202 | "mime-types": { 1203 | "version": "2.1.21", 1204 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", 1205 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 1206 | "requires": { 1207 | "mime-db": "~1.37.0" 1208 | } 1209 | }, 1210 | "minimist": { 1211 | "version": "1.2.0", 1212 | "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 1213 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 1214 | }, 1215 | "mkdirp": { 1216 | "version": "0.5.1", 1217 | "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1218 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1219 | "requires": { 1220 | "minimist": "0.0.8" 1221 | }, 1222 | "dependencies": { 1223 | "minimist": { 1224 | "version": "0.0.8", 1225 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1226 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 1227 | } 1228 | } 1229 | }, 1230 | "mosaic-image-stream": { 1231 | "version": "1.0.2", 1232 | "resolved": "https://registry.npmjs.org/mosaic-image-stream/-/mosaic-image-stream-1.0.2.tgz", 1233 | "integrity": "sha1-jE2FFq7stmqlwKsW9zyUOvghmzs=", 1234 | "requires": { 1235 | "block-stream2": "^1.1.0", 1236 | "buffer-peek-stream": "^1.0.1", 1237 | "from2": "^2.3.0", 1238 | "inherits": "^2.0.1", 1239 | "interleave-stream": "^1.0.2", 1240 | "multistream": "^2.1.0", 1241 | "pumpify": "^1.3.5" 1242 | } 1243 | }, 1244 | "ms": { 1245 | "version": "2.1.1", 1246 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1247 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1248 | }, 1249 | "multistream": { 1250 | "version": "2.1.1", 1251 | "resolved": "https://registry.npmjs.org/multistream/-/multistream-2.1.1.tgz", 1252 | "integrity": "sha512-xasv76hl6nr1dEy3lPvy7Ej7K/Lx3O/FCvwge8PeVJpciPPoNCbaANcNiBug3IpdvTveZUcAV0DJzdnUDMesNQ==", 1253 | "requires": { 1254 | "inherits": "^2.0.1", 1255 | "readable-stream": "^2.0.5" 1256 | }, 1257 | "dependencies": { 1258 | "isarray": { 1259 | "version": "1.0.0", 1260 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1261 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 1262 | }, 1263 | "process-nextick-args": { 1264 | "version": "2.0.0", 1265 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1266 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 1267 | }, 1268 | "readable-stream": { 1269 | "version": "2.3.6", 1270 | "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 1271 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1272 | "requires": { 1273 | "core-util-is": "~1.0.0", 1274 | "inherits": "~2.0.3", 1275 | "isarray": "~1.0.0", 1276 | "process-nextick-args": "~2.0.0", 1277 | "safe-buffer": "~5.1.1", 1278 | "string_decoder": "~1.1.1", 1279 | "util-deprecate": "~1.0.1" 1280 | } 1281 | }, 1282 | "string_decoder": { 1283 | "version": "1.1.1", 1284 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1285 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1286 | "requires": { 1287 | "safe-buffer": "~5.1.0" 1288 | } 1289 | } 1290 | } 1291 | }, 1292 | "murmurhash-js": { 1293 | "version": "1.0.0", 1294 | "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", 1295 | "integrity": "sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E=" 1296 | }, 1297 | "ndarray": { 1298 | "version": "1.0.18", 1299 | "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.18.tgz", 1300 | "integrity": "sha1-tg06cyJOxVXQ+qeXEeUCRI/T95M=", 1301 | "requires": { 1302 | "iota-array": "^1.0.0", 1303 | "is-buffer": "^1.0.2" 1304 | } 1305 | }, 1306 | "ndarray-ops": { 1307 | "version": "1.2.2", 1308 | "resolved": "https://registry.npmjs.org/ndarray-ops/-/ndarray-ops-1.2.2.tgz", 1309 | "integrity": "sha1-WeiNLDKn7ryxvGkPrhQVeVV6YU4=", 1310 | "requires": { 1311 | "cwise-compiler": "^1.0.0" 1312 | } 1313 | }, 1314 | "normalize-package-data": { 1315 | "version": "2.4.0", 1316 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 1317 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 1318 | "requires": { 1319 | "hosted-git-info": "^2.1.4", 1320 | "is-builtin-module": "^1.0.0", 1321 | "semver": "2 || 3 || 4 || 5", 1322 | "validate-npm-package-license": "^3.0.1" 1323 | } 1324 | }, 1325 | "nugget": { 1326 | "version": "2.0.1", 1327 | "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz", 1328 | "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", 1329 | "requires": { 1330 | "debug": "^2.1.3", 1331 | "minimist": "^1.1.0", 1332 | "pretty-bytes": "^1.0.2", 1333 | "progress-stream": "^1.1.0", 1334 | "request": "^2.45.0", 1335 | "single-line-log": "^1.1.2", 1336 | "throttleit": "0.0.2" 1337 | }, 1338 | "dependencies": { 1339 | "debug": { 1340 | "version": "2.6.9", 1341 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1342 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1343 | "requires": { 1344 | "ms": "2.0.0" 1345 | } 1346 | }, 1347 | "ms": { 1348 | "version": "2.0.0", 1349 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1350 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1351 | } 1352 | } 1353 | }, 1354 | "number-is-nan": { 1355 | "version": "1.0.1", 1356 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 1357 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 1358 | }, 1359 | "oauth-sign": { 1360 | "version": "0.9.0", 1361 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 1362 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 1363 | }, 1364 | "object-assign": { 1365 | "version": "4.1.1", 1366 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1367 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1368 | }, 1369 | "object-inspect": { 1370 | "version": "1.4.1", 1371 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", 1372 | "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==" 1373 | }, 1374 | "object-keys": { 1375 | "version": "0.4.0", 1376 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", 1377 | "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" 1378 | }, 1379 | "once": { 1380 | "version": "1.4.0", 1381 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1382 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1383 | "requires": { 1384 | "wrappy": "1" 1385 | } 1386 | }, 1387 | "optionator": { 1388 | "version": "0.8.2", 1389 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 1390 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 1391 | "requires": { 1392 | "deep-is": "~0.1.3", 1393 | "fast-levenshtein": "~2.0.4", 1394 | "levn": "~0.3.0", 1395 | "prelude-ls": "~1.1.2", 1396 | "type-check": "~0.3.2", 1397 | "wordwrap": "~1.0.0" 1398 | } 1399 | }, 1400 | "parse-json": { 1401 | "version": "2.2.0", 1402 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1403 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1404 | "requires": { 1405 | "error-ex": "^1.2.0" 1406 | } 1407 | }, 1408 | "path-exists": { 1409 | "version": "3.0.0", 1410 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1411 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 1412 | }, 1413 | "path-parse": { 1414 | "version": "1.0.6", 1415 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1416 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" 1417 | }, 1418 | "path-type": { 1419 | "version": "1.1.0", 1420 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", 1421 | "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", 1422 | "requires": { 1423 | "graceful-fs": "^4.1.2", 1424 | "pify": "^2.0.0", 1425 | "pinkie-promise": "^2.0.0" 1426 | } 1427 | }, 1428 | "pbf": { 1429 | "version": "3.1.0", 1430 | "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.1.0.tgz", 1431 | "integrity": "sha512-/hYJmIsTmh7fMkHAWWXJ5b8IKLWdjdlAFb3IHkRBn1XUhIYBChVGfVwmHEAV3UfXTxsP/AKfYTXTS/dCPxJd5w==", 1432 | "requires": { 1433 | "ieee754": "^1.1.6", 1434 | "resolve-protobuf-schema": "^2.0.0" 1435 | } 1436 | }, 1437 | "pend": { 1438 | "version": "1.2.0", 1439 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 1440 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 1441 | }, 1442 | "performance-now": { 1443 | "version": "2.1.0", 1444 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1445 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 1446 | }, 1447 | "pify": { 1448 | "version": "2.3.0", 1449 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1450 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" 1451 | }, 1452 | "pinkie": { 1453 | "version": "2.0.4", 1454 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1455 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" 1456 | }, 1457 | "pinkie-promise": { 1458 | "version": "2.0.1", 1459 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1460 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1461 | "requires": { 1462 | "pinkie": "^2.0.0" 1463 | } 1464 | }, 1465 | "pixel-stream": { 1466 | "version": "1.0.3", 1467 | "resolved": "https://registry.npmjs.org/pixel-stream/-/pixel-stream-1.0.3.tgz", 1468 | "integrity": "sha1-U+jFSyHVUIOTtTvLMrZKd1Xx+l4=", 1469 | "requires": { 1470 | "shallow-copy": "0.0.1" 1471 | } 1472 | }, 1473 | "png-stream": { 1474 | "version": "1.0.5", 1475 | "resolved": "https://registry.npmjs.org/png-stream/-/png-stream-1.0.5.tgz", 1476 | "integrity": "sha1-W8cWh+qJWUJ+lQ5Sx8yknipvBMY=", 1477 | "requires": { 1478 | "bl": "^0.9.3", 1479 | "buffer-crc32": "^0.2.3", 1480 | "buffer-equal": "^0.0.1", 1481 | "pixel-stream": "^1.0.3" 1482 | } 1483 | }, 1484 | "potpack": { 1485 | "version": "1.0.1", 1486 | "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.1.tgz", 1487 | "integrity": "sha512-15vItUAbViaYrmaB/Pbw7z6qX2xENbFSTA7Ii4tgbPtasxm5v6ryKhKtL91tpWovDJzTiZqdwzhcFBCwiMVdVw==" 1488 | }, 1489 | "prelude-ls": { 1490 | "version": "1.1.2", 1491 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1492 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 1493 | }, 1494 | "pretty-bytes": { 1495 | "version": "1.0.4", 1496 | "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", 1497 | "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", 1498 | "requires": { 1499 | "get-stdin": "^4.0.1", 1500 | "meow": "^3.1.0" 1501 | } 1502 | }, 1503 | "process-nextick-args": { 1504 | "version": "1.0.7", 1505 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 1506 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" 1507 | }, 1508 | "progress-stream": { 1509 | "version": "1.2.0", 1510 | "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz", 1511 | "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=", 1512 | "requires": { 1513 | "speedometer": "~0.1.2", 1514 | "through2": "~0.2.3" 1515 | }, 1516 | "dependencies": { 1517 | "through2": { 1518 | "version": "0.2.3", 1519 | "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", 1520 | "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", 1521 | "requires": { 1522 | "readable-stream": "~1.1.9", 1523 | "xtend": "~2.1.1" 1524 | } 1525 | } 1526 | } 1527 | }, 1528 | "protocol-buffers-schema": { 1529 | "version": "3.3.2", 1530 | "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz", 1531 | "integrity": "sha512-Xdayp8sB/mU+sUV4G7ws8xtYMGdQnxbeIfLjyO9TZZRJdztBGhlmbI5x1qcY4TG5hBkIKGnc28i7nXxaugu88w==" 1532 | }, 1533 | "psl": { 1534 | "version": "1.1.29", 1535 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", 1536 | "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" 1537 | }, 1538 | "pump": { 1539 | "version": "3.0.0", 1540 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 1541 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 1542 | "requires": { 1543 | "end-of-stream": "^1.1.0", 1544 | "once": "^1.3.1" 1545 | } 1546 | }, 1547 | "pumpify": { 1548 | "version": "1.5.1", 1549 | "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", 1550 | "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", 1551 | "requires": { 1552 | "duplexify": "^3.6.0", 1553 | "inherits": "^2.0.3", 1554 | "pump": "^2.0.0" 1555 | }, 1556 | "dependencies": { 1557 | "pump": { 1558 | "version": "2.0.1", 1559 | "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", 1560 | "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", 1561 | "requires": { 1562 | "end-of-stream": "^1.1.0", 1563 | "once": "^1.3.1" 1564 | } 1565 | } 1566 | } 1567 | }, 1568 | "punycode": { 1569 | "version": "1.4.1", 1570 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 1571 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 1572 | }, 1573 | "qs": { 1574 | "version": "6.5.2", 1575 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1576 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 1577 | }, 1578 | "quickselect": { 1579 | "version": "1.1.1", 1580 | "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-1.1.1.tgz", 1581 | "integrity": "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ==" 1582 | }, 1583 | "quote-stream": { 1584 | "version": "1.0.2", 1585 | "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz", 1586 | "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=", 1587 | "requires": { 1588 | "buffer-equal": "0.0.1", 1589 | "minimist": "^1.1.3", 1590 | "through2": "^2.0.0" 1591 | } 1592 | }, 1593 | "rc": { 1594 | "version": "1.2.8", 1595 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 1596 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 1597 | "requires": { 1598 | "deep-extend": "^0.6.0", 1599 | "ini": "~1.3.0", 1600 | "minimist": "^1.2.0", 1601 | "strip-json-comments": "~2.0.1" 1602 | } 1603 | }, 1604 | "read-pkg": { 1605 | "version": "1.1.0", 1606 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", 1607 | "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", 1608 | "requires": { 1609 | "load-json-file": "^1.0.0", 1610 | "normalize-package-data": "^2.3.2", 1611 | "path-type": "^1.0.0" 1612 | } 1613 | }, 1614 | "read-pkg-up": { 1615 | "version": "1.0.1", 1616 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", 1617 | "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", 1618 | "requires": { 1619 | "find-up": "^1.0.0", 1620 | "read-pkg": "^1.0.0" 1621 | } 1622 | }, 1623 | "readable-stream": { 1624 | "version": "1.1.14", 1625 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 1626 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 1627 | "requires": { 1628 | "core-util-is": "~1.0.0", 1629 | "inherits": "~2.0.1", 1630 | "isarray": "0.0.1", 1631 | "string_decoder": "~0.10.x" 1632 | } 1633 | }, 1634 | "redent": { 1635 | "version": "1.0.0", 1636 | "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", 1637 | "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", 1638 | "requires": { 1639 | "indent-string": "^2.1.0", 1640 | "strip-indent": "^1.0.1" 1641 | } 1642 | }, 1643 | "redeyed": { 1644 | "version": "0.4.4", 1645 | "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", 1646 | "integrity": "sha1-N+mQpvKyGyoRwuakj9QTVpjLqX8=", 1647 | "requires": { 1648 | "esprima": "~1.0.4" 1649 | }, 1650 | "dependencies": { 1651 | "esprima": { 1652 | "version": "1.0.4", 1653 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", 1654 | "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=" 1655 | } 1656 | } 1657 | }, 1658 | "repeating": { 1659 | "version": "2.0.1", 1660 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 1661 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 1662 | "requires": { 1663 | "is-finite": "^1.0.0" 1664 | } 1665 | }, 1666 | "request": { 1667 | "version": "2.88.0", 1668 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 1669 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 1670 | "requires": { 1671 | "aws-sign2": "~0.7.0", 1672 | "aws4": "^1.8.0", 1673 | "caseless": "~0.12.0", 1674 | "combined-stream": "~1.0.6", 1675 | "extend": "~3.0.2", 1676 | "forever-agent": "~0.6.1", 1677 | "form-data": "~2.3.2", 1678 | "har-validator": "~5.1.0", 1679 | "http-signature": "~1.2.0", 1680 | "is-typedarray": "~1.0.0", 1681 | "isstream": "~0.1.2", 1682 | "json-stringify-safe": "~5.0.1", 1683 | "mime-types": "~2.1.19", 1684 | "oauth-sign": "~0.9.0", 1685 | "performance-now": "^2.1.0", 1686 | "qs": "~6.5.2", 1687 | "safe-buffer": "^5.1.2", 1688 | "tough-cookie": "~2.4.3", 1689 | "tunnel-agent": "^0.6.0", 1690 | "uuid": "^3.3.2" 1691 | }, 1692 | "dependencies": { 1693 | "safe-buffer": { 1694 | "version": "5.1.2", 1695 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1696 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1697 | } 1698 | } 1699 | }, 1700 | "resolve": { 1701 | "version": "1.8.1", 1702 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", 1703 | "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", 1704 | "requires": { 1705 | "path-parse": "^1.0.5" 1706 | } 1707 | }, 1708 | "resolve-protobuf-schema": { 1709 | "version": "2.1.0", 1710 | "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", 1711 | "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", 1712 | "requires": { 1713 | "protocol-buffers-schema": "^3.3.1" 1714 | } 1715 | }, 1716 | "rw": { 1717 | "version": "1.3.3", 1718 | "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", 1719 | "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" 1720 | }, 1721 | "safe-buffer": { 1722 | "version": "5.1.1", 1723 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 1724 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 1725 | }, 1726 | "safer-buffer": { 1727 | "version": "2.1.2", 1728 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1729 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1730 | }, 1731 | "semver": { 1732 | "version": "5.6.0", 1733 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", 1734 | "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" 1735 | }, 1736 | "shallow-copy": { 1737 | "version": "0.0.1", 1738 | "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", 1739 | "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=" 1740 | }, 1741 | "sharkdown": { 1742 | "version": "0.1.0", 1743 | "resolved": "https://registry.npmjs.org/sharkdown/-/sharkdown-0.1.0.tgz", 1744 | "integrity": "sha1-YdT+Up510CRCEnzJI0NiJlCZIU8=", 1745 | "requires": { 1746 | "cardinal": "~0.4.2", 1747 | "expect.js": "~0.2.0", 1748 | "minimist": "0.0.5", 1749 | "split": "~0.2.10", 1750 | "stream-spigot": "~2.1.2", 1751 | "through": "~2.3.4" 1752 | }, 1753 | "dependencies": { 1754 | "minimist": { 1755 | "version": "0.0.5", 1756 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz", 1757 | "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=" 1758 | } 1759 | } 1760 | }, 1761 | "signal-exit": { 1762 | "version": "3.0.2", 1763 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1764 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 1765 | }, 1766 | "single-line-log": { 1767 | "version": "1.1.2", 1768 | "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz", 1769 | "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=", 1770 | "requires": { 1771 | "string-width": "^1.0.1" 1772 | } 1773 | }, 1774 | "source-map": { 1775 | "version": "0.6.1", 1776 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1777 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1778 | "optional": true 1779 | }, 1780 | "spdx-correct": { 1781 | "version": "3.0.2", 1782 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", 1783 | "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", 1784 | "requires": { 1785 | "spdx-expression-parse": "^3.0.0", 1786 | "spdx-license-ids": "^3.0.0" 1787 | } 1788 | }, 1789 | "spdx-exceptions": { 1790 | "version": "2.2.0", 1791 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", 1792 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" 1793 | }, 1794 | "spdx-expression-parse": { 1795 | "version": "3.0.0", 1796 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 1797 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 1798 | "requires": { 1799 | "spdx-exceptions": "^2.1.0", 1800 | "spdx-license-ids": "^3.0.0" 1801 | } 1802 | }, 1803 | "spdx-license-ids": { 1804 | "version": "3.0.2", 1805 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", 1806 | "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==" 1807 | }, 1808 | "speedometer": { 1809 | "version": "0.1.4", 1810 | "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz", 1811 | "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=" 1812 | }, 1813 | "split": { 1814 | "version": "0.2.10", 1815 | "resolved": "https://registry.npmjs.org/split/-/split-0.2.10.tgz", 1816 | "integrity": "sha1-Zwl8YB1pfOE2j0GPBs0gHPBSGlc=", 1817 | "requires": { 1818 | "through": "2" 1819 | } 1820 | }, 1821 | "sshpk": { 1822 | "version": "1.15.2", 1823 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", 1824 | "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", 1825 | "requires": { 1826 | "asn1": "~0.2.3", 1827 | "assert-plus": "^1.0.0", 1828 | "bcrypt-pbkdf": "^1.0.0", 1829 | "dashdash": "^1.12.0", 1830 | "ecc-jsbn": "~0.1.1", 1831 | "getpass": "^0.1.1", 1832 | "jsbn": "~0.1.0", 1833 | "safer-buffer": "^2.0.2", 1834 | "tweetnacl": "~0.14.0" 1835 | } 1836 | }, 1837 | "static-eval": { 1838 | "version": "2.0.0", 1839 | "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.0.tgz", 1840 | "integrity": "sha512-6flshd3F1Gwm+Ksxq463LtFd1liC77N/PX1FVVc3OzL3hAmo2fwHFbuArkcfi7s9rTNsLEhcRmXGFZhlgy40uw==", 1841 | "requires": { 1842 | "escodegen": "^1.8.1" 1843 | } 1844 | }, 1845 | "static-module": { 1846 | "version": "2.2.5", 1847 | "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.5.tgz", 1848 | "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==", 1849 | "requires": { 1850 | "concat-stream": "~1.6.0", 1851 | "convert-source-map": "^1.5.1", 1852 | "duplexer2": "~0.1.4", 1853 | "escodegen": "~1.9.0", 1854 | "falafel": "^2.1.0", 1855 | "has": "^1.0.1", 1856 | "magic-string": "^0.22.4", 1857 | "merge-source-map": "1.0.4", 1858 | "object-inspect": "~1.4.0", 1859 | "quote-stream": "~1.0.2", 1860 | "readable-stream": "~2.3.3", 1861 | "shallow-copy": "~0.0.1", 1862 | "static-eval": "^2.0.0", 1863 | "through2": "~2.0.3" 1864 | }, 1865 | "dependencies": { 1866 | "isarray": { 1867 | "version": "1.0.0", 1868 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1869 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 1870 | }, 1871 | "process-nextick-args": { 1872 | "version": "2.0.0", 1873 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1874 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 1875 | }, 1876 | "readable-stream": { 1877 | "version": "2.3.6", 1878 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 1879 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1880 | "requires": { 1881 | "core-util-is": "~1.0.0", 1882 | "inherits": "~2.0.3", 1883 | "isarray": "~1.0.0", 1884 | "process-nextick-args": "~2.0.0", 1885 | "safe-buffer": "~5.1.1", 1886 | "string_decoder": "~1.1.1", 1887 | "util-deprecate": "~1.0.1" 1888 | } 1889 | }, 1890 | "string_decoder": { 1891 | "version": "1.1.1", 1892 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1893 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1894 | "requires": { 1895 | "safe-buffer": "~5.1.0" 1896 | } 1897 | } 1898 | } 1899 | }, 1900 | "stream-shift": { 1901 | "version": "1.0.0", 1902 | "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", 1903 | "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" 1904 | }, 1905 | "stream-spigot": { 1906 | "version": "2.1.2", 1907 | "resolved": "https://registry.npmjs.org/stream-spigot/-/stream-spigot-2.1.2.tgz", 1908 | "integrity": "sha1-feFF6Bn43Q20UJDRPc9zqO08wDU=", 1909 | "requires": { 1910 | "readable-stream": "~1.1.0" 1911 | } 1912 | }, 1913 | "string-width": { 1914 | "version": "1.0.2", 1915 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 1916 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 1917 | "requires": { 1918 | "code-point-at": "^1.0.0", 1919 | "is-fullwidth-code-point": "^1.0.0", 1920 | "strip-ansi": "^3.0.0" 1921 | } 1922 | }, 1923 | "string_decoder": { 1924 | "version": "0.10.31", 1925 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1926 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 1927 | }, 1928 | "strip-ansi": { 1929 | "version": "3.0.1", 1930 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1931 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1932 | "requires": { 1933 | "ansi-regex": "^2.0.0" 1934 | } 1935 | }, 1936 | "strip-bom": { 1937 | "version": "2.0.0", 1938 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 1939 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 1940 | "requires": { 1941 | "is-utf8": "^0.2.0" 1942 | } 1943 | }, 1944 | "strip-indent": { 1945 | "version": "1.0.1", 1946 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", 1947 | "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", 1948 | "requires": { 1949 | "get-stdin": "^4.0.1" 1950 | } 1951 | }, 1952 | "strip-json-comments": { 1953 | "version": "2.0.1", 1954 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1955 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 1956 | }, 1957 | "sumchecker": { 1958 | "version": "2.0.2", 1959 | "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-2.0.2.tgz", 1960 | "integrity": "sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=", 1961 | "requires": { 1962 | "debug": "^2.2.0" 1963 | }, 1964 | "dependencies": { 1965 | "debug": { 1966 | "version": "2.6.9", 1967 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1968 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1969 | "requires": { 1970 | "ms": "2.0.0" 1971 | } 1972 | }, 1973 | "ms": { 1974 | "version": "2.0.0", 1975 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1976 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1977 | } 1978 | } 1979 | }, 1980 | "supercluster": { 1981 | "version": "4.1.1", 1982 | "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-4.1.1.tgz", 1983 | "integrity": "sha512-sF0FfUOPFp96DKzwWFLeQOEqqKu2PpcesxAFeFsknA/q7g7igVVn/p3NI2XHEghNSyDAqunKNKqAbqNO8+7NDQ==", 1984 | "requires": { 1985 | "kdbush": "^2.0.1" 1986 | } 1987 | }, 1988 | "throttleit": { 1989 | "version": "0.0.2", 1990 | "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", 1991 | "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=" 1992 | }, 1993 | "through": { 1994 | "version": "2.3.8", 1995 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1996 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 1997 | }, 1998 | "through2": { 1999 | "version": "2.0.3", 2000 | "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", 2001 | "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", 2002 | "requires": { 2003 | "readable-stream": "^2.1.5", 2004 | "xtend": "~4.0.1" 2005 | }, 2006 | "dependencies": { 2007 | "isarray": { 2008 | "version": "1.0.0", 2009 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 2010 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 2011 | }, 2012 | "readable-stream": { 2013 | "version": "2.3.3", 2014 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 2015 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 2016 | "requires": { 2017 | "core-util-is": "~1.0.0", 2018 | "inherits": "~2.0.3", 2019 | "isarray": "~1.0.0", 2020 | "process-nextick-args": "~1.0.6", 2021 | "safe-buffer": "~5.1.1", 2022 | "string_decoder": "~1.0.3", 2023 | "util-deprecate": "~1.0.1" 2024 | } 2025 | }, 2026 | "string_decoder": { 2027 | "version": "1.0.3", 2028 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 2029 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 2030 | "requires": { 2031 | "safe-buffer": "~5.1.0" 2032 | } 2033 | }, 2034 | "xtend": { 2035 | "version": "4.0.1", 2036 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 2037 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 2038 | } 2039 | } 2040 | }, 2041 | "through2-spy": { 2042 | "version": "2.0.0", 2043 | "resolved": "https://registry.npmjs.org/through2-spy/-/through2-spy-2.0.0.tgz", 2044 | "integrity": "sha1-m4hMPf+avYoJEjfwLE8ZGZ8/8Kg=", 2045 | "requires": { 2046 | "through2": "~2.0.0", 2047 | "xtend": "~4.0.0" 2048 | }, 2049 | "dependencies": { 2050 | "xtend": { 2051 | "version": "4.0.1", 2052 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 2053 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 2054 | } 2055 | } 2056 | }, 2057 | "tinyqueue": { 2058 | "version": "1.2.3", 2059 | "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz", 2060 | "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA==" 2061 | }, 2062 | "tough-cookie": { 2063 | "version": "2.4.3", 2064 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 2065 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 2066 | "requires": { 2067 | "psl": "^1.1.24", 2068 | "punycode": "^1.4.1" 2069 | } 2070 | }, 2071 | "trim-newlines": { 2072 | "version": "1.0.0", 2073 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", 2074 | "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" 2075 | }, 2076 | "tunnel-agent": { 2077 | "version": "0.6.0", 2078 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 2079 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 2080 | "requires": { 2081 | "safe-buffer": "^5.0.1" 2082 | } 2083 | }, 2084 | "tweetnacl": { 2085 | "version": "0.14.5", 2086 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 2087 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 2088 | }, 2089 | "type-check": { 2090 | "version": "0.3.2", 2091 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2092 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2093 | "requires": { 2094 | "prelude-ls": "~1.1.2" 2095 | } 2096 | }, 2097 | "typedarray": { 2098 | "version": "0.0.6", 2099 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 2100 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 2101 | }, 2102 | "typedarray-pool": { 2103 | "version": "1.1.0", 2104 | "resolved": "https://registry.npmjs.org/typedarray-pool/-/typedarray-pool-1.1.0.tgz", 2105 | "integrity": "sha1-0RT0hIAUifU+yrXoCIqiMET0mNk=", 2106 | "requires": { 2107 | "bit-twiddle": "^1.0.0", 2108 | "dup": "^1.0.0" 2109 | } 2110 | }, 2111 | "uniq": { 2112 | "version": "1.0.1", 2113 | "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", 2114 | "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" 2115 | }, 2116 | "universalify": { 2117 | "version": "0.1.2", 2118 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 2119 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 2120 | }, 2121 | "util-deprecate": { 2122 | "version": "1.0.2", 2123 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2124 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 2125 | }, 2126 | "uuid": { 2127 | "version": "3.3.2", 2128 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 2129 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 2130 | }, 2131 | "validate-npm-package-license": { 2132 | "version": "3.0.4", 2133 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 2134 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 2135 | "requires": { 2136 | "spdx-correct": "^3.0.0", 2137 | "spdx-expression-parse": "^3.0.0" 2138 | } 2139 | }, 2140 | "verror": { 2141 | "version": "1.10.0", 2142 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 2143 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 2144 | "requires": { 2145 | "assert-plus": "^1.0.0", 2146 | "core-util-is": "1.0.2", 2147 | "extsprintf": "^1.2.0" 2148 | } 2149 | }, 2150 | "vlq": { 2151 | "version": "0.2.3", 2152 | "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", 2153 | "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==" 2154 | }, 2155 | "vt-pbf": { 2156 | "version": "3.1.1", 2157 | "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.1.tgz", 2158 | "integrity": "sha512-pHjWdrIoxurpmTcbfBWXaPwSmtPAHS105253P1qyEfSTV2HJddqjM+kIHquaT/L6lVJIk9ltTGc0IxR/G47hYA==", 2159 | "requires": { 2160 | "@mapbox/point-geometry": "0.1.0", 2161 | "@mapbox/vector-tile": "^1.3.1", 2162 | "pbf": "^3.0.5" 2163 | } 2164 | }, 2165 | "wgs84": { 2166 | "version": "0.0.0", 2167 | "resolved": "https://registry.npmjs.org/wgs84/-/wgs84-0.0.0.tgz", 2168 | "integrity": "sha1-NP3FVZF7blfPKigu0ENxDASc3HY=" 2169 | }, 2170 | "wordwrap": { 2171 | "version": "1.0.0", 2172 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2173 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" 2174 | }, 2175 | "wrappy": { 2176 | "version": "1.0.2", 2177 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2178 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 2179 | }, 2180 | "xtend": { 2181 | "version": "2.1.2", 2182 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", 2183 | "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", 2184 | "requires": { 2185 | "object-keys": "~0.4.0" 2186 | } 2187 | }, 2188 | "yargs-parser": { 2189 | "version": "11.0.0", 2190 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.0.0.tgz", 2191 | "integrity": "sha512-dvsafRjM45h79WOTvS/dP35Sb31SlGAKz6tFjI97kGC4MJFBuzTZY6TTYHrz0QSMQdkyd8Y+RsOMLr+JY0nPFQ==", 2192 | "requires": { 2193 | "camelcase": "^5.0.0", 2194 | "decamelize": "^1.2.0" 2195 | }, 2196 | "dependencies": { 2197 | "camelcase": { 2198 | "version": "5.0.0", 2199 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", 2200 | "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==" 2201 | } 2202 | } 2203 | }, 2204 | "yauzl": { 2205 | "version": "2.4.1", 2206 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", 2207 | "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", 2208 | "requires": { 2209 | "fd-slicer": "~1.0.1" 2210 | } 2211 | } 2212 | } 2213 | } 2214 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mapbox-map-image-export", 3 | "version": "2.4.1", 4 | "description": "Export a Mapbox GL map to a hi-res image for printing", 5 | "main": "index.js", 6 | "bin": { 7 | "export-map": "./cmd.js" 8 | }, 9 | "license": "MIT", 10 | "author": "Gregor MacLennan (Digital Democracy)", 11 | "dependencies": { 12 | "@turf/bbox-polygon": "^6.0.1", 13 | "decimal.js": "^10.0.1", 14 | "electron": "^3.0.7", 15 | "from2": "^2.3.0", 16 | "gl-fbo": "^2.0.5", 17 | "gl-pixel-stream": "^1.2.0", 18 | "js-quantities": "^1.7.2", 19 | "mapbox-gl": "^0.49.0", 20 | "minimist": "^1.2.0", 21 | "mosaic-image-stream": "^1.0.1", 22 | "multistream": "^2.1.1", 23 | "once": "^1.4.0", 24 | "png-stream": "^1.0.4", 25 | "pump": "^3.0.0", 26 | "pumpify": "^1.5.1", 27 | "single-line-log": "^1.1.2", 28 | "through2": "^2.0.1", 29 | "through2-spy": "^2.0.0", 30 | "yargs-parser": "^11.0.0" 31 | }, 32 | "devDependencies": {}, 33 | "scripts": { 34 | "example": "node ./cmd.js mapbox://styles/mapbox/streets-v9 -w=11in -h=8.5in -b=-7.1354,57.9095,-6.1357,58.516 -t=pk.eyJ1IjoidGF0aWFuYSIsImEiOiJjaWs1bzRiZGQwMDdjcHRrc285bTdwcWU5In0.0EWPVHyjaE9jTzNvOiIO-w -o=lewis.png" 35 | }, 36 | "keywords": [ 37 | "mapbox", 38 | "mapbox-gl", 39 | "print", 40 | "image", 41 | "export", 42 | "map" 43 | ], 44 | "repository": { 45 | "type": "git", 46 | "url": "git+https://github.com/digidem/mapbox-map-image-export.git" 47 | }, 48 | "bugs": { 49 | "url": "https://github.com/digidem/mapbox-map-image-export/issues" 50 | }, 51 | "homepage": "https://github.com/digidem/mapbox-map-image-export#readme" 52 | } 53 | -------------------------------------------------------------------------------- /renderer.js: -------------------------------------------------------------------------------- 1 | var remote = require('electron').remote 2 | var fs = require('fs') 3 | var path = require('path') 4 | var pump = require('pump') 5 | var log = require('single-line-log').stderr 6 | 7 | var exportMap = require('./lib/map_mosaic_stream.js') 8 | 9 | window.console = remote.require('./main').console 10 | var argv = remote.require('./main').argv 11 | 12 | var style = argv._[0] 13 | var format = {} 14 | var width = 40 15 | var last = 0 16 | 17 | var writeStream = argv.output ? fs.createWriteStream(abs(argv.output)) : process.stdout 18 | 19 | var mapDiv = document.createElement('div') 20 | document.body.appendChild(mapDiv) 21 | 22 | var mapStream = exportMap(style, mapDiv, argv) 23 | .on('progress', function (percent, total) { 24 | if ((percent - last) * width < 1) return 25 | var completeStr = Array(Math.floor(percent * width)).join('=') 26 | var incompleteStr = Array(Math.ceil((1 - percent) * width)).join(' ') 27 | var str = 'exporting [' + completeStr + '>' + incompleteStr + '] ' + Math.round(percent * 100) + '%' 28 | last = percent 29 | log(str) 30 | }) 31 | .on('format', function (f) { 32 | format = f 33 | }) 34 | pump(mapStream, writeStream, done) 35 | 36 | function done (err) { 37 | log.clear() 38 | log('') 39 | if (err) { 40 | process.stderr.write(err.stack + '\n', () => process.exit(1)) 41 | } 42 | if (argv.output) { 43 | console.error('Saved %dpx x %dpx map to %s', format.width, format.height, argv.output) 44 | } 45 | window.close() 46 | } 47 | 48 | function abs (file) { 49 | return path.isAbsolute(file) 50 | ? file 51 | : path.resolve(process.cwd(), file) 52 | } 53 | -------------------------------------------------------------------------------- /usage.txt: -------------------------------------------------------------------------------- 1 | Usage: 2 | export-map mapboxStyleUrl 3 | 4 | Options: 5 | --bounds, -b comma-separated bounding box [required] 'minLon,minLat,maxLon,maxLat' eg. '-7.1354,57.9095,-6.1357,58.516' 6 | --token, -t Mapbox API token [required]: https://www.mapbox.com/studio/account/tokens/ 7 | --output, -o image output path, optional, defaults to std.out 8 | --dpi, -d dpi of output image, default 192dpi (equivalent to how the map renders on a retina screen) 9 | --format, -f output format, "jpg", "webp" or "png" (default) 10 | --quality, -q encoding quality for jpg and webp, default 0.9 11 | --width, -w output width for printing e.g. 11in or 297mm 12 | --height, -h output height for printing 13 | --help show this help 14 | --version, -v show version 15 | --debug renders bounding box and (print) tile boundaries and opens the developer tools console 16 | 17 | Exports a map for a given mapbox style url for the specified bounding box. 18 | 19 | If no `--output` is given, the PNG is written to stdout. 20 | --------------------------------------------------------------------------------