├── .dockerignore ├── .gitignore ├── Dockerfile ├── Procfile ├── README.md ├── airport-codes.csv ├── airports.js ├── index.js ├── lib └── index.js ├── native ├── Cargo.lock ├── Cargo.toml ├── artifacts.json ├── build.rs ├── index.node └── src │ └── lib.rs ├── package-lock.json ├── package.json └── public └── index.html /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | native/target -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | native/target -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.19.0 2 | 3 | RUN apt update && \ 4 | apt install build-essential sudo -y && \ 5 | curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - && \ 6 | apt-get install -y nodejs 7 | 8 | 9 | WORKDIR /usr/src/myapp 10 | COPY . . 11 | 12 | RUN npm i -g neon-cli && npm i && neon build 13 | 14 | EXPOSE 5000 15 | CMD ["node", "index.js"] -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node index.js -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Find Airports Close to You Webapp 2 | This is a sample webapp to demonstrate the usage of [Rust 🦀](https://rust-lang.org)-based modules with [NodeJS](https://nodejs.org) webapps. 3 | 4 | # How the algorithm works 5 | There is a [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) file containing about 46.000 airports. For each record we have a lot of data, including its Latitude and Longitude. 6 | 7 | Our algorithm is quite naive and there is a lot of room for improvements. Basically, we parse the CSV file into a large array of objects and then iterate over this array doing some math to calculate the [Harversine distance](https://en.wikipedia.org/wiki/Haversine_formula) between your location and the airport, if it is below 30km then that airport is included in the results. 8 | 9 | There is no parallelism involved even though it would speedup the code a lot. 10 | 11 | > REMARK: Of course there are tons of ways of solving this, going from having it all in an Oracle database with some functions in PL/SQL to calculate everthing with a simple SELECT to having a ton of microservices or serverless lambda functions figuring this out using some third-party API you have no control of. **The main objective of this sample, is to show how easy it is to build Rust-based NodeJS modules by presenting an useful and rich sample.** 12 | 13 | # How to setup 14 | 15 | You need both NodeJS and Rust installed for this to work. You also need [Neon Bindings](https://guides.neon-bindings.com/) to be able to compile the Rust code. 16 | 17 | Use: 18 | 19 | ``` 20 | $ npm install 21 | ``` 22 | 23 | To install all the required NodeJS modules. To build the Rust-based module using Neon Bindings: 24 | 25 | ``` 26 | $ neon build 27 | ``` 28 | 29 | Run the application with: 30 | 31 | ``` 32 | $ node index.js 33 | ``` 34 | 35 | 36 | -------------------------------------------------------------------------------- /airports.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const parse = require('csv-parse'); 3 | const geolib = require('geolib'); 4 | 5 | module.exports = function (file, lat, lon, cb) { 6 | 7 | fs.readFile(file, (err, content) => { 8 | if (err) { 9 | throw err; 10 | } 11 | 12 | parse(content, { columns: true }, (err, data) => { 13 | if (err) { 14 | throw err; 15 | } 16 | 17 | let found = data 18 | .filter(e => { 19 | let lat1, lon1, lat2, lon2; 20 | [lon1, lat1] = e.coordinates.split(","); 21 | [lat2, lon2] = [lat, lon]; 22 | 23 | let dist = geolib.getDistance( 24 | { latitude: lat1, longitude: lon1 }, 25 | { latitude: lat2, longitude: lon2 } 26 | ); 27 | 28 | return dist <= 30000; 29 | }) 30 | 31 | cb(found) 32 | 33 | }); 34 | 35 | }) 36 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | let express = require('express'); 2 | let get_airports_node = require("./airports.js"); 3 | let get_airports_rust = require("./lib"); 4 | 5 | let router = express(); 6 | 7 | router 8 | .use(express.static('public')) 9 | .get('/airports/node/:lat/:lon', function (req, res) { 10 | console.log("params", req.params); 11 | let lat = parseFloat(req.params.lat); 12 | let lon = parseFloat(req.params.lon); 13 | console.time("node"); 14 | get_airports_node("./airport-codes.csv", lat, lon, data => { 15 | console.log("node, result count", data.length); 16 | console.timeEnd("node"); 17 | res.send(data); 18 | }); 19 | }) 20 | .get('/airports/rust/:lat/:lon', function (req, res) { 21 | console.log("params", req.params); 22 | let lat = parseFloat(req.params.lat); 23 | let lon = parseFloat(req.params.lon); 24 | console.time("rust"); 25 | get_airports_rust("./airport-codes.csv", lat, lon, data => { 26 | console.log("rust, result count", data.length); 27 | console.timeEnd("rust"); 28 | res.send(data); 29 | }); 30 | }) 31 | .listen(5000, () => console.log('Listening on http://localhost:5000/ ')) 32 | 33 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | var addon = require('../native'); 2 | 3 | module.exports = addon.airport_distance; -------------------------------------------------------------------------------- /native/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "aho-corasick" 3 | version = "0.6.3" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | dependencies = [ 6 | "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 7 | ] 8 | 9 | [[package]] 10 | name = "airport_distance" 11 | version = "0.1.0" 12 | dependencies = [ 13 | "csv 1.0.0-beta.5 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "geo 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "neon 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "neon-build 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 17 | "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", 18 | "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", 19 | ] 20 | 21 | [[package]] 22 | name = "alga" 23 | version = "0.5.2" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | dependencies = [ 26 | "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 27 | "num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 28 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 29 | ] 30 | 31 | [[package]] 32 | name = "approx" 33 | version = "0.1.1" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | 36 | [[package]] 37 | name = "bitflags" 38 | version = "0.7.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | 41 | [[package]] 42 | name = "cgmath" 43 | version = "0.14.1" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | dependencies = [ 46 | "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 47 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 48 | "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 49 | ] 50 | 51 | [[package]] 52 | name = "clamp" 53 | version = "0.1.0" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | 56 | [[package]] 57 | name = "cslice" 58 | version = "0.2.0" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | 61 | [[package]] 62 | name = "csv" 63 | version = "1.0.0-beta.5" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | dependencies = [ 66 | "csv-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 67 | "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", 68 | ] 69 | 70 | [[package]] 71 | name = "csv-core" 72 | version = "0.1.3" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | dependencies = [ 75 | "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 76 | ] 77 | 78 | [[package]] 79 | name = "fuchsia-zircon" 80 | version = "0.2.1" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | dependencies = [ 83 | "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 84 | ] 85 | 86 | [[package]] 87 | name = "fuchsia-zircon-sys" 88 | version = "0.2.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | dependencies = [ 91 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 92 | ] 93 | 94 | [[package]] 95 | name = "gcc" 96 | version = "0.3.54" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | 99 | [[package]] 100 | name = "generic-array" 101 | version = "0.2.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | dependencies = [ 104 | "typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 105 | ] 106 | 107 | [[package]] 108 | name = "geo" 109 | version = "0.6.3" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | dependencies = [ 112 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", 114 | "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", 115 | "spade 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 116 | ] 117 | 118 | [[package]] 119 | name = "lazy_static" 120 | version = "0.2.10" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | 123 | [[package]] 124 | name = "libc" 125 | version = "0.2.33" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | 128 | [[package]] 129 | name = "memchr" 130 | version = "1.0.2" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | dependencies = [ 133 | "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 134 | ] 135 | 136 | [[package]] 137 | name = "nalgebra" 138 | version = "0.12.3" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | dependencies = [ 141 | "alga 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 142 | "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 143 | "generic-array 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 144 | "num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 145 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 146 | "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 147 | "typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 148 | ] 149 | 150 | [[package]] 151 | name = "neon" 152 | version = "0.1.21" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | dependencies = [ 155 | "cslice 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 156 | "neon-build 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 157 | "neon-runtime 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 158 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 159 | ] 160 | 161 | [[package]] 162 | name = "neon-build" 163 | version = "0.1.21" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | 166 | [[package]] 167 | name = "neon-runtime" 168 | version = "0.1.21" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | dependencies = [ 171 | "cslice 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 172 | "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", 173 | "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 174 | ] 175 | 176 | [[package]] 177 | name = "num" 178 | version = "0.1.40" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | dependencies = [ 181 | "num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 182 | "num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 183 | "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", 185 | "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 186 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 187 | ] 188 | 189 | [[package]] 190 | name = "num-bigint" 191 | version = "0.1.40" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | dependencies = [ 194 | "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 195 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 196 | "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 197 | "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", 198 | ] 199 | 200 | [[package]] 201 | name = "num-complex" 202 | version = "0.1.40" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | dependencies = [ 205 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 206 | "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", 207 | ] 208 | 209 | [[package]] 210 | name = "num-integer" 211 | version = "0.1.35" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | dependencies = [ 214 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 215 | ] 216 | 217 | [[package]] 218 | name = "num-iter" 219 | version = "0.1.34" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | dependencies = [ 222 | "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 223 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 224 | ] 225 | 226 | [[package]] 227 | name = "num-rational" 228 | version = "0.1.40" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | dependencies = [ 231 | "num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 232 | "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 233 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 234 | "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", 235 | ] 236 | 237 | [[package]] 238 | name = "num-traits" 239 | version = "0.1.40" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | 242 | [[package]] 243 | name = "quote" 244 | version = "0.3.15" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | 247 | [[package]] 248 | name = "rand" 249 | version = "0.3.18" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | dependencies = [ 252 | "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 253 | "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 254 | ] 255 | 256 | [[package]] 257 | name = "regex" 258 | version = "0.2.2" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | dependencies = [ 261 | "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 262 | "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 263 | "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 264 | "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 265 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 266 | ] 267 | 268 | [[package]] 269 | name = "regex-syntax" 270 | version = "0.4.1" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | 273 | [[package]] 274 | name = "rustc-serialize" 275 | version = "0.3.24" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | 278 | [[package]] 279 | name = "semver" 280 | version = "0.9.0" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | dependencies = [ 283 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 284 | ] 285 | 286 | [[package]] 287 | name = "semver-parser" 288 | version = "0.7.0" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | 291 | [[package]] 292 | name = "serde" 293 | version = "1.0.20" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | 296 | [[package]] 297 | name = "serde_derive" 298 | version = "1.0.20" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | dependencies = [ 301 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 302 | "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", 303 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 304 | ] 305 | 306 | [[package]] 307 | name = "serde_derive_internals" 308 | version = "0.17.0" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | dependencies = [ 311 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 312 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 313 | ] 314 | 315 | [[package]] 316 | name = "smallvec" 317 | version = "0.3.3" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | 320 | [[package]] 321 | name = "spade" 322 | version = "1.2.0" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | dependencies = [ 325 | "cgmath 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", 326 | "clamp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 327 | "nalgebra 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 328 | "num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 329 | "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 330 | ] 331 | 332 | [[package]] 333 | name = "syn" 334 | version = "0.11.11" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | dependencies = [ 337 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 338 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 339 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 340 | ] 341 | 342 | [[package]] 343 | name = "synom" 344 | version = "0.11.3" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | dependencies = [ 347 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 348 | ] 349 | 350 | [[package]] 351 | name = "thread_local" 352 | version = "0.3.4" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | dependencies = [ 355 | "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 356 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 357 | ] 358 | 359 | [[package]] 360 | name = "typenum" 361 | version = "1.9.0" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | 364 | [[package]] 365 | name = "unicode-xid" 366 | version = "0.0.4" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | 369 | [[package]] 370 | name = "unreachable" 371 | version = "1.0.0" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | dependencies = [ 374 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 375 | ] 376 | 377 | [[package]] 378 | name = "utf8-ranges" 379 | version = "1.0.0" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | 382 | [[package]] 383 | name = "void" 384 | version = "1.0.2" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | 387 | [metadata] 388 | "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" 389 | "checksum alga 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9a9749cf5cfdca30ac35de67358fb24e2d26a88e2819ee83efb794a09f0b421b" 390 | "checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94" 391 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" 392 | "checksum cgmath 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87f025a17ad3f30d49015c787903976d5f9cd6115ece1eb7f4d6ffe06b8c4080" 393 | "checksum clamp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0113a8ae379a061c89a71d57a809439f5ce550b6a76063ab5ba2b1cb180971f" 394 | "checksum cslice 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "697c714f50560202b1f4e2e09cd50a421881c83e9025db75d15f276616f04f40" 395 | "checksum csv 1.0.0-beta.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e7a9e063dcebdb56c306f23e672bfd31df3da8ec5f6d696b35f2c29c2a9572f0" 396 | "checksum csv-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1fbabf21d9a52d04675cc5b032d7bae24ecdcd22646f7eefcd0496a122686c" 397 | "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" 398 | "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" 399 | "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" 400 | "checksum generic-array 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3406a3975bc944fdd85b7964d53296a0ff11f4b6c4704fa4972c9a7c8ba27367" 401 | "checksum geo 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f3f587a8e7ce8b1633c44a4a24bbeb6dad09f1db740ec335a072e7a1eeb6de8" 402 | "checksum lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "236eb37a62591d4a41a89b7763d7de3e06ca02d5ab2815446a8bae5d2f8c2d57" 403 | "checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" 404 | "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" 405 | "checksum nalgebra 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c03e373ef04941f13088ef9814b90754e0d370a9b8cc9ce31d159f580e32b1a9" 406 | "checksum neon 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "db10beb9c26bc6e505075387aaa7251d8d65076f06acfe85ef4df728ed5785b7" 407 | "checksum neon-build 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "e137cafeb2297a81d4c3e41a7c703570459c49a7c0a1623a4925e2a9fdb3eeb9" 408 | "checksum neon-runtime 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fa795c92c21498f215ee610671b2cc9260dbb5e02239e6b2d91f42d6d98014" 409 | "checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525" 410 | "checksum num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "8fd0f8dbb4c0960998958a796281d88c16fbe68d87b1baa6f31e2979e81fd0bd" 411 | "checksum num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "503e668405c5492d67cf662a81e05be40efe2e6bcf10f7794a07bd9865e704e6" 412 | "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" 413 | "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" 414 | "checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" 415 | "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" 416 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 417 | "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" 418 | "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" 419 | "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" 420 | "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" 421 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 422 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 423 | "checksum serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "5a2b181dd2b4a6353e828e44807269a761d3ecbc388a1f5ed3998ea69a516d9c" 424 | "checksum serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "31ce3c16ec18abb97d977f75880986549213b0c18f2695eda8b31eadc96eda4a" 425 | "checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" 426 | "checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e" 427 | "checksum spade 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22bd542364c0c964e90ddc146d7b44a4035b618dc347033918994c431cb69d76" 428 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 429 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 430 | "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" 431 | "checksum typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd" 432 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 433 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 434 | "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" 435 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 436 | -------------------------------------------------------------------------------- /native/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "airport_distance" 3 | version = "0.1.0" 4 | authors = ["andre alves garzia "] 5 | license = "MIT" 6 | build = "build.rs" 7 | 8 | [lib] 9 | name = "airport_distance" 10 | crate-type = ["dylib"] 11 | 12 | [build-dependencies] 13 | neon-build = "0.1.20" 14 | 15 | [dependencies] 16 | neon = "0.1.20" 17 | csv = "1.0.0-beta.5" 18 | serde = "1.0.20" 19 | serde_derive = "1.0.20" 20 | geo = "0.6.3" 21 | -------------------------------------------------------------------------------- /native/artifacts.json: -------------------------------------------------------------------------------- 1 | {"active":"x86_64-pc-windows-msvc\\release","targets":{"x86_64-pc-windows-msvc\\release":{"rustc":"rustc 1.23.0-nightly (45594d5de 2017-11-22)","env":{"npm_config_target":null,"npm_config_arch":null,"npm_config_target_arch":null,"npm_config_disturl":null,"npm_config_runtime":null,"npm_config_build_from_source":null,"npm_config_devdir":null}}}} -------------------------------------------------------------------------------- /native/build.rs: -------------------------------------------------------------------------------- 1 | extern crate neon_build; 2 | 3 | fn main() { 4 | neon_build::setup(); // must be called in build.rs 5 | 6 | // add project-specific build logic here... 7 | } 8 | -------------------------------------------------------------------------------- /native/index.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soapdog/nodejs-rust-sample-module/254700edb59ff0ef70be9e238282bffd14b2ea1c/native/index.node -------------------------------------------------------------------------------- /native/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate neon; 3 | 4 | extern crate csv; 5 | extern crate serde; 6 | extern crate geo; 7 | 8 | #[macro_use] 9 | extern crate serde_derive; 10 | 11 | use std::string::String; 12 | use std::str::FromStr; 13 | 14 | use geo::Point; 15 | use geo::algorithm::haversine_distance::HaversineDistance; 16 | 17 | use neon::vm::{Call, JsResult}; 18 | use neon::js::{JsNull, JsString, JsUndefined, JsFunction, JsArray, Object, JsObject, JsNumber}; 19 | use neon::mem::Handle; 20 | use neon::js::error::JsError; 21 | use neon::js::error::Kind::TypeError; 22 | 23 | #[derive(Debug, Deserialize, Serialize, Clone)] 24 | struct Airport { 25 | ident: String, 26 | kind: String, 27 | name: String, 28 | coordinates: String, 29 | elevation_ft: String, 30 | continent: String, 31 | iso_country: String, 32 | iso_region: String, 33 | municipality: String, 34 | gps_code: String, 35 | iata_code: String, 36 | local_code: String 37 | } 38 | 39 | fn airport_distance(call: Call) -> JsResult { 40 | let fn_handle = call.arguments.get(call.scope, 3).unwrap(); 41 | 42 | let scope = call.scope; 43 | let file: String = call.arguments.require(scope, 0)?.check::()?.value(); 44 | let lat2: f64 = call.arguments.require(scope, 1)?.check::()?.value(); 45 | let lon2: f64 = call.arguments.require(scope, 2)?.check::()?.value(); 46 | 47 | let mut rdr = csv::Reader::from_path(file).expect("csv filename"); 48 | let mut r: Vec = vec![]; 49 | 50 | for result in rdr.deserialize() { 51 | let airport: Airport = match result { 52 | Ok(f) => f, 53 | Err(_e) => return Ok(JsUndefined::new()) 54 | }; 55 | 56 | let v: Vec<&str> = airport.coordinates.split(", ").collect(); 57 | let lon1: f64 = f64::from_str(v[0]).or_else(|_e| JsError::throw(TypeError, "longitude from CSV is wrong"))?; 58 | let lat1: f64 = f64::from_str(v[1]).or_else(|_e| JsError::throw(TypeError, "latitude from CSV is wrong"))?; 59 | let p = Point::new(lat1, lon1); 60 | let dist = p.haversine_distance(&Point::new(lat2, lon2)); 61 | 62 | if dist < 30_000.0 { 63 | r.push(airport.clone()); 64 | 65 | } 66 | } 67 | 68 | let arr = JsArray::new(scope, r.len() as u32); 69 | let mut i = 0; 70 | 71 | for a in r.into_iter() { 72 | let obj = JsObject::new(scope); 73 | 74 | obj.set("ident", JsString::new(scope, &a.ident).expect("ident from results array is wrong"))?; 75 | obj.set("kind", JsString::new(scope, &a.kind).expect("kind from results array is wrong"))?; 76 | obj.set("name", JsString::new(scope, &a.name).expect("name from results array is wrong"))?; 77 | obj.set("coordinates", JsString::new(scope, &a.coordinates).expect("coordinates from results array is wrong"))?; 78 | obj.set("elevation_ft", JsString::new(scope, &a.elevation_ft).expect("elevation_ft from results array is wrong"))?; 79 | obj.set("continent", JsString::new(scope, &a.continent).expect("continent from results array is wrong"))?; 80 | obj.set("iso_country", JsString::new(scope, &a.iso_country).expect("iso_country from results array is wrong"))?; 81 | obj.set("iso_region", JsString::new(scope, &a.iso_region).expect("iso_region from results array is wrong"))?; 82 | obj.set("municipality", JsString::new(scope, &a.municipality).expect("municipality from results array is wrong"))?; 83 | obj.set("gps_code", JsString::new(scope, &a.gps_code).expect("gps_code from results array is wrong"))?; 84 | obj.set("iata_code", JsString::new(scope, &a.iata_code).expect("iata_code from results array is wrong"))?; 85 | obj.set("local_code", JsString::new(scope, &a.local_code).expect("local_code from results array is wrong"))?; 86 | 87 | arr.set(i, obj)?; 88 | i = i + 1; 89 | } 90 | 91 | 92 | 93 | if let Some(function) = fn_handle.downcast::() { 94 | let args: Vec> = vec![arr]; 95 | let _ = function.call(scope, JsNull::new(), args); 96 | } 97 | 98 | Ok(JsUndefined::new()) 99 | } 100 | 101 | register_module!(m, { 102 | m.export("airport_distance", airport_distance) 103 | }); 104 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exemplo", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.4", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", 10 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", 11 | "requires": { 12 | "mime-types": "2.1.17", 13 | "negotiator": "0.6.1" 14 | } 15 | }, 16 | "align-text": { 17 | "version": "0.1.4", 18 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 19 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 20 | "requires": { 21 | "kind-of": "3.2.2", 22 | "longest": "1.0.1", 23 | "repeat-string": "1.6.1" 24 | } 25 | }, 26 | "amdefine": { 27 | "version": "1.0.1", 28 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 29 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" 30 | }, 31 | "ansi-escape-sequences": { 32 | "version": "4.0.0", 33 | "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz", 34 | "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==", 35 | "requires": { 36 | "array-back": "2.0.0" 37 | } 38 | }, 39 | "ansi-escapes": { 40 | "version": "3.0.0", 41 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", 42 | "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==" 43 | }, 44 | "ansi-regex": { 45 | "version": "3.0.0", 46 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 47 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 48 | }, 49 | "ansi-styles": { 50 | "version": "3.2.0", 51 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", 52 | "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", 53 | "requires": { 54 | "color-convert": "1.9.1" 55 | } 56 | }, 57 | "array-back": { 58 | "version": "2.0.0", 59 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", 60 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", 61 | "requires": { 62 | "typical": "2.6.1" 63 | } 64 | }, 65 | "array-flatten": { 66 | "version": "1.1.1", 67 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 68 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 69 | }, 70 | "async": { 71 | "version": "1.5.2", 72 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 73 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" 74 | }, 75 | "balanced-match": { 76 | "version": "1.0.0", 77 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 78 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 79 | }, 80 | "body-parser": { 81 | "version": "1.18.2", 82 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 83 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", 84 | "requires": { 85 | "bytes": "3.0.0", 86 | "content-type": "1.0.4", 87 | "debug": "2.6.9", 88 | "depd": "1.1.1", 89 | "http-errors": "1.6.2", 90 | "iconv-lite": "0.4.19", 91 | "on-finished": "2.3.0", 92 | "qs": "6.5.1", 93 | "raw-body": "2.3.2", 94 | "type-is": "1.6.15" 95 | } 96 | }, 97 | "brace-expansion": { 98 | "version": "1.1.8", 99 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 100 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 101 | "requires": { 102 | "balanced-match": "1.0.0", 103 | "concat-map": "0.0.1" 104 | } 105 | }, 106 | "builtins": { 107 | "version": "1.0.3", 108 | "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", 109 | "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" 110 | }, 111 | "bytes": { 112 | "version": "3.0.0", 113 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 114 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 115 | }, 116 | "camelcase": { 117 | "version": "1.2.1", 118 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 119 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 120 | "optional": true 121 | }, 122 | "center-align": { 123 | "version": "0.1.3", 124 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 125 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 126 | "optional": true, 127 | "requires": { 128 | "align-text": "0.1.4", 129 | "lazy-cache": "1.0.4" 130 | } 131 | }, 132 | "chalk": { 133 | "version": "2.1.0", 134 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", 135 | "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", 136 | "requires": { 137 | "ansi-styles": "3.2.0", 138 | "escape-string-regexp": "1.0.5", 139 | "supports-color": "4.5.0" 140 | } 141 | }, 142 | "chardet": { 143 | "version": "0.4.0", 144 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.0.tgz", 145 | "integrity": "sha1-C74TVaxE16PtSpJXB8TvcPgZD2w=" 146 | }, 147 | "cli-cursor": { 148 | "version": "2.1.0", 149 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 150 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 151 | "requires": { 152 | "restore-cursor": "2.0.0" 153 | } 154 | }, 155 | "cli-width": { 156 | "version": "2.2.0", 157 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 158 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" 159 | }, 160 | "cliui": { 161 | "version": "2.1.0", 162 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 163 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 164 | "optional": true, 165 | "requires": { 166 | "center-align": "0.1.3", 167 | "right-align": "0.1.3", 168 | "wordwrap": "0.0.2" 169 | }, 170 | "dependencies": { 171 | "wordwrap": { 172 | "version": "0.0.2", 173 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 174 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 175 | "optional": true 176 | } 177 | } 178 | }, 179 | "color-convert": { 180 | "version": "1.9.1", 181 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", 182 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", 183 | "requires": { 184 | "color-name": "1.1.3" 185 | } 186 | }, 187 | "color-name": { 188 | "version": "1.1.3", 189 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 190 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 191 | }, 192 | "command-line-args": { 193 | "version": "4.0.7", 194 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", 195 | "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", 196 | "requires": { 197 | "array-back": "2.0.0", 198 | "find-replace": "1.0.3", 199 | "typical": "2.6.1" 200 | } 201 | }, 202 | "command-line-commands": { 203 | "version": "2.0.1", 204 | "resolved": "https://registry.npmjs.org/command-line-commands/-/command-line-commands-2.0.1.tgz", 205 | "integrity": "sha512-m8c2p1DrNd2ruIAggxd/y6DgygQayf6r8RHwchhXryaLF8I6koYjoYroVP+emeROE9DXN5b9sP1Gh+WtvTTdtQ==", 206 | "requires": { 207 | "array-back": "2.0.0" 208 | } 209 | }, 210 | "command-line-usage": { 211 | "version": "4.0.1", 212 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.0.1.tgz", 213 | "integrity": "sha512-IqYzZuXizukrdhnbdUj2hh4iceycow+Jn10mER4lwU4IapYvl5ZzoRPsj5Yraew5oRk4yfFKMuULGvAfb5o29w==", 214 | "requires": { 215 | "ansi-escape-sequences": "4.0.0", 216 | "array-back": "2.0.0", 217 | "table-layout": "0.4.2", 218 | "typical": "2.6.1" 219 | } 220 | }, 221 | "concat-map": { 222 | "version": "0.0.1", 223 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 224 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 225 | }, 226 | "content-disposition": { 227 | "version": "0.5.2", 228 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 229 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 230 | }, 231 | "content-type": { 232 | "version": "1.0.4", 233 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 234 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 235 | }, 236 | "cookie": { 237 | "version": "0.3.1", 238 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 239 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 240 | }, 241 | "cookie-signature": { 242 | "version": "1.0.6", 243 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 244 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 245 | }, 246 | "csv": { 247 | "version": "2.0.0", 248 | "resolved": "https://registry.npmjs.org/csv/-/csv-2.0.0.tgz", 249 | "integrity": "sha1-DVHY+j7OJ4tUCfeVcX/PzVrOmz4=", 250 | "requires": { 251 | "csv-generate": "2.0.0", 252 | "csv-parse": "2.0.0", 253 | "csv-stringify": "2.0.0", 254 | "stream-transform": "1.0.0" 255 | } 256 | }, 257 | "csv-generate": { 258 | "version": "2.0.0", 259 | "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-2.0.0.tgz", 260 | "integrity": "sha1-q0/cMNtc5niwfVOITGn6VFYYslw=" 261 | }, 262 | "csv-parse": { 263 | "version": "2.0.0", 264 | "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-2.0.0.tgz", 265 | "integrity": "sha1-TqIslzIzmH8HaIxgGi1GAjT/VtE=" 266 | }, 267 | "csv-stringify": { 268 | "version": "2.0.0", 269 | "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-2.0.0.tgz", 270 | "integrity": "sha1-knu1X9FAggXORE0ogBhGJ7JLZPE=", 271 | "requires": { 272 | "lodash.get": "4.4.2" 273 | } 274 | }, 275 | "debug": { 276 | "version": "2.6.9", 277 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 278 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 279 | "requires": { 280 | "ms": "2.0.0" 281 | } 282 | }, 283 | "decamelize": { 284 | "version": "1.2.0", 285 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 286 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 287 | "optional": true 288 | }, 289 | "deep-extend": { 290 | "version": "0.5.0", 291 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.0.tgz", 292 | "integrity": "sha1-bvSgmwX5iw41jW2T1Mo8rsZnKAM=" 293 | }, 294 | "depd": { 295 | "version": "1.1.1", 296 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 297 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 298 | }, 299 | "destroy": { 300 | "version": "1.0.4", 301 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 302 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 303 | }, 304 | "ee-first": { 305 | "version": "1.1.1", 306 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 307 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 308 | }, 309 | "encodeurl": { 310 | "version": "1.0.1", 311 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 312 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" 313 | }, 314 | "escape-html": { 315 | "version": "1.0.3", 316 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 317 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 318 | }, 319 | "escape-string-regexp": { 320 | "version": "1.0.5", 321 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 322 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 323 | }, 324 | "etag": { 325 | "version": "1.8.1", 326 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 327 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 328 | }, 329 | "express": { 330 | "version": "4.16.2", 331 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", 332 | "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", 333 | "requires": { 334 | "accepts": "1.3.4", 335 | "array-flatten": "1.1.1", 336 | "body-parser": "1.18.2", 337 | "content-disposition": "0.5.2", 338 | "content-type": "1.0.4", 339 | "cookie": "0.3.1", 340 | "cookie-signature": "1.0.6", 341 | "debug": "2.6.9", 342 | "depd": "1.1.1", 343 | "encodeurl": "1.0.1", 344 | "escape-html": "1.0.3", 345 | "etag": "1.8.1", 346 | "finalhandler": "1.1.0", 347 | "fresh": "0.5.2", 348 | "merge-descriptors": "1.0.1", 349 | "methods": "1.1.2", 350 | "on-finished": "2.3.0", 351 | "parseurl": "1.3.2", 352 | "path-to-regexp": "0.1.7", 353 | "proxy-addr": "2.0.2", 354 | "qs": "6.5.1", 355 | "range-parser": "1.2.0", 356 | "safe-buffer": "5.1.1", 357 | "send": "0.16.1", 358 | "serve-static": "1.13.1", 359 | "setprototypeof": "1.1.0", 360 | "statuses": "1.3.1", 361 | "type-is": "1.6.15", 362 | "utils-merge": "1.0.1", 363 | "vary": "1.1.2" 364 | } 365 | }, 366 | "external-editor": { 367 | "version": "2.1.0", 368 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", 369 | "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", 370 | "requires": { 371 | "chardet": "0.4.0", 372 | "iconv-lite": "0.4.19", 373 | "tmp": "0.0.33" 374 | } 375 | }, 376 | "figures": { 377 | "version": "2.0.0", 378 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 379 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 380 | "requires": { 381 | "escape-string-regexp": "1.0.5" 382 | } 383 | }, 384 | "finalhandler": { 385 | "version": "1.1.0", 386 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", 387 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", 388 | "requires": { 389 | "debug": "2.6.9", 390 | "encodeurl": "1.0.1", 391 | "escape-html": "1.0.3", 392 | "on-finished": "2.3.0", 393 | "parseurl": "1.3.2", 394 | "statuses": "1.3.1", 395 | "unpipe": "1.0.0" 396 | } 397 | }, 398 | "find-replace": { 399 | "version": "1.0.3", 400 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", 401 | "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", 402 | "requires": { 403 | "array-back": "1.0.4", 404 | "test-value": "2.1.0" 405 | }, 406 | "dependencies": { 407 | "array-back": { 408 | "version": "1.0.4", 409 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", 410 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", 411 | "requires": { 412 | "typical": "2.6.1" 413 | } 414 | } 415 | } 416 | }, 417 | "forwarded": { 418 | "version": "0.1.2", 419 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 420 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 421 | }, 422 | "fresh": { 423 | "version": "0.5.2", 424 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 425 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 426 | }, 427 | "fs.realpath": { 428 | "version": "1.0.0", 429 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 430 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 431 | }, 432 | "geolib": { 433 | "version": "2.0.24", 434 | "resolved": "https://registry.npmjs.org/geolib/-/geolib-2.0.24.tgz", 435 | "integrity": "sha512-NR0AyYyEnGrFS9JvSFmmotQDxVCORJgDHdvBwSatxl5aHarOLMh3KuGI83bCvCfObjfoEiDe8Ung8GGLGAtthw==" 436 | }, 437 | "git-config": { 438 | "version": "0.0.7", 439 | "resolved": "https://registry.npmjs.org/git-config/-/git-config-0.0.7.tgz", 440 | "integrity": "sha1-qcij7wendsPXImE1bYtye2IgKyg=", 441 | "requires": { 442 | "iniparser": "1.0.5" 443 | } 444 | }, 445 | "glob": { 446 | "version": "7.1.2", 447 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 448 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 449 | "requires": { 450 | "fs.realpath": "1.0.0", 451 | "inflight": "1.0.6", 452 | "inherits": "2.0.3", 453 | "minimatch": "3.0.4", 454 | "once": "1.4.0", 455 | "path-is-absolute": "1.0.1" 456 | } 457 | }, 458 | "handlebars": { 459 | "version": "4.0.11", 460 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", 461 | "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", 462 | "requires": { 463 | "async": "1.5.2", 464 | "optimist": "0.6.1", 465 | "source-map": "0.4.4", 466 | "uglify-js": "2.8.29" 467 | } 468 | }, 469 | "has-flag": { 470 | "version": "2.0.0", 471 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 472 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" 473 | }, 474 | "http-errors": { 475 | "version": "1.6.2", 476 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 477 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 478 | "requires": { 479 | "depd": "1.1.1", 480 | "inherits": "2.0.3", 481 | "setprototypeof": "1.0.3", 482 | "statuses": "1.3.1" 483 | }, 484 | "dependencies": { 485 | "setprototypeof": { 486 | "version": "1.0.3", 487 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 488 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 489 | } 490 | } 491 | }, 492 | "iconv-lite": { 493 | "version": "0.4.19", 494 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 495 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" 496 | }, 497 | "inflight": { 498 | "version": "1.0.6", 499 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 500 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 501 | "requires": { 502 | "once": "1.4.0", 503 | "wrappy": "1.0.2" 504 | } 505 | }, 506 | "inherits": { 507 | "version": "2.0.3", 508 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 509 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 510 | }, 511 | "iniparser": { 512 | "version": "1.0.5", 513 | "resolved": "https://registry.npmjs.org/iniparser/-/iniparser-1.0.5.tgz", 514 | "integrity": "sha1-g21r7+bfv87gvM8c+fKsxwJ/eD0=" 515 | }, 516 | "inquirer": { 517 | "version": "3.3.0", 518 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 519 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 520 | "requires": { 521 | "ansi-escapes": "3.0.0", 522 | "chalk": "2.1.0", 523 | "cli-cursor": "2.1.0", 524 | "cli-width": "2.2.0", 525 | "external-editor": "2.1.0", 526 | "figures": "2.0.0", 527 | "lodash": "4.17.4", 528 | "mute-stream": "0.0.7", 529 | "run-async": "2.3.0", 530 | "rx-lite": "4.0.8", 531 | "rx-lite-aggregates": "4.0.8", 532 | "string-width": "2.1.1", 533 | "strip-ansi": "4.0.0", 534 | "through": "2.3.8" 535 | } 536 | }, 537 | "ipaddr.js": { 538 | "version": "1.5.2", 539 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", 540 | "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" 541 | }, 542 | "is-buffer": { 543 | "version": "1.1.6", 544 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 545 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 546 | }, 547 | "is-fullwidth-code-point": { 548 | "version": "2.0.0", 549 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 550 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 551 | }, 552 | "is-promise": { 553 | "version": "2.1.0", 554 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 555 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 556 | }, 557 | "kind-of": { 558 | "version": "3.2.2", 559 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 560 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 561 | "requires": { 562 | "is-buffer": "1.1.6" 563 | } 564 | }, 565 | "lazy-cache": { 566 | "version": "1.0.4", 567 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 568 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 569 | "optional": true 570 | }, 571 | "lodash": { 572 | "version": "4.17.4", 573 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 574 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 575 | }, 576 | "lodash.get": { 577 | "version": "4.4.2", 578 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 579 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" 580 | }, 581 | "lodash.padend": { 582 | "version": "4.6.1", 583 | "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", 584 | "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=" 585 | }, 586 | "longest": { 587 | "version": "1.0.1", 588 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 589 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" 590 | }, 591 | "media-typer": { 592 | "version": "0.3.0", 593 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 594 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 595 | }, 596 | "merge-descriptors": { 597 | "version": "1.0.1", 598 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 599 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 600 | }, 601 | "methods": { 602 | "version": "1.1.2", 603 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 604 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 605 | }, 606 | "mime": { 607 | "version": "1.4.1", 608 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 609 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" 610 | }, 611 | "mime-db": { 612 | "version": "1.30.0", 613 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", 614 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" 615 | }, 616 | "mime-types": { 617 | "version": "2.1.17", 618 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", 619 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", 620 | "requires": { 621 | "mime-db": "1.30.0" 622 | } 623 | }, 624 | "mimic-fn": { 625 | "version": "1.1.0", 626 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", 627 | "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" 628 | }, 629 | "minimatch": { 630 | "version": "3.0.4", 631 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 632 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 633 | "requires": { 634 | "brace-expansion": "1.1.8" 635 | } 636 | }, 637 | "minimist": { 638 | "version": "0.0.10", 639 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", 640 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" 641 | }, 642 | "mkdirp": { 643 | "version": "0.5.1", 644 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 645 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 646 | "requires": { 647 | "minimist": "0.0.8" 648 | }, 649 | "dependencies": { 650 | "minimist": { 651 | "version": "0.0.8", 652 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 653 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 654 | } 655 | } 656 | }, 657 | "ms": { 658 | "version": "2.0.0", 659 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 660 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 661 | }, 662 | "mute-stream": { 663 | "version": "0.0.7", 664 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 665 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" 666 | }, 667 | "negotiator": { 668 | "version": "0.6.1", 669 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 670 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 671 | }, 672 | "neon-cli": { 673 | "version": "0.1.21", 674 | "resolved": "https://registry.npmjs.org/neon-cli/-/neon-cli-0.1.21.tgz", 675 | "integrity": "sha512-TXvj/7vSbMPdPwQokmVRh2NAAAmCNWyUguy+ucGfkOHJgzlJYIB385NiDLBluVT0QLzzqaRQ9UBDMwVPxzduiQ==", 676 | "requires": { 677 | "chalk": "2.1.0", 678 | "command-line-args": "4.0.7", 679 | "command-line-commands": "2.0.1", 680 | "command-line-usage": "4.0.1", 681 | "git-config": "0.0.7", 682 | "handlebars": "4.0.11", 683 | "inquirer": "3.3.0", 684 | "mkdirp": "0.5.1", 685 | "quickly-copy-file": "1.0.0", 686 | "rimraf": "2.6.2", 687 | "rsvp": "4.7.0", 688 | "semver": "5.4.1", 689 | "toml": "2.3.3", 690 | "ts-typed-json": "0.2.2", 691 | "validate-npm-package-license": "3.0.1", 692 | "validate-npm-package-name": "3.0.0" 693 | } 694 | }, 695 | "on-finished": { 696 | "version": "2.3.0", 697 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 698 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 699 | "requires": { 700 | "ee-first": "1.1.1" 701 | } 702 | }, 703 | "once": { 704 | "version": "1.4.0", 705 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 706 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 707 | "requires": { 708 | "wrappy": "1.0.2" 709 | } 710 | }, 711 | "onetime": { 712 | "version": "2.0.1", 713 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 714 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 715 | "requires": { 716 | "mimic-fn": "1.1.0" 717 | } 718 | }, 719 | "optimist": { 720 | "version": "0.6.1", 721 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 722 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 723 | "requires": { 724 | "minimist": "0.0.10", 725 | "wordwrap": "0.0.3" 726 | } 727 | }, 728 | "os-tmpdir": { 729 | "version": "1.0.2", 730 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 731 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 732 | }, 733 | "parseurl": { 734 | "version": "1.3.2", 735 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 736 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 737 | }, 738 | "path-is-absolute": { 739 | "version": "1.0.1", 740 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 741 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 742 | }, 743 | "path-to-regexp": { 744 | "version": "0.1.7", 745 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 746 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 747 | }, 748 | "proxy-addr": { 749 | "version": "2.0.2", 750 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", 751 | "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", 752 | "requires": { 753 | "forwarded": "0.1.2", 754 | "ipaddr.js": "1.5.2" 755 | } 756 | }, 757 | "qs": { 758 | "version": "6.5.1", 759 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 760 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" 761 | }, 762 | "quickly-copy-file": { 763 | "version": "1.0.0", 764 | "resolved": "https://registry.npmjs.org/quickly-copy-file/-/quickly-copy-file-1.0.0.tgz", 765 | "integrity": "sha1-n4/wZiMFEO50IrASFHKwk6hpCFk=", 766 | "requires": { 767 | "mkdirp": "0.5.1" 768 | } 769 | }, 770 | "range-parser": { 771 | "version": "1.2.0", 772 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 773 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 774 | }, 775 | "raw-body": { 776 | "version": "2.3.2", 777 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 778 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 779 | "requires": { 780 | "bytes": "3.0.0", 781 | "http-errors": "1.6.2", 782 | "iconv-lite": "0.4.19", 783 | "unpipe": "1.0.0" 784 | } 785 | }, 786 | "reduce-flatten": { 787 | "version": "1.0.1", 788 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", 789 | "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=" 790 | }, 791 | "repeat-string": { 792 | "version": "1.6.1", 793 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 794 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" 795 | }, 796 | "restore-cursor": { 797 | "version": "2.0.0", 798 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 799 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 800 | "requires": { 801 | "onetime": "2.0.1", 802 | "signal-exit": "3.0.2" 803 | } 804 | }, 805 | "right-align": { 806 | "version": "0.1.3", 807 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 808 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 809 | "optional": true, 810 | "requires": { 811 | "align-text": "0.1.4" 812 | } 813 | }, 814 | "rimraf": { 815 | "version": "2.6.2", 816 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 817 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 818 | "requires": { 819 | "glob": "7.1.2" 820 | } 821 | }, 822 | "rsvp": { 823 | "version": "4.7.0", 824 | "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.7.0.tgz", 825 | "integrity": "sha1-3BsLGlNvfeydK+ReChKtQZfJ/ZY=" 826 | }, 827 | "run-async": { 828 | "version": "2.3.0", 829 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 830 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 831 | "requires": { 832 | "is-promise": "2.1.0" 833 | } 834 | }, 835 | "rx-lite": { 836 | "version": "4.0.8", 837 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 838 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" 839 | }, 840 | "rx-lite-aggregates": { 841 | "version": "4.0.8", 842 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 843 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", 844 | "requires": { 845 | "rx-lite": "4.0.8" 846 | } 847 | }, 848 | "safe-buffer": { 849 | "version": "5.1.1", 850 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 851 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 852 | }, 853 | "semver": { 854 | "version": "5.4.1", 855 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", 856 | "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" 857 | }, 858 | "send": { 859 | "version": "0.16.1", 860 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", 861 | "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", 862 | "requires": { 863 | "debug": "2.6.9", 864 | "depd": "1.1.1", 865 | "destroy": "1.0.4", 866 | "encodeurl": "1.0.1", 867 | "escape-html": "1.0.3", 868 | "etag": "1.8.1", 869 | "fresh": "0.5.2", 870 | "http-errors": "1.6.2", 871 | "mime": "1.4.1", 872 | "ms": "2.0.0", 873 | "on-finished": "2.3.0", 874 | "range-parser": "1.2.0", 875 | "statuses": "1.3.1" 876 | } 877 | }, 878 | "serve-static": { 879 | "version": "1.13.1", 880 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", 881 | "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", 882 | "requires": { 883 | "encodeurl": "1.0.1", 884 | "escape-html": "1.0.3", 885 | "parseurl": "1.3.2", 886 | "send": "0.16.1" 887 | } 888 | }, 889 | "setprototypeof": { 890 | "version": "1.1.0", 891 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 892 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 893 | }, 894 | "signal-exit": { 895 | "version": "3.0.2", 896 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 897 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 898 | }, 899 | "source-map": { 900 | "version": "0.4.4", 901 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", 902 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", 903 | "requires": { 904 | "amdefine": "1.0.1" 905 | } 906 | }, 907 | "spdx-correct": { 908 | "version": "1.0.2", 909 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", 910 | "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", 911 | "requires": { 912 | "spdx-license-ids": "1.2.2" 913 | } 914 | }, 915 | "spdx-expression-parse": { 916 | "version": "1.0.4", 917 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", 918 | "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" 919 | }, 920 | "spdx-license-ids": { 921 | "version": "1.2.2", 922 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", 923 | "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" 924 | }, 925 | "statuses": { 926 | "version": "1.3.1", 927 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", 928 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 929 | }, 930 | "stream-transform": { 931 | "version": "1.0.0", 932 | "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-1.0.0.tgz", 933 | "integrity": "sha1-1O84aRPW7BAgUrx1/AUWlHqWHxA=" 934 | }, 935 | "string-width": { 936 | "version": "2.1.1", 937 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 938 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 939 | "requires": { 940 | "is-fullwidth-code-point": "2.0.0", 941 | "strip-ansi": "4.0.0" 942 | } 943 | }, 944 | "strip-ansi": { 945 | "version": "4.0.0", 946 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 947 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 948 | "requires": { 949 | "ansi-regex": "3.0.0" 950 | } 951 | }, 952 | "supports-color": { 953 | "version": "4.5.0", 954 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", 955 | "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", 956 | "requires": { 957 | "has-flag": "2.0.0" 958 | } 959 | }, 960 | "table-layout": { 961 | "version": "0.4.2", 962 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.2.tgz", 963 | "integrity": "sha512-tygyl5+eSHj4chpq5Zfy6cpc7MOUBClAW9ozghFH7hg9bAUzShOYn+/vUzTRkKOSLJWKfgYtP2tAU2c0oAD8eg==", 964 | "requires": { 965 | "array-back": "2.0.0", 966 | "deep-extend": "0.5.0", 967 | "lodash.padend": "4.6.1", 968 | "typical": "2.6.1", 969 | "wordwrapjs": "3.0.0" 970 | } 971 | }, 972 | "test-value": { 973 | "version": "2.1.0", 974 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", 975 | "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", 976 | "requires": { 977 | "array-back": "1.0.4", 978 | "typical": "2.6.1" 979 | }, 980 | "dependencies": { 981 | "array-back": { 982 | "version": "1.0.4", 983 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", 984 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", 985 | "requires": { 986 | "typical": "2.6.1" 987 | } 988 | } 989 | } 990 | }, 991 | "through": { 992 | "version": "2.3.8", 993 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 994 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 995 | }, 996 | "tmp": { 997 | "version": "0.0.33", 998 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 999 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1000 | "requires": { 1001 | "os-tmpdir": "1.0.2" 1002 | } 1003 | }, 1004 | "toml": { 1005 | "version": "2.3.3", 1006 | "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.3.tgz", 1007 | "integrity": "sha512-O7L5hhSQHxuufWUdcTRPfuTh3phKfAZ/dqfxZFoxPCj2RYmpaSGLEIs016FCXItQwNr08yefUB5TSjzRYnajTA==" 1008 | }, 1009 | "ts-typed-json": { 1010 | "version": "0.2.2", 1011 | "resolved": "https://registry.npmjs.org/ts-typed-json/-/ts-typed-json-0.2.2.tgz", 1012 | "integrity": "sha1-UxhL7ok+RZkbc8jEY6OLWeJ81H4=", 1013 | "requires": { 1014 | "rsvp": "3.6.2" 1015 | }, 1016 | "dependencies": { 1017 | "rsvp": { 1018 | "version": "3.6.2", 1019 | "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", 1020 | "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==" 1021 | } 1022 | } 1023 | }, 1024 | "type-is": { 1025 | "version": "1.6.15", 1026 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", 1027 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", 1028 | "requires": { 1029 | "media-typer": "0.3.0", 1030 | "mime-types": "2.1.17" 1031 | } 1032 | }, 1033 | "typical": { 1034 | "version": "2.6.1", 1035 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", 1036 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=" 1037 | }, 1038 | "uglify-js": { 1039 | "version": "2.8.29", 1040 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 1041 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 1042 | "optional": true, 1043 | "requires": { 1044 | "source-map": "0.5.7", 1045 | "uglify-to-browserify": "1.0.2", 1046 | "yargs": "3.10.0" 1047 | }, 1048 | "dependencies": { 1049 | "source-map": { 1050 | "version": "0.5.7", 1051 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1052 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 1053 | "optional": true 1054 | } 1055 | } 1056 | }, 1057 | "uglify-to-browserify": { 1058 | "version": "1.0.2", 1059 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 1060 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 1061 | "optional": true 1062 | }, 1063 | "unpipe": { 1064 | "version": "1.0.0", 1065 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1066 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1067 | }, 1068 | "utils-merge": { 1069 | "version": "1.0.1", 1070 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1071 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1072 | }, 1073 | "validate-npm-package-license": { 1074 | "version": "3.0.1", 1075 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", 1076 | "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", 1077 | "requires": { 1078 | "spdx-correct": "1.0.2", 1079 | "spdx-expression-parse": "1.0.4" 1080 | } 1081 | }, 1082 | "validate-npm-package-name": { 1083 | "version": "3.0.0", 1084 | "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", 1085 | "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", 1086 | "requires": { 1087 | "builtins": "1.0.3" 1088 | } 1089 | }, 1090 | "vary": { 1091 | "version": "1.1.2", 1092 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1093 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1094 | }, 1095 | "window-size": { 1096 | "version": "0.1.0", 1097 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 1098 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 1099 | "optional": true 1100 | }, 1101 | "wordwrap": { 1102 | "version": "0.0.3", 1103 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 1104 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" 1105 | }, 1106 | "wordwrapjs": { 1107 | "version": "3.0.0", 1108 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", 1109 | "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", 1110 | "requires": { 1111 | "reduce-flatten": "1.0.1", 1112 | "typical": "2.6.1" 1113 | } 1114 | }, 1115 | "wrappy": { 1116 | "version": "1.0.2", 1117 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1118 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1119 | }, 1120 | "yargs": { 1121 | "version": "3.10.0", 1122 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 1123 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 1124 | "optional": true, 1125 | "requires": { 1126 | "camelcase": "1.2.1", 1127 | "cliui": "2.1.0", 1128 | "decamelize": "1.2.0", 1129 | "window-size": "0.1.0" 1130 | } 1131 | } 1132 | } 1133 | } 1134 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exemplo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "engines" : { 10 | "node" : ">=8.x" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "csv": "^2.0.0", 16 | "express": "^4.16.2", 17 | "geolib": "^2.0.24", 18 | "neon-cli": "^0.1.20" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 19 | 20 | 21 |

Airports close to you

22 |

Find airports close to a given location.

23 |

24 | 25 | 26 | 27 | 28 | 29 |

30 | 31 | 32 | 33 | 34 |
35 |

Results

36 |
37 |
No results
38 |
No results
39 |
40 | 41 | 132 | 133 | 134 | --------------------------------------------------------------------------------