diff --git a/.idea/misc.xml b/.idea/misc.xml
index eabe228..28a804d 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,14 +3,4 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index 3e81aa4..719b91e 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,14 @@
# nfc-pcsc
-[![npm](https://img.shields.io/npm/v/nfc-pcsc.svg)](https://www.npmjs.com/package/nfc-pcsc)
+[![npm](https://img.shields.io/npm/v/nfc-pcsc.svg?maxAge=2592000)](https://www.npmjs.com/package/nfc-pcsc)
+[![nfc-pcsc channel on discord](https://img.shields.io/badge/discord-join%20chat-61dafb.svg)](https://discord.gg/bg3yazg)
A simple wrapper around [pokusew/node-pcsclite](https://github.com/pokusew/node-pcsclite) to work easier with NFC tags.
Built-in support for reading **card UIDs** and reading tags emulated with [**Android HCE**](https://developer.android.com/guide/topics/connectivity/nfc/hce.html).
> **NOTE:** Reading tag UID and methods for writing and reading tag content **depend on NFC reader commands support**.
-It is tested to work with **ARC122 USB reader** but it can work with others too.
+It is tested to work with **ACR122 USB reader** but it can work with others too.
When detecting tags does not work see [Alternative usage](#alternative-usage).
## Content
@@ -22,6 +23,8 @@ When detecting tags does not work see [Alternative usage](#alternative-usage).
- [Running examples locally](#running-examples-locally)
- [Alternative usage](#alternative-usage)
- [Reading and writing data](#reading-and-writing-data)
+- [FAQ](#faq)
+ - [Can I use this library in my Electron app?](#can-i-use-this-library-in-my-electron-app)
- [LICENSE](#license)
@@ -62,11 +65,11 @@ When a NFC tag (card) is attached to the reader, the following is done:
## Basic usage
> ### Running examples locally
-> If you want see it in action, clone this repository, install dependencies with npm and run `npm run test`.
+> If you want see it in action, clone this repository, install dependencies with npm and run `npm run example`.
> ```bash
> git clone https://github.com/pokusew/nfc-pcsc.git
> npm install
-> npm run test
+> npm run example
> ```
@@ -113,7 +116,7 @@ nfc.on('error', err => {
## Alternative usage
You can **disable auto processing of tags** and process them yourself.
-It may be useful when you are using other than ARC122 USB reader or non-standard tags.
+It may be useful when you are using other than ACR122 USB reader or non-standard tags.
```javascript
import NFC from 'nfc-pcsc';
@@ -242,6 +245,23 @@ reader.on('card', async card => {
});
```
+
+## FAQ
+
+### Can I use this library in my [Electron](http://electron.atom.io/) app?
+
+Yes, you can! It works well.
+
+**But please note**, that this library uses [Node Native Modules](https://nodejs.org/api/addons.html) (underlying library [pokusew/node-pcsclite](https://github.com/pokusew/node-pcsclite) which provides access to PC/SC API).
+
+Read carefully **[Using Native Node Modules](http://electron.atom.io/docs/tutorial/using-native-node-modules/) guide in Electron documentation** to fully understand the problematic.
+
+**Note**, that because of Node Native Modules, you must build your app on target platform (you must run Windows build on Windows machine, etc.).
+You can use CI/CD server to build your app for certain platforms.
+For Windows, I recommend you to use [AppVeyor](https://appveyor.com/).
+For macOS and Linux build, there are plenty of services to choose from, for example [CircleCI](https://circleci.com/), [Travis CI](https://travis-ci.com/) [CodeShip](https://codeship.com/).
+
+
## LICENSE
The nfc node module, documentation, tests, and build scripts are licensed
diff --git a/examples/desfire.js b/examples/desfire.js
new file mode 100644
index 0000000..65ff065
--- /dev/null
+++ b/examples/desfire.js
@@ -0,0 +1,212 @@
+"use strict";
+
+// #############
+// Example accessing and authenticating Mifare DESFIRE cards
+// #############
+
+import winston from 'winston';
+import NFC, { TAG_ISO_14443_3, TAG_ISO_14443_4, KEY_TYPE_A, KEY_TYPE_B } from '../src/NFC';
+import pretty from './pretty';
+import crypto from 'crypto';
+
+
+// config
+const desfire = {
+ key: '00000000000000000000000000000000',
+ appId: [0x00, 0x00, 0x00],
+ keyId: [0x00],
+ read: {
+ fileId: [0x02],
+ offset: [0x00, 0x00, 0x00],
+ length: [14, 0x00, 0x00]
+ }
+};
+
+
+function decrypt(key, data, iv = Buffer.alloc(8).fill(0)) {
+
+ const decipher = crypto.createDecipheriv('DES-EDE-CBC', key, iv);
+ decipher.setAutoPadding(false);
+
+ return Buffer.concat([decipher.update(data), decipher.final()]);
+
+}
+
+function encrypt(key, data, iv = Buffer.alloc(8).fill(0)) {
+
+ const decipher = crypto.createCipheriv('DES-EDE-CBC', key, iv);
+ decipher.setAutoPadding(false);
+
+ return Buffer.concat([decipher.update(data), decipher.final()]);
+
+}
+
+
+const nfc = new NFC();
+
+let readers = [];
+
+nfc.on('reader', async reader => {
+
+ pretty.info(`device attached`, { reader: reader.name });
+
+ readers.push(reader);
+
+ // we have to handle Mifare DESFIRE
+ reader.autoProcessing = false;
+
+ // just handy shortcut to send data
+ const send = async(cmd, comment = null, responseMaxLength = 40) => {
+
+ const b = Buffer.from(cmd);
+
+ console.log((comment ? `[${comment}] ` : '') + `sending`, b);
+
+ const data = await reader.transmit(b, responseMaxLength);
+
+ console.log((comment ? `[${comment}] ` : '') + `received data`, data);
+
+ return data;
+
+ };
+
+ const wrap = (cmd, dataIn) => ([0x90, cmd, 0x00, 0x00, dataIn.length, ...dataIn, 0x00]);
+
+ reader.on('card', async card => {
+
+ pretty.info(`card detected`, { reader: reader.name, card });
+
+ const selectApplication = async() => {
+
+ // 1: [0x5A] SelectApplication(appId) [4 bytes] - Selects one specific application for further access
+ // DataIn: appId (3 bytes)
+ const res = await send(wrap(0x5a, desfire.appId), 'step 1 - select app');
+
+ // something went wrong
+ if (res.slice(-1)[0] !== 0x00) {
+ throw new Error('error in step 1');
+ }
+
+
+ };
+
+ const authenticate = async(key) => {
+
+ // 2: [0x0a] Authenticate(keyId) [2bytes]
+ // DataIn: keyId (1 byte)
+ const res1 = await send(wrap(0x0a, desfire.keyId), 'step 2 - authenticate');
+
+ // something went wrong
+ if (res1.slice(-1)[0] !== 0xaf) {
+ throw new Error('error in step 2 - authenticate');
+ }
+
+ // encrypted RndB from reader
+ // cut out status code (last 2 bytes)
+ const ecRndB = res1.slice(0, -2);
+
+ // decrypt it
+ const RndB = decrypt(key, ecRndB);
+
+ // rotate RndB
+ const RndBp = Buffer.concat([RndB.slice(1, 8), RndB.slice(0, 1)]);
+
+ // generate a 8 byte Random Number A
+ const RndA = crypto.randomBytes(8);
+
+ // concat RndA and RndBp
+ const msg = encrypt(key, Buffer.concat([RndA, RndBp]));
+
+ // send it back to the reader
+ const res2 = await send(wrap(0xaf, msg), 'step 2 - set up RndA');
+
+ // something went wrong
+ if (res2.slice(-1)[0] !== 0x00) {
+ throw new Error('error in step 2 - set up RndA');
+ }
+
+ // encrypted RndAp from reader
+ // cut out status code (last 2 bytes)
+ const ecRndAp = res2.slice(0, -2);
+
+ // decrypt to get rotated value of RndA2
+ const RndAp = decrypt(key, ecRndAp);
+
+ // rotate
+ const RndA2 = Buffer.concat([RndAp.slice(7, 8), RndAp.slice(0, 7)]);
+
+ // compare decrypted RndA2 response from reader with our RndA
+ // if it equals authentication process was successful
+ if (!RndA.equals(RndA2)) {
+ throw new Error('error in step 2 - match RndA random bytes');
+ }
+
+ return {
+ RndA,
+ RndB
+ };
+
+ };
+
+ const readData = async() => {
+
+ // 3: [0xBD] ReadData(FileNo,Offset,Length) [8bytes] - Reads data from Standard Data Files or Backup Data Files
+ const res = await send(wrap(0xbd, [desfire.read.fileId, ...desfire.read.offset, ...desfire.read.length]), 'step 3 - read', 255);
+
+ // something went wrong
+ if (res.slice(-1)[0] !== 0x00) {
+ throw new Error('error in step 3 - read');
+ }
+
+ console.log('data', res);
+
+ };
+
+
+ try {
+
+ // step 1
+ await selectApplication();
+
+ // step 2
+ const key = new Buffer(desfire.key, 'hex');
+ await authenticate(key);
+
+ // step 3
+ await readData();
+
+
+ } catch (err) {
+
+ pretty.error(`error occurred during processing steps`, { reader: reader.name });
+ console.log(err);
+
+ }
+
+
+ });
+
+ reader.on('error', err => {
+
+ pretty.error(`an error occurred`, { reader: reader.name, err });
+
+ });
+
+ reader.on('end', () => {
+
+ pretty.info(`device removed`, { reader: reader.name });
+
+ delete readers[readers.indexOf(reader)];
+
+ console.log(readers);
+
+ });
+
+
+});
+
+nfc.on('error', err => {
+
+ pretty.error(`an error occurred`, err);
+
+});
diff --git a/test/index.js b/examples/index.js
similarity index 92%
rename from test/index.js
rename to examples/index.js
index 5df0935..7702ac3 100644
--- a/test/index.js
+++ b/examples/index.js
@@ -1,5 +1,13 @@
"use strict";
+// #############
+// Basic example
+// - example reading and writing data on from/to card
+// - should work well with any compatible PC/SC card reader
+// - tested with Mifare Ultralight cards but should work with many others
+// - example authentication for Mifare Classic cards
+// #############
+
import winston from 'winston';
import NFC, { TAG_ISO_14443_3, TAG_ISO_14443_4, KEY_TYPE_A, KEY_TYPE_B } from '../src/NFC';
import pretty from './pretty';
diff --git a/examples/led.js b/examples/led.js
new file mode 100644
index 0000000..36e1806
--- /dev/null
+++ b/examples/led.js
@@ -0,0 +1,179 @@
+"use strict";
+
+// #############
+// ACR122U example controlling LED and buzzer
+// - custom buzzer output
+// - repeated beeping on unsuccessful read/write operation
+// #############
+
+import winston from 'winston';
+import NFC, { TAG_ISO_14443_3, TAG_ISO_14443_4, KEY_TYPE_A, KEY_TYPE_B, CONNECT_MODE_DIRECT } from '../src/NFC';
+import pretty from './pretty';
+
+
+// minilogger for debugging
+
+function log() {
+ console.log(...arguments);
+}
+
+const minilogger = {
+ log: log,
+ debug: log,
+ info: log,
+ warn: log,
+ error: log
+};
+
+const nfc = new NFC(minilogger); // const nfc = new NFC(minilogger); // optionally you can pass logger to see internal debug logs
+
+let readers = [];
+
+nfc.on('reader', async reader => {
+
+ pretty.info(`device attached`, { reader: reader.name });
+
+ readers.push(reader);
+
+
+ // needed for reading tags emulated with Android HCE AID
+ // see https://developer.android.com/guide/topics/connectivity/nfc/hce.html
+ reader.aid = 'F222222222';
+
+ console.log();
+
+ try {
+ await reader.connect(CONNECT_MODE_DIRECT);
+ await reader.setBuzzerOutput(false);
+ await reader.disconnect();
+ } catch (err) {
+ console.log(err);
+ }
+
+ reader.on('card', async card => {
+
+
+ // standard nfc tags like Mifare
+ if (card.type === TAG_ISO_14443_3) {
+ // const uid = card.uid;
+ pretty.info(`card detected`, { reader: reader.name, card });
+ }
+ // Android HCE
+ else if (card.type === TAG_ISO_14443_4) {
+ // process raw Buffer data
+ const data = card.data.toString('utf8');
+ pretty.info(`card detected`, { reader: reader.name, card: { ...card, data } });
+ }
+ // not possible, just to be sure
+ else {
+ pretty.info(`card detected`, { reader: reader.name, card });
+ }
+
+ // Notice: reading data from Mifare Classic cards (e.g. Mifare 1K) requires,
+ // that the data block must be authenticated first
+ // don't forget to fill your keys and types
+ // reader.authenticate(blockNumber, keyType, key, obsolete = false)
+ // if you are experiencing problems, you can try using obsolete = true which is compatible with PC/SC V2.01
+ // uncomment when you need it
+
+ // try {
+ //
+ // const key = 'FFFFFFFFFFFF';
+ // const keyType = KEY_TYPE_A;
+ //
+ // // we will authenticate block 4, 5, 6, 7 (which we want to read)
+ // await Promise.all([
+ // reader.authenticate(4, keyType, key),
+ // reader.authenticate(5, keyType, key),
+ // reader.authenticate(6, keyType, key),
+ // reader.authenticate(7, keyType, key)
+ // ]);
+ //
+ // pretty.info(`blocks successfully authenticated`);
+ //
+ // } catch (err) {
+ // pretty.error(`error when authenticating data`, { reader: reader.name, card, err });
+ // return;
+ // }
+
+
+ // example reading 16 bytes assuming containing 16bit integer
+ try {
+
+ // reader.read(blockNumber, length, blockSize = 4, packetSize = 16)
+ // - blockNumber - memory block number where to start reading
+ // - length - how many bytes to read
+ // ! Caution! length must be divisible by blockSize
+
+ const data = await reader.read(4, 16);
+
+ pretty.info(`data read`, { reader: reader.name, card, data });
+
+ const payload = data.readInt16BE();
+
+ pretty.info(`data converted`, payload);
+
+ } catch (err) {
+ pretty.error(`error when reading data`, { reader: reader.name, card, err });
+ await reader.led(0b01011101, [0x02, 0x01, 0x05, 0x01]);
+ return;
+ }
+
+
+ // example write 16bit integer
+ try {
+
+ // reader.write(blockNumber, data, blockSize = 4)
+ // - blockNumber - memory block number where to start writing
+ // - data - what to write
+ // ! Caution! data.length must be divisible by blockSize
+
+ const data = Buffer.allocUnsafe(16);
+ data.writeInt16BE(800);
+
+ await reader.write(4, data);
+
+ pretty.info(`data written`, { reader: reader.name, card });
+
+ } catch (err) {
+ pretty.error(`error when writing data`, { reader: reader.name, card, err });
+ await reader.led(0b01011101, [0x02, 0x01, 0x05, 0x01]);
+ return;
+ }
+
+
+ try {
+
+ await reader.led(0b00101110, [0x01, 0x00, 0x01, 0x01]);
+
+ } catch (err) {
+ pretty.error(`error when writing led`);
+ }
+
+
+ });
+
+ reader.on('error', err => {
+
+ pretty.error(`an error occurred`, { reader: reader.name, err });
+
+ });
+
+ reader.on('end', () => {
+
+ pretty.info(`device removed`, { reader: reader.name });
+
+ delete readers[readers.indexOf(reader)];
+
+ console.log(readers);
+
+ });
+
+
+});
+
+nfc.on('error', err => {
+
+ pretty.error(`an error occurred`, err);
+
+});
diff --git a/test/pretty.js b/examples/pretty.js
similarity index 96%
rename from test/pretty.js
rename to examples/pretty.js
index 6500674..099b5d0 100644
--- a/test/pretty.js
+++ b/examples/pretty.js
@@ -56,7 +56,7 @@ function formatConsoleLog(options) {
delete options.meta.reader;
}
- let log = time + level + reader + ' '
+ let log = time + level + reader + ' '
+ (options.message !== undefined ? options.message : '')
+ (options.meta && Object.keys(options.meta).length ? '\n' + json(options.meta) : '' );
diff --git a/package.json b/package.json
index 8d3846e..b95e367 100644
--- a/package.json
+++ b/package.json
@@ -24,20 +24,22 @@
},
"scripts": {
"build": "babel src --out-dir dist",
- "test": "node -r babel-register test/index.js"
+ "example": "node -r babel-register examples/index.js",
+ "example-led": "node -r babel-register examples/led.js",
+ "example-desfire": "node -r babel-register examples/desfire.js"
},
"dependencies": {
- "@pokusew/pcsclite": "^0.4.13"
+ "@pokusew/pcsclite": "^0.4.15"
},
"devDependencies": {
- "babel-cli": "^6.14.0",
- "babel-plugin-transform-async-to-generator": "^6.8.0",
- "babel-plugin-transform-class-properties": "^6.11.5",
- "babel-plugin-transform-object-rest-spread": "^6.8.0",
- "babel-preset-es2015-node6": "^0.3.0",
- "babel-register": "^6.14.0",
+ "babel-cli": "^6.22.2",
+ "babel-plugin-transform-async-to-generator": "^6.22.0",
+ "babel-plugin-transform-class-properties": "^6.22.0",
+ "babel-plugin-transform-object-rest-spread": "^6.22.0",
+ "babel-preset-es2015-node6": "^0.4.0",
+ "babel-register": "^6.22.0",
"chalk": "^1.1.3",
- "prettyjson": "^1.1.3",
- "winston": "^2.2.0"
+ "prettyjson": "^1.2.1",
+ "winston": "^2.3.1"
}
}
diff --git a/src/ACR122Reader.js b/src/ACR122Reader.js
new file mode 100644
index 0000000..291e3cd
--- /dev/null
+++ b/src/ACR122Reader.js
@@ -0,0 +1,235 @@
+"use strict";
+
+import Reader from './Reader';
+import {
+ ConnectError,
+ DisconnectError,
+ TransmitError,
+ ControlError,
+ AuthenticationError,
+ LoadAuthenticationKeyError,
+ ReadError,
+ WriteError,
+ GetUIDError,
+ CARD_NOT_CONNECTED,
+ OPERATION_FAILED,
+ UNKNOWN_ERROR,
+ FAILURE
+} from './errors';
+
+
+class ACR122Reader extends Reader {
+
+ async inAutoPoll() {
+
+ const payload = [
+ 0xD4,
+ 0x60,
+ 0xFF, // PollNr (0xFF = Endless polling)
+ 0x01, // Period (0x01 – 0x0F) indicates the polling period in units of 150 ms
+ 0x00 // Type 1 0x00 = Generic passive 106 kbps (ISO/IEC14443-4A, Mifare and DEP)
+ ];
+
+ // CMD: Direct Transmit (to inner PN532 chip InAutoPoll CMD)
+ const packet = new Buffer([
+ 0xff, // Class
+ 0x00, // INS
+ 0x00, // P1
+ 0x00, // P2
+ payload.length, // Lc: Number of Bytes to send (Maximum 255 bytes)
+ ...payload
+ ]);
+
+ console.log(packet);
+
+ let response = null;
+
+ try {
+
+ response = await this.control(packet, 2);
+
+ this.logger.info('response received', response);
+
+ // Red OFF Green OFF 0x00
+ // Red ON Green OFF 0x01
+ // Red OFF Green ON 0x02
+ // Red ON Green ON 0x03
+
+ console.log(response.slice(1));
+
+
+ } catch (err) {
+
+ throw err;
+
+ }
+
+ // const statusCode = response.readUInt16BE(0);
+ //
+ // if (statusCode !== 0x9000) {
+ // //throw new LoadAuthenticationKeyError(OPERATION_FAILED, `Load authentication key operation failed: Status code: ${statusCode}`);
+ // }
+
+ }
+
+ async led(led, blinking) {
+
+ // P2: LED State Control (1 byte = 8 bits)
+ // format:
+ /*
+ +-----+----------------------------------+-------------------------------------+
+ | Bit | Item | Description |
+ +-----+----------------------------------+-------------------------------------+
+ | 0 | Final Red LED State | 1 = On; 0 = Off |
+ | 1 | Final Green LED State | 1 = On; 0 = Off |
+ | 2 | Red LED State Mask | 1 = Update the State; 0 = No change |
+ | 3 | Green LED State Mask | 1 = Update the State; 0 = No change |
+ | 4 | Initial Red LED Blinking State | 1 = On; 0 = Off |
+ | 5 | Initial Green LED Blinking State | 1 = On; 0 = Off |
+ | 6 | Red LED Blinking Mask | 1 = Blink
; 0 = Not Blink |
+ | 7 | Green LED Blinking Mask | 1 = Blink
; 0 = Not Blink |
+ +-----+----------------------------------+-------------------------------------+
+ */
+
+ //const led = 0b00001111;
+ //const led = 0x50;
+
+ // Data In: Blinking Duration Control (4 bytes)
+ // Byte 0: T1 Duration Initial Blinking State (Unit = 100 ms)
+ // Byte 1: T2 Duration Toggle Blinking State (Unit = 100 ms)
+ // Byte 2: Number of repetition
+ // Byte 3: Link to Buzzer
+ // - 00: The buzzer will not turn on
+ // - 01: The buzzer will turn on during the T1 Duration
+ // - 02: The buzzer will turn on during the T2 Duration
+ // - 03: The buzzer will turn on during the T1 and T2 Duration
+
+ // const blinking = [
+ // 0x00,
+ // 0x00,
+ // 0x00,
+ // 0x00
+ // ];
+
+
+ // CMD: Bi-Color LED and Buzzer Control
+ const packet = new Buffer([
+ 0xff, // Class
+ 0x00, // INS
+ 0x40, // P1
+ led, // P2: LED State Control
+ 0x04, // Lc
+ ...blinking, // Data In: Blinking Duration Control (4 bytes)
+ ]);
+
+ console.log(packet);
+
+ let response = null;
+
+ try {
+
+ response = await this.control(packet, 2);
+
+ this.logger.info('response received', response);
+
+ // Red OFF Green OFF 0x00
+ // Red ON Green OFF 0x01
+ // Red OFF Green ON 0x02
+ // Red ON Green ON 0x03
+
+ console.log(response.slice(1));
+
+
+ } catch (err) {
+
+ throw err;
+
+ }
+
+ // const statusCode = response.readUInt16BE(0);
+ //
+ // if (statusCode !== 0x9000) {
+ // //throw new LoadAuthenticationKeyError(OPERATION_FAILED, `Load authentication key operation failed: Status code: ${statusCode}`);
+ // }
+
+ }
+
+ async setBuzzerOutput(enabled = true) {
+
+
+ // CMD: Set Buzzer Output Enable for Card Detection
+ const packet = new Buffer([
+ 0xff, // Class
+ 0x00, // INS
+ 0x52, // P1
+ enabled ? 0xff : 0x00, // P2: PollBuzzStatus
+ 0x00, // Le
+ ]);
+
+ console.log(packet);
+
+ let response = null;
+
+ try {
+
+ response = await this.control(packet, 2);
+
+ this.logger.info('response received', response);
+
+
+ } catch (err) {
+
+ throw err;
+
+ }
+
+ const statusCode = response.readUInt16BE(0);
+
+ if (statusCode !== 0x9000) {
+ //throw new LoadAuthenticationKeyError(OPERATION_FAILED, `Load authentication key operation failed: Status code: ${statusCode}`);
+ }
+
+ }
+
+ async setPICC(picc) {
+
+ // just enable Auto ATS Generation
+ // const picc = 0b01000000;
+
+ // CMD: Set PICC Operating Parameter
+ const packet = new Buffer([
+ 0xff, // Class
+ 0x00, // INS
+ 0x51, // P1
+ picc, // P2: New PICC Operating Parameter
+ 0x00, // Le
+ ]);
+
+ console.log(packet);
+
+ let response = null;
+
+ try {
+
+ response = await this.control(packet, 1);
+
+ this.logger.info('response received', response);
+
+
+ } catch (err) {
+
+ throw err;
+
+ }
+
+ // const statusCode = response.readUInt16BE(0);
+ //
+ // if (statusCode !== 0x9000) {
+ // //throw new LoadAuthenticationKeyError(OPERATION_FAILED, `Load authentication key operation failed: Status code: ${statusCode}`);
+ // }
+
+ }
+
+}
+
+export default ACR122Reader;
diff --git a/src/NFC.js b/src/NFC.js
index 23ae48c..d53d269 100644
--- a/src/NFC.js
+++ b/src/NFC.js
@@ -3,6 +3,7 @@
import pcsclite from '@pokusew/pcsclite';
import EventEmitter from 'events';
import Reader from './Reader';
+import ACR122Reader from './ACR122Reader';
export * from './Reader';
@@ -41,6 +42,17 @@ class NFC extends EventEmitter {
this.logger.info('New reader detected', reader.name);
+ // create special object for ARC122U reader with commands specific to this reader
+ if (reader.name.toLowerCase().indexOf('acr122') !== -1) {
+
+ const device = new ACR122Reader(reader, this.logger);
+
+ this.emit('reader', device);
+
+ return;
+
+ }
+
const device = new Reader(reader, this.logger);
this.emit('reader', device);
diff --git a/src/Reader.js b/src/Reader.js
index eba131f..f1e5644 100644
--- a/src/Reader.js
+++ b/src/Reader.js
@@ -5,6 +5,7 @@ import {
ConnectError,
DisconnectError,
TransmitError,
+ ControlError,
AuthenticationError,
LoadAuthenticationKeyError,
ReadError,
@@ -23,12 +24,16 @@ export const TAG_ISO_14443_4 = 'TAG_ISO_14443_4';
export const KEY_TYPE_A = 0x60;
export const KEY_TYPE_B = 0x61;
+export const CONNECT_MODE_DIRECT = 'CONNECT_MODE_DIRECT';
+export const CONNECT_MODE_CARD = 'CONNECT_MODE_CARD';
+
class Reader extends EventEmitter {
reader = null;
logger = null;
+ connection = null;
card = null;
autoProcessing = true;
@@ -46,7 +51,7 @@ class Reader extends EventEmitter {
let buffer = new Buffer(src.length);
- for (var i = 0, j = src.length - 1; i <= j; ++i, --j) {
+ for (let i = 0, j = src.length - 1; i <= j; ++i, --j) {
buffer[i] = src[j];
buffer[j] = src[i];
}
@@ -147,7 +152,10 @@ class Reader extends EventEmitter {
try {
- await this.disconnect();
+ this.card = null;
+ if (this.connection) {
+ await this.disconnect();
+ }
} catch (err) {
@@ -205,28 +213,41 @@ class Reader extends EventEmitter {
}
- connect() {
+ connect(mode = CONNECT_MODE_CARD) {
+
+ const modes = {
+ [CONNECT_MODE_DIRECT]: this.reader.SCARD_SHARE_DIRECT,
+ [CONNECT_MODE_CARD]: this.reader.SCARD_SHARE_SHARED,
+ };
+
+ if (!modes[mode]) {
+ throw new ConnectError('invalid_mode', 'Invalid mode')
+ }
- this.logger.info('trying to connect');
+ this.logger.info('trying to connect', mode, modes[mode]);
return new Promise((resolve, reject) => {
// connect card
- this.reader.connect({ share_mode: this.reader.SCARD_SHARE_SHARED }, (err, protocol) => {
+ this.reader.connect({
+ share_mode: modes[mode],
+ //protocol: this.reader.SCARD_PROTOCOL_UNDEFINED
+ }, (err, protocol) => {
if (err) {
- if (err) {
- const error = new ConnectError(FAILURE, 'An error occurred while connecting.', err);
- this.logger.error(error);
- return reject(error);
- }
+ const error = new ConnectError(FAILURE, 'An error occurred while connecting.', err);
+ this.logger.error(error);
+ return reject(error);
}
- this.card.protocol = protocol;
+ this.connection = {
+ type: modes[mode],
+ protocol: protocol
+ };
- this.logger.info('card connected', protocol);
+ this.logger.info('connected', this.connection);
- return resolve(protocol);
+ return resolve(this.connection);
});
@@ -236,11 +257,11 @@ class Reader extends EventEmitter {
disconnect() {
- if (!this.card) {
- throw new DisconnectError(CARD_NOT_CONNECTED, 'Reader in not connected to any card.')
+ if (!this.connection) {
+ throw new DisconnectError('not_connected', 'Reader in not connected. No need for disconnecting.')
}
- this.logger.info('trying to disconnect card', this.card);
+ this.logger.info('trying to disconnect', this.connection);
return new Promise((resolve, reject) => {
@@ -253,9 +274,9 @@ class Reader extends EventEmitter {
return reject(error);
}
- this.card = null;
+ this.connection = null;
- this.logger.info('card disconnected');
+ this.logger.info('disconnected');
return resolve(true);
@@ -267,15 +288,15 @@ class Reader extends EventEmitter {
transmit(data, responseMaxLength) {
- if (!this.card || !this.card.protocol) {
- throw new TransmitError(CARD_NOT_CONNECTED, 'No card or protocol available.');
+ if (!this.card || !this.connection) {
+ throw new TransmitError(CARD_NOT_CONNECTED, 'No card or connection available.');
}
return new Promise((resolve, reject) => {
- //console.log('transmitting', data, responseMaxLength);
+ this.logger.log('transmitting', data, responseMaxLength);
- this.reader.transmit(data, responseMaxLength, this.card.protocol, (err, response) => {
+ this.reader.transmit(data, responseMaxLength, this.connection.protocol, (err, response) => {
if (err) {
const error = new TransmitError(FAILURE, 'An error occurred while transmitting.', err);
@@ -290,6 +311,31 @@ class Reader extends EventEmitter {
}
+ control(data, responseMaxLength) {
+
+ if (!this.connection) {
+ throw new ControlError('not_connected', 'No connection available.');
+ }
+
+ return new Promise((resolve, reject) => {
+
+ this.logger.log('transmitting control', data, responseMaxLength);
+
+ this.reader.control(data, this.reader.IOCTL_CCID_ESCAPE, responseMaxLength, (err, response) => {
+
+ if (err) {
+ const error = new ControlError(FAILURE, 'An error occurred while transmitting control.', err);
+ return reject(error);
+ }
+
+ return resolve(response);
+
+ });
+
+ });
+
+ }
+
async loadAuthenticationKey(keyNumber, key) {
if (!(keyNumber === 0 || keyNumber === 1)) {
@@ -313,8 +359,6 @@ class Reader extends EventEmitter {
...keyData
]);
- // console.log(packet);
-
let response = null;
try {
@@ -386,31 +430,31 @@ class Reader extends EventEmitter {
}
const packet = !obsolete ? (
- // CMD: Authentication
- new Buffer([
- 0xff, // Class
- 0x86, // INS
- 0x00, // P1
- 0x00, // P2
- 0x05, // Lc
- // Data In: Authenticate Data Bytes (5 bytes)
- 0x01, // Byte 1: Version
- 0x00, // Byte 2
- blockNumber, // Byte 3: Block Number
- keyType, // Byte 4: Key Type
- keyNumber, // Byte 5: Key Number
- ])
- ) : (
- // CMD: Authentication (obsolete)
- new Buffer([
- 0xff, // Class
- 0x88, // INS
- 0x00, // P1
- blockNumber, // P2: Block Number
- keyType, // P3: Key Type
- keyNumber // Data In: Key Number
- ])
- );
+ // CMD: Authentication
+ new Buffer([
+ 0xff, // Class
+ 0x86, // INS
+ 0x00, // P1
+ 0x00, // P2
+ 0x05, // Lc
+ // Data In: Authenticate Data Bytes (5 bytes)
+ 0x01, // Byte 1: Version
+ 0x00, // Byte 2
+ blockNumber, // Byte 3: Block Number
+ keyType, // Byte 4: Key Type
+ keyNumber, // Byte 5: Key Number
+ ])
+ ) : (
+ // CMD: Authentication (obsolete)
+ new Buffer([
+ 0xff, // Class
+ 0x88, // INS
+ 0x00, // P1
+ blockNumber, // P2: Block Number
+ keyType, // P3: Key Type
+ keyNumber // Data In: Key Number
+ ])
+ );
let response = null;
@@ -430,7 +474,7 @@ class Reader extends EventEmitter {
const statusCode = response.readUInt16BE(0);
if (statusCode !== 0x9000) {
- //console.log('[authentication operation failed][request packet]', packet);
+ this.logger.error('[authentication operation failed][request packet]', packet);
throw new AuthenticationError(OPERATION_FAILED, `Authentication operation failed: Status code: 0x${statusCode.toString(16)}`);
}
@@ -612,7 +656,7 @@ class Reader extends EventEmitter {
// TODO: improve error handling and debugging
async handle_Iso_14443_3_Tag() {
- if (!this.card || !this.card.protocol) {
+ if (!this.card || !this.connection) {
return false;
}
@@ -675,7 +719,7 @@ class Reader extends EventEmitter {
// TODO: improve error handling and debugging
async handle_Iso_14443_4_Tag() {
- if (!this.card || !this.card.protocol) {
+ if (!this.card || !this.connection) {
return false;
}
diff --git a/src/errors.js b/src/errors.js
index b663ab9..05e93ec 100755
--- a/src/errors.js
+++ b/src/errors.js
@@ -43,6 +43,18 @@ export class TransmitError extends BaseError {
}
+export class ControlError extends BaseError {
+
+ constructor(code, message, previousError) {
+
+ super(code, message, previousError);
+
+ this.name = 'ControlError';
+
+ }
+
+}
+
export class ReadError extends BaseError {
constructor(code, message, previousError) {
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..fd7c032
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,1400 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@pokusew/pcsclite@^0.4.15":
+ version "0.4.15"
+ resolved "https://registry.yarnpkg.com/@pokusew/pcsclite/-/pcsclite-0.4.15.tgz#469768723afdc5dcc87b677caaa38e928117fe4a"
+ dependencies:
+ bindings "^1.2.1"
+ nan "^2.5.1"
+
+abbrev@1:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
+
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+anymatch@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
+ dependencies:
+ arrify "^1.0.0"
+ micromatch "^2.1.5"
+
+aproba@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0"
+
+are-we-there-yet@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3"
+ dependencies:
+ delegates "^1.0.0"
+ readable-stream "^2.0.0 || ^1.1.13"
+
+arr-diff@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
+ dependencies:
+ arr-flatten "^1.0.1"
+
+arr-flatten@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b"
+
+array-unique@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+
+arrify@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
+asn1@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+
+assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+async-each@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
+
+async@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+aws-sign2@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+
+aws4@^1.2.1:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755"
+
+babel-cli@^6.22.2:
+ version "6.22.2"
+ resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.22.2.tgz#3f814c8acf52759082b8fedd9627f938936ab559"
+ dependencies:
+ babel-core "^6.22.1"
+ babel-polyfill "^6.22.0"
+ babel-register "^6.22.0"
+ babel-runtime "^6.22.0"
+ commander "^2.8.1"
+ convert-source-map "^1.1.0"
+ fs-readdir-recursive "^1.0.0"
+ glob "^7.0.0"
+ lodash "^4.2.0"
+ output-file-sync "^1.1.0"
+ path-is-absolute "^1.0.0"
+ slash "^1.0.0"
+ source-map "^0.5.0"
+ v8flags "^2.0.10"
+ optionalDependencies:
+ chokidar "^1.6.1"
+
+babel-code-frame@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
+ dependencies:
+ chalk "^1.1.0"
+ esutils "^2.0.2"
+ js-tokens "^3.0.0"
+
+babel-core@^6.22.0, babel-core@^6.22.1:
+ version "6.22.1"
+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.22.1.tgz#9c5fd658ba1772d28d721f6d25d968fc7ae21648"
+ dependencies:
+ babel-code-frame "^6.22.0"
+ babel-generator "^6.22.0"
+ babel-helpers "^6.22.0"
+ babel-messages "^6.22.0"
+ babel-register "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.22.0"
+ babel-traverse "^6.22.1"
+ babel-types "^6.22.0"
+ babylon "^6.11.0"
+ convert-source-map "^1.1.0"
+ debug "^2.1.1"
+ json5 "^0.5.0"
+ lodash "^4.2.0"
+ minimatch "^3.0.2"
+ path-is-absolute "^1.0.0"
+ private "^0.1.6"
+ slash "^1.0.0"
+ source-map "^0.5.0"
+
+babel-generator@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.22.0.tgz#d642bf4961911a8adc7c692b0c9297f325cda805"
+ dependencies:
+ babel-messages "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-types "^6.22.0"
+ detect-indent "^4.0.0"
+ jsesc "^1.3.0"
+ lodash "^4.2.0"
+ source-map "^0.5.0"
+
+babel-helper-call-delegate@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz#119921b56120f17e9dae3f74b4f5cc7bcc1b37ef"
+ dependencies:
+ babel-helper-hoist-variables "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-helper-function-name@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.22.0.tgz#51f1bdc4bb89b15f57a9b249f33d742816dcbefc"
+ dependencies:
+ babel-helper-get-function-arity "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.22.0"
+ babel-traverse "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-helper-get-function-arity@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz#0beb464ad69dc7347410ac6ade9f03a50634f5ce"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-helper-hoist-variables@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.22.0.tgz#3eacbf731d80705845dd2e9718f600cfb9b4ba72"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-helper-remap-async-to-generator@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.22.0.tgz#2186ae73278ed03b8b15ced089609da981053383"
+ dependencies:
+ babel-helper-function-name "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.22.0"
+ babel-traverse "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-helpers@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.22.0.tgz#d275f55f2252b8101bff07bc0c556deda657392c"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-template "^6.22.0"
+
+babel-messages@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.22.0.tgz#36066a214f1217e4ed4164867669ecb39e3ea575"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-syntax-async-functions@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
+
+babel-plugin-syntax-class-properties@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
+
+babel-plugin-syntax-object-rest-spread@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
+
+babel-plugin-transform-async-to-generator@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz#194b6938ec195ad36efc4c33a971acf00d8cd35e"
+ dependencies:
+ babel-helper-remap-async-to-generator "^6.22.0"
+ babel-plugin-syntax-async-functions "^6.8.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-class-properties@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.22.0.tgz#aa78f8134495c7de06c097118ba061844e1dc1d8"
+ dependencies:
+ babel-helper-function-name "^6.22.0"
+ babel-plugin-syntax-class-properties "^6.8.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.22.0"
+
+babel-plugin-transform-es2015-destructuring@^6.6.5:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.22.0.tgz#8e0af2f885a0b2cf999d47c4c1dd23ce88cfa4c6"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-function-name@^6.5.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz#f5fcc8b09093f9a23c76ac3d9e392c3ec4b77104"
+ dependencies:
+ babel-helper-function-name "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-plugin-transform-es2015-modules-commonjs@^6.7.4:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.22.0.tgz#6ca04e22b8e214fb50169730657e7a07dc941145"
+ dependencies:
+ babel-plugin-transform-strict-mode "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-plugin-transform-es2015-parameters@^6.8.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.22.0.tgz#57076069232019094f27da8c68bb7162fe208dbb"
+ dependencies:
+ babel-helper-call-delegate "^6.22.0"
+ babel-helper-get-function-arity "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.22.0"
+ babel-traverse "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-plugin-transform-object-rest-spread@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.22.0.tgz#1d419b55e68d2e4f64a5ff3373bd67d73c8e83bc"
+ dependencies:
+ babel-plugin-syntax-object-rest-spread "^6.8.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-strict-mode@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz#e008df01340fdc87e959da65991b7e05970c8c7c"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.22.0"
+
+babel-polyfill@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.22.0.tgz#1ac99ebdcc6ba4db1e2618c387b2084a82154a3b"
+ dependencies:
+ babel-runtime "^6.22.0"
+ core-js "^2.4.0"
+ regenerator-runtime "^0.10.0"
+
+babel-preset-es2015-node6@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/babel-preset-es2015-node6/-/babel-preset-es2015-node6-0.4.0.tgz#f8893f81b6533747924c657348867bd63b4f9dc2"
+ dependencies:
+ babel-plugin-transform-es2015-destructuring "^6.6.5"
+ babel-plugin-transform-es2015-function-name "^6.5.0"
+ babel-plugin-transform-es2015-modules-commonjs "^6.7.4"
+ babel-plugin-transform-es2015-parameters "^6.8.0"
+
+babel-register@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.22.0.tgz#a61dd83975f9ca4a9e7d6eff3059494cd5ea4c63"
+ dependencies:
+ babel-core "^6.22.0"
+ babel-runtime "^6.22.0"
+ core-js "^2.4.0"
+ home-or-tmp "^2.0.0"
+ lodash "^4.2.0"
+ mkdirp "^0.5.1"
+ source-map-support "^0.4.2"
+
+babel-runtime@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611"
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.10.0"
+
+babel-template@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.22.0.tgz#403d110905a4626b317a2a1fcb8f3b73204b2edb"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.22.0"
+ babel-types "^6.22.0"
+ babylon "^6.11.0"
+ lodash "^4.2.0"
+
+babel-traverse@^6.22.0, babel-traverse@^6.22.1:
+ version "6.22.1"
+ resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.22.1.tgz#3b95cd6b7427d6f1f757704908f2fc9748a5f59f"
+ dependencies:
+ babel-code-frame "^6.22.0"
+ babel-messages "^6.22.0"
+ babel-runtime "^6.22.0"
+ babel-types "^6.22.0"
+ babylon "^6.15.0"
+ debug "^2.2.0"
+ globals "^9.0.0"
+ invariant "^2.2.0"
+ lodash "^4.2.0"
+
+babel-types@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.22.0.tgz#2a447e8d0ea25d2512409e4175479fd78cc8b1db"
+ dependencies:
+ babel-runtime "^6.22.0"
+ esutils "^2.0.2"
+ lodash "^4.2.0"
+ to-fast-properties "^1.0.1"
+
+babylon@^6.11.0, babylon@^6.15.0:
+ version "6.15.0"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e"
+
+balanced-match@^0.4.1:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
+
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz#3ca76b85241c7170bf7d9703e7b9aa74630040d4"
+ dependencies:
+ tweetnacl "^0.14.3"
+
+binary-extensions@^1.0.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774"
+
+bindings@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11"
+
+block-stream@*:
+ version "0.0.9"
+ resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
+ dependencies:
+ inherits "~2.0.0"
+
+boom@2.x.x:
+ version "2.10.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+ dependencies:
+ hoek "2.x.x"
+
+brace-expansion@^1.0.0:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9"
+ dependencies:
+ balanced-match "^0.4.1"
+ concat-map "0.0.1"
+
+braces@^1.8.2:
+ version "1.8.5"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
+ dependencies:
+ expand-range "^1.8.1"
+ preserve "^0.2.0"
+ repeat-element "^1.1.2"
+
+buffer-shims@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
+
+caseless@~0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
+
+chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+chokidar@^1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
+ dependencies:
+ anymatch "^1.3.0"
+ async-each "^1.0.0"
+ glob-parent "^2.0.0"
+ inherits "^2.0.1"
+ is-binary-path "^1.0.0"
+ is-glob "^2.0.0"
+ path-is-absolute "^1.0.0"
+ readdirp "^2.0.0"
+ optionalDependencies:
+ fsevents "^1.0.0"
+
+code-point-at@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+
+colors@1.0.x:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
+
+colors@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+ dependencies:
+ delayed-stream "~1.0.0"
+
+commander@^2.8.1, commander@^2.9.0:
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
+ dependencies:
+ graceful-readlink ">= 1.0.0"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+console-control-strings@^1.0.0, console-control-strings@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
+
+convert-source-map@^1.1.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67"
+
+core-js@^2.4.0:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
+
+core-util-is@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+cryptiles@2.x.x:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+ dependencies:
+ boom "2.x.x"
+
+cycle@1.0.x:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
+
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ dependencies:
+ assert-plus "^1.0.0"
+
+debug@^2.1.1, debug@^2.2.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b"
+ dependencies:
+ ms "0.7.2"
+
+debug@~2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
+ dependencies:
+ ms "0.7.1"
+
+deep-extend@~0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+delegates@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
+
+detect-indent@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
+ dependencies:
+ repeating "^2.0.0"
+
+ecc-jsbn@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+ dependencies:
+ jsbn "~0.1.0"
+
+escape-string-regexp@^1.0.2:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+esutils@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+
+expand-brackets@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
+ dependencies:
+ is-posix-bracket "^0.1.0"
+
+expand-range@^1.8.1:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
+ dependencies:
+ fill-range "^2.1.0"
+
+extend@~3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4"
+
+extglob@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
+ dependencies:
+ is-extglob "^1.0.0"
+
+extsprintf@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
+
+eyes@0.1.x:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
+
+filename-regex@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775"
+
+fill-range@^2.1.0:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
+ dependencies:
+ is-number "^2.1.0"
+ isobject "^2.0.0"
+ randomatic "^1.1.3"
+ repeat-element "^1.1.2"
+ repeat-string "^1.5.2"
+
+for-in@^0.1.5:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8"
+
+for-own@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072"
+ dependencies:
+ for-in "^0.1.5"
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~2.1.1:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
+
+fs-readdir-recursive@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+fsevents@^1.0.0:
+ version "1.0.17"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.17.tgz#8537f3f12272678765b4fd6528c0f1f66f8f4558"
+ dependencies:
+ nan "^2.3.0"
+ node-pre-gyp "^0.6.29"
+
+fstream-ignore@~1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
+ dependencies:
+ fstream "^1.0.0"
+ inherits "2"
+ minimatch "^3.0.0"
+
+fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822"
+ dependencies:
+ graceful-fs "^4.1.2"
+ inherits "~2.0.0"
+ mkdirp ">=0.5 0"
+ rimraf "2"
+
+gauge@~2.7.1:
+ version "2.7.2"
+ resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.2.tgz#15cecc31b02d05345a5d6b0e171cdb3ad2307774"
+ dependencies:
+ aproba "^1.0.3"
+ console-control-strings "^1.0.0"
+ has-unicode "^2.0.0"
+ object-assign "^4.1.0"
+ signal-exit "^3.0.0"
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+ supports-color "^0.2.0"
+ wide-align "^1.1.0"
+
+generate-function@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
+
+generate-object-property@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
+ dependencies:
+ is-property "^1.0.0"
+
+getpass@^0.1.1:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6"
+ dependencies:
+ assert-plus "^1.0.0"
+
+glob-base@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
+ dependencies:
+ glob-parent "^2.0.0"
+ is-glob "^2.0.0"
+
+glob-parent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
+ dependencies:
+ is-glob "^2.0.0"
+
+glob@^7.0.0, glob@^7.0.5:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.2"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+globals@^9.0.0:
+ version "9.14.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034"
+
+graceful-fs@^4.1.2, graceful-fs@^4.1.4:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+"graceful-readlink@>= 1.0.0":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
+
+har-validator@~2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
+ dependencies:
+ chalk "^1.1.1"
+ commander "^2.9.0"
+ is-my-json-valid "^2.12.4"
+ pinkie-promise "^2.0.0"
+
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+has-unicode@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
+
+hawk@~3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+ dependencies:
+ boom "2.x.x"
+ cryptiles "2.x.x"
+ hoek "2.x.x"
+ sntp "1.x.x"
+
+hoek@2.x.x:
+ version "2.16.3"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+
+home-or-tmp@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.1"
+
+http-signature@~1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+ dependencies:
+ assert-plus "^0.2.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+ini@~1.3.0:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
+
+invariant@^2.2.0:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
+ dependencies:
+ loose-envify "^1.0.0"
+
+is-binary-path@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
+ dependencies:
+ binary-extensions "^1.0.0"
+
+is-buffer@^1.0.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b"
+
+is-dotfile@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d"
+
+is-equal-shallow@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
+ dependencies:
+ is-primitive "^2.0.0"
+
+is-extendable@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+
+is-extglob@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
+
+is-finite@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-glob@^2.0.0, is-glob@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
+ dependencies:
+ is-extglob "^1.0.0"
+
+is-my-json-valid@^2.12.4:
+ version "2.15.0"
+ resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b"
+ dependencies:
+ generate-function "^2.0.0"
+ generate-object-property "^1.1.0"
+ jsonpointer "^4.0.0"
+ xtend "^4.0.0"
+
+is-number@^2.0.2, is-number@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-posix-bracket@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
+
+is-primitive@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
+
+is-property@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
+
+is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+isarray@1.0.0, isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+
+isobject@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
+ dependencies:
+ isarray "1.0.0"
+
+isstream@0.1.x, isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+jodid25519@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
+ dependencies:
+ jsbn "~0.1.0"
+
+js-tokens@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.0.tgz#a2f2a969caae142fb3cd56228358c89366957bd1"
+
+jsbn@~0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd"
+
+jsesc@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
+
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+json5@^0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
+
+jsonpointer@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
+
+jsprim@^1.2.2:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252"
+ dependencies:
+ extsprintf "1.0.2"
+ json-schema "0.2.3"
+ verror "1.3.6"
+
+kind-of@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47"
+ dependencies:
+ is-buffer "^1.0.2"
+
+lodash@^4.2.0:
+ version "4.17.4"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+
+loose-envify@^1.0.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
+ dependencies:
+ js-tokens "^3.0.0"
+
+micromatch@^2.1.5:
+ version "2.3.11"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
+ dependencies:
+ arr-diff "^2.0.0"
+ array-unique "^0.2.1"
+ braces "^1.8.2"
+ expand-brackets "^0.1.4"
+ extglob "^0.3.1"
+ filename-regex "^2.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.1"
+ kind-of "^3.0.2"
+ normalize-path "^2.0.1"
+ object.omit "^2.0.0"
+ parse-glob "^3.0.4"
+ regex-cache "^0.4.2"
+
+mime-db@~1.26.0:
+ version "1.26.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff"
+
+mime-types@^2.1.12, mime-types@~2.1.7:
+ version "2.1.14"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee"
+ dependencies:
+ mime-db "~1.26.0"
+
+minimatch@^3.0.0, minimatch@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
+ dependencies:
+ brace-expansion "^1.0.0"
+
+minimist@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+
+minimist@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+"mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+ dependencies:
+ minimist "0.0.8"
+
+ms@0.7.1:
+ version "0.7.1"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
+
+ms@0.7.2:
+ version "0.7.2"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
+
+nan@^2.3.0, nan@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2"
+
+node-pre-gyp@^0.6.29:
+ version "0.6.32"
+ resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.32.tgz#fc452b376e7319b3d255f5f34853ef6fd8fe1fd5"
+ dependencies:
+ mkdirp "~0.5.1"
+ nopt "~3.0.6"
+ npmlog "^4.0.1"
+ rc "~1.1.6"
+ request "^2.79.0"
+ rimraf "~2.5.4"
+ semver "~5.3.0"
+ tar "~2.2.1"
+ tar-pack "~3.3.0"
+
+nopt@~3.0.6:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
+ dependencies:
+ abbrev "1"
+
+normalize-path@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a"
+
+npmlog@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f"
+ dependencies:
+ are-we-there-yet "~1.1.2"
+ console-control-strings "~1.1.0"
+ gauge "~2.7.1"
+ set-blocking "~2.0.0"
+
+number-is-nan@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+
+oauth-sign@~0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^4.1.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object.omit@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
+ dependencies:
+ for-own "^0.1.4"
+ is-extendable "^0.1.1"
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+once@~1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
+ dependencies:
+ wrappy "1"
+
+os-homedir@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+
+os-tmpdir@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+
+output-file-sync@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76"
+ dependencies:
+ graceful-fs "^4.1.4"
+ mkdirp "^0.5.1"
+ object-assign "^4.1.0"
+
+parse-glob@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
+ dependencies:
+ glob-base "^0.3.0"
+ is-dotfile "^1.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.0"
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+pinkie-promise@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+preserve@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+
+prettyjson@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/prettyjson/-/prettyjson-1.2.1.tgz#fcffab41d19cab4dfae5e575e64246619b12d289"
+ dependencies:
+ colors "^1.1.2"
+ minimist "^1.2.0"
+
+private@^0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1"
+
+process-nextick-args@~1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+
+punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@~6.3.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442"
+
+randomatic@^1.1.3:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb"
+ dependencies:
+ is-number "^2.0.2"
+ kind-of "^3.0.2"
+
+rc@~1.1.6:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9"
+ dependencies:
+ deep-extend "~0.4.0"
+ ini "~1.3.0"
+ minimist "^1.2.0"
+ strip-json-comments "~1.0.4"
+
+"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e"
+ dependencies:
+ buffer-shims "^1.0.0"
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "~1.0.0"
+ process-nextick-args "~1.0.6"
+ string_decoder "~0.10.x"
+ util-deprecate "~1.0.1"
+
+readable-stream@~2.1.4:
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
+ dependencies:
+ buffer-shims "^1.0.0"
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "~1.0.0"
+ process-nextick-args "~1.0.6"
+ string_decoder "~0.10.x"
+ util-deprecate "~1.0.1"
+
+readdirp@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
+ dependencies:
+ graceful-fs "^4.1.2"
+ minimatch "^3.0.2"
+ readable-stream "^2.0.2"
+ set-immediate-shim "^1.0.1"
+
+regenerator-runtime@^0.10.0:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz#257f41961ce44558b18f7814af48c17559f9faeb"
+
+regex-cache@^0.4.2:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
+ dependencies:
+ is-equal-shallow "^0.1.3"
+ is-primitive "^2.0.0"
+
+repeat-element@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
+
+repeat-string@^1.5.2:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+
+repeating@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+ dependencies:
+ is-finite "^1.0.0"
+
+request@^2.79.0:
+ version "2.79.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
+ dependencies:
+ aws-sign2 "~0.6.0"
+ aws4 "^1.2.1"
+ caseless "~0.11.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.0"
+ forever-agent "~0.6.1"
+ form-data "~2.1.1"
+ har-validator "~2.0.6"
+ hawk "~3.1.3"
+ http-signature "~1.1.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.7"
+ oauth-sign "~0.8.1"
+ qs "~6.3.0"
+ stringstream "~0.0.4"
+ tough-cookie "~2.3.0"
+ tunnel-agent "~0.4.1"
+ uuid "^3.0.0"
+
+rimraf@2, rimraf@~2.5.1, rimraf@~2.5.4:
+ version "2.5.4"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04"
+ dependencies:
+ glob "^7.0.5"
+
+semver@~5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+
+set-blocking@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+
+set-immediate-shim@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
+
+signal-exit@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+
+slash@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+
+sntp@1.x.x:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+ dependencies:
+ hoek "2.x.x"
+
+source-map-support@^0.4.2:
+ version "0.4.11"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322"
+ dependencies:
+ source-map "^0.5.3"
+
+source-map@^0.5.0, source-map@^0.5.3:
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
+
+sshpk@^1.7.0:
+ version "1.10.2"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.2.tgz#d5a804ce22695515638e798dbe23273de070a5fa"
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ dashdash "^1.12.0"
+ getpass "^0.1.1"
+ optionalDependencies:
+ bcrypt-pbkdf "^1.0.0"
+ ecc-jsbn "~0.1.1"
+ jodid25519 "^1.0.0"
+ jsbn "~0.1.0"
+ tweetnacl "~0.14.0"
+
+stack-trace@0.0.x:
+ version "0.0.9"
+ resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
+
+string-width@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ strip-ansi "^3.0.0"
+
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+
+stringstream@~0.0.4:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-json-comments@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"
+
+supports-color@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a"
+
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+tar-pack@~3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae"
+ dependencies:
+ debug "~2.2.0"
+ fstream "~1.0.10"
+ fstream-ignore "~1.0.5"
+ once "~1.3.3"
+ readable-stream "~2.1.4"
+ rimraf "~2.5.1"
+ tar "~2.2.1"
+ uid-number "~0.0.6"
+
+tar@~2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
+ dependencies:
+ block-stream "*"
+ fstream "^1.0.2"
+ inherits "2"
+
+to-fast-properties@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
+
+tough-cookie@~2.3.0:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
+ dependencies:
+ punycode "^1.4.1"
+
+tunnel-agent@~0.4.1:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+uid-number@~0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
+
+user-home@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
+
+util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+
+uuid@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
+
+v8flags@^2.0.10:
+ version "2.0.11"
+ resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881"
+ dependencies:
+ user-home "^1.1.1"
+
+verror@1.3.6:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
+ dependencies:
+ extsprintf "1.0.2"
+
+wide-align@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad"
+ dependencies:
+ string-width "^1.0.1"
+
+winston@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/winston/-/winston-2.3.1.tgz#0b48420d978c01804cf0230b648861598225a119"
+ dependencies:
+ async "~1.0.0"
+ colors "1.0.x"
+ cycle "1.0.x"
+ eyes "0.1.x"
+ isstream "0.1.x"
+ stack-trace "0.0.x"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+xtend@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"