├── .gitignore
├── .perf.yml
├── .travis.yml
├── LICENSE
├── README.md
├── build-status.png
├── index.js
├── logo.png
├── mock
├── lighthouse.js
└── results.json
├── package-lock.json
├── package.json
├── src
├── api.js
├── build.js
├── config.json
├── lighthouse.js
├── properties.js
├── reporter.js
├── settings.js
├── setup.js
└── token.js
└── store
├── .env.sample
├── dummy.js
├── firebase.js
├── github.js
├── index.js
├── package-lock.json
├── package.json
├── static
└── styles.css
└── views
├── auth.pug
└── build.pug
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | debug.json
6 |
7 | # Coverage directory used by tools like istanbul
8 | coverage
9 |
10 | # Dependency directories
11 | node_modules
12 |
13 | # OS specific files
14 | .DS_Store
15 | store/.env
16 |
--------------------------------------------------------------------------------
/.perf.yml:
--------------------------------------------------------------------------------
1 | runs: 2
2 | fail: false
3 | url: https://siddharthkp.github.io
4 | thresholds:
5 | - time-to-interactive: 500
6 | - page-ready: 1500
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | language: node_js
3 | node_js:
4 | - "6"
5 | cache:
6 | directories:
7 | - node_modules
8 | notifications:
9 | email: false
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Siddharth Kshetrapal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Continuous integration for performance monitoring
5 |
6 |
7 |
8 |
9 |
10 | [](https://travis-ci.org/siddharthkp/perfbench)
11 |
12 |
13 |
14 | #### install
15 | ```
16 | npm install perfbench --save
17 | ```
18 |
19 |
20 |
21 | #### usage
22 |
23 | Build and run your application in your CI and then invoke perfbench
24 |
25 | `package.json`:
26 |
27 | ```json
28 | "name": "my-awesome-app",
29 | "scripts": {
30 | "pretest": "npm run build && pm2 start server.js",
31 | "test": "perfbench"
32 | }
33 | ```
34 |
35 | #### metrics measured
36 |
37 | - First meaningful paint
38 | - Speed index metric
39 | - Time to interactive
40 | - Total byte weight
41 |
42 |
43 |
44 | #### test conditions
45 |
46 | - Network: Fast 3G (150ms RTT, 1.6Mbps down, 0.7Mbps up)
47 | - Device emulation: Nexus 5X
48 | - CPU: 5x slowdown
49 |
50 |
51 |
52 | #### setup
53 |
54 | 1. configuration
55 |
56 | Drop a YAML file `.perf.yml` in the root of your repository.
57 |
58 | ```yaml
59 | url: http://localhost:3000 # the url you want to test
60 | fail: false # optional, default: true. false will only show a warning
61 | thresholds: # all rows are optional. add to customize the threshold
62 | - first-meaningful-paint: 1600 # optional, default: 1600, value in ms
63 | - speed-index-metric: 1250 # optional, default: 1250
64 | - time-to-interactive: 2500 # optional, default: 2500, value in ms
65 | - total-byte-weight: 1600 # optional, default: 1600, value in Kb
66 | ```
67 |
68 |
69 |
70 | #### custom properties
71 |
72 | You can also add custom properties.
73 |
74 | Send a user timing performance event from your javascript.
75 | ```js
76 | performance.mark('Page ready')
77 | ```
78 |
79 | And add the kebabcased key to `.perf.yml`
80 |
81 | ```yaml
82 | thresholds:
83 | - page-ready: 1500
84 | ```
85 |
86 | ##### event-type
87 |
88 | For travis users, if you would like to run perfbench in `pull_request` instead of `push`,
89 | set `event-type: pull_request`
90 |
91 | ```yaml
92 | event-type: pull_request
93 | ```
94 |
95 |
96 |
97 | 2) github token for status
98 |
99 | 
100 |
101 | Currently works for [Travis CI](https://travis-ci.org), [CircleCI](https://circleci.com/), [Wercker](wercker.com), and [Drone](http://readme.drone.io/).
102 |
103 | - [Authorize `perfbench` for status access](https://github.com/login/oauth/authorize?scope=repo%3Astatus&client_id=5be3b09eacb8977c79e6), copy the generated token.
104 |
105 | - Add this token as `PERFBENCH_GITHUB_TOKEN` as environment parameter in your CIs project settings.
106 |
107 | (Ask me for help if you're stuck)
108 |
109 |
110 | #### like it?
111 |
112 | :star: this repo
113 |
114 |
115 |
116 | #### todo
117 |
118 | - support multiple urls
119 |
120 |
121 |
122 | #### license
123 |
124 | MIT © [siddharthkp](https://github.com/siddharthkp)
125 |
--------------------------------------------------------------------------------
/build-status.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siddharthkp/perfbench/007df5249132de1e1c18deae761e4d2e9b37fbad/build-status.png
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const setup = require('./src/setup')
4 | const lighthouse = require('./src/lighthouse')
5 | const reporter = require('./src/reporter')
6 | let settings = require('./src/settings')
7 | const build = require('./src/build')
8 | const { event, branch } = require('ci-env')
9 | const { warn } = require('prettycli')
10 |
11 | const WAIT_BETWEEN_RUNS = 2500
12 |
13 | const results = []
14 | let runs = settings.runs
15 |
16 | const run = () => {
17 | runs = runs - 1
18 | lighthouse
19 | .run(settings.url)
20 | .then(result => {
21 | results.push(result)
22 | if (runs > 0) setTimeout(run, WAIT_BETWEEN_RUNS)
23 | else reporter.print(results)
24 | })
25 | .catch(err => {
26 | throw err
27 | })
28 | }
29 |
30 | const start = () => {
31 | run()
32 | }
33 |
34 | process.on('unhandledRejection', function(reason, p) {
35 | console.log('Unhandled Promise: ', p, ' reason: ', reason)
36 | build.error()
37 | })
38 |
39 | if (process.env.CI) {
40 | if (branch === 'master' || event === settings.event) {
41 | setup().then(start).catch(error => console.log('Setup failed', error))
42 | } else if (event === 'pull_request') {
43 | warn(
44 | `perfbench does not run on travis:pull_request
45 |
46 | If you would like to run this in travis:pull_request instead of travis:push,
47 | check configuration options: https://siddharthkp/perfbench#event
48 | `
49 | )
50 | }
51 | } else start()
52 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siddharthkp/perfbench/007df5249132de1e1c18deae761e4d2e9b37fbad/logo.png
--------------------------------------------------------------------------------
/mock/lighthouse.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 |
3 | const run = () =>
4 | new Promise(resolve => {
5 | const results = fs.readFileSync("./results.json", "utf8");
6 | resolve(JSON.parse(results));
7 | });
8 |
9 | module.exports = { run };
10 |
--------------------------------------------------------------------------------
/mock/results.json:
--------------------------------------------------------------------------------
1 | {
2 | "lighthouseVersion": "1.6.3",
3 | "generatedTime": "2017-04-20T11:17:47.016Z",
4 | "initialUrl": "https://www.practo.com/tests/bangalore/pregnancy-test-stick-random-urine",
5 | "url": "https://www.practo.com/tests/bangalore/pregnancy-test-stick-random-urine",
6 | "audits": {
7 | "first-meaningful-paint": {
8 | "score": 52,
9 | "displayValue": "3892.2ms",
10 | "rawValue": 3892.2,
11 | "optimalValue": "1,600ms",
12 | "extendedInfo": {
13 | "value": {
14 | "timestamps": {
15 | "navStart": 17792594079,
16 | "fCP": 17794792290,
17 | "fMP": 17796486232
18 | },
19 | "timings": {
20 | "navStart": 0,
21 | "fCP": 2198.211,
22 | "fMP": 3892.153
23 | }
24 | },
25 | "formatter": "null"
26 | },
27 | "name": "first-meaningful-paint",
28 | "category": "Performance",
29 | "description": "First meaningful paint",
30 | "helpText": "First meaningful paint measures when the primary content of a page is visible. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)."
31 | },
32 | "speed-index-metric": {
33 | "score": 18,
34 | "displayValue": "10569",
35 | "rawValue": 10569,
36 | "optimalValue": "1,250",
37 | "extendedInfo": {
38 | "formatter": "speedline",
39 | "value": {
40 | "timings": {
41 | "firstVisualChange": 2336,
42 | "visuallyComplete": 11148,
43 | "speedIndex": 10972.417849997617,
44 | "perceptualSpeedIndex": 10569.103989511119
45 | },
46 | "timestamps": {
47 | "firstVisualChange": 17794922324,
48 | "visuallyComplete": 17803734324,
49 | "speedIndex": 17803558741.85,
50 | "perceptualSpeedIndex": 17803155427.989513
51 | },
52 | "frames": [
53 | {
54 | "timestamp": 17792586.324,
55 | "progress": 0
56 | },
57 | {
58 | "timestamp": 17794922.596,
59 | "progress": 4.632249349660438
60 | },
61 | {
62 | "timestamp": 17795126.564,
63 | "progress": 4.638469205268419
64 | },
65 | {
66 | "timestamp": 17795142.727,
67 | "progress": 4.639162153739748
68 | },
69 | {
70 | "timestamp": 17795159.005,
71 | "progress": 4.639162153739748
72 | },
73 | {
74 | "timestamp": 17795175.597,
75 | "progress": 4.6383741780565035
76 | },
77 | {
78 | "timestamp": 17795192.217,
79 | "progress": 4.638587482913058
80 | },
81 | {
82 | "timestamp": 17795210.542,
83 | "progress": 4.637244992051461
84 | },
85 | {
86 | "timestamp": 17795225.995,
87 | "progress": 4.637244992051461
88 | },
89 | {
90 | "timestamp": 17795243.533,
91 | "progress": 4.637953967463672
92 | },
93 | {
94 | "timestamp": 17795259.447,
95 | "progress": 4.6370528900459895
96 | },
97 | {
98 | "timestamp": 17795275.711,
99 | "progress": 4.636640133487143
100 | },
101 | {
102 | "timestamp": 17795292.433,
103 | "progress": 4.636618346846205
104 | },
105 | {
106 | "timestamp": 17795309.134,
107 | "progress": 4.636011510211239
108 | },
109 | {
110 | "timestamp": 17795325.872,
111 | "progress": 4.636011510211239
112 | },
113 | {
114 | "timestamp": 17795359.179,
115 | "progress": 4.636618346846205
116 | },
117 | {
118 | "timestamp": 17795375.957,
119 | "progress": 4.636618346846205
120 | },
121 | {
122 | "timestamp": 17795392.592,
123 | "progress": 4.636527245341333
124 | },
125 | {
126 | "timestamp": 17795409.451,
127 | "progress": 4.637116350915429
128 | },
129 | {
130 | "timestamp": 17795426.061,
131 | "progress": 4.636885746263546
132 | },
133 | {
134 | "timestamp": 17795442.423,
135 | "progress": 4.638401735049216
136 | },
137 | {
138 | "timestamp": 17795459.172,
139 | "progress": 4.6335601902197
140 | },
141 | {
142 | "timestamp": 17795475.751,
143 | "progress": 4.635364693172085
144 | },
145 | {
146 | "timestamp": 17795493.111,
147 | "progress": 4.6398566089640445
148 | },
149 | {
150 | "timestamp": 17795509.452,
151 | "progress": 4.638880754657769
152 | },
153 | {
154 | "timestamp": 17795526.141,
155 | "progress": 4.637390129200676
156 | },
157 | {
158 | "timestamp": 17795543.42,
159 | "progress": 4.638401735049216
160 | },
161 | {
162 | "timestamp": 17795559.622,
163 | "progress": 4.638392666163962
164 | },
165 | {
166 | "timestamp": 17795575.855,
167 | "progress": 4.637996589584445
168 | },
169 | {
170 | "timestamp": 17795592.921,
171 | "progress": 4.63732150328746
172 | },
173 | {
174 | "timestamp": 17795609.26,
175 | "progress": 4.637440730119833
176 | },
177 | {
178 | "timestamp": 17795628.902,
179 | "progress": 4.63732150328746
180 | },
181 | {
182 | "timestamp": 17795643.117,
183 | "progress": 4.63732150328746
184 | },
185 | {
186 | "timestamp": 17795661.901,
187 | "progress": 4.6379907697333005
188 | },
189 | {
190 | "timestamp": 17795675.243,
191 | "progress": 4.581219930990162
192 | },
193 | {
194 | "timestamp": 17795690.956,
195 | "progress": 4.580643695618719
196 | },
197 | {
198 | "timestamp": 17795711.454,
199 | "progress": 4.577274207347641
200 | },
201 | {
202 | "timestamp": 17795729.208,
203 | "progress": 4.576147537400308
204 | },
205 | {
206 | "timestamp": 17795744.569,
207 | "progress": 4.577795075216585
208 | },
209 | {
210 | "timestamp": 17795761.263,
211 | "progress": 4.578494761805252
212 | },
213 | {
214 | "timestamp": 17795779.165,
215 | "progress": 4.578494761805252
216 | },
217 | {
218 | "timestamp": 17795796.153,
219 | "progress": 4.578494761805252
220 | },
221 | {
222 | "timestamp": 17795812.536,
223 | "progress": 4.574407482535909
224 | },
225 | {
226 | "timestamp": 17795827.969,
227 | "progress": 4.577221331204453
228 | },
229 | {
230 | "timestamp": 17795845.406,
231 | "progress": 4.577010120031013
232 | },
233 | {
234 | "timestamp": 17795861.113,
235 | "progress": 4.576269619845564
236 | },
237 | {
238 | "timestamp": 17795885.176,
239 | "progress": 4.57558772301686
240 | },
241 | {
242 | "timestamp": 17795901.519,
243 | "progress": 4.575993357688476
244 | },
245 | {
246 | "timestamp": 17795915.508,
247 | "progress": 4.575993357688476
248 | },
249 | {
250 | "timestamp": 17796498.284,
251 | "progress": 6.179595809749249
252 | },
253 | {
254 | "timestamp": 17796746.562,
255 | "progress": 6.111114320815328
256 | },
257 | {
258 | "timestamp": 17802215.577,
259 | "progress": 6.111114320815328
260 | },
261 | {
262 | "timestamp": 17802222.034,
263 | "progress": 10.013069352260459
264 | },
265 | {
266 | "timestamp": 17802249.022,
267 | "progress": 10.015132176729548
268 | },
269 | {
270 | "timestamp": 17802267.02,
271 | "progress": 10.016492849422198
272 | },
273 | {
274 | "timestamp": 17802282.475,
275 | "progress": 10.017086329389011
276 | },
277 | {
278 | "timestamp": 17802299.472,
279 | "progress": 10.016891902669332
280 | },
281 | {
282 | "timestamp": 17802316.071,
283 | "progress": 10.017006942727388
284 | },
285 | {
286 | "timestamp": 17802332.541,
287 | "progress": 10.017058225941424
288 | },
289 | {
290 | "timestamp": 17802818.936,
291 | "progress": 10.246347440889462
292 | },
293 | {
294 | "timestamp": 17803584.603,
295 | "progress": 12.126349602182376
296 | },
297 | {
298 | "timestamp": 17803734.343,
299 | "progress": 100
300 | }
301 | ]
302 | }
303 | },
304 | "name": "speed-index-metric",
305 | "category": "Performance",
306 | "description": "Perceptual Speed Index",
307 | "helpText": "Speed Index shows how quickly the contents of a page are visibly populated. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/speed-index)."
308 | },
309 | "time-to-interactive": {
310 | "score": 8,
311 | "displayValue": "11140.3ms",
312 | "rawValue": 11140.3,
313 | "optimalValue": "5,000ms",
314 | "extendedInfo": {
315 | "value": {
316 | "timings": {
317 | "fMP": 3892.2,
318 | "visuallyReady": 11140.264,
319 | "timeToInteractive": 11140.264
320 | },
321 | "timestamps": {
322 | "fMP": 17796486232,
323 | "visuallyReady": 17803734343,
324 | "timeToInteractive": 17803734343
325 | },
326 | "expectedLatencyAtTTI": 26.834,
327 | "foundLatencies": [
328 | {
329 | "estLatency": 26.834000000000003,
330 | "startTime": "11140.3"
331 | }
332 | ]
333 | },
334 | "formatter": "null"
335 | },
336 | "name": "time-to-interactive",
337 | "category": "Performance",
338 | "description": "Time To Interactive (alpha)",
339 | "helpText": "Time to Interactive identifies the time at which your app appears to be ready enough to interact with. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive)."
340 | },
341 | "total-byte-weight": {
342 | "score": 100,
343 | "displayValue": "Total size was 649 KB",
344 | "rawValue": 665062,
345 | "optimalValue": "1,600 KB",
346 | "extendedInfo": {
347 | "formatter": "table",
348 | "value": {
349 | "results": [
350 | {
351 | "url": "…dist/main.fc52823….bundle.js",
352 | "totalBytes": 158755,
353 | "totalKb": "155 KB",
354 | "totalMs": "1,670ms"
355 | },
356 | {
357 | "url": "…dist/CityTestListingPage.9011acf….bundle.js",
358 | "totalBytes": 120354,
359 | "totalKb": "118 KB",
360 | "totalMs": "1,270ms"
361 | },
362 | {
363 | "url": "…dist/vendor.d87444f….bundle.js",
364 | "totalBytes": 63479,
365 | "totalKb": "62 KB",
366 | "totalMs": "670ms"
367 | },
368 | {
369 | "url": "…v6/practicon.woff2",
370 | "totalBytes": 49882,
371 | "totalKb": "49 KB",
372 | "totalMs": "530ms"
373 | },
374 | {
375 | "url": "…camphor/677b110e-fe2c-4af7-b50b-3e8f00c371ce.woff2",
376 | "totalBytes": 37494,
377 | "totalKb": "37 KB",
378 | "totalMs": "400ms"
379 | },
380 | {
381 | "url": "…camphor/c96be38e-ea64-418f-ae54-e757ed92b069.woff2",
382 | "totalBytes": 37452,
383 | "totalKb": "37 KB",
384 | "totalMs": "390ms"
385 | },
386 | {
387 | "url": "…bangalore/pregnancy-test-stick-random-urine",
388 | "totalBytes": 30671,
389 | "totalKb": "30 KB",
390 | "totalMs": "320ms"
391 | },
392 | {
393 | "url": "…dist/main.fc52823….css",
394 | "totalBytes": 30141,
395 | "totalKb": "29 KB",
396 | "totalMs": "320ms"
397 | },
398 | {
399 | "url": "…js/practonav.js",
400 | "totalBytes": 18651,
401 | "totalKb": "18 KB",
402 | "totalMs": "200ms"
403 | },
404 | {
405 | "url": "/nr-spa-974.min.js",
406 | "totalBytes": 12354,
407 | "totalKb": "12 KB",
408 | "totalMs": "130ms"
409 | }
410 | ],
411 | "tableHeadings": {
412 | "url": "URL",
413 | "totalKb": "Total Size",
414 | "totalMs": "Transfer Time"
415 | }
416 | }
417 | },
418 | "informative": true,
419 | "name": "total-byte-weight",
420 | "category": "Network",
421 | "description": "Avoids enormous network payloads",
422 | "helpText": "Network transfer size [costs users real dollars](https://whatdoesmysitecost.com/) and is [highly correlated](http://httparchive.org/interesting.php#onLoad) with long load times. Try to find ways to reduce the size of required files."
423 | },
424 | "user-timings": {
425 | "score": true,
426 | "displayValue": "0",
427 | "rawValue": true,
428 | "extendedInfo": {
429 | "formatter": "userTimings",
430 | "value": []
431 | },
432 | "informative": true,
433 | "name": "user-timings",
434 | "category": "Performance",
435 | "description": "User Timing marks and measures",
436 | "helpText": "Consider instrumenting your app with the User Timing API to create custom, real-world measurements of key user experiences. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/user-timing)."
437 | }
438 | },
439 | "runtimeConfig": {
440 | "environment": [
441 | {
442 | "name": "Device Emulation",
443 | "enabled": false,
444 | "description": "Nexus 5X"
445 | },
446 | {
447 | "name": "Network Throttling",
448 | "enabled": true,
449 | "description": "150ms RTT, 0.7Mbps down, 0.2Mbps up"
450 | },
451 | {
452 | "name": "CPU Throttling",
453 | "enabled": true,
454 | "description": "5x slowdown"
455 | }
456 | ],
457 | "blockedUrlPatterns": []
458 | },
459 | "aggregations": []
460 | }
461 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "perfbench",
3 | "version": "1.8.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "adm-zip": {
8 | "version": "0.4.7",
9 | "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz",
10 | "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E="
11 | },
12 | "agent-base": {
13 | "version": "2.1.1",
14 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
15 | "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
16 | "requires": {
17 | "extend": "3.0.1",
18 | "semver": "5.0.3"
19 | },
20 | "dependencies": {
21 | "semver": {
22 | "version": "5.0.3",
23 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
24 | "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no="
25 | }
26 | }
27 | },
28 | "ajv": {
29 | "version": "4.11.8",
30 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
31 | "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
32 | "requires": {
33 | "co": "4.6.0",
34 | "json-stable-stringify": "1.0.1"
35 | }
36 | },
37 | "amdefine": {
38 | "version": "1.0.1",
39 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
40 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
41 | },
42 | "ansi-escapes": {
43 | "version": "1.4.0",
44 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
45 | "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
46 | "dev": true
47 | },
48 | "ansi-regex": {
49 | "version": "2.1.1",
50 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
51 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
52 | },
53 | "ansi-styles": {
54 | "version": "2.2.1",
55 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
56 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
57 | },
58 | "app-root-path": {
59 | "version": "2.0.1",
60 | "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz",
61 | "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=",
62 | "dev": true
63 | },
64 | "argparse": {
65 | "version": "1.0.9",
66 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
67 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
68 | "requires": {
69 | "sprintf-js": "1.0.3"
70 | }
71 | },
72 | "array-find-index": {
73 | "version": "1.0.2",
74 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
75 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
76 | },
77 | "array-union": {
78 | "version": "1.0.2",
79 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
80 | "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
81 | "requires": {
82 | "array-uniq": "1.0.3"
83 | }
84 | },
85 | "array-uniq": {
86 | "version": "1.0.3",
87 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
88 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
89 | },
90 | "arrify": {
91 | "version": "1.0.1",
92 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
93 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
94 | },
95 | "asn1": {
96 | "version": "0.2.3",
97 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
98 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
99 | },
100 | "assert-plus": {
101 | "version": "0.2.0",
102 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
103 | "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ="
104 | },
105 | "ast-types": {
106 | "version": "0.9.8",
107 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.8.tgz",
108 | "integrity": "sha1-bLakC+ujH0nyCSjihDn8FKPasHg=",
109 | "dev": true
110 | },
111 | "async": {
112 | "version": "1.5.2",
113 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
114 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
115 | },
116 | "asynckit": {
117 | "version": "0.4.0",
118 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
119 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
120 | },
121 | "aws-sign2": {
122 | "version": "0.6.0",
123 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
124 | "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8="
125 | },
126 | "aws4": {
127 | "version": "1.6.0",
128 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
129 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
130 | },
131 | "axe-core": {
132 | "version": "2.1.7",
133 | "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-2.1.7.tgz",
134 | "integrity": "sha1-T2bys+47WOwtPbQzndEkxbM7ecM="
135 | },
136 | "axios": {
137 | "version": "0.15.3",
138 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz",
139 | "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=",
140 | "requires": {
141 | "follow-redirects": "1.0.0"
142 | }
143 | },
144 | "babar": {
145 | "version": "0.0.3",
146 | "resolved": "https://registry.npmjs.org/babar/-/babar-0.0.3.tgz",
147 | "integrity": "sha1-LzlNSlkY9+GunlQI6alvP5Ne4eI=",
148 | "requires": {
149 | "colors": "0.6.2"
150 | },
151 | "dependencies": {
152 | "colors": {
153 | "version": "0.6.2",
154 | "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
155 | "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w="
156 | }
157 | }
158 | },
159 | "babel-code-frame": {
160 | "version": "6.22.0",
161 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
162 | "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
163 | "dev": true,
164 | "requires": {
165 | "chalk": "1.1.3",
166 | "esutils": "2.0.2",
167 | "js-tokens": "3.0.1"
168 | }
169 | },
170 | "babylon": {
171 | "version": "7.0.0-beta.8",
172 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.8.tgz",
173 | "integrity": "sha1-K9xa42YEFELCfgaMzm8NfAbqmUk=",
174 | "dev": true
175 | },
176 | "balanced-match": {
177 | "version": "0.4.2",
178 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
179 | "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
180 | },
181 | "bcrypt-pbkdf": {
182 | "version": "1.0.1",
183 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
184 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
185 | "optional": true,
186 | "requires": {
187 | "tweetnacl": "0.14.5"
188 | }
189 | },
190 | "boom": {
191 | "version": "2.10.1",
192 | "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
193 | "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
194 | "requires": {
195 | "hoek": "2.16.3"
196 | }
197 | },
198 | "brace-expansion": {
199 | "version": "1.1.7",
200 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
201 | "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=",
202 | "requires": {
203 | "balanced-match": "0.4.2",
204 | "concat-map": "0.0.1"
205 | }
206 | },
207 | "buffer-crc32": {
208 | "version": "0.2.13",
209 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
210 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
211 | },
212 | "builtin-modules": {
213 | "version": "1.1.1",
214 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
215 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
216 | },
217 | "camelcase-keys": {
218 | "version": "2.1.0",
219 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
220 | "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
221 | "requires": {
222 | "camelcase": "2.1.1",
223 | "map-obj": "1.0.1"
224 | },
225 | "dependencies": {
226 | "camelcase": {
227 | "version": "2.1.1",
228 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
229 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
230 | }
231 | }
232 | },
233 | "caseless": {
234 | "version": "0.12.0",
235 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
236 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
237 | },
238 | "chalk": {
239 | "version": "1.1.3",
240 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
241 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
242 | "requires": {
243 | "ansi-styles": "2.2.1",
244 | "escape-string-regexp": "1.0.5",
245 | "has-ansi": "2.0.0",
246 | "strip-ansi": "3.0.1",
247 | "supports-color": "2.0.0"
248 | }
249 | },
250 | "chrome-devtools-frontend": {
251 | "version": "1.0.422034",
252 | "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.422034.tgz",
253 | "integrity": "sha1-BxyM4URmt2UwMvzRrRpKaNXjy9k="
254 | },
255 | "ci-env": {
256 | "version": "1.4.0",
257 | "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.4.0.tgz",
258 | "integrity": "sha512-IRvBrZSkdlsHgGZtaM41WBHJKEHpheqMO6B8lHN452zHiKN0imDcDjI9rIqIA4Y5/2uOAxnA8yYqWBzoYqxMMQ=="
259 | },
260 | "ci-info": {
261 | "version": "1.0.0",
262 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz",
263 | "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=",
264 | "dev": true
265 | },
266 | "cli-cursor": {
267 | "version": "1.0.2",
268 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
269 | "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
270 | "dev": true,
271 | "requires": {
272 | "restore-cursor": "1.0.1"
273 | }
274 | },
275 | "cli-spinners": {
276 | "version": "0.1.2",
277 | "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz",
278 | "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=",
279 | "dev": true
280 | },
281 | "cli-table2": {
282 | "version": "0.2.0",
283 | "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz",
284 | "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=",
285 | "requires": {
286 | "colors": "1.1.2",
287 | "lodash": "3.10.1",
288 | "string-width": "1.0.2"
289 | }
290 | },
291 | "cli-truncate": {
292 | "version": "0.2.1",
293 | "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
294 | "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
295 | "dev": true,
296 | "requires": {
297 | "slice-ansi": "0.0.4",
298 | "string-width": "1.0.2"
299 | }
300 | },
301 | "co": {
302 | "version": "4.6.0",
303 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
304 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
305 | },
306 | "code-point-at": {
307 | "version": "1.1.0",
308 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
309 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
310 | },
311 | "color-convert": {
312 | "version": "1.9.0",
313 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
314 | "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
315 | "dev": true,
316 | "requires": {
317 | "color-name": "1.1.2"
318 | }
319 | },
320 | "color-name": {
321 | "version": "1.1.2",
322 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz",
323 | "integrity": "sha1-XIq3K2S9IhXWF66VWeuxSEdc+Y0=",
324 | "dev": true
325 | },
326 | "colors": {
327 | "version": "1.1.2",
328 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
329 | "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM="
330 | },
331 | "combined-stream": {
332 | "version": "1.0.5",
333 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
334 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
335 | "requires": {
336 | "delayed-stream": "1.0.0"
337 | }
338 | },
339 | "commander": {
340 | "version": "2.9.0",
341 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
342 | "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
343 | "dev": true,
344 | "requires": {
345 | "graceful-readlink": "1.0.1"
346 | }
347 | },
348 | "concat-map": {
349 | "version": "0.0.1",
350 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
351 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
352 | },
353 | "cosmiconfig": {
354 | "version": "1.1.0",
355 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-1.1.0.tgz",
356 | "integrity": "sha1-DeoPmATv37kp+7GxiOJVU+oFPTc=",
357 | "dev": true,
358 | "requires": {
359 | "graceful-fs": "4.1.11",
360 | "js-yaml": "3.8.4",
361 | "minimist": "1.2.0",
362 | "object-assign": "4.1.1",
363 | "os-homedir": "1.0.2",
364 | "parse-json": "2.2.0",
365 | "pinkie-promise": "2.0.1",
366 | "require-from-string": "1.2.1"
367 | },
368 | "dependencies": {
369 | "minimist": {
370 | "version": "1.2.0",
371 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
372 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
373 | "dev": true
374 | }
375 | }
376 | },
377 | "cross-spawn": {
378 | "version": "5.1.0",
379 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
380 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
381 | "dev": true,
382 | "requires": {
383 | "lru-cache": "4.0.2",
384 | "shebang-command": "1.2.0",
385 | "which": "1.2.14"
386 | }
387 | },
388 | "cryptiles": {
389 | "version": "2.0.5",
390 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
391 | "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
392 | "requires": {
393 | "boom": "2.10.1"
394 | }
395 | },
396 | "currently-unhandled": {
397 | "version": "0.4.1",
398 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
399 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
400 | "requires": {
401 | "array-find-index": "1.0.2"
402 | }
403 | },
404 | "dashdash": {
405 | "version": "1.14.1",
406 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
407 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
408 | "requires": {
409 | "assert-plus": "1.0.0"
410 | },
411 | "dependencies": {
412 | "assert-plus": {
413 | "version": "1.0.0",
414 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
415 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
416 | }
417 | }
418 | },
419 | "date-fns": {
420 | "version": "1.28.4",
421 | "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.28.4.tgz",
422 | "integrity": "sha1-eTiuw0ujH8i9E00jRLwuC7/ZUWU=",
423 | "dev": true
424 | },
425 | "debug": {
426 | "version": "2.2.0",
427 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
428 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
429 | "requires": {
430 | "ms": "0.7.1"
431 | }
432 | },
433 | "decamelize": {
434 | "version": "1.2.0",
435 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
436 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
437 | },
438 | "del": {
439 | "version": "2.2.2",
440 | "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
441 | "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
442 | "requires": {
443 | "globby": "5.0.0",
444 | "is-path-cwd": "1.0.0",
445 | "is-path-in-cwd": "1.0.0",
446 | "object-assign": "4.1.1",
447 | "pify": "2.3.0",
448 | "pinkie-promise": "2.0.1",
449 | "rimraf": "2.2.8"
450 | }
451 | },
452 | "delayed-stream": {
453 | "version": "1.0.0",
454 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
455 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
456 | },
457 | "devtools-timeline-model": {
458 | "version": "1.1.6",
459 | "resolved": "https://registry.npmjs.org/devtools-timeline-model/-/devtools-timeline-model-1.1.6.tgz",
460 | "integrity": "sha1-e+Uac7VdcntZe7MN0e0ujiEGOaU=",
461 | "requires": {
462 | "chrome-devtools-frontend": "1.0.401423",
463 | "resolve": "1.1.7"
464 | },
465 | "dependencies": {
466 | "chrome-devtools-frontend": {
467 | "version": "1.0.401423",
468 | "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.401423.tgz",
469 | "integrity": "sha1-MqibjQTjeKSUvjyNYycXA74cBOo="
470 | }
471 | }
472 | },
473 | "dmg": {
474 | "version": "0.1.0",
475 | "resolved": "https://registry.npmjs.org/dmg/-/dmg-0.1.0.tgz",
476 | "integrity": "sha1-s46iEH9vCwcEQrv3mb/E8q7apfg="
477 | },
478 | "ecc-jsbn": {
479 | "version": "0.1.1",
480 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
481 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
482 | "optional": true,
483 | "requires": {
484 | "jsbn": "0.1.1"
485 | }
486 | },
487 | "elegant-spinner": {
488 | "version": "1.0.1",
489 | "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
490 | "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
491 | "dev": true
492 | },
493 | "error-ex": {
494 | "version": "1.3.1",
495 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
496 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
497 | "requires": {
498 | "is-arrayish": "0.2.1"
499 | }
500 | },
501 | "escape-string-regexp": {
502 | "version": "1.0.5",
503 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
504 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
505 | },
506 | "esprima": {
507 | "version": "3.1.3",
508 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
509 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
510 | },
511 | "esutils": {
512 | "version": "2.0.2",
513 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
514 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
515 | "dev": true
516 | },
517 | "execa": {
518 | "version": "0.6.3",
519 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.3.tgz",
520 | "integrity": "sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4=",
521 | "dev": true,
522 | "requires": {
523 | "cross-spawn": "5.1.0",
524 | "get-stream": "3.0.0",
525 | "is-stream": "1.1.0",
526 | "npm-run-path": "2.0.2",
527 | "p-finally": "1.0.0",
528 | "signal-exit": "3.0.2",
529 | "strip-eof": "1.0.0"
530 | }
531 | },
532 | "exit-hook": {
533 | "version": "1.1.1",
534 | "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
535 | "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
536 | "dev": true
537 | },
538 | "extend": {
539 | "version": "3.0.1",
540 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
541 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
542 | },
543 | "extsprintf": {
544 | "version": "1.0.2",
545 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
546 | "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA="
547 | },
548 | "fd-slicer": {
549 | "version": "1.0.1",
550 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
551 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
552 | "requires": {
553 | "pend": "1.2.0"
554 | }
555 | },
556 | "figures": {
557 | "version": "1.7.0",
558 | "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
559 | "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
560 | "dev": true,
561 | "requires": {
562 | "escape-string-regexp": "1.0.5",
563 | "object-assign": "4.1.1"
564 | }
565 | },
566 | "find-parent-dir": {
567 | "version": "0.3.0",
568 | "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz",
569 | "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=",
570 | "dev": true
571 | },
572 | "find-up": {
573 | "version": "1.1.2",
574 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
575 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
576 | "requires": {
577 | "path-exists": "2.1.0",
578 | "pinkie-promise": "2.0.1"
579 | }
580 | },
581 | "flow-parser": {
582 | "version": "0.43.0",
583 | "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.43.0.tgz",
584 | "integrity": "sha1-4rjrGsg91T97awSnw1tqUsM0ebc=",
585 | "dev": true
586 | },
587 | "follow-redirects": {
588 | "version": "1.0.0",
589 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz",
590 | "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=",
591 | "requires": {
592 | "debug": "2.2.0"
593 | }
594 | },
595 | "forever-agent": {
596 | "version": "0.6.1",
597 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
598 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
599 | },
600 | "form-data": {
601 | "version": "2.1.4",
602 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
603 | "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
604 | "requires": {
605 | "asynckit": "0.4.0",
606 | "combined-stream": "1.0.5",
607 | "mime-types": "2.1.15"
608 | }
609 | },
610 | "fs-extra": {
611 | "version": "2.1.2",
612 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
613 | "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
614 | "requires": {
615 | "graceful-fs": "4.1.11",
616 | "jsonfile": "2.4.0"
617 | }
618 | },
619 | "fs.realpath": {
620 | "version": "1.0.0",
621 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
622 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
623 | },
624 | "get-stdin": {
625 | "version": "4.0.1",
626 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
627 | "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
628 | },
629 | "get-stream": {
630 | "version": "3.0.0",
631 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
632 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
633 | "dev": true
634 | },
635 | "getpass": {
636 | "version": "0.1.7",
637 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
638 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
639 | "requires": {
640 | "assert-plus": "1.0.0"
641 | },
642 | "dependencies": {
643 | "assert-plus": {
644 | "version": "1.0.0",
645 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
646 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
647 | }
648 | }
649 | },
650 | "github-build": {
651 | "version": "1.2.0",
652 | "resolved": "https://registry.npmjs.org/github-build/-/github-build-1.2.0.tgz",
653 | "integrity": "sha512-Iq7NialLYz5yRZDkiX8zaOWd+N3BssJJfUvG7wd8r4MeLCN88SdxEYo2esseMLpLtP4vNXhgamg1eRm7hw59qw==",
654 | "requires": {
655 | "axios": "0.15.3"
656 | }
657 | },
658 | "gl-matrix": {
659 | "version": "2.3.2",
660 | "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-2.3.2.tgz",
661 | "integrity": "sha1-qsgIx0r31dsF/gTLYMoaD8sXTXQ="
662 | },
663 | "glob": {
664 | "version": "7.1.1",
665 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
666 | "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
667 | "requires": {
668 | "fs.realpath": "1.0.0",
669 | "inflight": "1.0.6",
670 | "inherits": "2.0.3",
671 | "minimatch": "3.0.4",
672 | "once": "1.4.0",
673 | "path-is-absolute": "1.0.1"
674 | }
675 | },
676 | "globby": {
677 | "version": "5.0.0",
678 | "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
679 | "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
680 | "requires": {
681 | "array-union": "1.0.2",
682 | "arrify": "1.0.1",
683 | "glob": "7.1.1",
684 | "object-assign": "4.1.1",
685 | "pify": "2.3.0",
686 | "pinkie-promise": "2.0.1"
687 | }
688 | },
689 | "graceful-fs": {
690 | "version": "4.1.11",
691 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
692 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
693 | },
694 | "graceful-readlink": {
695 | "version": "1.0.1",
696 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
697 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
698 | "dev": true
699 | },
700 | "handlebars": {
701 | "version": "4.0.5",
702 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.5.tgz",
703 | "integrity": "sha1-ksbta7FkEQxQ1NjQ+93HCAbG+Oc=",
704 | "requires": {
705 | "async": "1.5.2",
706 | "optimist": "0.6.1",
707 | "source-map": "0.4.4",
708 | "uglify-js": "2.8.27"
709 | }
710 | },
711 | "har-schema": {
712 | "version": "1.0.5",
713 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
714 | "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4="
715 | },
716 | "har-validator": {
717 | "version": "4.2.1",
718 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
719 | "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
720 | "requires": {
721 | "ajv": "4.11.8",
722 | "har-schema": "1.0.5"
723 | }
724 | },
725 | "has-ansi": {
726 | "version": "2.0.0",
727 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
728 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
729 | "requires": {
730 | "ansi-regex": "2.1.1"
731 | }
732 | },
733 | "hawk": {
734 | "version": "3.1.3",
735 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
736 | "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
737 | "requires": {
738 | "boom": "2.10.1",
739 | "cryptiles": "2.0.5",
740 | "hoek": "2.16.3",
741 | "sntp": "1.0.9"
742 | }
743 | },
744 | "hoek": {
745 | "version": "2.16.3",
746 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
747 | "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
748 | },
749 | "hosted-git-info": {
750 | "version": "2.4.2",
751 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz",
752 | "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc="
753 | },
754 | "http-signature": {
755 | "version": "1.1.1",
756 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
757 | "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
758 | "requires": {
759 | "assert-plus": "0.2.0",
760 | "jsprim": "1.4.0",
761 | "sshpk": "1.13.0"
762 | }
763 | },
764 | "https-proxy-agent": {
765 | "version": "1.0.0",
766 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
767 | "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
768 | "requires": {
769 | "agent-base": "2.1.1",
770 | "debug": "2.2.0",
771 | "extend": "3.0.1"
772 | }
773 | },
774 | "husky": {
775 | "version": "0.13.3",
776 | "resolved": "https://registry.npmjs.org/husky/-/husky-0.13.3.tgz",
777 | "integrity": "sha1-vCBmCAutyLj+NRbogfW8aKVwUv8=",
778 | "dev": true,
779 | "requires": {
780 | "chalk": "1.1.3",
781 | "find-parent-dir": "0.3.0",
782 | "is-ci": "1.0.10",
783 | "normalize-path": "1.0.0"
784 | }
785 | },
786 | "image-ssim": {
787 | "version": "0.2.0",
788 | "resolved": "https://registry.npmjs.org/image-ssim/-/image-ssim-0.2.0.tgz",
789 | "integrity": "sha1-g7Qsei5uS4VQVHf+aRf128VkIOU="
790 | },
791 | "imurmurhash": {
792 | "version": "0.1.4",
793 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
794 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
795 | },
796 | "indent-string": {
797 | "version": "2.1.0",
798 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
799 | "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
800 | "requires": {
801 | "repeating": "2.0.1"
802 | }
803 | },
804 | "inflight": {
805 | "version": "1.0.6",
806 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
807 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
808 | "requires": {
809 | "once": "1.4.0",
810 | "wrappy": "1.0.2"
811 | }
812 | },
813 | "inherits": {
814 | "version": "2.0.3",
815 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
816 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
817 | },
818 | "invert-kv": {
819 | "version": "1.0.0",
820 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
821 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
822 | },
823 | "is-arrayish": {
824 | "version": "0.2.1",
825 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
826 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
827 | },
828 | "is-builtin-module": {
829 | "version": "1.0.0",
830 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
831 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
832 | "requires": {
833 | "builtin-modules": "1.1.1"
834 | }
835 | },
836 | "is-ci": {
837 | "version": "1.0.10",
838 | "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz",
839 | "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=",
840 | "dev": true,
841 | "requires": {
842 | "ci-info": "1.0.0"
843 | }
844 | },
845 | "is-finite": {
846 | "version": "1.0.2",
847 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
848 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
849 | "requires": {
850 | "number-is-nan": "1.0.1"
851 | }
852 | },
853 | "is-fullwidth-code-point": {
854 | "version": "1.0.0",
855 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
856 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
857 | "requires": {
858 | "number-is-nan": "1.0.1"
859 | }
860 | },
861 | "is-path-cwd": {
862 | "version": "1.0.0",
863 | "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
864 | "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0="
865 | },
866 | "is-path-in-cwd": {
867 | "version": "1.0.0",
868 | "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
869 | "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
870 | "requires": {
871 | "is-path-inside": "1.0.0"
872 | }
873 | },
874 | "is-path-inside": {
875 | "version": "1.0.0",
876 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
877 | "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
878 | "requires": {
879 | "path-is-inside": "1.0.2"
880 | }
881 | },
882 | "is-promise": {
883 | "version": "2.1.0",
884 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
885 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
886 | "dev": true
887 | },
888 | "is-stream": {
889 | "version": "1.1.0",
890 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
891 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
892 | "dev": true
893 | },
894 | "is-typedarray": {
895 | "version": "1.0.0",
896 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
897 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
898 | },
899 | "is-utf8": {
900 | "version": "0.2.1",
901 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
902 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
903 | },
904 | "isexe": {
905 | "version": "2.0.0",
906 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
907 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
908 | },
909 | "isstream": {
910 | "version": "0.1.2",
911 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
912 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
913 | },
914 | "jest-matcher-utils": {
915 | "version": "19.0.0",
916 | "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz",
917 | "integrity": "sha1-Xs2bY1ZdKwAfYfv37Ex/U3lkVk0=",
918 | "dev": true,
919 | "requires": {
920 | "chalk": "1.1.3",
921 | "pretty-format": "19.0.0"
922 | }
923 | },
924 | "jest-validate": {
925 | "version": "19.0.0",
926 | "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-19.0.0.tgz",
927 | "integrity": "sha1-jGMYog7P6roLpTeL+7gner3tQXM=",
928 | "dev": true,
929 | "requires": {
930 | "chalk": "1.1.3",
931 | "jest-matcher-utils": "19.0.0",
932 | "leven": "2.1.0",
933 | "pretty-format": "19.0.0"
934 | }
935 | },
936 | "jodid25519": {
937 | "version": "1.0.2",
938 | "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz",
939 | "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=",
940 | "optional": true,
941 | "requires": {
942 | "jsbn": "0.1.1"
943 | }
944 | },
945 | "jpeg-js": {
946 | "version": "0.1.2",
947 | "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.1.2.tgz",
948 | "integrity": "sha1-E1uZLAV1yYXPoPSUoyJ+0jhYPs4="
949 | },
950 | "js-tokens": {
951 | "version": "3.0.1",
952 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz",
953 | "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=",
954 | "dev": true
955 | },
956 | "js-yaml": {
957 | "version": "3.8.4",
958 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz",
959 | "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=",
960 | "requires": {
961 | "argparse": "1.0.9",
962 | "esprima": "3.1.3"
963 | }
964 | },
965 | "jsbn": {
966 | "version": "0.1.1",
967 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
968 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
969 | "optional": true
970 | },
971 | "json-schema": {
972 | "version": "0.2.3",
973 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
974 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
975 | },
976 | "json-stable-stringify": {
977 | "version": "1.0.1",
978 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
979 | "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
980 | "requires": {
981 | "jsonify": "0.0.0"
982 | }
983 | },
984 | "json-stringify-safe": {
985 | "version": "5.0.1",
986 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
987 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
988 | },
989 | "jsonfile": {
990 | "version": "2.4.0",
991 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
992 | "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
993 | "requires": {
994 | "graceful-fs": "4.1.11"
995 | }
996 | },
997 | "jsonify": {
998 | "version": "0.0.0",
999 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
1000 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
1001 | },
1002 | "jsprim": {
1003 | "version": "1.4.0",
1004 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
1005 | "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=",
1006 | "requires": {
1007 | "assert-plus": "1.0.0",
1008 | "extsprintf": "1.0.2",
1009 | "json-schema": "0.2.3",
1010 | "verror": "1.3.6"
1011 | },
1012 | "dependencies": {
1013 | "assert-plus": {
1014 | "version": "1.0.0",
1015 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
1016 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
1017 | }
1018 | }
1019 | },
1020 | "lcid": {
1021 | "version": "1.0.0",
1022 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
1023 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
1024 | "requires": {
1025 | "invert-kv": "1.0.0"
1026 | }
1027 | },
1028 | "leven": {
1029 | "version": "2.1.0",
1030 | "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
1031 | "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
1032 | "dev": true
1033 | },
1034 | "lighthouse": {
1035 | "version": "1.6.3",
1036 | "resolved": "https://registry.npmjs.org/lighthouse/-/lighthouse-1.6.3.tgz",
1037 | "integrity": "sha1-CZ70hNlNhE+rcYnvEF4fM0ZDJrY=",
1038 | "requires": {
1039 | "axe-core": "2.1.7",
1040 | "chrome-devtools-frontend": "1.0.422034",
1041 | "debug": "2.2.0",
1042 | "devtools-timeline-model": "1.1.6",
1043 | "gl-matrix": "2.3.2",
1044 | "handlebars": "4.0.5",
1045 | "json-stringify-safe": "5.0.1",
1046 | "marked": "0.3.6",
1047 | "metaviewport-parser": "0.0.1",
1048 | "mkdirp": "0.5.1",
1049 | "opn": "4.0.2",
1050 | "rimraf": "2.2.8",
1051 | "semver": "5.3.0",
1052 | "speedline": "1.0.3",
1053 | "whatwg-url": "4.0.0",
1054 | "ws": "1.1.1",
1055 | "yargs": "3.32.0"
1056 | }
1057 | },
1058 | "lint-staged": {
1059 | "version": "3.4.0",
1060 | "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-3.4.0.tgz",
1061 | "integrity": "sha1-UvqF38krscb+itDQ2YyhOSTgPks=",
1062 | "dev": true,
1063 | "requires": {
1064 | "app-root-path": "2.0.1",
1065 | "cosmiconfig": "1.1.0",
1066 | "execa": "0.6.3",
1067 | "listr": "0.11.0",
1068 | "minimatch": "3.0.4",
1069 | "npm-which": "3.0.1",
1070 | "staged-git-files": "0.0.4"
1071 | }
1072 | },
1073 | "listr": {
1074 | "version": "0.11.0",
1075 | "resolved": "https://registry.npmjs.org/listr/-/listr-0.11.0.tgz",
1076 | "integrity": "sha1-XneLwjgGrDq5hO11VkRYFR85sD4=",
1077 | "dev": true,
1078 | "requires": {
1079 | "chalk": "1.1.3",
1080 | "cli-truncate": "0.2.1",
1081 | "figures": "1.7.0",
1082 | "indent-string": "2.1.0",
1083 | "is-promise": "2.1.0",
1084 | "is-stream": "1.1.0",
1085 | "listr-silent-renderer": "1.1.1",
1086 | "listr-update-renderer": "0.2.0",
1087 | "listr-verbose-renderer": "0.4.0",
1088 | "log-symbols": "1.0.2",
1089 | "log-update": "1.0.2",
1090 | "ora": "0.2.3",
1091 | "rxjs": "5.3.1",
1092 | "stream-to-observable": "0.1.0",
1093 | "strip-ansi": "3.0.1"
1094 | }
1095 | },
1096 | "listr-silent-renderer": {
1097 | "version": "1.1.1",
1098 | "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
1099 | "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
1100 | "dev": true
1101 | },
1102 | "listr-update-renderer": {
1103 | "version": "0.2.0",
1104 | "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz",
1105 | "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=",
1106 | "dev": true,
1107 | "requires": {
1108 | "chalk": "1.1.3",
1109 | "cli-truncate": "0.2.1",
1110 | "elegant-spinner": "1.0.1",
1111 | "figures": "1.7.0",
1112 | "indent-string": "3.1.0",
1113 | "log-symbols": "1.0.2",
1114 | "log-update": "1.0.2",
1115 | "strip-ansi": "3.0.1"
1116 | },
1117 | "dependencies": {
1118 | "indent-string": {
1119 | "version": "3.1.0",
1120 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.1.0.tgz",
1121 | "integrity": "sha1-CP9DNGAziDmbMp5rlTjcejz13n0=",
1122 | "dev": true
1123 | }
1124 | }
1125 | },
1126 | "listr-verbose-renderer": {
1127 | "version": "0.4.0",
1128 | "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.0.tgz",
1129 | "integrity": "sha1-RNwBuww0oDxXIVTU0Izemx3FYg8=",
1130 | "dev": true,
1131 | "requires": {
1132 | "chalk": "1.1.3",
1133 | "cli-cursor": "1.0.2",
1134 | "date-fns": "1.28.4",
1135 | "figures": "1.7.0"
1136 | }
1137 | },
1138 | "load-json-file": {
1139 | "version": "1.1.0",
1140 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
1141 | "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
1142 | "requires": {
1143 | "graceful-fs": "4.1.11",
1144 | "parse-json": "2.2.0",
1145 | "pify": "2.3.0",
1146 | "pinkie-promise": "2.0.1",
1147 | "strip-bom": "2.0.0"
1148 | }
1149 | },
1150 | "locate-path": {
1151 | "version": "2.0.0",
1152 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
1153 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
1154 | "requires": {
1155 | "p-locate": "2.0.0",
1156 | "path-exists": "3.0.0"
1157 | },
1158 | "dependencies": {
1159 | "path-exists": {
1160 | "version": "3.0.0",
1161 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
1162 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
1163 | }
1164 | }
1165 | },
1166 | "lodash": {
1167 | "version": "3.10.1",
1168 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
1169 | "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
1170 | },
1171 | "lodash.kebabcase": {
1172 | "version": "4.1.1",
1173 | "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
1174 | "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY="
1175 | },
1176 | "lodash.startcase": {
1177 | "version": "4.4.0",
1178 | "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
1179 | "integrity": "sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg="
1180 | },
1181 | "log-symbols": {
1182 | "version": "1.0.2",
1183 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
1184 | "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
1185 | "dev": true,
1186 | "requires": {
1187 | "chalk": "1.1.3"
1188 | }
1189 | },
1190 | "log-update": {
1191 | "version": "1.0.2",
1192 | "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz",
1193 | "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=",
1194 | "dev": true,
1195 | "requires": {
1196 | "ansi-escapes": "1.4.0",
1197 | "cli-cursor": "1.0.2"
1198 | }
1199 | },
1200 | "loud-rejection": {
1201 | "version": "1.6.0",
1202 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
1203 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
1204 | "requires": {
1205 | "currently-unhandled": "0.4.1",
1206 | "signal-exit": "3.0.2"
1207 | }
1208 | },
1209 | "lru-cache": {
1210 | "version": "4.0.2",
1211 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz",
1212 | "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=",
1213 | "dev": true,
1214 | "requires": {
1215 | "pseudomap": "1.0.2",
1216 | "yallist": "2.1.2"
1217 | }
1218 | },
1219 | "map-obj": {
1220 | "version": "1.0.1",
1221 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
1222 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
1223 | },
1224 | "marked": {
1225 | "version": "0.3.6",
1226 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz",
1227 | "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc="
1228 | },
1229 | "meow": {
1230 | "version": "3.7.0",
1231 | "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
1232 | "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
1233 | "requires": {
1234 | "camelcase-keys": "2.1.0",
1235 | "decamelize": "1.2.0",
1236 | "loud-rejection": "1.6.0",
1237 | "map-obj": "1.0.1",
1238 | "minimist": "1.2.0",
1239 | "normalize-package-data": "2.3.8",
1240 | "object-assign": "4.1.1",
1241 | "read-pkg-up": "1.0.1",
1242 | "redent": "1.0.0",
1243 | "trim-newlines": "1.0.0"
1244 | },
1245 | "dependencies": {
1246 | "minimist": {
1247 | "version": "1.2.0",
1248 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
1249 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
1250 | }
1251 | }
1252 | },
1253 | "metaviewport-parser": {
1254 | "version": "0.0.1",
1255 | "resolved": "https://registry.npmjs.org/metaviewport-parser/-/metaviewport-parser-0.0.1.tgz",
1256 | "integrity": "sha1-mygXllm3b/nSHehK4lWDJXkJsgY="
1257 | },
1258 | "mime-db": {
1259 | "version": "1.27.0",
1260 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
1261 | "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE="
1262 | },
1263 | "mime-types": {
1264 | "version": "2.1.15",
1265 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
1266 | "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=",
1267 | "requires": {
1268 | "mime-db": "1.27.0"
1269 | }
1270 | },
1271 | "minimatch": {
1272 | "version": "3.0.4",
1273 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1274 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1275 | "requires": {
1276 | "brace-expansion": "1.1.7"
1277 | }
1278 | },
1279 | "minimist": {
1280 | "version": "0.0.10",
1281 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
1282 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
1283 | },
1284 | "mkdirp": {
1285 | "version": "0.5.1",
1286 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
1287 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
1288 | "requires": {
1289 | "minimist": "0.0.8"
1290 | },
1291 | "dependencies": {
1292 | "minimist": {
1293 | "version": "0.0.8",
1294 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
1295 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
1296 | }
1297 | }
1298 | },
1299 | "ms": {
1300 | "version": "0.7.1",
1301 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
1302 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
1303 | },
1304 | "node-localstorage": {
1305 | "version": "1.3.0",
1306 | "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.0.tgz",
1307 | "integrity": "sha1-LkNqro3Mms6XtDxlwWwNV3vgpVw=",
1308 | "requires": {
1309 | "write-file-atomic": "1.3.4"
1310 | }
1311 | },
1312 | "normalize-package-data": {
1313 | "version": "2.3.8",
1314 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz",
1315 | "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=",
1316 | "requires": {
1317 | "hosted-git-info": "2.4.2",
1318 | "is-builtin-module": "1.0.0",
1319 | "semver": "5.3.0",
1320 | "validate-npm-package-license": "3.0.1"
1321 | }
1322 | },
1323 | "normalize-path": {
1324 | "version": "1.0.0",
1325 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
1326 | "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
1327 | "dev": true
1328 | },
1329 | "npm-path": {
1330 | "version": "2.0.3",
1331 | "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.3.tgz",
1332 | "integrity": "sha1-Fc/04ciaONp39W9gVbJPl137K74=",
1333 | "dev": true,
1334 | "requires": {
1335 | "which": "1.2.14"
1336 | }
1337 | },
1338 | "npm-run-path": {
1339 | "version": "2.0.2",
1340 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
1341 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
1342 | "dev": true,
1343 | "requires": {
1344 | "path-key": "2.0.1"
1345 | }
1346 | },
1347 | "npm-which": {
1348 | "version": "3.0.1",
1349 | "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz",
1350 | "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=",
1351 | "dev": true,
1352 | "requires": {
1353 | "commander": "2.9.0",
1354 | "npm-path": "2.0.3",
1355 | "which": "1.2.14"
1356 | }
1357 | },
1358 | "number-is-nan": {
1359 | "version": "1.0.1",
1360 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
1361 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
1362 | },
1363 | "oauth-sign": {
1364 | "version": "0.8.2",
1365 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
1366 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
1367 | },
1368 | "object-assign": {
1369 | "version": "4.1.1",
1370 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1371 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
1372 | },
1373 | "once": {
1374 | "version": "1.4.0",
1375 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1376 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1377 | "requires": {
1378 | "wrappy": "1.0.2"
1379 | }
1380 | },
1381 | "onetime": {
1382 | "version": "1.1.0",
1383 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
1384 | "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
1385 | "dev": true
1386 | },
1387 | "opn": {
1388 | "version": "4.0.2",
1389 | "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
1390 | "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=",
1391 | "requires": {
1392 | "object-assign": "4.1.1",
1393 | "pinkie-promise": "2.0.1"
1394 | }
1395 | },
1396 | "optimist": {
1397 | "version": "0.6.1",
1398 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
1399 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
1400 | "requires": {
1401 | "minimist": "0.0.10",
1402 | "wordwrap": "0.0.3"
1403 | }
1404 | },
1405 | "options": {
1406 | "version": "0.0.6",
1407 | "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
1408 | "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
1409 | },
1410 | "ora": {
1411 | "version": "0.2.3",
1412 | "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz",
1413 | "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=",
1414 | "dev": true,
1415 | "requires": {
1416 | "chalk": "1.1.3",
1417 | "cli-cursor": "1.0.2",
1418 | "cli-spinners": "0.1.2",
1419 | "object-assign": "4.1.1"
1420 | }
1421 | },
1422 | "os-homedir": {
1423 | "version": "1.0.2",
1424 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
1425 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
1426 | "dev": true
1427 | },
1428 | "os-locale": {
1429 | "version": "1.4.0",
1430 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
1431 | "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
1432 | "requires": {
1433 | "lcid": "1.0.0"
1434 | }
1435 | },
1436 | "os-tmpdir": {
1437 | "version": "1.0.2",
1438 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
1439 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
1440 | },
1441 | "p-finally": {
1442 | "version": "1.0.0",
1443 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
1444 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
1445 | "dev": true
1446 | },
1447 | "p-limit": {
1448 | "version": "1.1.0",
1449 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
1450 | "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw="
1451 | },
1452 | "p-locate": {
1453 | "version": "2.0.0",
1454 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
1455 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
1456 | "requires": {
1457 | "p-limit": "1.1.0"
1458 | }
1459 | },
1460 | "parse-json": {
1461 | "version": "2.2.0",
1462 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
1463 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
1464 | "requires": {
1465 | "error-ex": "1.3.1"
1466 | }
1467 | },
1468 | "path-exists": {
1469 | "version": "2.1.0",
1470 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
1471 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
1472 | "requires": {
1473 | "pinkie-promise": "2.0.1"
1474 | }
1475 | },
1476 | "path-is-absolute": {
1477 | "version": "1.0.1",
1478 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1479 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
1480 | },
1481 | "path-is-inside": {
1482 | "version": "1.0.2",
1483 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
1484 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
1485 | },
1486 | "path-key": {
1487 | "version": "2.0.1",
1488 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
1489 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
1490 | "dev": true
1491 | },
1492 | "path-type": {
1493 | "version": "1.1.0",
1494 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
1495 | "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
1496 | "requires": {
1497 | "graceful-fs": "4.1.11",
1498 | "pify": "2.3.0",
1499 | "pinkie-promise": "2.0.1"
1500 | }
1501 | },
1502 | "pend": {
1503 | "version": "1.2.0",
1504 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
1505 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
1506 | },
1507 | "performance-now": {
1508 | "version": "0.2.0",
1509 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
1510 | "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU="
1511 | },
1512 | "pify": {
1513 | "version": "2.3.0",
1514 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1515 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
1516 | },
1517 | "pinkie": {
1518 | "version": "2.0.4",
1519 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
1520 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
1521 | },
1522 | "pinkie-promise": {
1523 | "version": "2.0.1",
1524 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
1525 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
1526 | "requires": {
1527 | "pinkie": "2.0.4"
1528 | }
1529 | },
1530 | "pkg-dir": {
1531 | "version": "2.0.0",
1532 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
1533 | "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
1534 | "requires": {
1535 | "find-up": "2.1.0"
1536 | },
1537 | "dependencies": {
1538 | "find-up": {
1539 | "version": "2.1.0",
1540 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
1541 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
1542 | "requires": {
1543 | "locate-path": "2.0.0"
1544 | }
1545 | }
1546 | }
1547 | },
1548 | "prettier": {
1549 | "version": "1.2.2",
1550 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.2.2.tgz",
1551 | "integrity": "sha1-ItF8ETL6quofHU+uox8Z96GVnz4=",
1552 | "dev": true,
1553 | "requires": {
1554 | "ast-types": "0.9.8",
1555 | "babel-code-frame": "6.22.0",
1556 | "babylon": "7.0.0-beta.8",
1557 | "chalk": "1.1.3",
1558 | "esutils": "2.0.2",
1559 | "flow-parser": "0.43.0",
1560 | "get-stdin": "5.0.1",
1561 | "glob": "7.1.1",
1562 | "jest-validate": "19.0.0",
1563 | "minimist": "1.2.0"
1564 | },
1565 | "dependencies": {
1566 | "get-stdin": {
1567 | "version": "5.0.1",
1568 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
1569 | "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
1570 | "dev": true
1571 | },
1572 | "minimist": {
1573 | "version": "1.2.0",
1574 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
1575 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
1576 | "dev": true
1577 | }
1578 | }
1579 | },
1580 | "pretty-format": {
1581 | "version": "19.0.0",
1582 | "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-19.0.0.tgz",
1583 | "integrity": "sha1-VlMNMqy5ij+khRxOK503tCBoTIQ=",
1584 | "dev": true,
1585 | "requires": {
1586 | "ansi-styles": "3.0.0"
1587 | },
1588 | "dependencies": {
1589 | "ansi-styles": {
1590 | "version": "3.0.0",
1591 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.0.0.tgz",
1592 | "integrity": "sha1-VATpOlRMT+x/BIJil3vr/jFV4ME=",
1593 | "dev": true,
1594 | "requires": {
1595 | "color-convert": "1.9.0"
1596 | }
1597 | }
1598 | }
1599 | },
1600 | "prettycli": {
1601 | "version": "1.3.0",
1602 | "resolved": "https://registry.npmjs.org/prettycli/-/prettycli-1.3.0.tgz",
1603 | "integrity": "sha1-HGoFAYBkxN+23RMyQ1/WcV5JsnM=",
1604 | "requires": {
1605 | "chalk": "1.1.3"
1606 | }
1607 | },
1608 | "pseudomap": {
1609 | "version": "1.0.2",
1610 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
1611 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
1612 | "dev": true
1613 | },
1614 | "punycode": {
1615 | "version": "1.4.1",
1616 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
1617 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
1618 | },
1619 | "qs": {
1620 | "version": "6.4.0",
1621 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
1622 | "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
1623 | },
1624 | "read-pkg": {
1625 | "version": "1.1.0",
1626 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
1627 | "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
1628 | "requires": {
1629 | "load-json-file": "1.1.0",
1630 | "normalize-package-data": "2.3.8",
1631 | "path-type": "1.1.0"
1632 | }
1633 | },
1634 | "read-pkg-up": {
1635 | "version": "1.0.1",
1636 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
1637 | "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
1638 | "requires": {
1639 | "find-up": "1.1.2",
1640 | "read-pkg": "1.1.0"
1641 | }
1642 | },
1643 | "redent": {
1644 | "version": "1.0.0",
1645 | "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
1646 | "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
1647 | "requires": {
1648 | "indent-string": "2.1.0",
1649 | "strip-indent": "1.0.1"
1650 | }
1651 | },
1652 | "repeating": {
1653 | "version": "2.0.1",
1654 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
1655 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
1656 | "requires": {
1657 | "is-finite": "1.0.2"
1658 | }
1659 | },
1660 | "request": {
1661 | "version": "2.81.0",
1662 | "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
1663 | "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
1664 | "requires": {
1665 | "aws-sign2": "0.6.0",
1666 | "aws4": "1.6.0",
1667 | "caseless": "0.12.0",
1668 | "combined-stream": "1.0.5",
1669 | "extend": "3.0.1",
1670 | "forever-agent": "0.6.1",
1671 | "form-data": "2.1.4",
1672 | "har-validator": "4.2.1",
1673 | "hawk": "3.1.3",
1674 | "http-signature": "1.1.1",
1675 | "is-typedarray": "1.0.0",
1676 | "isstream": "0.1.2",
1677 | "json-stringify-safe": "5.0.1",
1678 | "mime-types": "2.1.15",
1679 | "oauth-sign": "0.8.2",
1680 | "performance-now": "0.2.0",
1681 | "qs": "6.4.0",
1682 | "safe-buffer": "5.0.1",
1683 | "stringstream": "0.0.5",
1684 | "tough-cookie": "2.3.2",
1685 | "tunnel-agent": "0.6.0",
1686 | "uuid": "3.0.1"
1687 | }
1688 | },
1689 | "require-from-string": {
1690 | "version": "1.2.1",
1691 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
1692 | "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
1693 | "dev": true
1694 | },
1695 | "resolve": {
1696 | "version": "1.1.7",
1697 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
1698 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs="
1699 | },
1700 | "restore-cursor": {
1701 | "version": "1.0.1",
1702 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
1703 | "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
1704 | "dev": true,
1705 | "requires": {
1706 | "exit-hook": "1.1.1",
1707 | "onetime": "1.1.0"
1708 | }
1709 | },
1710 | "rimraf": {
1711 | "version": "2.2.8",
1712 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
1713 | "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI="
1714 | },
1715 | "rxjs": {
1716 | "version": "5.3.1",
1717 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.3.1.tgz",
1718 | "integrity": "sha1-nsyeciJH5PRJDTCoeFd6N0D9DLc=",
1719 | "dev": true,
1720 | "requires": {
1721 | "symbol-observable": "1.0.4"
1722 | }
1723 | },
1724 | "safe-buffer": {
1725 | "version": "5.0.1",
1726 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
1727 | "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c="
1728 | },
1729 | "sauce-connect-launcher": {
1730 | "version": "1.2.2",
1731 | "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.2.tgz",
1732 | "integrity": "sha1-c0bMj73EQxkTI0ObBzNFH181IfI=",
1733 | "requires": {
1734 | "adm-zip": "0.4.7",
1735 | "async": "2.4.0",
1736 | "https-proxy-agent": "1.0.0",
1737 | "lodash": "4.17.4",
1738 | "rimraf": "2.6.1"
1739 | },
1740 | "dependencies": {
1741 | "async": {
1742 | "version": "2.4.0",
1743 | "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz",
1744 | "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=",
1745 | "requires": {
1746 | "lodash": "4.17.4"
1747 | }
1748 | },
1749 | "lodash": {
1750 | "version": "4.17.4",
1751 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
1752 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
1753 | },
1754 | "rimraf": {
1755 | "version": "2.6.1",
1756 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
1757 | "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
1758 | "requires": {
1759 | "glob": "7.1.1"
1760 | }
1761 | }
1762 | }
1763 | },
1764 | "sax": {
1765 | "version": "1.2.2",
1766 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.2.tgz",
1767 | "integrity": "sha1-/YYxojvHgmvvXYcb24c3jJVkeCg="
1768 | },
1769 | "selenium-assistant": {
1770 | "version": "5.0.5",
1771 | "resolved": "https://registry.npmjs.org/selenium-assistant/-/selenium-assistant-5.0.5.tgz",
1772 | "integrity": "sha1-Gwg5pd+Upz9VJZTobmXrW6+esp0=",
1773 | "requires": {
1774 | "chalk": "1.1.3",
1775 | "del": "2.2.2",
1776 | "dmg": "0.1.0",
1777 | "fs-extra": "2.1.2",
1778 | "mkdirp": "0.5.1",
1779 | "node-localstorage": "1.3.0",
1780 | "request": "2.81.0",
1781 | "sauce-connect-launcher": "1.2.2",
1782 | "selenium-webdriver": "3.4.0",
1783 | "semver": "5.3.0",
1784 | "which": "1.2.14",
1785 | "yauzl": "2.8.0"
1786 | }
1787 | },
1788 | "selenium-webdriver": {
1789 | "version": "3.4.0",
1790 | "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.4.0.tgz",
1791 | "integrity": "sha1-FR90RSlNpqZsScwwB0eioX5TxSo=",
1792 | "requires": {
1793 | "adm-zip": "0.4.7",
1794 | "rimraf": "2.6.1",
1795 | "tmp": "0.0.30",
1796 | "xml2js": "0.4.17"
1797 | },
1798 | "dependencies": {
1799 | "rimraf": {
1800 | "version": "2.6.1",
1801 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
1802 | "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
1803 | "requires": {
1804 | "glob": "7.1.1"
1805 | }
1806 | }
1807 | }
1808 | },
1809 | "semver": {
1810 | "version": "5.3.0",
1811 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
1812 | "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
1813 | },
1814 | "shebang-command": {
1815 | "version": "1.2.0",
1816 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
1817 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
1818 | "dev": true,
1819 | "requires": {
1820 | "shebang-regex": "1.0.0"
1821 | }
1822 | },
1823 | "shebang-regex": {
1824 | "version": "1.0.0",
1825 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
1826 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
1827 | "dev": true
1828 | },
1829 | "signal-exit": {
1830 | "version": "3.0.2",
1831 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
1832 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
1833 | },
1834 | "slice-ansi": {
1835 | "version": "0.0.4",
1836 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
1837 | "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
1838 | "dev": true
1839 | },
1840 | "slide": {
1841 | "version": "1.1.6",
1842 | "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
1843 | "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc="
1844 | },
1845 | "sntp": {
1846 | "version": "1.0.9",
1847 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
1848 | "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
1849 | "requires": {
1850 | "hoek": "2.16.3"
1851 | }
1852 | },
1853 | "source-map": {
1854 | "version": "0.4.4",
1855 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
1856 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
1857 | "requires": {
1858 | "amdefine": "1.0.1"
1859 | }
1860 | },
1861 | "spdx-correct": {
1862 | "version": "1.0.2",
1863 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
1864 | "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
1865 | "requires": {
1866 | "spdx-license-ids": "1.2.2"
1867 | }
1868 | },
1869 | "spdx-expression-parse": {
1870 | "version": "1.0.4",
1871 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
1872 | "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw="
1873 | },
1874 | "spdx-license-ids": {
1875 | "version": "1.2.2",
1876 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
1877 | "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
1878 | },
1879 | "speedline": {
1880 | "version": "1.0.3",
1881 | "resolved": "https://registry.npmjs.org/speedline/-/speedline-1.0.3.tgz",
1882 | "integrity": "sha1-7h2YwY1YOi2EiKre0tuTNLlD270=",
1883 | "requires": {
1884 | "babar": "0.0.3",
1885 | "image-ssim": "0.2.0",
1886 | "jpeg-js": "0.1.2",
1887 | "loud-rejection": "1.6.0",
1888 | "meow": "3.7.0"
1889 | }
1890 | },
1891 | "sprintf-js": {
1892 | "version": "1.0.3",
1893 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1894 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
1895 | },
1896 | "sshpk": {
1897 | "version": "1.13.0",
1898 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz",
1899 | "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=",
1900 | "requires": {
1901 | "asn1": "0.2.3",
1902 | "assert-plus": "1.0.0",
1903 | "bcrypt-pbkdf": "1.0.1",
1904 | "dashdash": "1.14.1",
1905 | "ecc-jsbn": "0.1.1",
1906 | "getpass": "0.1.7",
1907 | "jodid25519": "1.0.2",
1908 | "jsbn": "0.1.1",
1909 | "tweetnacl": "0.14.5"
1910 | },
1911 | "dependencies": {
1912 | "assert-plus": {
1913 | "version": "1.0.0",
1914 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
1915 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
1916 | }
1917 | }
1918 | },
1919 | "staged-git-files": {
1920 | "version": "0.0.4",
1921 | "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz",
1922 | "integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=",
1923 | "dev": true
1924 | },
1925 | "statistics": {
1926 | "version": "3.3.0",
1927 | "resolved": "https://registry.npmjs.org/statistics/-/statistics-3.3.0.tgz",
1928 | "integrity": "sha1-7HtHUP8DqySmTdmzV6eDFr6teKo="
1929 | },
1930 | "stream-to-observable": {
1931 | "version": "0.1.0",
1932 | "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz",
1933 | "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=",
1934 | "dev": true
1935 | },
1936 | "string-width": {
1937 | "version": "1.0.2",
1938 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
1939 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
1940 | "requires": {
1941 | "code-point-at": "1.1.0",
1942 | "is-fullwidth-code-point": "1.0.0",
1943 | "strip-ansi": "3.0.1"
1944 | }
1945 | },
1946 | "stringstream": {
1947 | "version": "0.0.5",
1948 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
1949 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
1950 | },
1951 | "strip-ansi": {
1952 | "version": "3.0.1",
1953 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
1954 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
1955 | "requires": {
1956 | "ansi-regex": "2.1.1"
1957 | }
1958 | },
1959 | "strip-bom": {
1960 | "version": "2.0.0",
1961 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
1962 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
1963 | "requires": {
1964 | "is-utf8": "0.2.1"
1965 | }
1966 | },
1967 | "strip-eof": {
1968 | "version": "1.0.0",
1969 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
1970 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
1971 | "dev": true
1972 | },
1973 | "strip-indent": {
1974 | "version": "1.0.1",
1975 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
1976 | "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
1977 | "requires": {
1978 | "get-stdin": "4.0.1"
1979 | }
1980 | },
1981 | "supports-color": {
1982 | "version": "2.0.0",
1983 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1984 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
1985 | },
1986 | "symbol-observable": {
1987 | "version": "1.0.4",
1988 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz",
1989 | "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=",
1990 | "dev": true
1991 | },
1992 | "sync-exec": {
1993 | "version": "0.6.2",
1994 | "resolved": "https://registry.npmjs.org/sync-exec/-/sync-exec-0.6.2.tgz",
1995 | "integrity": "sha1-cX0izFPwzh3vVZQ2LzqJouu5EQU="
1996 | },
1997 | "tmp": {
1998 | "version": "0.0.30",
1999 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
2000 | "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
2001 | "requires": {
2002 | "os-tmpdir": "1.0.2"
2003 | }
2004 | },
2005 | "tough-cookie": {
2006 | "version": "2.3.2",
2007 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
2008 | "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=",
2009 | "requires": {
2010 | "punycode": "1.4.1"
2011 | }
2012 | },
2013 | "tr46": {
2014 | "version": "0.0.3",
2015 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
2016 | "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
2017 | },
2018 | "trim-newlines": {
2019 | "version": "1.0.0",
2020 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
2021 | "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
2022 | },
2023 | "tunnel-agent": {
2024 | "version": "0.6.0",
2025 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
2026 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
2027 | "requires": {
2028 | "safe-buffer": "5.0.1"
2029 | }
2030 | },
2031 | "tweetnacl": {
2032 | "version": "0.14.5",
2033 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
2034 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
2035 | "optional": true
2036 | },
2037 | "uglify-js": {
2038 | "version": "2.8.27",
2039 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.27.tgz",
2040 | "integrity": "sha1-R3h/kSsPJC5bmENDvo416V9pTJw=",
2041 | "optional": true,
2042 | "requires": {
2043 | "source-map": "0.5.6",
2044 | "uglify-to-browserify": "1.0.2",
2045 | "yargs": "3.10.0"
2046 | },
2047 | "dependencies": {
2048 | "source-map": {
2049 | "version": "0.5.6",
2050 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
2051 | "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
2052 | "optional": true
2053 | },
2054 | "yargs": {
2055 | "version": "3.10.0",
2056 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
2057 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
2058 | "optional": true,
2059 | "requires": {
2060 | "decamelize": "1.2.0"
2061 | }
2062 | }
2063 | }
2064 | },
2065 | "uglify-to-browserify": {
2066 | "version": "1.0.2",
2067 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
2068 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
2069 | "optional": true
2070 | },
2071 | "ultron": {
2072 | "version": "1.0.2",
2073 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
2074 | "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
2075 | },
2076 | "uuid": {
2077 | "version": "3.0.1",
2078 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz",
2079 | "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE="
2080 | },
2081 | "validate-npm-package-license": {
2082 | "version": "3.0.1",
2083 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
2084 | "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
2085 | "requires": {
2086 | "spdx-correct": "1.0.2",
2087 | "spdx-expression-parse": "1.0.4"
2088 | }
2089 | },
2090 | "verror": {
2091 | "version": "1.3.6",
2092 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
2093 | "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=",
2094 | "requires": {
2095 | "extsprintf": "1.0.2"
2096 | }
2097 | },
2098 | "webidl-conversions": {
2099 | "version": "3.0.1",
2100 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
2101 | "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
2102 | },
2103 | "whatwg-url": {
2104 | "version": "4.0.0",
2105 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.0.0.tgz",
2106 | "integrity": "sha1-W+Ni8Lbi+HYPcmDfbg4d9Tb1R5w=",
2107 | "requires": {
2108 | "tr46": "0.0.3",
2109 | "webidl-conversions": "3.0.1"
2110 | }
2111 | },
2112 | "which": {
2113 | "version": "1.2.14",
2114 | "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
2115 | "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
2116 | "requires": {
2117 | "isexe": "2.0.0"
2118 | }
2119 | },
2120 | "wordwrap": {
2121 | "version": "0.0.3",
2122 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
2123 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
2124 | },
2125 | "wrap-ansi": {
2126 | "version": "2.1.0",
2127 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
2128 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
2129 | "requires": {
2130 | "string-width": "1.0.2",
2131 | "strip-ansi": "3.0.1"
2132 | }
2133 | },
2134 | "wrappy": {
2135 | "version": "1.0.2",
2136 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2137 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
2138 | },
2139 | "write-file-atomic": {
2140 | "version": "1.3.4",
2141 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz",
2142 | "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=",
2143 | "requires": {
2144 | "graceful-fs": "4.1.11",
2145 | "imurmurhash": "0.1.4",
2146 | "slide": "1.1.6"
2147 | }
2148 | },
2149 | "ws": {
2150 | "version": "1.1.1",
2151 | "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.1.tgz",
2152 | "integrity": "sha1-CC3bbGQehdS7RR8D1S8G6r2x8Bg=",
2153 | "requires": {
2154 | "options": "0.0.6",
2155 | "ultron": "1.0.2"
2156 | }
2157 | },
2158 | "xml2js": {
2159 | "version": "0.4.17",
2160 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
2161 | "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
2162 | "requires": {
2163 | "sax": "1.2.2",
2164 | "xmlbuilder": "4.2.1"
2165 | }
2166 | },
2167 | "xmlbuilder": {
2168 | "version": "4.2.1",
2169 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
2170 | "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
2171 | "requires": {
2172 | "lodash": "4.17.4"
2173 | },
2174 | "dependencies": {
2175 | "lodash": {
2176 | "version": "4.17.4",
2177 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
2178 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
2179 | }
2180 | }
2181 | },
2182 | "y18n": {
2183 | "version": "3.2.1",
2184 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
2185 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
2186 | },
2187 | "yallist": {
2188 | "version": "2.1.2",
2189 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
2190 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
2191 | "dev": true
2192 | },
2193 | "yargs": {
2194 | "version": "3.32.0",
2195 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
2196 | "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
2197 | "requires": {
2198 | "camelcase": "2.1.1",
2199 | "cliui": "3.2.0",
2200 | "decamelize": "1.2.0",
2201 | "os-locale": "1.4.0",
2202 | "string-width": "1.0.2",
2203 | "window-size": "0.1.4",
2204 | "y18n": "3.2.1"
2205 | },
2206 | "dependencies": {
2207 | "camelcase": {
2208 | "version": "2.1.1",
2209 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
2210 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
2211 | },
2212 | "cliui": {
2213 | "version": "3.2.0",
2214 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
2215 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
2216 | "requires": {
2217 | "string-width": "1.0.2",
2218 | "strip-ansi": "3.0.1",
2219 | "wrap-ansi": "2.1.0"
2220 | }
2221 | },
2222 | "window-size": {
2223 | "version": "0.1.4",
2224 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
2225 | "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
2226 | }
2227 | }
2228 | },
2229 | "yargs-parser": {
2230 | "version": "5.0.0",
2231 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
2232 | "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
2233 | "requires": {
2234 | "camelcase": "3.0.0"
2235 | },
2236 | "dependencies": {
2237 | "camelcase": {
2238 | "version": "3.0.0",
2239 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
2240 | "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
2241 | }
2242 | }
2243 | },
2244 | "yauzl": {
2245 | "version": "2.8.0",
2246 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz",
2247 | "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=",
2248 | "requires": {
2249 | "buffer-crc32": "0.2.13",
2250 | "fd-slicer": "1.0.1"
2251 | }
2252 | }
2253 | }
2254 | }
2255 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "perfbench",
3 | "version": "1.8.1",
4 | "description": "Benchmark metrics for your web application",
5 | "main": "index.js",
6 | "bin": "index.js",
7 | "scripts": {
8 | "precommit": "lint-staged",
9 | "test": "test=true node index"
10 | },
11 | "engines": {
12 | "node": "8.x.x"
13 | },
14 | "keywords": [
15 | "benchmark",
16 | "application",
17 | "metrics"
18 | ],
19 | "repository": "siddharthkp/perfbench",
20 | "files": [
21 | "index.js",
22 | "src"
23 | ],
24 | "author": "siddharthkp",
25 | "license": "MIT",
26 | "dependencies": {
27 | "ci-env": "1.4.0",
28 | "cli-table2": "0.2.0",
29 | "colors": "1.1.2",
30 | "github-build": "1.2.0",
31 | "js-yaml": "3.8.4",
32 | "lighthouse": "1.6.3",
33 | "lodash.kebabcase": "4.1.1",
34 | "lodash.startcase": "4.4.0",
35 | "pkg-dir": "2.0.0",
36 | "prettycli": "1.3.0",
37 | "selenium-assistant": "5.0.5",
38 | "statistics": "3.3.0",
39 | "sync-exec": "0.6.2",
40 | "yargs-parser": "5.0.0"
41 | },
42 | "devDependencies": {
43 | "husky": "0.13.3",
44 | "lint-staged": "3.4.0",
45 | "prettier": "1.2.2"
46 | },
47 | "lint-staged": {
48 | "*.js": [
49 | "prettier --write --no-semi --single-quote",
50 | "git add"
51 | ]
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/api.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios')
2 | const { repo, sha } = require('ci-env')
3 | const token = require('./token')
4 | const url = 'https://perfbench-store.now.sh/values'
5 |
6 | let enabled = false
7 | let values = {}
8 |
9 | if (repo && token) {
10 | enabled = true
11 | axios
12 | .get(`${url}?repo=${repo}&token=${token}`)
13 | .then(response => (values = response.data))
14 | .catch(error => console.log(error))
15 | }
16 |
17 | const get = () => values
18 |
19 | const set = values => {
20 | if (repo && token) {
21 | axios
22 | .post(url, { repo, token, sha, values })
23 | .catch(error => console.log(error))
24 | }
25 | }
26 |
27 | const store = { enabled, set, get }
28 | module.exports = store
29 |
--------------------------------------------------------------------------------
/src/build.js:
--------------------------------------------------------------------------------
1 | const Build = require('github-build')
2 | const startcase = require('lodash.startcase')
3 | const { repo, sha, event } = require('ci-env')
4 |
5 | const { thresholds } = require('./settings')
6 | const { units } = require('./properties')
7 | const token = require('./token')
8 | const store = require('./api')
9 |
10 | const label = 'perfbench'
11 | const description = 'Running performance tests...'
12 | const meta = { repo, sha, token, label, description }
13 |
14 | const build = new Build(meta)
15 |
16 | let pass = () => {} // noop
17 | let fail = () => process.exit(1)
18 | let error = () => process.exit(1)
19 |
20 | if (token) {
21 | build.start()
22 |
23 | pass = (values, url) => {
24 | /* default message */
25 | let message = 'Good Job! Performance checks passed!'
26 |
27 | if (store.enabled) {
28 | const master = store.get()
29 | /* If master values are empty, send default message */
30 | if (!Object.keys(master).length) build.pass(message)
31 |
32 | const keys = ['time-to-interactive', 'first-meaningful-paint']
33 | let properties = []
34 | let increased = false
35 |
36 | for (let key of keys) {
37 | if (values[key] > parseFloat(master[key])) {
38 | increased = key
39 | break
40 | }
41 | }
42 |
43 | /* If it did not increase, must have improved */
44 | const key = increased || keys[0]
45 | const starter = increased ? 'Warning:' : 'Good job!'
46 | const verb = increased ? 'increased' : 'improved'
47 | const difference = Math.round(Math.abs(values[key] - master[key]))
48 |
49 | /*
50 | Show diff in build if it is at least 100ms,
51 | anything below that is not reliable
52 | */
53 | if (difference >= 100) {
54 | message = `${starter} ${startcase(key)} has ${verb} by ${difference} ${units(key)}`
55 | }
56 | }
57 |
58 | build.pass(message, url)
59 | }
60 |
61 | fail = (values, unreliableResults, url) => {
62 | let properties = []
63 | let message
64 |
65 | const keys = Object.keys(values)
66 | for (key of keys) {
67 | if (values[key] > thresholds[key]) properties.push(key)
68 | }
69 |
70 | if (properties.length === 1) {
71 | const key = properties[0]
72 | message = `${startcase(key)} is above threshold (${values[key]} > ${thresholds[key]})`
73 | } else {
74 | message = `${properties
75 | .map(p => startcase(p))
76 | .join(', ')
77 | .replace(/,([^,]*)$/, ' and$1')} are above threshold`
78 | }
79 |
80 | if (unreliableResults.length) {
81 | message = `Results for ${unreliableResults.join(', ')} are not reliable due to high variations`
82 | }
83 |
84 | build.fail(message, url)
85 | }
86 |
87 | error = () => {
88 | build.error('Tests errored out! Check build logs for errors')
89 | }
90 | }
91 |
92 | module.exports = { pass, fail, error }
93 |
--------------------------------------------------------------------------------
/src/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "passes": [{
3 | "recordNetwork": true,
4 | "recordTrace": true,
5 | "pauseBeforeTraceEndMs": 500,
6 | "useThrottling": true,
7 | "gatherers": [
8 | "url",
9 | "content-width"
10 | ]
11 | }],
12 |
13 | "audits": [
14 | "first-meaningful-paint",
15 | "speed-index-metric",
16 | "time-to-interactive",
17 | "byte-efficiency/total-byte-weight",
18 | "user-timings"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/src/lighthouse.js:
--------------------------------------------------------------------------------
1 | const syncExec = require('sync-exec')
2 |
3 | const flags = { disableCpuThrottling: false }
4 |
5 | let configPath = './node_modules/perfbench/src/config.json'
6 | if (process.env.test) configPath = './src/config.json'
7 |
8 | const run = url =>
9 | new Promise((resolve, reject) => {
10 | const command = [
11 | './node_modules/.bin/lighthouse',
12 | url,
13 | '--output=json',
14 | '--disable-cpu-throttling=false',
15 | '--config-path=' + configPath
16 | ].join(' ')
17 |
18 | const output = syncExec(command)
19 |
20 | if (output.stderr) reject(output.stderr)
21 | else resolve(JSON.parse(output.stdout))
22 | })
23 |
24 | module.exports = { run }
25 |
--------------------------------------------------------------------------------
/src/properties.js:
--------------------------------------------------------------------------------
1 | const optimalValues = {
2 | 'first-meaningful-paint': 1600,
3 | 'speed-index-metric': 1250,
4 | 'time-to-interactive': 2500,
5 | 'total-byte-weight': 1600
6 | }
7 |
8 | const units = property => {
9 | return (
10 | {
11 | 'first-meaningful-paint': 'ms',
12 | 'speed-index-metric': ' ',
13 | 'time-to-interactive': 'ms',
14 | 'total-byte-weight': 'Kb'
15 | }[property] || 'ms'
16 | )
17 | }
18 |
19 | module.exports = { optimalValues, units }
20 |
--------------------------------------------------------------------------------
/src/reporter.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const Table = require('cli-table2')
3 | const { white, yellow, green, red } = require('colors/safe')
4 | const statistics = require('statistics')
5 | const kebabcase = require('lodash.kebabcase')
6 | const { repo, branch, commit_message, sha } = require('ci-env')
7 |
8 | const build = require('./build')
9 | const { units } = require('./properties')
10 | let { debug, fail, thresholds } = require('./settings')
11 | const store = require('./api')
12 |
13 | /* Table headers */
14 | let head = [white('Property'), white('Values'), white('Threshold')]
15 | let table = new Table({ head })
16 |
17 | let error = false
18 | let averageValues = {}
19 | let unreliableResults = []
20 | let master = {}
21 |
22 | const print = results => {
23 | if (debug) fs.writeFileSync('./debug.json', JSON.stringify(results, null, 2))
24 |
25 | /*
26 | If store is enabled
27 | 1. fetch values from api
28 | 2. add column in table header
29 | */
30 | if (store.enabled) {
31 | table.options.head.splice(2, 0, white('Master'))
32 | master = store.get()
33 | }
34 |
35 | /* Print the test conditions */
36 | console.log('Test conditions: \n')
37 | const conditions = results[0].runtimeConfig.environment
38 | for (let { enabled, name, description } of conditions) {
39 | if (enabled) console.log(yellow(name), yellow(description))
40 | }
41 |
42 | /* Flatten user timings results */
43 | for (let i = 0; i < results.length; i++) {
44 | results[i].audits['user-timings'].extendedInfo.value.map(
45 | audit =>
46 | (results[i].audits[kebabcase(audit.name)] = {
47 | description: audit.name,
48 | rawValue: audit.startTime
49 | })
50 | )
51 | delete results[i].audits['user-timings']
52 | }
53 |
54 | /* Get all the audit keys */
55 | const keys = Object.keys(results[0].audits)
56 |
57 | for (let key of keys) {
58 | const property = results[0].audits[key].description
59 | const threshold = thresholds[key] || 0
60 |
61 | let values = []
62 | for (let i = 0; i < results.length; i++) {
63 | values.push(results[i].audits[key].rawValue)
64 | }
65 |
66 | if (debug) console.log(property, threshold, values)
67 |
68 | let { sum, stdev } = values.reduce(statistics)
69 |
70 | if (key === 'total-byte-weight') {
71 | sum = sum / 1024
72 | stdev = stdev / 1024
73 | }
74 |
75 | /* Take average of all values */
76 | let numberOfDecimals = 2
77 | if (key === 'speed-index-metric') numberOfDecimals = 0
78 |
79 | const average = (sum / results.length).toFixed(numberOfDecimals)
80 |
81 | let color
82 | if (average < threshold) color = green
83 | else {
84 | color = red
85 | error = true
86 | }
87 |
88 | const row = [
89 | color(property),
90 | color(average + ' ' + units(key)),
91 | color(threshold + ' ' + units(key))
92 | ]
93 | if (store.enabled) {
94 | let value = ''
95 | if (master[key]) value = master[key] + ' ' + units(key)
96 | row.splice(2, 0, color(value))
97 | }
98 |
99 | averageValues[key] = average
100 | table.push(row)
101 |
102 | /* if average crosses threshold by standard deviation, throw a warning */
103 | if (average > threshold && average - stdev < threshold)
104 | unreliableResults.push(`${property}: ± ${stdev.toFixed(2)} ${units(key)}`)
105 | }
106 |
107 | console.log(table.toString())
108 | console.log()
109 |
110 | /* warnings for unreliable results due to variation */
111 | if (unreliableResults.length) {
112 | console.log(
113 | yellow('The following results are not reliable due to high variations:')
114 | )
115 | console.log()
116 | console.log(unreliableResults.join('\n'))
117 | console.log()
118 | }
119 |
120 | if (branch === 'master') store.set(averageValues)
121 |
122 | /* prepare details page url */
123 | const params = encodeURIComponent(
124 | JSON.stringify({
125 | averageValues,
126 | master,
127 | thresholds,
128 | repo,
129 | branch,
130 | commit_message,
131 | sha
132 | })
133 | )
134 | const url = `https://perfbench-store.now.sh/build?info=${params}`
135 |
136 | /* error build if average > threshold */
137 | if (error && fail) build.fail(averageValues, unreliableResults, url)
138 | else build.pass(averageValues, url)
139 | }
140 |
141 | module.exports = { print }
142 |
--------------------------------------------------------------------------------
/src/settings.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const argv = require('yargs-parser')(process.argv.slice(2))
3 | const pkgDir = require('pkg-dir')
4 | const { resolve } = require('path')
5 | const { error } = require('prettycli')
6 | const yaml = require('js-yaml')
7 | const { optimalValues } = require('./properties')
8 |
9 | let settings = {}
10 | const properties = ['runs', 'fail', 'url', 'debug', 'thresholds']
11 |
12 | /*
13 | There are 3 layers of settings.
14 |
15 | In increasing order of priority:
16 | 1. defaults
17 | 2. config file
18 | 3. cli params
19 | */
20 |
21 | const defaults = {
22 | runs: 3,
23 | fail: true,
24 | debug: false,
25 | thresholds: {},
26 | event: 'push'
27 | }
28 | let fileSettings = {}
29 | let cliParams = {}
30 |
31 | const root = pkgDir.sync()
32 | const configPath = resolve(root, '.perf.yml')
33 | const configFileExists = fs.existsSync(configPath)
34 |
35 | /* file */
36 | if (configFileExists) {
37 | try {
38 | fileSettings = yaml.safeLoad(fs.readFileSync(configPath))
39 | } catch ({ message }) {
40 | error(message, { silent: true })
41 | }
42 | }
43 |
44 | /* cli */
45 | for (let property of properties) {
46 | if (argv[property]) cliParams[property] = argv[property]
47 | }
48 | if (process.argv[2]) cliParams.url = process.argv[2]
49 |
50 | Object.assign(settings, defaults, fileSettings, cliParams)
51 |
52 | /* validation */
53 | for (let property of properties) {
54 | if (typeof settings[property] === 'undefined')
55 | error(`${property} is missing`, { silent: true })
56 | }
57 |
58 | if (!Array.isArray(settings.thresholds)) settings.thresholds = []
59 |
60 | /* Merge defaults and settings to get thresholds */
61 | settings.thresholds = Object.assign({}, optimalValues, ...settings.thresholds)
62 | if (settings.debug) console.log('setting: ', settings)
63 |
64 | module.exports = settings
65 |
--------------------------------------------------------------------------------
/src/setup.js:
--------------------------------------------------------------------------------
1 | const seleniumAssistant = require('selenium-assistant')
2 | const syncExec = require('sync-exec')
3 | const path = require('path')
4 |
5 | const setup = () => {
6 | process.env.DISPLAY = ':99.0'
7 | const output = syncExec('sh -e /etc/init.d/xvfb start')
8 | return seleniumAssistant.downloadLocalBrowser('chrome', 'stable')
9 | }
10 |
11 | module.exports = setup
12 |
--------------------------------------------------------------------------------
/src/token.js:
--------------------------------------------------------------------------------
1 | const token =
2 | process.env.github_token ||
3 | process.env.GITHUB_TOKEN ||
4 | process.env.perfbench_github_token ||
5 | process.env.PERFBENCH_GITHUB_TOKEN
6 |
7 | module.exports = token
8 |
--------------------------------------------------------------------------------
/store/.env.sample:
--------------------------------------------------------------------------------
1 | apiKey=firebase-api-key
2 | databaseURL=firebase-database-url
3 | githubId=github-client-id
4 | githubSecret=github-client-secret
5 | newrelicKey=newrelic-key
6 |
--------------------------------------------------------------------------------
/store/dummy.js:
--------------------------------------------------------------------------------
1 | const params = {
2 | averageValues: {
3 | 'first-meaningful-paint': '955',
4 | 'time-to-interactive': '1251',
5 | 'speed-index-metric': '610',
6 | 'search-ready': '2700'
7 | },
8 | master: {
9 | 'first-meaningful-paint': '955',
10 | 'speed-index-metric': '586',
11 | 'time-to-interactive': '610',
12 | 'search-ready': '2305'
13 | },
14 | thresholds: {
15 | 'first-meaningful-paint': 1600,
16 | 'speed-index-metric': 1250,
17 | 'time-to-interactive': 1700,
18 | 'search-ready': '2500'
19 | },
20 | repo: 'practo/medicine-info',
21 | branch: 'awesome-feature',
22 | commit_message: 'Add super awesome feature',
23 | sha: 'da87b46702da847ad80f18c04408cf931c318b2d'
24 | }
25 |
26 | const stuff =
27 | 'http://localhost:3001/build?info=' +
28 | encodeURIComponent(JSON.stringify(params))
29 | console.log(stuff)
30 |
--------------------------------------------------------------------------------
/store/firebase.js:
--------------------------------------------------------------------------------
1 | const firebase = require('firebase')
2 |
3 | if (process.env.dev) {
4 | require('dotenv').config()
5 | }
6 |
7 | const { apiKey, databaseURL } = process.env
8 |
9 | firebase.initializeApp({ apiKey, databaseURL })
10 |
11 | const database = firebase.database()
12 |
13 | const authenticate = token => {
14 | const credential = firebase.auth.GithubAuthProvider.credential(token)
15 | return firebase
16 | .auth()
17 | .signInWithCredential(credential)
18 | .catch(error => console.log(error))
19 | }
20 |
21 | const logout = () => firebase.auth().signOut()
22 |
23 | const set = (repo, sha, values, token) => {
24 | authenticate(token)
25 | const ref = `${token}/${repo}`
26 | values.sha = sha
27 | firebase.database().ref(ref).push(values)
28 | logout()
29 | }
30 |
31 | const get = (repo, token) => {
32 | authenticate(token)
33 | const ref = `${token}/${repo}`
34 | return firebase
35 | .database()
36 | .ref(ref)
37 | .limitToLast(1)
38 | .once('value')
39 | .then(snapshot => {
40 | return snapshot.val() || {}
41 | })
42 | logout()
43 | }
44 |
45 | module.exports = { set, get }
46 |
--------------------------------------------------------------------------------
/store/github.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios')
2 |
3 | if (process.env.dev) {
4 | require('dotenv').config()
5 | }
6 |
7 | const token = code => {
8 | return axios({
9 | method: 'POST',
10 | url: 'https://github.com/login/oauth/access_token',
11 | 'Content-type': 'application/x-www-form-urlencoded',
12 | data: {
13 | code: code,
14 | client_id: process.env.githubId,
15 | client_secret: process.env.githubSecret
16 | }
17 | })
18 | .then(response => response.data)
19 | .catch(response => response.response.status)
20 | }
21 |
22 | module.exports = { token }
23 |
--------------------------------------------------------------------------------
/store/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const server = express()
3 | const lowercase = require('lodash.lowercase')
4 | const bodyParser = require('body-parser')
5 | const querystring = require('querystring')
6 | const { get, set } = require('./firebase')
7 | const github = require('./github')
8 |
9 | server.use(bodyParser.json())
10 | server.set('view engine', 'pug')
11 | server.use(express.static('static'))
12 |
13 | server.get('/status', (req, res) => {
14 | res.status(200).end('OK')
15 | })
16 |
17 | server.get('/values', (req, res) => {
18 | const { repo, token } = req.query
19 | if (!repo) res.status(400).end('repo missing')
20 | else if (!token) res.status(401).end('token missing')
21 | else {
22 | get(repo, token).then(response => {
23 | /* Firebase returns a list */
24 | const values = Object.values(response)[0]
25 | res.end(JSON.stringify(values))
26 | })
27 | }
28 | })
29 |
30 | server.post('/values', (req, res) => {
31 | const { repo, sha, values, token } = req.body
32 | if (!token) res.status(401).end('token missing')
33 | else {
34 | set(repo, sha, values, token)
35 | res.status(200).end()
36 | }
37 | })
38 |
39 | server.get('/auth', (req, res) => {
40 | const { code } = req.query
41 | if (!code) res.status(400).end('code missing')
42 | else
43 | github
44 | .token(code)
45 | .then(response => {
46 | const token = querystring.parse(response).access_token
47 | res.render('auth', { token })
48 | })
49 | .catch(() => res.status(500).end('Oops'))
50 | })
51 |
52 | server.get('/build', (req, res) => {
53 | let { info } = req.query
54 | info = JSON.parse(info)
55 |
56 | const data = {
57 | repo: info.repo,
58 | branch: info.branch,
59 | sha: info.sha.slice(0, 8),
60 | commit_message: info.commit_message || '',
61 | metrics: []
62 | }
63 |
64 | const keys = Object.keys(info.averageValues)
65 | keys.map(key => {
66 | const name = lowercase(key)
67 | const value = info.averageValues[key]
68 | const threshold = info.thresholds[key]
69 |
70 | const values = { name, value, threshold }
71 |
72 | if (key != 'speed-index-metric') values.unit = 'ms'
73 |
74 | if (info.master && info.master[key]) {
75 | let diff = (value - info.master[key]).toFixed(0)
76 | if (diff >= 0) diff = `+${diff}`
77 | values.diff = diff
78 | }
79 |
80 | /* Logic to draw bars */
81 | values.maxLength = Math.max(value, threshold)
82 | if (value < values.maxLength) {
83 | values.fillLength = value
84 | values.baseColor = '#EEE'
85 | } else {
86 | values.fillLength = threshold
87 | values.baseColor = '#FA5E7C'
88 | values.class = 'fail'
89 | }
90 |
91 | data.metrics.push(values)
92 | })
93 |
94 | res.render('build', data)
95 | })
96 |
97 | server.get('/', (req, res) => {
98 | res.redirect('/status')
99 | })
100 |
101 | server.listen(3001)
102 |
--------------------------------------------------------------------------------
/store/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "perfbench-store",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.3",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
10 | "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
11 | "requires": {
12 | "mime-types": "2.1.15",
13 | "negotiator": "0.6.1"
14 | }
15 | },
16 | "acorn": {
17 | "version": "3.3.0",
18 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
19 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
20 | },
21 | "acorn-globals": {
22 | "version": "3.1.0",
23 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
24 | "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
25 | "requires": {
26 | "acorn": "4.0.13"
27 | },
28 | "dependencies": {
29 | "acorn": {
30 | "version": "4.0.13",
31 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
32 | "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
33 | }
34 | }
35 | },
36 | "align-text": {
37 | "version": "0.1.4",
38 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
39 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
40 | "requires": {
41 | "kind-of": "3.2.2",
42 | "longest": "1.0.1",
43 | "repeat-string": "1.6.1"
44 | }
45 | },
46 | "amdefine": {
47 | "version": "1.0.1",
48 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
49 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
50 | },
51 | "array-flatten": {
52 | "version": "1.1.1",
53 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
54 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
55 | },
56 | "asap": {
57 | "version": "2.0.5",
58 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz",
59 | "integrity": "sha1-UidltQw1EEkOUtfc/ghe+bqWlY8="
60 | },
61 | "axios": {
62 | "version": "0.16.1",
63 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.16.1.tgz",
64 | "integrity": "sha1-wLbSZgCEI4S49QnlcRHw0t+CI8o=",
65 | "requires": {
66 | "follow-redirects": "1.2.4"
67 | }
68 | },
69 | "body-parser": {
70 | "version": "1.17.2",
71 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
72 | "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=",
73 | "requires": {
74 | "bytes": "2.4.0",
75 | "content-type": "1.0.2",
76 | "debug": "2.6.7",
77 | "depd": "1.1.0",
78 | "http-errors": "1.6.1",
79 | "iconv-lite": "0.4.15",
80 | "on-finished": "2.3.0",
81 | "qs": "6.4.0",
82 | "raw-body": "2.2.0",
83 | "type-is": "1.6.15"
84 | },
85 | "dependencies": {
86 | "debug": {
87 | "version": "2.6.7",
88 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
89 | "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=",
90 | "requires": {
91 | "ms": "2.0.0"
92 | }
93 | },
94 | "ms": {
95 | "version": "2.0.0",
96 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
97 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
98 | }
99 | }
100 | },
101 | "bytes": {
102 | "version": "2.4.0",
103 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
104 | "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
105 | },
106 | "camelcase": {
107 | "version": "1.2.1",
108 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
109 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
110 | },
111 | "center-align": {
112 | "version": "0.1.3",
113 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
114 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
115 | "requires": {
116 | "align-text": "0.1.4",
117 | "lazy-cache": "1.0.4"
118 | }
119 | },
120 | "character-parser": {
121 | "version": "2.2.0",
122 | "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
123 | "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
124 | "requires": {
125 | "is-regex": "1.0.4"
126 | }
127 | },
128 | "clean-css": {
129 | "version": "3.4.26",
130 | "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.26.tgz",
131 | "integrity": "sha1-VTI7NE/zvO5oSi6sgck9+Ppz3us=",
132 | "requires": {
133 | "commander": "2.8.1",
134 | "source-map": "0.4.4"
135 | }
136 | },
137 | "cliui": {
138 | "version": "2.1.0",
139 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
140 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
141 | "requires": {
142 | "center-align": "0.1.3",
143 | "right-align": "0.1.3",
144 | "wordwrap": "0.0.2"
145 | }
146 | },
147 | "commander": {
148 | "version": "2.8.1",
149 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
150 | "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
151 | "requires": {
152 | "graceful-readlink": "1.0.1"
153 | }
154 | },
155 | "constantinople": {
156 | "version": "3.1.0",
157 | "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.0.tgz",
158 | "integrity": "sha1-dWnKqKo/jVk11i4fqW+fcCzYHHk=",
159 | "requires": {
160 | "acorn": "3.3.0",
161 | "is-expression": "2.1.0"
162 | }
163 | },
164 | "content-disposition": {
165 | "version": "0.5.2",
166 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
167 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
168 | },
169 | "content-type": {
170 | "version": "1.0.2",
171 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
172 | "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0="
173 | },
174 | "cookie": {
175 | "version": "0.3.1",
176 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
177 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
178 | },
179 | "cookie-signature": {
180 | "version": "1.0.6",
181 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
182 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
183 | },
184 | "debug": {
185 | "version": "2.6.1",
186 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz",
187 | "integrity": "sha1-eYVQkLosTjEVzH2HaUkdWPBJE1E=",
188 | "requires": {
189 | "ms": "0.7.2"
190 | }
191 | },
192 | "decamelize": {
193 | "version": "1.2.0",
194 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
195 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
196 | },
197 | "depd": {
198 | "version": "1.1.0",
199 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
200 | "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM="
201 | },
202 | "destroy": {
203 | "version": "1.0.4",
204 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
205 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
206 | },
207 | "doctypes": {
208 | "version": "1.1.0",
209 | "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
210 | "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
211 | },
212 | "dotenv": {
213 | "version": "4.0.0",
214 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz",
215 | "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0="
216 | },
217 | "ee-first": {
218 | "version": "1.1.1",
219 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
220 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
221 | },
222 | "encodeurl": {
223 | "version": "1.0.1",
224 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
225 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
226 | },
227 | "escape-html": {
228 | "version": "1.0.3",
229 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
230 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
231 | },
232 | "etag": {
233 | "version": "1.8.0",
234 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz",
235 | "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE="
236 | },
237 | "express": {
238 | "version": "4.15.2",
239 | "resolved": "https://registry.npmjs.org/express/-/express-4.15.2.tgz",
240 | "integrity": "sha1-rxB/wUhQRFfy3Kmm8lcdcSm5ezU=",
241 | "requires": {
242 | "accepts": "1.3.3",
243 | "array-flatten": "1.1.1",
244 | "content-disposition": "0.5.2",
245 | "content-type": "1.0.2",
246 | "cookie": "0.3.1",
247 | "cookie-signature": "1.0.6",
248 | "debug": "2.6.1",
249 | "depd": "1.1.0",
250 | "encodeurl": "1.0.1",
251 | "escape-html": "1.0.3",
252 | "etag": "1.8.0",
253 | "finalhandler": "1.0.2",
254 | "fresh": "0.5.0",
255 | "merge-descriptors": "1.0.1",
256 | "methods": "1.1.2",
257 | "on-finished": "2.3.0",
258 | "parseurl": "1.3.1",
259 | "path-to-regexp": "0.1.7",
260 | "proxy-addr": "1.1.4",
261 | "qs": "6.4.0",
262 | "range-parser": "1.2.0",
263 | "send": "0.15.1",
264 | "serve-static": "1.12.1",
265 | "setprototypeof": "1.0.3",
266 | "statuses": "1.3.1",
267 | "type-is": "1.6.15",
268 | "utils-merge": "1.0.0",
269 | "vary": "1.1.1"
270 | }
271 | },
272 | "finalhandler": {
273 | "version": "1.0.2",
274 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.2.tgz",
275 | "integrity": "sha1-0ONvnbxVfy3hRCPfYmGInp1gyTo=",
276 | "requires": {
277 | "debug": "2.6.4",
278 | "encodeurl": "1.0.1",
279 | "escape-html": "1.0.3",
280 | "on-finished": "2.3.0",
281 | "parseurl": "1.3.1",
282 | "statuses": "1.3.1",
283 | "unpipe": "1.0.0"
284 | },
285 | "dependencies": {
286 | "debug": {
287 | "version": "2.6.4",
288 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.4.tgz",
289 | "integrity": "sha1-dYaps8OXQcAoKuM0RcTorHRzT+A=",
290 | "requires": {
291 | "ms": "0.7.3"
292 | }
293 | },
294 | "ms": {
295 | "version": "0.7.3",
296 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz",
297 | "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8="
298 | }
299 | }
300 | },
301 | "firebase": {
302 | "version": "4.1.2",
303 | "resolved": "https://registry.npmjs.org/firebase/-/firebase-4.1.2.tgz",
304 | "integrity": "sha1-shOrIp62XjG9vR0mIFmxux7frB8=",
305 | "requires": {
306 | "dom-storage": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.0.2.tgz",
307 | "faye-websocket": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.9.3.tgz",
308 | "jsonwebtoken": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.1.tgz",
309 | "promise-polyfill": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.0.2.tgz",
310 | "xmlhttprequest": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz"
311 | },
312 | "dependencies": {
313 | "base64url": {
314 | "version": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
315 | "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs="
316 | },
317 | "buffer-equal-constant-time": {
318 | "version": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
319 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
320 | },
321 | "dom-storage": {
322 | "version": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.0.2.tgz",
323 | "integrity": "sha1-7RfL9oq9EOCu+BgnE+KXxeS1ALA="
324 | },
325 | "ecdsa-sig-formatter": {
326 | "version": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz",
327 | "integrity": "sha1-S8kmJ07Dtau1AW5+HWCSGsJisqE=",
328 | "requires": {
329 | "base64url": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
330 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz"
331 | }
332 | },
333 | "faye-websocket": {
334 | "version": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.9.3.tgz",
335 | "integrity": "sha1-SCpQWw3wrmJrlphm0710DNuWLoM=",
336 | "requires": {
337 | "websocket-driver": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz"
338 | }
339 | },
340 | "hoek": {
341 | "version": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
342 | "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
343 | },
344 | "isemail": {
345 | "version": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz",
346 | "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo="
347 | },
348 | "joi": {
349 | "version": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz",
350 | "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=",
351 | "requires": {
352 | "hoek": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
353 | "isemail": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz",
354 | "moment": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
355 | "topo": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz"
356 | }
357 | },
358 | "jsonwebtoken": {
359 | "version": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.1.tgz",
360 | "integrity": "sha1-fKMk9SFfi+A5zTWmxFu4y3SkSPs=",
361 | "requires": {
362 | "joi": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz",
363 | "jws": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz",
364 | "lodash.once": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
365 | "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
366 | "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
367 | }
368 | },
369 | "jwa": {
370 | "version": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz",
371 | "integrity": "sha1-oFUs4CIHQs1S4VN3SjKQXDDnVuU=",
372 | "requires": {
373 | "base64url": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
374 | "buffer-equal-constant-time": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
375 | "ecdsa-sig-formatter": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz",
376 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz"
377 | }
378 | },
379 | "jws": {
380 | "version": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz",
381 | "integrity": "sha1-+ei5M46KhHJ31kRLFGT2GIDgUKI=",
382 | "requires": {
383 | "base64url": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
384 | "jwa": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz",
385 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz"
386 | }
387 | },
388 | "lodash.once": {
389 | "version": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
390 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
391 | },
392 | "moment": {
393 | "version": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
394 | "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
395 | },
396 | "ms": {
397 | "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
398 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
399 | },
400 | "promise-polyfill": {
401 | "version": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.0.2.tgz",
402 | "integrity": "sha1-2chtPcTcLfkBboiUbe/Wm0m0EWI="
403 | },
404 | "safe-buffer": {
405 | "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz",
406 | "integrity": "sha1-/kyEYDl/nqqqWOc75GJzQIpF4iM="
407 | },
408 | "topo": {
409 | "version": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz",
410 | "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=",
411 | "requires": {
412 | "hoek": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
413 | }
414 | },
415 | "websocket-driver": {
416 | "version": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
417 | "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=",
418 | "requires": {
419 | "websocket-extensions": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz"
420 | }
421 | },
422 | "websocket-extensions": {
423 | "version": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz",
424 | "integrity": "sha1-domUmcGEtu91Q3fC27DNbLVdKec="
425 | },
426 | "xmlhttprequest": {
427 | "version": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
428 | "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
429 | },
430 | "xtend": {
431 | "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
432 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
433 | }
434 | }
435 | },
436 | "follow-redirects": {
437 | "version": "1.2.4",
438 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.4.tgz",
439 | "integrity": "sha512-Suw6KewLV2hReSyEOeql+UUkBVyiBm3ok1VPrVFRZnQInWpdoZbbiG5i8aJVSjTr0yQ4Ava0Sh6/joCg1Brdqw==",
440 | "requires": {
441 | "debug": "2.6.1"
442 | }
443 | },
444 | "forwarded": {
445 | "version": "0.1.0",
446 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz",
447 | "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M="
448 | },
449 | "fresh": {
450 | "version": "0.5.0",
451 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz",
452 | "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44="
453 | },
454 | "function-bind": {
455 | "version": "1.1.0",
456 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz",
457 | "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E="
458 | },
459 | "graceful-readlink": {
460 | "version": "1.0.1",
461 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
462 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
463 | },
464 | "has": {
465 | "version": "1.0.1",
466 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
467 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
468 | "requires": {
469 | "function-bind": "1.1.0"
470 | }
471 | },
472 | "http-errors": {
473 | "version": "1.6.1",
474 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz",
475 | "integrity": "sha1-X4uO2YrKVFZWv1cplzh/kEpyIlc=",
476 | "requires": {
477 | "depd": "1.1.0",
478 | "inherits": "2.0.3",
479 | "setprototypeof": "1.0.3",
480 | "statuses": "1.3.1"
481 | }
482 | },
483 | "iconv-lite": {
484 | "version": "0.4.15",
485 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
486 | "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es="
487 | },
488 | "inherits": {
489 | "version": "2.0.3",
490 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
491 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
492 | },
493 | "ipaddr.js": {
494 | "version": "1.3.0",
495 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.3.0.tgz",
496 | "integrity": "sha1-HgOlL9rYOou7KyXL9JmLTP/NPew="
497 | },
498 | "is-buffer": {
499 | "version": "1.1.5",
500 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
501 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
502 | },
503 | "is-expression": {
504 | "version": "2.1.0",
505 | "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-2.1.0.tgz",
506 | "integrity": "sha1-kb6dR968/vB3l36XIr5tz7RGXvA=",
507 | "requires": {
508 | "acorn": "3.3.0",
509 | "object-assign": "4.1.1"
510 | }
511 | },
512 | "is-promise": {
513 | "version": "2.1.0",
514 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
515 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
516 | },
517 | "is-regex": {
518 | "version": "1.0.4",
519 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
520 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
521 | "requires": {
522 | "has": "1.0.1"
523 | }
524 | },
525 | "js-stringify": {
526 | "version": "1.0.2",
527 | "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
528 | "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds="
529 | },
530 | "jstransformer": {
531 | "version": "1.0.0",
532 | "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
533 | "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
534 | "requires": {
535 | "is-promise": "2.1.0",
536 | "promise": "7.1.1"
537 | }
538 | },
539 | "kind-of": {
540 | "version": "3.2.2",
541 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
542 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
543 | "requires": {
544 | "is-buffer": "1.1.5"
545 | }
546 | },
547 | "lazy-cache": {
548 | "version": "1.0.4",
549 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
550 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
551 | },
552 | "lodash.lowercase": {
553 | "version": "4.3.0",
554 | "resolved": "https://registry.npmjs.org/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz",
555 | "integrity": "sha1-RlFaztSssLcJMTMzOvBo5MOxTp0="
556 | },
557 | "longest": {
558 | "version": "1.0.1",
559 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
560 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
561 | },
562 | "media-typer": {
563 | "version": "0.3.0",
564 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
565 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
566 | },
567 | "merge-descriptors": {
568 | "version": "1.0.1",
569 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
570 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
571 | },
572 | "methods": {
573 | "version": "1.1.2",
574 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
575 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
576 | },
577 | "mime": {
578 | "version": "1.3.4",
579 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
580 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
581 | },
582 | "mime-db": {
583 | "version": "1.27.0",
584 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
585 | "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE="
586 | },
587 | "mime-types": {
588 | "version": "2.1.15",
589 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
590 | "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=",
591 | "requires": {
592 | "mime-db": "1.27.0"
593 | }
594 | },
595 | "ms": {
596 | "version": "0.7.2",
597 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
598 | "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
599 | },
600 | "negotiator": {
601 | "version": "0.6.1",
602 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
603 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
604 | },
605 | "object-assign": {
606 | "version": "4.1.1",
607 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
608 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
609 | },
610 | "on-finished": {
611 | "version": "2.3.0",
612 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
613 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
614 | "requires": {
615 | "ee-first": "1.1.1"
616 | }
617 | },
618 | "parseurl": {
619 | "version": "1.3.1",
620 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz",
621 | "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY="
622 | },
623 | "path-parse": {
624 | "version": "1.0.5",
625 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
626 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
627 | },
628 | "path-to-regexp": {
629 | "version": "0.1.7",
630 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
631 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
632 | },
633 | "promise": {
634 | "version": "7.1.1",
635 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz",
636 | "integrity": "sha1-SJZUxpJha4qlWwck+oCbt9tJxb8=",
637 | "requires": {
638 | "asap": "2.0.5"
639 | }
640 | },
641 | "proxy-addr": {
642 | "version": "1.1.4",
643 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.4.tgz",
644 | "integrity": "sha1-J+VF9pYKRKYn2bREZ+NcG2tM4vM=",
645 | "requires": {
646 | "forwarded": "0.1.0",
647 | "ipaddr.js": "1.3.0"
648 | }
649 | },
650 | "pug": {
651 | "version": "2.0.0-rc.2",
652 | "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.0-rc.2.tgz",
653 | "integrity": "sha1-B4RVJ3kKssa+Z9z16x8xgECB8Eo=",
654 | "requires": {
655 | "pug-code-gen": "1.1.1",
656 | "pug-filters": "2.1.3",
657 | "pug-lexer": "3.1.0",
658 | "pug-linker": "3.0.1",
659 | "pug-load": "2.0.7",
660 | "pug-parser": "3.0.0",
661 | "pug-runtime": "2.0.3",
662 | "pug-strip-comments": "1.0.2"
663 | }
664 | },
665 | "pug-attrs": {
666 | "version": "2.0.2",
667 | "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.2.tgz",
668 | "integrity": "sha1-i+KyIlVo/6ddG4Zpgr/59BEa/8s=",
669 | "requires": {
670 | "constantinople": "3.1.0",
671 | "js-stringify": "1.0.2",
672 | "pug-runtime": "2.0.3"
673 | }
674 | },
675 | "pug-code-gen": {
676 | "version": "1.1.1",
677 | "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-1.1.1.tgz",
678 | "integrity": "sha1-HPcnRO8qA56uajNAyqoRBYcSWOg=",
679 | "requires": {
680 | "constantinople": "3.1.0",
681 | "doctypes": "1.1.0",
682 | "js-stringify": "1.0.2",
683 | "pug-attrs": "2.0.2",
684 | "pug-error": "1.3.2",
685 | "pug-runtime": "2.0.3",
686 | "void-elements": "2.0.1",
687 | "with": "5.1.1"
688 | }
689 | },
690 | "pug-error": {
691 | "version": "1.3.2",
692 | "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.2.tgz",
693 | "integrity": "sha1-U659nSm7A89WRJOgJhCfVMR/XyY="
694 | },
695 | "pug-filters": {
696 | "version": "2.1.3",
697 | "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-2.1.3.tgz",
698 | "integrity": "sha1-1ZdnoiDeeX3XVUifZoNM+aqDqlQ=",
699 | "requires": {
700 | "clean-css": "3.4.26",
701 | "constantinople": "3.1.0",
702 | "jstransformer": "1.0.0",
703 | "pug-error": "1.3.2",
704 | "pug-walk": "1.1.3",
705 | "resolve": "1.3.3",
706 | "uglify-js": "2.8.29"
707 | }
708 | },
709 | "pug-lexer": {
710 | "version": "3.1.0",
711 | "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-3.1.0.tgz",
712 | "integrity": "sha1-/QhzdtSmdbT1n4/vQiiDQ06VgaI=",
713 | "requires": {
714 | "character-parser": "2.2.0",
715 | "is-expression": "3.0.0",
716 | "pug-error": "1.3.2"
717 | },
718 | "dependencies": {
719 | "acorn": {
720 | "version": "4.0.13",
721 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
722 | "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
723 | },
724 | "is-expression": {
725 | "version": "3.0.0",
726 | "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
727 | "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
728 | "requires": {
729 | "acorn": "4.0.13",
730 | "object-assign": "4.1.1"
731 | }
732 | }
733 | }
734 | },
735 | "pug-linker": {
736 | "version": "3.0.1",
737 | "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.1.tgz",
738 | "integrity": "sha1-uj+P8hPKjzowSFm0T+0Tynud+hk=",
739 | "requires": {
740 | "pug-error": "1.3.2",
741 | "pug-walk": "1.1.3"
742 | }
743 | },
744 | "pug-load": {
745 | "version": "2.0.7",
746 | "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.7.tgz",
747 | "integrity": "sha1-Ux0MbhFUYBDphGMNA99AY2fS3nc=",
748 | "requires": {
749 | "object-assign": "4.1.1",
750 | "pug-walk": "1.1.3"
751 | }
752 | },
753 | "pug-parser": {
754 | "version": "3.0.0",
755 | "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-3.0.0.tgz",
756 | "integrity": "sha1-N8YZ3YAPZCGHzk1s4aFkzddUh6M=",
757 | "requires": {
758 | "pug-error": "1.3.2",
759 | "token-stream": "0.0.1"
760 | }
761 | },
762 | "pug-runtime": {
763 | "version": "2.0.3",
764 | "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.3.tgz",
765 | "integrity": "sha1-mBYmB7D86eJU1CfzOYelrucWi9o="
766 | },
767 | "pug-strip-comments": {
768 | "version": "1.0.2",
769 | "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.2.tgz",
770 | "integrity": "sha1-0xOvoBvMN0mA4TmeI+vy65vchRM=",
771 | "requires": {
772 | "pug-error": "1.3.2"
773 | }
774 | },
775 | "pug-walk": {
776 | "version": "1.1.3",
777 | "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.3.tgz",
778 | "integrity": "sha1-181bI9s8qHxjbIaglz+c2OAwQ2w="
779 | },
780 | "qs": {
781 | "version": "6.4.0",
782 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
783 | "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
784 | },
785 | "range-parser": {
786 | "version": "1.2.0",
787 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
788 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
789 | },
790 | "raw-body": {
791 | "version": "2.2.0",
792 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz",
793 | "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=",
794 | "requires": {
795 | "bytes": "2.4.0",
796 | "iconv-lite": "0.4.15",
797 | "unpipe": "1.0.0"
798 | }
799 | },
800 | "repeat-string": {
801 | "version": "1.6.1",
802 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
803 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
804 | },
805 | "resolve": {
806 | "version": "1.3.3",
807 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz",
808 | "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=",
809 | "requires": {
810 | "path-parse": "1.0.5"
811 | }
812 | },
813 | "right-align": {
814 | "version": "0.1.3",
815 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
816 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
817 | "requires": {
818 | "align-text": "0.1.4"
819 | }
820 | },
821 | "send": {
822 | "version": "0.15.1",
823 | "resolved": "https://registry.npmjs.org/send/-/send-0.15.1.tgz",
824 | "integrity": "sha1-igI1TCbm9cynAAZfXwzeupDse18=",
825 | "requires": {
826 | "debug": "2.6.1",
827 | "depd": "1.1.0",
828 | "destroy": "1.0.4",
829 | "encodeurl": "1.0.1",
830 | "escape-html": "1.0.3",
831 | "etag": "1.8.0",
832 | "fresh": "0.5.0",
833 | "http-errors": "1.6.1",
834 | "mime": "1.3.4",
835 | "ms": "0.7.2",
836 | "on-finished": "2.3.0",
837 | "range-parser": "1.2.0",
838 | "statuses": "1.3.1"
839 | }
840 | },
841 | "serve-static": {
842 | "version": "1.12.1",
843 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.1.tgz",
844 | "integrity": "sha1-dEOpZePO1kes61Y5+ga/TRu+ADk=",
845 | "requires": {
846 | "encodeurl": "1.0.1",
847 | "escape-html": "1.0.3",
848 | "parseurl": "1.3.1",
849 | "send": "0.15.1"
850 | }
851 | },
852 | "setprototypeof": {
853 | "version": "1.0.3",
854 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
855 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
856 | },
857 | "source-map": {
858 | "version": "0.4.4",
859 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
860 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
861 | "requires": {
862 | "amdefine": "1.0.1"
863 | }
864 | },
865 | "statuses": {
866 | "version": "1.3.1",
867 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
868 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
869 | },
870 | "token-stream": {
871 | "version": "0.0.1",
872 | "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
873 | "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
874 | },
875 | "type-is": {
876 | "version": "1.6.15",
877 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
878 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
879 | "requires": {
880 | "media-typer": "0.3.0",
881 | "mime-types": "2.1.15"
882 | }
883 | },
884 | "uglify-js": {
885 | "version": "2.8.29",
886 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
887 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
888 | "requires": {
889 | "source-map": "0.5.6",
890 | "uglify-to-browserify": "1.0.2",
891 | "yargs": "3.10.0"
892 | },
893 | "dependencies": {
894 | "source-map": {
895 | "version": "0.5.6",
896 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
897 | "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
898 | }
899 | }
900 | },
901 | "uglify-to-browserify": {
902 | "version": "1.0.2",
903 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
904 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
905 | "optional": true
906 | },
907 | "unpipe": {
908 | "version": "1.0.0",
909 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
910 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
911 | },
912 | "utils-merge": {
913 | "version": "1.0.0",
914 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
915 | "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
916 | },
917 | "vary": {
918 | "version": "1.1.1",
919 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz",
920 | "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc="
921 | },
922 | "void-elements": {
923 | "version": "2.0.1",
924 | "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
925 | "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
926 | },
927 | "window-size": {
928 | "version": "0.1.0",
929 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
930 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
931 | },
932 | "with": {
933 | "version": "5.1.1",
934 | "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
935 | "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
936 | "requires": {
937 | "acorn": "3.3.0",
938 | "acorn-globals": "3.1.0"
939 | }
940 | },
941 | "wordwrap": {
942 | "version": "0.0.2",
943 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
944 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
945 | },
946 | "yargs": {
947 | "version": "3.10.0",
948 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
949 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
950 | "requires": {
951 | "camelcase": "1.2.1",
952 | "cliui": "2.1.0",
953 | "decamelize": "1.2.0",
954 | "window-size": "0.1.0"
955 | }
956 | }
957 | }
958 | }
959 |
--------------------------------------------------------------------------------
/store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "perfbench-store",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "dev=true node index",
7 | "start": "node index"
8 | },
9 | "engines": {
10 | "node": "8.x.x"
11 | },
12 | "now": {
13 | "env": {
14 | "apiKey": "@perfbench_apikey",
15 | "databaseURL": "@perfbench_databaseurl",
16 | "githubId": "@perfbench_githubid",
17 | "githubSecret": "@perfbench_githubsecret"
18 | },
19 | "files": [
20 | "index.js",
21 | "github.js",
22 | "firebase.js",
23 | "views",
24 | "static"
25 | ]
26 | },
27 | "keywords": [],
28 | "author": "siddharthkp",
29 | "license": "MIT",
30 | "dependencies": {
31 | "axios": "0.16.1",
32 | "body-parser": "1.17.2",
33 | "dotenv": "4.0.0",
34 | "express": "4.15.2",
35 | "firebase": "4.1.2",
36 | "lodash.lowercase": "4.3.0",
37 | "pug": "2.0.0-rc.2"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/store/static/styles.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 0;
3 | padding: 0;
4 | }
5 | body {
6 | background: #F5F7FA;
7 | font-family: 'Nunito', sans-serif;
8 | font-size: 16px;
9 | line-height: 1.6;
10 | }
11 | .logo {
12 | display: block;
13 | height: 100px;
14 | margin: 50px auto;
15 | }
16 | .big {
17 | font-size: 25px;
18 | }
19 | .dark {
20 | color: #192235;
21 | }
22 | .light {
23 | color: #969FA5;
24 | }
25 | .card {
26 | width: 80%;
27 | margin: 0 auto;
28 | padding: 25px;
29 | background: #FFF;
30 | border-radius: 5px;
31 | box-shadow: 0px 3px 5px 2px rgba(201, 214, 255, 0.15);
32 | }
33 | .metrics {
34 | margin: 50px 0;
35 | }
36 | .metrics .label {
37 | display: inline-block;
38 | font-size: 12px;
39 | }
40 | .metric {
41 | margin: 25px 0;
42 | }
43 | .metric > div {
44 | display: inline-block;
45 | }
46 | .metric.fail {
47 | color: #FA5E7C;
48 | }
49 | .name {
50 | width: 20%;
51 | }
52 | .threshold {
53 | width: 50%;
54 | }
55 | .metric.fail .light {
56 | color: #FA5E7C;
57 | }
58 | .size {
59 | text-align: right;
60 | width: 15%;
61 | }
62 | .master {
63 | text-align: right;
64 | width: 10%;
65 | }
66 | .bar {
67 | height: 7px;
68 | background: #EEE;
69 | border-radius: 10px;
70 | width: 100%;
71 | }
72 | .bar.first {
73 | background: #4680FF;
74 | z-index: 2;
75 | position: relative;
76 | top: 7px;
77 | }
78 | .guides {
79 | line-height: 2;
80 | }
81 |
82 | .mobile {
83 | display: none;
84 | }
85 | @media (max-width: 800px) {
86 | .desktop {
87 | display: none;
88 | }
89 | .mobile {
90 | display: inline;
91 | }
92 | .name {
93 | width: 50%;
94 | }
95 | .threshold {
96 | width: 100%;
97 | padding: 10px 0;
98 | }
99 | .size, .master {
100 | width: 100%;
101 | text-align: left;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/store/views/auth.pug:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | BUNDLESIZE_GITHUB_TOKEN:
13 | #{token}
14 |
15 |
Add this as an environment variable in your CIs project settings
16 |
17 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/store/views/build.pug:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | #{commit_message}
13 | ##{sha}
14 |
15 |
#{repo} : #{branch}
16 |
17 |
18 |
19 |
NAME
20 |
21 |
SIZE/THRESHOLD
22 |
MASTER
23 |
24 | each metric in metrics
25 |
26 |
#{metric.name}
27 |
31 |
#{metric.value}/#{metric.threshold} #{metric.unit}
32 | if metric.diff
33 |
master #{metric.diff} #{metric.unit}
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------