diff --git a/._postinstall.js b/._postinstall.js new file mode 100644 index 00000000..17d1a300 Binary files /dev/null and b/._postinstall.js differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a9926c1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# compiled output +/dist +/tmp +/out-tsc +/app-builds +/release +main.js +src/**/*.js +*.js.map +lib/*.js + +# dependencies +/node_modules +!src/assets/*.js + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/typings +package-lock.json + +# e2e +/e2e/*.js +!/e2e/protractor.conf.js +/e2e/*.map + +# System Files +.DS_Store +Thumbs.db + diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..3ccd8d0c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/*.js.map": true, + "**/*.js": { + "when": "$(basename).ts" + } + } +} \ No newline at end of file diff --git a/angular.json b/angular.json new file mode 100644 index 00000000..143d18ca --- /dev/null +++ b/angular.json @@ -0,0 +1,149 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "altitude": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist", + "index": "src/index.html", + "main": "src/main.ts", + "tsConfig": "src/tsconfig.app.json", + "polyfills": "src/polyfills.ts", + "assets": [ + "src/assets" + ], + "styles": [ + "src/styles.scss", + "node_modules/angular-notifier/styles.scss" + ] + }, + "configurations": { + "dev": { + "optimization": false, + "outputHashing": "all", + "sourceMap": true, + "extractCss": true, + "namedChunks": false, + "aot": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": false, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.dev.ts" + } + ] + }, + "production": { + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "altitude:build" + }, + "configurations": { + "dev": { + "browserTarget": "altitude:build:dev" + }, + "production": { + "browserTarget": "altitude:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "altitude:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills-test.ts", + "tsConfig": "src/tsconfig.spec.json", + "karmaConfig": "src/karma.conf.js", + "scripts": [], + "styles": [ + "src/styles.scss" + ], + "assets": [ + "src/assets" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "altitude-e2e": { + "root": "e2e", + "projectType": "application", + "architect": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "altitude:serve" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "e2e/tsconfig.e2e.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "altitude", + "schematics": { + "@schematics/angular:component": { + "prefix": "app", + "styleext": "scss" + }, + "@schematics/angular:directive": { + "prefix": "app" + } + } +} \ No newline at end of file diff --git a/assets/README.md b/assets/README.md new file mode 100644 index 00000000..b0750d67 --- /dev/null +++ b/assets/README.md @@ -0,0 +1,5 @@ +Cross platform images are generated with electron-icon-maker using a source 1024x1024 png image with the following command + +``` +./node_modules/.bin/electron-icon-maker --input=./assets/logo1024x1024.png --output=./assets +``` \ No newline at end of file diff --git a/assets/icons/mac/icon.icns b/assets/icons/mac/icon.icns new file mode 100644 index 00000000..cfb8341a Binary files /dev/null and b/assets/icons/mac/icon.icns differ diff --git a/assets/icons/png/1024x1024.png b/assets/icons/png/1024x1024.png new file mode 100644 index 00000000..a1cdf4e6 Binary files /dev/null and b/assets/icons/png/1024x1024.png differ diff --git a/assets/icons/png/128x128.png b/assets/icons/png/128x128.png new file mode 100644 index 00000000..a4a53e15 Binary files /dev/null and b/assets/icons/png/128x128.png differ diff --git a/assets/icons/png/16x16.png b/assets/icons/png/16x16.png new file mode 100644 index 00000000..e67f6b83 Binary files /dev/null and b/assets/icons/png/16x16.png differ diff --git a/assets/icons/png/24x24.png b/assets/icons/png/24x24.png new file mode 100644 index 00000000..bb70936d Binary files /dev/null and b/assets/icons/png/24x24.png differ diff --git a/assets/icons/png/256x256.png b/assets/icons/png/256x256.png new file mode 100644 index 00000000..edab81a6 Binary files /dev/null and b/assets/icons/png/256x256.png differ diff --git a/assets/icons/png/32x32.png b/assets/icons/png/32x32.png new file mode 100644 index 00000000..b46eca72 Binary files /dev/null and b/assets/icons/png/32x32.png differ diff --git a/assets/icons/png/48x48.png b/assets/icons/png/48x48.png new file mode 100644 index 00000000..79d021f8 Binary files /dev/null and b/assets/icons/png/48x48.png differ diff --git a/assets/icons/png/512x512.png b/assets/icons/png/512x512.png new file mode 100644 index 00000000..64faa761 Binary files /dev/null and b/assets/icons/png/512x512.png differ diff --git a/assets/icons/png/64x64.png b/assets/icons/png/64x64.png new file mode 100644 index 00000000..f797b7e7 Binary files /dev/null and b/assets/icons/png/64x64.png differ diff --git a/assets/icons/win/icon.ico b/assets/icons/win/icon.ico new file mode 100644 index 00000000..1ced71f3 Binary files /dev/null and b/assets/icons/win/icon.ico differ diff --git a/assets/logo1024x1024.png b/assets/logo1024x1024.png new file mode 100644 index 00000000..264d52a6 Binary files /dev/null and b/assets/logo1024x1024.png differ diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts new file mode 100644 index 00000000..e0e1c460 --- /dev/null +++ b/e2e/app.e2e-spec.ts @@ -0,0 +1,15 @@ +import { AltitudePage } from './app.po'; +import { browser, element, by } from 'protractor'; + +describe('altitude App', () => { + let page: AltitudePage; + + beforeEach(() => { + page = new AltitudePage(); + }); + + it('should display message saying App works !', () => { + page.navigateTo('/'); + expect(element(by.css('app-home h1')).getText()).toMatch('App works !'); + }); +}); diff --git a/e2e/app.po.ts b/e2e/app.po.ts new file mode 100644 index 00000000..45d85237 --- /dev/null +++ b/e2e/app.po.ts @@ -0,0 +1,8 @@ +import { browser, element, by } from 'protractor'; + +/* tslint:disable */ +export class AltitudePage { + navigateTo(route: string) { + return browser.get(route); + } +} diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js new file mode 100644 index 00000000..e46f106b --- /dev/null +++ b/e2e/protractor.conf.js @@ -0,0 +1,37 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 25000, + delayBrowserTimeInSeconds: 0, + specs: [ + './**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome', + chromeOptions: { + args: ["--no-sandbox", "--headless", "--disable-gpu"] + } + }, + chromeOnly: true, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine2', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function () { }, + realtimeFailure: true + }, + useAllAngular2AppRoots: true, + beforeLaunch: function () { + require('ts-node').register({ + project: 'e2e/tsconfig.e2e.json' + }); + }, + onPrepare() { + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json new file mode 100644 index 00000000..ac7a3732 --- /dev/null +++ b/e2e/tsconfig.e2e.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/e2e", + "module": "commonjs", + "target": "es5", + "types":[ + "jasmine", + "node" + ] + } +} diff --git a/electron-builder.json b/electron-builder.json new file mode 100644 index 00000000..c111ae32 --- /dev/null +++ b/electron-builder.json @@ -0,0 +1,44 @@ +{ + "productName": "Altitude", + "directories": { + "output": "release/" + }, + "files": [ + "**/*", + "!**/*.ts", + "!*.code-workspace", + "!LICENSE.md", + "!package.json", + "!package-lock.json", + "!src/", + "!e2e/", + "!hooks/", + "!angular.json", + "!_config.yml", + "!karma.conf.js", + "!tsconfig.json", + "!tslint.json" + ], + "win": { + "icon": "assets/icons/win/icon.ico", + "target": [ + "nsis" + ], + "legalTrademarks": "Copyright © 2018 Linda Project Inc.", + "publisherName": "Linda Project Inc." + }, + "mac": { + "icon": "assets/icons/mac/icon.icns", + "target": [ + "dmg" + ], + "category": "public.app-category.utilities" + }, + "linux": { + "icon": "assets/icons/png", + "target": [ + "AppImage" + ], + "category": "Utility" + } +} \ No newline at end of file diff --git a/lib/client.ts b/lib/client.ts new file mode 100644 index 00000000..f10d8036 --- /dev/null +++ b/lib/client.ts @@ -0,0 +1,417 @@ + +import { app, ipcMain } from 'electron'; +import * as os from 'os'; +import * as path from 'path'; +import * as request from 'request'; +import { spawn, ChildProcess } from 'child_process'; +import * as helpers from './helpers'; +import * as log from 'electron-log'; +import * as settings from './settings'; +var localClientBinaries = require('../clientBinaries.json'); + +const sleep = require('util').promisify(setTimeout) + +export default class Client { + // client details + clientsLocation = path.join(app.getPath('userData'), 'clients'); + clientName = 'Lindad'; + clientConfigLocation = '' + clientConfig: ClientConfig; + clientLocalLocation: string; + clientDownloadLocation: string; + // rpc credentials + rpcUser: string; + rpcPassword: string; + rpcPort: number; + // rpc status + rpcRunning = false; + rpcMessage = ""; + // client node process + proc: ChildProcess; + // electron window + win: any; + // user response when client update available + updateResponse; + // client status + status: ClientStatus = ClientStatus.INITIALISING; + + constructor(win) { + this.win = win; + this.setupListeners(); + this.getClientConfigLocation(); + this.startClient(); + } + + getClientConfigLocation() { + if (os.platform() === 'win32') { + this.clientConfigLocation = path.join(app.getPath('userData'), '../', 'Linda', 'Linda.conf'); + } else if (os.platform() === 'linux') { + this.clientConfigLocation = path.join(app.getPath('home'), '.Linda', 'Linda.conf'); + } else if (os.platform() === 'darwin') { + this.clientConfigLocation = path.join(app.getPath('home'), 'Library', 'Application Support', 'Linda', 'Linda.conf'); + } + log.info('Client', 'Config location', this.clientConfigLocation); + } + + setupListeners() { + ipcMain.on('client-node', (event, cmd, data) => { + log.debug('Received IPC:client-node', cmd, data); + switch (cmd) { + case 'CREDENTIALS': + this.IPC_sendCredentials(); + break; + case 'STATUS': + this.setClientStatus(this.status); + break; + case 'RPC': + this.sendRPCStatus(); + break; + case 'RESTART': + this.stop(false).then(() => this.startClient(true, data)); + break; + case 'CHECKUPDATE': + this.checkClientUpdate(); + break; + case 'APPLYUPDATE': + this.stop(false).then(() => this.startClient(true, true, data)); + break; + case 'UPDATE': + if (this.updateResponse) this.updateResponse(true); + break; + case 'NOUPDATE': + if (data === true) settings.set_skipCoreUpdate(this.clientConfig.download.sha256); // skip this update + if (this.updateResponse) this.updateResponse(false); + break; + } + }); + } + + IPC_sendCredentials() { + if (this.win) this.win.webContents.send('client-node', 'CREDENTIALS', { rpcUser: this.rpcUser, rpcPassword: this.rpcPassword, rpcPort: this.rpcPort }); + } + + async startClient(restart = false, update = false, commands = []) { + try { + this.setClientStatus(ClientStatus.INITIALISING); + // get the client info + await this.getClientBinaries(restart); + // load config + this.setClientStatus(ClientStatus.CHECKEXISTS); + if (await this.getClientConfig()) { + log.info("Client", "Config exists"); + // check we got credentials + if (!this.rpcUser || !this.rpcPassword || !this.rpcPort) { + log.info("Client", "Couldn't get credentials from config"); + this.setClientStatus(ClientStatus.NOCREDENTIALS); + return; + } + // send credentials to renderer + this.IPC_sendCredentials(); + // if already running exit here + log.info("Client", "Check if already running"); + if ((await this.callClient('help') as any).success) { + log.info("Client", "Client is already running"); + if (this.proc) this.setClientStatus(ClientStatus.RUNNING); + else this.setClientStatus(ClientStatus.RUNNINGEXTERNAL); + await this.waitForClientReady(); + return; + } + } + // if we don't already have a local client download it + log.info("Client", "Check client exists", this.clientLocalLocation); + if (!await helpers.pathExists(this.clientLocalLocation)) { + // check if we need to make the directory + if (!await helpers.pathExists(this.clientsLocation)) + await helpers.makeFolder(this.clientsLocation); + + if (!await this.downloadClient()) return + } else { + // if we have a client check for an update + log.info("Client", "Client exists. Checking for update"); + const localHash = await helpers.getFileHash(this.clientLocalLocation); + if (localHash !== this.clientConfig.download.sha256) { + log.info("Client", "Update available"); + // check if we should skip this update + if (update || settings.getSettings().skipCoreUpdate !== this.clientConfig.download.sha256) { + if (update) { + if (!await this.downloadClient()) return + } else { + // wait here for response on update or not + this.setClientStatus(ClientStatus.UPDATEAVAILABLE); + if (await this.waitForUpdateResponse()) { + if (!await this.downloadClient()) return + } + else log.info("Client", "Skipping Update"); + } + } + else log.info("Client", "Skipping Update"); + } + } + // run the client + this.setClientStatus(ClientStatus.STARTING); + log.info("Client", "Running client"); + this.runClient(this.clientConfig.bin, commands); + await this.waitForCredentials(); + await this.waitForClientReady(); + } catch (ex) { + log.error("Client", "Start error", ex); + this.setClientStatus(ex) + } + return; + } + + async getClientBinaries(restart) { + const arch = os.arch(); + const platform = os.platform(); + log.verbose("Client", "Running on platform", platform, arch); + // load local client binaries + let clientBinaries = localClientBinaries; + // try to get remote file for updates. Skip this if we are restarted the client + if (!restart) { + try { + const res: any = await helpers.getRequest("https://raw.githubusercontent.com/thelindaprojectinc/altitude/master/clientBinaries.json"); + clientBinaries = JSON.parse(res.body); + } catch (ex) { + log.info("Client", "Failed to get remote client binaries, using local"); + } + } + // check we support this platform + if (!clientBinaries[this.clientName][platform] || !clientBinaries[this.clientName][platform][arch]) { + log.info("Client", "Unsupported platform", platform, arch); + throw ClientStatus.UNSUPPORTEDPLATFORM + } + // set client details + this.clientConfig = clientBinaries[this.clientName][platform][arch]; + this.clientLocalLocation = path.join(this.clientsLocation, this.clientConfig.bin); + this.clientDownloadLocation = path.join(this.clientsLocation, 'download'); + } + + async waitForUpdateResponse() { + return new Promise((resolve, reject) => { + this.updateResponse = resolve; + }) + } + + async downloadClient() { + try { + this.setClientStatus(ClientStatus.DOWNLOADCLIENT); + log.info("Client", "Deleting old client"); + await helpers.deleteFile(this.clientDownloadLocation); + log.info("Client", "Downloading client"); + const fileHash = await helpers.downloadFile(this.clientConfig.download.url, this.clientDownloadLocation); + if (fileHash != this.clientConfig.download.sha256) { + log.info("Client", "Invalid SHA256"); + this.setClientStatus(ClientStatus.INVALIDHASH); + return false; + } else { + helpers.renameFile(this.clientDownloadLocation, this.clientLocalLocation); + if (os.platform() !== 'win32') helpers.setFileExecutable(this.clientLocalLocation); + } + return true; + } catch (ex) { + this.setClientStatus(ClientStatus.DOWNLOADFAILED); + return false; + } + } + + async waitForCredentials() { + if (this.status === ClientStatus.SHUTTINGDOWN || this.status === ClientStatus.RESTARTING || this.status === ClientStatus.CLOSEDUNEXPECTED) + return; + if (await this.getClientConfig()) { + log.info("Client", "Config exists"); + // check we got credentials + if (!this.rpcUser || !this.rpcPassword || !this.rpcPort) { + log.info("Client", "Couldn't get credentials from config"); + this.setClientStatus(ClientStatus.NOCREDENTIALS); + } else { + // send credentials to renderer + this.IPC_sendCredentials(); + // set status as running + this.setClientStatus(ClientStatus.RUNNING); + } + } else { + log.info("Client", "Config doesn't exist. Checking in 1000ms"); + await sleep(1000); + return this.waitForCredentials(); + } + } + + async waitForClientReady(): Promise { + // check if we interrupted the startup + if (this.status === ClientStatus.SHUTTINGDOWN || this.status === ClientStatus.RESTARTING || this.status === ClientStatus.CLOSEDUNEXPECTED) { + this.rpcMessage = ""; + this.rpcRunning = false; + this.sendRPCStatus(); + return; + } + + const res: any = await this.callClient('getinfo'); + this.rpcMessage = ""; + + if (res.error) { + try { + if (res.error.code === -28) this.rpcMessage = res.error.message; + } catch (ex) { + //error isn't formed as expected + } + this.rpcRunning = false; + this.sendRPCStatus(); + log.info("Client", "RPC not ready. retrying in 1000ms", this.rpcMessage); + await sleep(1000); + return this.waitForClientReady(); + } else { + this.rpcRunning = true; + this.sendRPCStatus(); + log.info("Client", "RPC Ready"); + } + } + + runClient(bin, commands) { + let startupCommands = []; + startupCommands = startupCommands.concat(commands); + log.info("Client", "Running with commands", startupCommands); + this.proc = spawn('"' + path.join(this.clientsLocation, bin) + '"', startupCommands, { shell: true }); + this.proc.once('close', () => { + if ( + this.proc && + this.status !== ClientStatus.SHUTTINGDOWN && + this.status !== ClientStatus.RESTARTING && + this.status !== ClientStatus.STOPPED + ) { + log.info("Client", "closed unexpectedly status:", this.status); + this.destroyClientProccess(); + this.setClientStatus(ClientStatus.CLOSEDUNEXPECTED); + } + }); + } + + public stop(shuttingDown = true) { + if (shuttingDown) this.setClientStatus(ClientStatus.SHUTTINGDOWN); + else this.setClientStatus(ClientStatus.RESTARTING); + + return new Promise((resolve, reject) => { + if (this.proc) { + log.info("Client", "Kill client"); + // setup force kill function + const forceKill = () => { + if (this.proc) { + log.info("Client", "failed to exit gracefully. force killing."); + this.proc.kill(); + } + this.destroyClientProccess(); + resolve(); + } + // attempt to gracefully exit + this.callClient('stop').then(success => { + if (!success) forceKill() + }); + // force close if we fail to exit gracefully + let killTimeout = setTimeout(forceKill, 10000); + // if we hear the close cancel force kill and notify app + this.proc.once('close', () => { + clearTimeout(killTimeout); + this.destroyClientProccess(); + resolve(); + }); + } else { + resolve(); + } + }) + } + + destroyClientProccess() { + this.setClientStatus(ClientStatus.STOPPED); + if (this.proc) this.proc.removeAllListeners() + this.proc = null; + } + + async getClientConfig() { + try { + if (await helpers.pathExists(this.clientConfigLocation)) { + let data = await helpers.readFile(this.clientConfigLocation) as string; + let lines = data.split(os.EOL); + for (let i = 0; i < lines.length; i++) { + if (lines[i].indexOf('=') > -1) { + lines[i] = lines[i].replace('\r', '').replace('\n', ''); + const key = lines[i].split("=")[0].trim(); + const val = lines[i].split("=")[1].trim(); + if (key === 'rpcuser') this.rpcUser = val; + if (key === 'rpcpassword') this.rpcPassword = val; + if (key === 'rpcport') this.rpcPort = Number(val); + } + } + return true; + } + } catch (ex) { + // if we fail to read the config file + } + return false; + } + + async callClient(method): Promise<{}> { + return new Promise((resolve, reject) => { + const options = { + method: 'POST', + url: `http://${this.rpcUser}:${this.rpcPassword}@127.0.0.1:${this.rpcPort}/`, + body: { jsonrpc: '1.0', id: 'Tunnel', method: method, params: [] }, + json: true + }; + + request(options, (error, response, body) => { + if (error || body.error) resolve({ success: false, error: error || body.error }); + else resolve({ success: true, body }); + }); + }) + } + + setClientStatus(status: ClientStatus) { + this.status = status; + if (this.win) this.win.webContents.send('client-node', 'STATUS', this.status); + } + + sendRPCStatus() { + if (this.win) this.win.webContents.send('client-node', 'RPC', { ready: this.rpcRunning, message: this.rpcMessage }); + } + + async checkClientUpdate() { + try { + await this.getClientBinaries(false); + const localHash = await helpers.getFileHash(this.clientLocalLocation); + const hasUpdate = localHash !== this.clientConfig.download.sha256; + if (this.win) this.win.webContents.send('client-node', 'CHECKUPDATE', hasUpdate); + } catch (ex) { + } + return; + } + + destroy() { + this.win = null; + } + +} + +export enum ClientStatus { + INITIALISING, + CHECKEXISTS, + DOWNLOADCLIENT, + UPDATEAVAILABLE, + STARTING, + RUNNING, + RUNNINGEXTERNAL, + STOPPED, + NOCREDENTIALS, + INVALIDHASH, + DOWNLOADFAILED, + UNSUPPORTEDPLATFORM, + SHUTTINGDOWN, + RESTARTING, + CLOSEDUNEXPECTED +} + +class ClientConfig { + download: { + url: string, + sha256: string, + } + bin: string +} \ No newline at end of file diff --git a/lib/helpers.ts b/lib/helpers.ts new file mode 100644 index 00000000..fe812109 --- /dev/null +++ b/lib/helpers.ts @@ -0,0 +1,113 @@ + +import * as https from 'https'; +import * as fs from 'fs' +import * as crypto from 'crypto' +import { exec } from 'child_process'; +import * as log from 'electron-log'; + +export async function pathExists(path) { + return new Promise((resolve, reject) => { + fs.exists(path, exists => { + resolve(exists) + }) + }) +} + +export async function readFile(file, encoding = 'utf-8') { + return new Promise((resolve, reject) => { + fs.readFile(file, { encoding: encoding }, (err, data) => { + if (err) reject(err); + else resolve(data); + }); + }); +} + +export async function setFileExecutable(file: string) { + exec(`chmod +x "${file}"`); +} + +export async function renameFile(original: string, rename: string) { + return new Promise((resolve, reject) => { + fs.rename(original, rename, (err) => { + if (err) reject(err); + else resolve(); + }); + }); +} + +export async function deleteFile(file: string) { + return new Promise((resolve, reject) => { + pathExists(file).then((exits) => { + if (exits) { + fs.unlink(file, (err) => { + if (err) reject(err); + else resolve(); + }); + } else { + resolve(); + } + }) + }); +} + +export async function downloadFile(url, dest) { + return new Promise((resolve, reject) => { + https.get(url, response => { + if (response.statusCode >= 200 && response.statusCode < 300) { + var fileStream = fs.createWriteStream(dest); + fileStream.on('error', err => + reject(err)); + fileStream.on('close', () => + resolve(getFileHash(dest))); + response.pipe(fileStream); + } else if (response.headers.location) { + const location = response.headers.location + resolve(downloadFile(location, dest)); + } else { + reject(new Error(response.statusCode + ' ' + response.statusMessage)); + } + }).on('error', err => { + reject(err); + }); + }) +} + +export async function getFileHash(path) { + return new Promise((resolve, reject) => { + const hash = crypto.createHash('sha256'); + let stream = fs.createReadStream(path); + stream.on('error', err => reject(err)); + stream.on('data', chunk => hash.update(chunk)); + stream.on('end', () => resolve(hash.digest('hex').toUpperCase())); + }); +} + +export async function getRequest(url) { + return new Promise((resolve, reject) => { + https.get(url, response => { + if (response.statusCode >= 200 && response.statusCode < 300) { + let body = '' + response.on('data', (chunk) => { + body += chunk; + }); + response.on('end', () => { + resolve({ response, body }); + }); + } else { + reject(new Error(response.statusCode + ' ' + response.statusMessage)); + } + }).on('error', err => { + reject(err); + }); + }) +} + + +export async function makeFolder(path) { + return new Promise((resolve, reject) => { + fs.mkdir(path, (err) => { + if (err) reject(err); + else resolve(); + }); + }); +} \ No newline at end of file diff --git a/lib/settings.ts b/lib/settings.ts new file mode 100644 index 00000000..6f49e8b8 --- /dev/null +++ b/lib/settings.ts @@ -0,0 +1,96 @@ +import { ipcMain, BrowserWindow } from 'electron'; +import * as log from 'electron-log'; +import * as storage from 'electron-json-storage'; + +let settings: Settings; +let win: BrowserWindow; + +export function getSettings(): Settings { + return settings; +} + +export function set_skipCoreUpdate(hash: string) { + settings.skipCoreUpdate = hash; + saveSettings(); +} + +export function set_skipWalletUpdate(version: string) { + settings.skipWalletUpdate = version; + saveSettings(); +} + +export function set_hideCoinControlFeatures(hide: boolean) { + settings.hideCoinControlFeatures = hide; + saveSettings(); +} + +export function set_locale(locale: string) { + settings.locale = locale; + saveSettings(); +} + +export function set_fullScreen(fullScreen: boolean) { + settings.fullScreen = fullScreen; + saveSettings(); +} + +export function setWindow(window) { + win = window; +} + +function loadSettings() { + settings = new Settings(); + storage.get('settings', (error, data) => { + if (!error && data) { + if (data.skipCoreUpdate) settings.skipCoreUpdate = data.skipCoreUpdate; + if (data.skipWalletUpdate) settings.skipWalletUpdate = data.skipWalletUpdate; + if (data.locale) settings.locale = data.locale; + } + }); +} + +function saveSettings() { + IPC_sendSettings(); + storage.set('settings', settings, () => { }); +} + +function setupIPC() { + ipcMain.on('settings', (event, cmd, data) => { + log.debug('Received IPC:settings', cmd, data); + switch (cmd) { + case 'GET': + IPC_sendSettings(); + break; + case 'SETSKIPWALLETUPDATE': + set_skipWalletUpdate(data); + break; + case 'SETHIDECOINCONTROLFEATURES': + set_hideCoinControlFeatures(data); + break; + case 'SETLOCALE': + set_locale(data); + break; + case 'SETFULLSCREEN': + set_fullScreen(data); + break; + } + }); +} + +function IPC_sendSettings() { + if (win) win.webContents.send('settings', 'GET', settings); +} + + +export class Settings { + skipCoreUpdate: string = ""; + skipWalletUpdate: string = ""; + hideCoinControlFeatures: boolean = true; + locale: string = "en"; + fullScreen: boolean = false; +} + +// load settings from storage straight away +loadSettings(); +// connect IPC +setupIPC(); \ No newline at end of file diff --git a/main.ts b/main.ts new file mode 100644 index 00000000..34302cf7 --- /dev/null +++ b/main.ts @@ -0,0 +1,185 @@ +import { app, BrowserWindow, screen, Menu, Tray, MenuItem } from 'electron'; +import * as path from 'path'; +import * as url from 'url'; +import Client from './lib/client'; +import * as log from 'electron-log'; +import * as settings from './lib/settings'; + +log.transports.console.level = 'info' +log.transports.file.level = 'info' + +let mainWindow, serve, client; +const args = process.argv.slice(1); +serve = args.some(val => val === '--serve'); + +let tray: Tray +let isHidden = false; + +function createApp() { + createTray(); + createWindow(); +} + +function createWindow() { + // Create the browser window. + const electronScreen = screen; + const size = electronScreen.getPrimaryDisplay().workAreaSize; + let height = 600; + let width = 900; + if (!app.isPackaged) { + height = size.height; + width = size.width; + } + mainWindow = new BrowserWindow({ + center: true, + minWidth: 800, + minHeight: 500, + title: 'Altitude', + width: width < size.width ? width : size.width, + height: height < size.height ? height : size.height, + icon: path.join(__dirname, 'assets/icons/png/512x512.png'), + webPreferences: { webSecurity: false }, + frame: process.platform !== 'win32', + titleBarStyle: 'hidden' + }); + + if (serve) { + require('electron-reload')(__dirname, { + electron: require(`${__dirname}/node_modules/electron`) + }); + mainWindow.loadURL('http://localhost:4200'); + } else { + mainWindow.loadURL(url.format({ + pathname: path.join(__dirname, 'dist/index.html'), + protocol: 'file:', + slashes: true + })); + } + + // setup settings + log.info('Initiate settings'); + settings.setWindow(mainWindow); + // set windowsize + const handler = () => { + const appSettings = settings.getSettings(); + if (!appSettings) setTimeout(handler, 100); + else { + if (appSettings.fullScreen) mainWindow.maximize(); + } + } + handler(); + + // start client + log.info('Start client'); + client = new Client(mainWindow) + + // open dev tools + if (!app.isPackaged) mainWindow.webContents.openDevTools(); + + // Emitted when the window is closed. + mainWindow.on('closed', () => { + client.destroy(); + mainWindow = null; + }); + + mainWindow.on("close", e => { + if (client.proc) { + closeApp(e); + } else { + e.returnValue = true; + } + }); + +} + +function createTray() { + // Create the Tray icon + tray = new Tray(path.resolve(__dirname, 'assets/icons/png/16x16.png')); + tray.setToolTip('Altitude') + tray.on('click', toggleMainWindows) + updateTray() +} + +function toggleMainWindows(): void { + if (isHidden) { + mainWindow.show() + isHidden = false + updateTray() + } else { + mainWindow.hide() + isHidden = true + updateTray() + } +} + +function updateTray(): void { + const contextMenu: Menu = Menu.buildFromTemplate( + (isHidden + ? [{ + click: toggleMainWindows, + label: 'Show Altitude', + }] + : [{ + click: toggleMainWindows, + label: 'Hide Altitude', + }] + ).concat( + [{ + click: () => app.quit(), + label: 'Exit', + }] + ) + ) + tray.setContextMenu(contextMenu) +} + +function closeApp(event) { + if (client.proc) { + event.preventDefault(); + // save window size + settings.set_fullScreen(mainWindow.isMinimized()); + client.stop().then(() => { + app.quit(); + }); + } +} + +try { + // check single instance + if (!app.requestSingleInstanceLock()) { + app.quit() + } else { + app.on('second-instance', () => { + if (mainWindow) { + if (mainWindow.isMinimized()) mainWindow.restore() + mainWindow.focus() + } + }) + + // create app + app.on('ready', createApp); + + // register on quit handler to close client if running + app.on('before-quit', closeApp); + + // Quit when all windows are closed. + app.on('window-all-closed', (event) => { + // On OS X it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit(); + } + }); + + app.on('activate', () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (mainWindow === null) { + createApp(); + } + }); + } +} catch (e) { + // Catch Error + // throw e; +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..fdd3185e --- /dev/null +++ b/package.json @@ -0,0 +1,91 @@ +{ + "name": "altitude", + "version": "1.0.0", + "description": "The Altitude wallet by Linda Project Inc.", + "homepage": "https://github.com/thelindaprojectinc/altitude", + "author": { + "name": "Linda Project Inc.", + "email": "dave@lindacoin.com" + }, + "keywords": [ + "wallet", + "linda", + "altitude" + ], + "main": "main.js", + "private": true, + "scripts": { + "postinstall": "npm run postinstall:electron && electron-builder install-app-deps", + "postinstall:web": "node postinstall-web", + "postinstall:electron": "node postinstall", + "ng": "ng", + "start": "npm run postinstall:electron && npm-run-all -p ng:serve electron:serve", + "build": "npm run postinstall:electron && npm run electron:serve-tsc && ng build", + "build:dev": "npm run build -- -c dev", + "build:prod": "npm run build -- -c production", + "ng:serve": "ng serve", + "ng:serve:web": "npm run postinstall:web && ng serve -o", + "electron:serve-tsc": "tsc -p tsconfig-serve.json", + "electron:serve": "wait-on http-get://localhost:4200/ && npm run electron:serve-tsc && electron . --serve", + "electron:local": "npm run build:prod && electron .", + "electron:linux": "npm run build:prod && electron-builder build --linux", + "electron:windows": "npm run build:prod && electron-builder build --windows", + "electron:windows32": "npm run build:prod && electron-builder build --windows --ia32", + "electron:mac": "npm run build:prod && electron-builder build --mac", + "test": "npm run postinstall:web && ng test", + "e2e": "npm run postinstall:web && ng e2e" + }, + "dependencies": { + "@fortawesome/angular-fontawesome": "^0.3.0", + "@fortawesome/fontawesome-svg-core": "^1.2.12", + "@fortawesome/free-solid-svg-icons": "^5.6.3", + "angular-notifier": "^4.1.1", + "compare-versions": "^3.4.0", + "electron-json-storage": "^4.1.5", + "electron-log": "^2.2.17", + "ngx-smart-modal": "^7.1.0", + "ngx-virtual-scroller": "^1.0.16", + "request": "^2.88.0", + "web-animations-js": "^2.3.1" + }, + "devDependencies": { + "@angular-devkit/build-angular": "0.11.4", + "@angular/cli": "^7.1.4", + "@angular/common": "^7.1.4", + "@angular/compiler": "^7.1.4", + "@angular/compiler-cli": "^7.1.4", + "@angular/core": "^7.1.4", + "@angular/forms": "^7.1.4", + "@angular/http": "^7.1.4", + "@angular/language-service": "^7.1.4", + "@angular/platform-browser": "^7.1.4", + "@angular/platform-browser-dynamic": "^7.1.4", + "@angular/router": "^7.1.4", + "@ngx-translate/core": "11.0.1", + "@ngx-translate/http-loader": "4.0.0", + "@types/jasmine": "3.3.4", + "@types/jasminewd2": "2.0.6", + "@types/node": "10.12.18", + "codelyzer": "4.5.0", + "core-js": "2.6.1", + "electron": "^4.0.0", + "electron-builder": "20.38.4", + "electron-reload": "1.4.0", + "google-translate": "^2.2.0", + "jasmine-core": "3.3.0", + "jasmine-spec-reporter": "4.2.1", + "karma": "3.1.4", + "karma-chrome-launcher": "2.2.0", + "karma-coverage-istanbul-reporter": "2.0.4", + "karma-jasmine": "2.0.1", + "karma-jasmine-html-reporter": "1.4.0", + "npm-run-all": "4.1.5", + "protractor": "5.4.1", + "ts-node": "7.0.1", + "tslint": "5.12.0", + "typescript": "3.1.6", + "wait-on": "3.2.0", + "webdriver-manager": "12.1.0", + "zone.js": "0.8.26" + } +} diff --git a/postinstall-web.js b/postinstall-web.js new file mode 100644 index 00000000..7dce7645 --- /dev/null +++ b/postinstall-web.js @@ -0,0 +1,16 @@ +// Allow angular using electron module (native node modules) +const fs = require('fs'); +const f_angular = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js'; + +fs.readFile(f_angular, 'utf8', function (err, data) { + if (err) { + return console.log(err); + } + var result = data.replace(/target: "electron-renderer",/g, ''); + var result = result.replace(/target: "web",/g, ''); + var result = result.replace(/return \{/g, 'return {target: "web",'); + + fs.writeFile(f_angular, result, 'utf8', function (err) { + if (err) return console.log(err); + }); +}); \ No newline at end of file diff --git a/postinstall.js b/postinstall.js new file mode 100644 index 00000000..1fb12759 --- /dev/null +++ b/postinstall.js @@ -0,0 +1,16 @@ +// Allow angular using electron module (native node modules) +const fs = require('fs'); +const f_angular = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js'; + +fs.readFile(f_angular, 'utf8', function (err, data) { + if (err) { + return console.log(err); + } + var result = data.replace(/target: "electron-renderer",/g, ''); + var result = result.replace(/target: "web",/g, ''); + var result = result.replace(/return \{/g, 'return {target: "electron-renderer",'); + + fs.writeFile(f_angular, result, 'utf8', function (err) { + if (err) return console.log(err); + }); +}); \ No newline at end of file diff --git a/src/app/app-components.module.ts b/src/app/app-components.module.ts new file mode 100644 index 00000000..b528f505 --- /dev/null +++ b/src/app/app-components.module.ts @@ -0,0 +1,28 @@ + +import { PromptComponent } from './components/prompt/prompt.component'; +import { PromptService } from './components/prompt/prompt.service'; +import { ContextMenuComponent } from './components/context-menu/context-menu.component'; +import { ContextMenuService } from './components/context-menu/context-menu.service'; +import { TitlebarComponent } from './components/titlebar/titlebar.component'; +import { ClientStatusComponent } from './components/client-status/client-status.component'; +import { AddressBookComponent } from './components/address-book/address-book.component'; +import { AddressBookService } from './components/address-book/address-book.service'; +import { SyncStatusComponent } from './components/sync-status/sync-status.component'; +import { SideBarComponent } from './components/side-bar/side-bar.component'; + +export const componentDeclarations = [ + PromptComponent, + TitlebarComponent, + ClientStatusComponent, + AddressBookComponent, + ContextMenuComponent, + SyncStatusComponent, + SideBarComponent +] + +export const componentProviders = [ + PromptService, + AddressBookService, + ContextMenuService +] + diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts new file mode 100644 index 00000000..db26e1b9 --- /dev/null +++ b/src/app/app-routing.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { SendComponent } from './pages/send/send.component'; +import { TransactionsComponent } from './pages/transactions/transactions.component'; +import { DashboardComponent } from './pages/dashboard/dashboard.component'; +import { ManageAccountComponent } from './pages/manage-account/manage-account.component'; +import { ToolsComponent } from './pages/tools/tools.component'; +import { StakingComponent } from './pages/staking/staking.component'; +import { SignMessageComponent } from './pages/signmessage/signmessage.component'; +import { MasternodesComponent } from './pages/masternodes/masternodes.component'; +import { AboutComponent } from './pages/about/about.component'; +import { LocaleComponent } from './pages/locale/locale.component'; +import { ExplorerComponent } from './pages/explorer/explorer.component'; + +export const routingDeclarations = [ + SendComponent, + TransactionsComponent, + DashboardComponent, + ManageAccountComponent, + ToolsComponent, + StakingComponent, + SignMessageComponent, + MasternodesComponent, + AboutComponent, + LocaleComponent, + ExplorerComponent +] + +const routes: Routes = [ + { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, + { path: 'dashboard', component: DashboardComponent }, + { path: 'manage-account/:address', component: ManageAccountComponent }, + { path: 'send', component: SendComponent }, + { path: 'staking', component: StakingComponent }, + { path: 'transactions', component: TransactionsComponent }, + { path: 'masternodes', component: MasternodesComponent }, + { path: 'signmessage/:tab', component: SignMessageComponent }, + { path: 'tools/:tab', component: ToolsComponent }, + { path: 'about/:tab', component: AboutComponent }, + { path: 'locale', component: LocaleComponent }, + { path: 'explorer/:search', component: ExplorerComponent }, +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes, { useHash: true })], + exports: [RouterModule] +}) +export class AppRoutingModule { } + diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 00000000..62e8def7 --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,19 @@ + +
+ + + + +
+ +
+ +
+ +
+ + + + + + \ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts new file mode 100644 index 00000000..e8f25b53 --- /dev/null +++ b/src/app/app.component.spec.ts @@ -0,0 +1,33 @@ +import { TestBed, async } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; +import { TranslateModule } from '@ngx-translate/core'; +import { ElectronService } from './providers/electron.service'; + +describe('AppComponent', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + AppComponent + ], + providers: [ + ElectronService + ], + imports: [ + RouterTestingModule, + TranslateModule.forRoot() + ] + }).compileComponents(); + })); + + it('should create the app', async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + })); +}); + +class TranslateServiceStub { + setDefaultLang(lang: string): void { + } +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 00000000..1afb40cc --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,27 @@ +import { Component, isDevMode } from '@angular/core'; +import { ElectronService } from './providers/electron.service'; +import { AppConfig } from '../environments/environment'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'] +}) +export class AppComponent { + + constructor( + public electron: ElectronService + ) { + if (isDevMode()) { + console.log('AppConfig', AppConfig); + if (electron.isElectron()) { + console.log('Mode electron'); + console.log('Electron ipcRenderer', electron.ipcRenderer); + } else { + console.log('Mode web'); + } + } + + } + +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 00000000..3b39c5a6 --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,85 @@ +import 'zone.js/dist/zone-mix'; +import 'reflect-metadata'; +import '../polyfills'; +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { HttpClientModule, HttpClient } from '@angular/common/http'; +// modal +import { NgxSmartModalModule } from 'ngx-smart-modal'; +// virtual scroll +import { VirtualScrollerModule } from 'ngx-virtual-scroller'; +// NG Translate +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +// icons +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { setupIcons } from './icon-module'; +// alerts +import { NotifierModule } from 'angular-notifier'; + +// routing +import { AppRoutingModule, routingDeclarations } from './app-routing.module'; +// components +import { componentDeclarations, componentProviders } from './app-components.module'; +// services +import { ElectronService } from './providers/electron.service'; +import { RpcService } from './providers/rpc.service'; +import { WalletService } from './providers/wallet.service'; +import { ErrorService } from './providers/error.service'; +import { NotificationService } from './providers/notification.service'; +import { TranslationService } from './providers/translation.service'; +// app +import { AppComponent } from './app.component'; + +// AoT requires an exported function for factories +export function HttpLoaderFactory(http: HttpClient) { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); +} +// AoT requires the files to be explicitly imported +setupIcons(); + +@NgModule({ + declarations: [ + AppComponent, + ...routingDeclarations, + ...componentDeclarations + ], + imports: [ + BrowserModule, + FormsModule, + HttpClientModule, + AppRoutingModule, + FontAwesomeModule, + VirtualScrollerModule, + NgxSmartModalModule.forRoot(), + NotifierModule.withConfig({ + position: { + horizontal: { position: 'right' } + }, + behaviour: { + autoHide: 3000, + } + }), + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: (HttpLoaderFactory), + deps: [HttpClient] + } + }) + ], + providers: [ + ElectronService, + RpcService, + WalletService, + ErrorService, + NotificationService, + TranslationService, + ...componentProviders + ], + bootstrap: [ + AppComponent + ] +}) +export class AppModule { } diff --git a/src/app/classes/account.ts b/src/app/classes/account.ts new file mode 100644 index 00000000..5f663c8c --- /dev/null +++ b/src/app/classes/account.ts @@ -0,0 +1,77 @@ +import Big from 'big.js'; +import { Address } from './address'; + +export class Account { + addresses = new Array
(); + + get balance(): Big { + let balance = Big(0); + this.addresses.forEach(address => balance = balance.add(address.balance)); + return balance; + } + + get name(): string { + let name; + for (let i = 0; i < this.addresses.length; i++) { + let address = this.addresses[i]; + if (address.account !== '(change)') { + //if has a name use it + if (address.newAccount !== '') { + name = address.newAccount; + break; + } + } + } + return name || 'Unnamed'; + } + + get address(): string { + let addr = ''; + for (let i = 0; i < this.addresses.length; i++) { + let address = this.addresses[i]; + //if has a name use it + if (address.account !== '(change)' && address.account !== '') { + addr = address.address; + break; + } + } + return addr || this.addresses[0].address; + } + + get mainAddress(): Address { + for (let i = 0; i < this.addresses.length; i++) { + let address = this.addresses[i]; + if (address.account !== '(change)' && address.account !== '') return address; + } + return this.addresses[0]; + } + + get identicon(): string { + return this.addresses[0].address + ' - ' + this.balance.toString(); + } + + syncAddresses(newAddresses: Array
) { + // add and update addresses from server + newAddresses.forEach(addr => { + let hasMatch = false; + for (let i = 0; i < this.addresses.length; i++) { + if (this.addresses[i].address === addr.address) { + this.addresses[i].removeFromAccount = false; + this.addresses[i].confirmations = addr.confirmations; + this.addresses[i].syncInputs(addr.allInputs()); + hasMatch = true; + } + } + if (!hasMatch) this.addresses.push(addr); + }) + } + + removeRenamedAddresses() { + // remove my addresses that are no longer in my account + for (let i = 0; i < this.addresses.length; i++) { + if (this.addresses[i].removeFromAccount) + this.addresses.splice(i--, 1); + } + } + +} \ No newline at end of file diff --git a/src/app/classes/address.ts b/src/app/classes/address.ts new file mode 100644 index 00000000..ae8f0402 --- /dev/null +++ b/src/app/classes/address.ts @@ -0,0 +1,73 @@ +import { Input } from "./input"; +import Big from 'big.js'; + +export class Address { + address: string; + account: string; + newAccount: string; + confirmations: number; + amount: number = 0; + private inputs: Array = []; + renaming: boolean = false; + + // used to denote if an address should be removed from this account + removeFromAccount: boolean = false; + + constructor(addressData, matureTime: number) { + this.address = addressData.address; + this.account = addressData.account; + this.newAccount = this.account; + this.confirmations = addressData.confirmations; + if (addressData.unspents) { + addressData.unspents.forEach(unspent => { + this.inputs.push(new Input(unspent, this, matureTime)); + }) + } + } + + get balance(): Big { + let balance = Big(0); + this.inputs.forEach(input => balance = balance.add(input.amount)); + return balance; + } + + syncInputs(newInputs: Array) { + // add and update inputs from server + newInputs.forEach(inp => { + let hasMatch = false; + for (let i = 0; i < this.inputs.length; i++) { + if (this.inputs[i].txid === inp.txid && this.inputs[i].vout === inp.vout) { + this.inputs[i].sync(inp); + hasMatch = true; + } + } + if (!hasMatch) this.inputs.push(inp); + }) + + // remove my inputs that aren't in the new list from the server + for (let i = 0; i < this.inputs.length; i++) { + let hasMatch = false; + for (let j = 0; j < newInputs.length; j++) { + if (this.inputs[i].txid === newInputs[j].txid && this.inputs[i].vout === newInputs[j].vout) { + hasMatch = true; + break; + } + } + if (!hasMatch) this.inputs.splice(i--, 1); + } + } + + spendableInputs(): Array { + let inputs = new Array(); + this.inputs.forEach(inp => { + if (!inp.locked) inputs.push(inp); + }); + return inputs; + } + + allInputs(): Array { + return this.inputs; + } + +} + diff --git a/src/app/classes/addressBookItem.ts b/src/app/classes/addressBookItem.ts new file mode 100644 index 00000000..068ee713 --- /dev/null +++ b/src/app/classes/addressBookItem.ts @@ -0,0 +1,5 @@ +export interface AddressBookItem { + address: string + account: string; +} + diff --git a/src/app/classes/index.ts b/src/app/classes/index.ts new file mode 100644 index 00000000..59bc03cf --- /dev/null +++ b/src/app/classes/index.ts @@ -0,0 +1,22 @@ +import { Account } from "./account"; +import { Address } from "./address"; +import { Input } from "./input"; +import { Transaction } from "./transaction"; +import { WalletStatus, EncryptionStatus } from './walletStatus'; +import { StakingStatus } from './stakingStatus'; +import { MasternodeStatus } from './masternodeStatus'; +import { Peer } from './peer'; +import { AddressBookItem } from './addressBookItem'; + +export { + Account, + Address, + AddressBookItem, + Input, + MasternodeStatus, + Peer, + StakingStatus, + Transaction, + WalletStatus, + EncryptionStatus +} \ No newline at end of file diff --git a/src/app/classes/input.ts b/src/app/classes/input.ts new file mode 100644 index 00000000..981fdae1 --- /dev/null +++ b/src/app/classes/input.ts @@ -0,0 +1,39 @@ + +import Big from 'big.js'; +import { Address } from './address'; + +export class Input { + account: string; + address: string; + amount: Big; + confirmations: number; + scriptPubKey: string; + txid: string; + vout: number; + blockTime: Date; + matureTime: Date; + locked: boolean; + + selected: boolean = false; + + constructor(rawData: any, address: Address, matureTime: number) { + this.account = address.account; + this.address = address.address; + this.amount = Big(rawData.amount); + this.confirmations = rawData.confirmations; + this.scriptPubKey = rawData.scriptPubKey; + this.txid = rawData.txid; + this.vout = rawData.vout; + this.locked = rawData.locked; + if (rawData.blockTime) { + let time = Number(rawData.blockTime); + this.blockTime = new Date(time * 1000); + this.matureTime = new Date((time + matureTime * 60 * 60) * 1000); + } + } + + sync(newInput: Input) { + this.confirmations = newInput.confirmations; + this.locked = newInput.locked; + } +} diff --git a/src/app/classes/masternodeStatus.ts b/src/app/classes/masternodeStatus.ts new file mode 100644 index 00000000..3de8d375 --- /dev/null +++ b/src/app/classes/masternodeStatus.ts @@ -0,0 +1,37 @@ +export class MasternodeStatus { + setup: boolean = false; + running: boolean = false; + started: boolean = false; + activeseconds: number = 0; + address: string = ''; + lastTimeSeen: number = 0; + pubkey: string = ''; + status: number = 0; + + list: Array = new Array(); + config: Array = new Array(); +} + +export interface masternode { + activeseconds: number; + address: string; + allowFreeTx: boolean + enabled: boolean; + lastDseep: number; + lastTimeSeen: number; + minProtoVersion: number; + nLastDsq: number; + protocolVersion: number; + pubkey: string; + rank: number; + vin: string; + status?; +} + +export interface masternodeConfig { + address: string; + alias: string; + outputIndex: number; + privateKey: string; + txHash: string; +} \ No newline at end of file diff --git a/src/app/classes/peer.ts b/src/app/classes/peer.ts new file mode 100644 index 00000000..998da282 --- /dev/null +++ b/src/app/classes/peer.ts @@ -0,0 +1,18 @@ +export interface Peer { + addr: string + addrlocal: string + banscore: number; + bytesrecv: number; + bytessent: number; + conntime: number; + inbound: boolean; + lastrecv: number; + lastsend: number; + pingtime: number; + services: string + startingheight: number; + subver: string; + syncnode: boolean; + version: number; +} + diff --git a/src/app/classes/stakingStatus.ts b/src/app/classes/stakingStatus.ts new file mode 100644 index 00000000..e0192294 --- /dev/null +++ b/src/app/classes/stakingStatus.ts @@ -0,0 +1,8 @@ +export class StakingStatus { + expectedTime: number = 0; + expectedType: string = ''; + weight: number = 0; + netStakeWeight: number = 0; + enabled: boolean = false; + staking: boolean = false; +} \ No newline at end of file diff --git a/src/app/classes/transaction.ts b/src/app/classes/transaction.ts new file mode 100644 index 00000000..749b1e5a --- /dev/null +++ b/src/app/classes/transaction.ts @@ -0,0 +1,33 @@ +import Big from 'big.js'; + +export class Transaction { + account: string; + address: string; + category: string; + amount: Big; + confirmations: number; + blockHash: string; + blockIndex: number; + blockTime: Date; + txId: string; + timestamp: Date; + fee: number; + + constructor(transactionData?) { + if (transactionData) { + this.account = transactionData.account; + this.address = transactionData.address; + this.category = transactionData.category; + this.amount = Big(transactionData.amount); + this.confirmations = transactionData.confirmations; + this.blockHash = transactionData.blockHash; + this.blockIndex = transactionData.blockIndex; + if (transactionData.blockTime) this.blockTime = new Date(transactionData.blockTime * 1000); + this.txId = transactionData.txId; + this.timestamp = new Date(transactionData.timestamp * 1000); + this.fee = transactionData.fee; + } + } + +} + diff --git a/src/app/classes/walletStatus.ts b/src/app/classes/walletStatus.ts new file mode 100644 index 00000000..2ca1cbbc --- /dev/null +++ b/src/app/classes/walletStatus.ts @@ -0,0 +1,20 @@ +export class WalletStatus { + connections: number = 0; + version: string = ""; + unlocked_until: number = 0; + encryption_status: string = EncryptionStatus.UNENCRYPTED; + protocolversion: string = ''; + walletversion: string = ''; + errors: string = ''; + latestBlockHeight: number = 0; + latestBlockTime: number = 0; +} + +export enum EncryptionStatus { + UNENCRYPTED = 'Unencrypted', + LOCKED = 'Locked', + ENCRYPTING = "Encrypting", + LOCKEDFORSTAKING = "LockedForStaking", + UNLOCKEDANONYMONLY = "UnlockedForAnonymizationOnly", + UNLOCKED = "Unlocked" +} \ No newline at end of file diff --git a/src/app/components/address-book/address-book.component.html b/src/app/components/address-book/address-book.component.html new file mode 100644 index 00000000..1bb0a9bc --- /dev/null +++ b/src/app/components/address-book/address-book.component.html @@ -0,0 +1,102 @@ + +

{{ 'COMPONENTS.ADDRESSBOOK.TITLE' | translate }}

+ + +
+ + +
+ + +
+

{{ 'COMPONENTS.ADDRESSBOOK.SENDINGINFO' | translate }}

+ + + + + + + + + + + + + + + + + + + + + + + +
{{ 'COMPONENTS.ADDRESSBOOK.TABLECOLUMNS_LABEL' | translate }}{{ 'COMPONENTS.ADDRESSBOOK.TABLECOLUMNS_ADDRESS' | translate }}
{{address.account}}{{address.address}} + + + +
+
+ +
+
+
+ +
+
+ +
+
+ + +
+

{{ 'COMPONENTS.ADDRESSBOOK.RECEIVINGINFO' | translate }}

+ + + + + + + + + + + + + + + + +
{{ 'COMPONENTS.ADDRESSBOOK.TABLECOLUMNS_LABEL' | translate }}{{ 'COMPONENTS.ADDRESSBOOK.TABLECOLUMNS_ADDRESS' | translate }}
{{account.name}}{{account.address}} + + +
+
+ + + +
\ No newline at end of file diff --git a/src/app/components/address-book/address-book.component.spec.ts b/src/app/components/address-book/address-book.component.spec.ts new file mode 100644 index 00000000..ce451f0d --- /dev/null +++ b/src/app/components/address-book/address-book.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AddressBookComponent } from './address-book.component'; + +describe('AddressBookComponent', () => { + let component: AddressBookComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AddressBookComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AddressBookComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/address-book/address-book.component.ts b/src/app/components/address-book/address-book.component.ts new file mode 100644 index 00000000..d782b1be --- /dev/null +++ b/src/app/components/address-book/address-book.component.ts @@ -0,0 +1,92 @@ +import { Component } from '@angular/core'; +import { WalletService } from '../../providers/wallet.service'; +import { NgxSmartModalService } from 'ngx-smart-modal'; +import { NotificationService } from '../../providers/notification.service'; +import { ElectronService } from '../../providers/electron.service'; +import { AddressBookService } from './address-book.service'; +import { ErrorService } from '../../providers/error.service'; + +@Component({ + selector: 'address-book', + templateUrl: './address-book.component.html', +}) +export class AddressBookComponent { + + promiseResolve; + + showSending; + + tab = 0; + + newAddress = "" + newLabel = "" + + constructor( + private wallet: WalletService, + private notification: NotificationService, + private ngxModal: NgxSmartModalService, + private addressBook: AddressBookService, + private electron: ElectronService, + private errorService: ErrorService + ) { + addressBook.getAddress = (showSending) => this.getAddress(showSending); + } + + show() { + this.tab = 0 + this.reset(); + this.ngxModal.getModal('addressBookModal').open(); + } + + hide() { + this.ngxModal.getModal('addressBookModal').close(); + } + + async addAddress() { + if (!this.newAddress || !this.newLabel) return this.notification.notify('error', 'NOTIFICATIONS.EMPTYFIELDS'); + try { + await this.wallet.addressBookAdd(this.newAddress, this.newLabel); + this.newAddress = ""; + this.newLabel = ""; + } catch (ex) { + this.errorService.diagnose(ex); + } + } + + async copyAddress(address) { + this.electron.clipboard.writeText(address.address); + this.notification.notify('success', 'NOTIFICATIONS.ADDRESSCOPIEDCLIPBOARD'); + } + + deleteAddress(address) { + try { + this.wallet.addressBookRemove(address.address); + } catch (ex) { + this.errorService.diagnose(ex); + } + } + + reset() { + this.newAddress = ""; + this.newLabel = ""; + } + + cancel() { + this.hide(); + this.promiseResolve("") + } + + selectAddress(address) { + this.hide(); + this.promiseResolve({ address: address.address, label: address.name }) + } + + async getAddress(showSending = true) { + return new Promise((resolve, reject) => { + this.showSending = showSending; + this.show(); + this.promiseResolve = resolve; + }) + } + +} diff --git a/src/app/components/address-book/address-book.service.ts b/src/app/components/address-book/address-book.service.ts new file mode 100644 index 00000000..48f211ba --- /dev/null +++ b/src/app/components/address-book/address-book.service.ts @@ -0,0 +1,15 @@ +import { Injectable, isDevMode, Output, EventEmitter } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import Big from 'big.js'; + +@Injectable() +export class AddressBookService { + + public getAddress; + + constructor() { + + } +} + + diff --git a/src/app/components/client-status/client-status.component.html b/src/app/components/client-status/client-status.component.html new file mode 100644 index 00000000..c037d35a --- /dev/null +++ b/src/app/components/client-status/client-status.component.html @@ -0,0 +1,11 @@ +
+
+
+
+

+ {{ getRPCStatus() | translate }} +

+

+ {{ rpc.RPCWarmupMessage }} +

+
\ No newline at end of file diff --git a/src/app/components/client-status/client-status.component.spec.ts b/src/app/components/client-status/client-status.component.spec.ts new file mode 100644 index 00000000..853b732e --- /dev/null +++ b/src/app/components/client-status/client-status.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ClientStatusComponent } from './client-status.component'; + +describe('ClientStatusComponent', () => { + let component: ClientStatusComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ClientStatusComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ClientStatusComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/client-status/client-status.component.ts b/src/app/components/client-status/client-status.component.ts new file mode 100644 index 00000000..6995304c --- /dev/null +++ b/src/app/components/client-status/client-status.component.ts @@ -0,0 +1,41 @@ +import { Component } from '@angular/core'; +import { RpcService } from '../../providers/rpc.service'; +import { ClientStatus } from '../../providers/electron.service'; + +@Component({ + selector: 'client-status', + templateUrl: './client-status.component.html' +}) +export class ClientStatusComponent { + + constructor( + public rpc: RpcService, + ) { + + } + + showStatusIndicator() { + return !this.rpc.RPCReady || (this.rpc.clientStatus !== ClientStatus.RUNNING && this.rpc.clientStatus !== ClientStatus.RUNNINGEXTERNAL) + } + + getRPCStatus() { + let translation = 'CLIENTSTATUS.INITIALISING'; + switch (this.rpc.clientStatus) { + case ClientStatus.DOWNLOADCLIENT: + translation = 'CLIENTSTATUS.DOWNLOADCLIENT'; + break; + case ClientStatus.UPDATEAVAILABLE: + translation = 'CLIENTSTATUS.UPDATEAVAILABLE'; + break; + case ClientStatus.SHUTTINGDOWN: + translation = 'CLIENTSTATUS.SHUTTINGDOWN'; + break; + case ClientStatus.RESTARTING: + translation = 'CLIENTSTATUS.RESTARTING'; + break; + } + return translation + } + + +} diff --git a/src/app/components/context-menu/context-menu.component.html b/src/app/components/context-menu/context-menu.component.html new file mode 100644 index 00000000..88e9ff91 --- /dev/null +++ b/src/app/components/context-menu/context-menu.component.html @@ -0,0 +1,7 @@ +
+ +
\ No newline at end of file diff --git a/src/app/components/context-menu/context-menu.component.spec.ts b/src/app/components/context-menu/context-menu.component.spec.ts new file mode 100644 index 00000000..9343e130 --- /dev/null +++ b/src/app/components/context-menu/context-menu.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ContextMenuComponent } from './context-menu.component'; + +describe('ContextMenuComponent', () => { + let component: ContextMenuComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ContextMenuComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ContextMenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/context-menu/context-menu.component.ts b/src/app/components/context-menu/context-menu.component.ts new file mode 100644 index 00000000..82d41b66 --- /dev/null +++ b/src/app/components/context-menu/context-menu.component.ts @@ -0,0 +1,39 @@ +import { Component, ViewChild, ElementRef } from '@angular/core'; +import { ContextMenuService } from './context-menu.service'; + +@Component({ + selector: 'context-menu', + templateUrl: './context-menu.component.html', + host: { + '(document:click)': 'documentClick($event)', + }, +}) +export class ContextMenuComponent { + + @ViewChild('contextMenu') contextMenu: ElementRef; + + menuActive = false; + position = { left: '0px', top: '0px' }; + menuItems = []; + + constructor( + public contextMenuService: ContextMenuService + ) { + contextMenuService.showContextMenu = (event) => { + this.menuActive = true; + let left = event.x; + if (left + 200 > window.innerWidth) left = window.innerWidth - 200; + this.position.left = left + "px"; + this.position.top = event.y + "px"; + + } + contextMenuService.hideContextMenu = () => { + this.menuActive = false; + } + } + + documentClick(event) { + this.menuActive = false + } + +} diff --git a/src/app/components/context-menu/context-menu.service.ts b/src/app/components/context-menu/context-menu.service.ts new file mode 100644 index 00000000..2338a1d6 --- /dev/null +++ b/src/app/components/context-menu/context-menu.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class ContextMenuService { + + public menuItems = []; + public showContextMenu + public hideContextMenu; + + constructor( + ) { + } + + public show(event, menuItems) { + this.menuItems = menuItems; + this.showContextMenu(event) + } + + public hide() { + this.menuItems = []; + this.hideContextMenu() + } + +} + + diff --git a/src/app/components/prompt/prompt.component.html b/src/app/components/prompt/prompt.component.html new file mode 100644 index 00000000..51edc5a0 --- /dev/null +++ b/src/app/components/prompt/prompt.component.html @@ -0,0 +1,117 @@ + + +
+

{{ 'COMPONENTS.PROMPT.ENTERPASSPHRASETITLE' | translate }}

+ + +
+ + +
+ + +
+
+ + + +

{{ 'COMPONENTS.PROMPT.CLIENTUPDATETITLE' | translate }}

+ {{ 'COMPONENTS.PROMPT.CLIENTUPDATEINFO' | translate }} + +
+ + + +

{{ 'COMPONENTS.PROMPT.WALLETUPDATETITLE' | translate }}

+ {{ 'COMPONENTS.PROMPT.WALLETUPDATEINFO' | translate }} + +
+ + + +
+

{{ 'COMPONENTS.PROMPT.CHANGEPASSPHRASETITLE' | translate }}

+ + + + + + +
+
+ + + +
+

{{ 'COMPONENTS.PROMPT.ENCRYPTTITLE' | translate }}

+ + + + + +
+
+ + + +

{{ alertModal.title | translate }}

+ +

{{ alertModal.content | translate }}

+ + +
\ No newline at end of file diff --git a/src/app/components/prompt/prompt.component.spec.ts b/src/app/components/prompt/prompt.component.spec.ts new file mode 100644 index 00000000..383657f6 --- /dev/null +++ b/src/app/components/prompt/prompt.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PromptComponent } from './prompt.component'; + +describe('PromptComponent', () => { + let component: PromptComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PromptComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PromptComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/prompt/prompt.component.ts b/src/app/components/prompt/prompt.component.ts new file mode 100644 index 00000000..70dc937c --- /dev/null +++ b/src/app/components/prompt/prompt.component.ts @@ -0,0 +1,195 @@ +import { Component, ViewChild, ElementRef } from '@angular/core'; +import { NgxSmartModalService } from 'ngx-smart-modal'; +import { PromptService } from './prompt.service'; + +@Component({ + selector: 'prompt-container', + templateUrl: './prompt.component.html' +}) +export class PromptComponent { + + @ViewChild("passphrase") passphraseField: ElementRef; + + passphraseModal = { + passphrase: "", + showStakingOnly: false, + stakingOnly: false, + resolve: null, + reject: null, + hide: () => this.ngxModal.getModal('passphraseModal').close(), + reset: () => { + this.passphraseModal.passphrase = ""; + this.passphraseModal.showStakingOnly = false; + this.passphraseModal.stakingOnly = false; + }, + show: (showStakingOnly = false) => { + this.passphraseModal.reset(); + this.passphraseModal.showStakingOnly = showStakingOnly; + this.passphraseModal.stakingOnly = showStakingOnly; + this.ngxModal.getModal('passphraseModal').open(); + setTimeout(() => this.passphraseField.nativeElement.focus(), 300); + return new Promise((resolve, reject) => { + this.passphraseModal.resolve = resolve; + this.passphraseModal.reject = reject; + }) + }, + buttonDone: () => { + this.passphraseModal.hide(); + if (!this.passphraseModal.passphrase) this.passphraseModal.reject(); + else this.passphraseModal.resolve([this.passphraseModal.passphrase, this.passphraseModal.stakingOnly]); + }, + buttonCancel: () => { + this.passphraseModal.hide(); + this.passphraseModal.reject(); + } + } + + clientUpdateModal = { + resolve: null, + reject: null, + showSkip: true, + hide: () => this.ngxModal.getModal('clientUpdateModal').close(), + show: (showSkip = true) => { + this.clientUpdateModal.showSkip = showSkip; + this.ngxModal.getModal('clientUpdateModal').open(); + return new Promise((resolve, reject) => { + this.clientUpdateModal.resolve = resolve; + this.clientUpdateModal.reject = reject; + }) + }, + buttonDone: () => { + this.clientUpdateModal.hide(); + this.clientUpdateModal.resolve(); + }, + buttonCancel: (skip) => { + this.clientUpdateModal.hide(); + this.clientUpdateModal.reject(skip); + } + } + + walletUpdateModal = { + resolve: null, + reject: null, + showSkip: true, + hide: () => this.ngxModal.getModal('walletUpdateModal').close(), + show: (showSkip = true) => { + this.walletUpdateModal.showSkip = showSkip; + this.ngxModal.getModal('walletUpdateModal').open(); + return new Promise((resolve, reject) => { + this.walletUpdateModal.resolve = resolve; + this.walletUpdateModal.reject = reject; + }) + }, + buttonDone: () => { + this.walletUpdateModal.hide(); + this.walletUpdateModal.resolve(); + }, + buttonCancel: (skip) => { + this.walletUpdateModal.hide(); + this.walletUpdateModal.reject(skip); + } + } + + changePassphraseModal = { + currentPassphrase: "", + newPassphrase: "", + confPassphrase: "", + resolve: null, + reject: null, + hide: () => this.ngxModal.getModal('changePassphraseModal').close(), + reset: () => { + this.changePassphraseModal.currentPassphrase = ""; + this.changePassphraseModal.newPassphrase = ""; + this.changePassphraseModal.confPassphrase = ""; + }, + show: () => { + this.changePassphraseModal.reset(); + this.ngxModal.getModal('changePassphraseModal').open(); + return new Promise((resolve, reject) => { + this.changePassphraseModal.resolve = resolve; + this.changePassphraseModal.reject = reject; + }) + }, + buttonDone: () => { + this.changePassphraseModal.hide(); + this.changePassphraseModal.resolve([this.changePassphraseModal.currentPassphrase, this.changePassphraseModal.newPassphrase, this.changePassphraseModal.confPassphrase]); + }, + buttonCancel: () => { + this.changePassphraseModal.hide(); + this.changePassphraseModal.reject(); + } + } + + encryptModal = { + newPassphrase: "", + confPassphrase: "", + resolve: null, + reject: null, + hide: () => this.ngxModal.getModal('encryptModal').close(), + reset: () => { + this.encryptModal.newPassphrase = ""; + this.encryptModal.confPassphrase = ""; + }, + show: () => { + this.encryptModal.reset(); + this.ngxModal.getModal('encryptModal').open(); + return new Promise((resolve, reject) => { + this.encryptModal.resolve = resolve; + this.encryptModal.reject = reject; + }) + }, + buttonDone: () => { + this.encryptModal.hide(); + this.encryptModal.resolve([this.encryptModal.newPassphrase, this.encryptModal.confPassphrase]); + }, + buttonCancel: () => { + this.encryptModal.hide(); + this.encryptModal.reject(); + } + } + + alertModal = { + resolve: null, + reject: null, + title: '', + content: '', + doneButtonContent: '', + cancelButtonContent: '', + hide: () => this.ngxModal.getModal('alertModal').close(), + show: (title, content, doneButtonContent, cancelButtonContent) => { + this.alertModal.title = title; + this.alertModal.content = content; + this.alertModal.doneButtonContent = doneButtonContent; + this.alertModal.cancelButtonContent = cancelButtonContent; + this.ngxModal.getModal('alertModal').open(); + return new Promise((resolve, reject) => { + this.alertModal.resolve = resolve; + this.alertModal.reject = reject; + }) + }, + buttonDone: () => { + this.alertModal.hide(); + this.alertModal.resolve(); + }, + buttonCancel: () => { + this.alertModal.hide(); + this.alertModal.reject(); + } + } + + constructor( + private prompt: PromptService, + private ngxModal: NgxSmartModalService + ) { + prompt.getPassphrase = this.passphraseModal.show; + prompt.promptUpdateClient = this.clientUpdateModal.show; + prompt.promptUpdateWallet = this.walletUpdateModal.show; + prompt.changePassphrase = this.changePassphraseModal.show; + prompt.encrypt = this.encryptModal.show; + prompt.alert = this.alertModal.show; + } + + + + +} diff --git a/src/app/components/prompt/prompt.service.ts b/src/app/components/prompt/prompt.service.ts new file mode 100644 index 00000000..b50188ae --- /dev/null +++ b/src/app/components/prompt/prompt.service.ts @@ -0,0 +1,60 @@ +import { Injectable } from '@angular/core'; +import { ElectronService, ClientStatus } from '../../providers/electron.service'; +import { NotificationService } from '../../providers/notification.service'; + +@Injectable() +export class PromptService { + + public getPassphrase; + public promptUpdateClient; + public promptUpdateWallet; + public changePassphrase; + public encrypt; + public alert; + + constructor( + private electron: ElectronService, + private notification: NotificationService, + ) { + if (electron.isElectron()) this.setupListeners() + } + + setupListeners() { + this.electron.clientStatusEvent.subscribe((status: ClientStatus) => { + if (status === ClientStatus.UPDATEAVAILABLE) this.notifyUpdateAvailable(); + }); + this.electron.checkUpdateEvent.subscribe((data: any) => { + if (data.type === 'core') this.notifyCheckCoreUpdateAvailable(data.hasUpdate); + if (data.type === 'wallet') this.notifyCheckWalletAvailable(data.version, data.showSkip); + }); + } + + async notifyUpdateAvailable() { + try { + await this.promptUpdateClient(); + this.electron.ipcRenderer.send('client-node', 'UPDATE'); + } catch (skip) { + this.electron.ipcRenderer.send('client-node', 'NOUPDATE', skip); + } + } + + async notifyCheckCoreUpdateAvailable(hasUpdate) { + if (!hasUpdate) return this.notification.notify('default', 'NOTIFICATIONS.NOUPDATE'); + try { + await this.promptUpdateClient(false); + this.electron.ipcRenderer.send('client-node', 'APPLYUPDATE'); + } catch (skip) { } + } + + async notifyCheckWalletAvailable(version: string, showSkip: boolean) { + try { + await this.promptUpdateWallet(showSkip); + this.electron.shell.openExternal('https://github.com/TheLindaProjectInc/Altitude/releases/latest'); + } catch (skip) { + if (skip) this.electron.ipcRenderer.send('settings', 'SETSKIPWALLETUPDATE', version); + } + } + +} + + diff --git a/src/app/components/side-bar/side-bar.component.html b/src/app/components/side-bar/side-bar.component.html new file mode 100644 index 00000000..b1bbe98e --- /dev/null +++ b/src/app/components/side-bar/side-bar.component.html @@ -0,0 +1,48 @@ + \ No newline at end of file diff --git a/src/app/components/side-bar/side-bar.component.spec.ts b/src/app/components/side-bar/side-bar.component.spec.ts new file mode 100644 index 00000000..fd6c49eb --- /dev/null +++ b/src/app/components/side-bar/side-bar.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SideBarComponent } from './side-bar.component'; + +describe('SideBarComponent', () => { + let component: SideBarComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SideBarComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SideBarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/side-bar/side-bar.component.ts b/src/app/components/side-bar/side-bar.component.ts new file mode 100644 index 00000000..c12252c4 --- /dev/null +++ b/src/app/components/side-bar/side-bar.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; + +import { WalletService } from '../../providers/wallet.service'; +import Helpers from '../../helpers'; + +@Component({ + selector: 'side-bar', + templateUrl: './side-bar.component.html', +}) + +export class SideBarComponent { + + public helpers = Helpers; + + constructor( + public wallet: WalletService, + ) { + + } + +} diff --git a/src/app/components/sync-status/sync-status.component.html b/src/app/components/sync-status/sync-status.component.html new file mode 100644 index 00000000..6959248a --- /dev/null +++ b/src/app/components/sync-status/sync-status.component.html @@ -0,0 +1,41 @@ +
+ + + {{ 'COMPONENTS.SIDEBAR.SYNC.CONNECTING' | translate }}... + + {{ 'COMPONENTS.SIDEBAR.SYNC.NOPEERS' | translate }}... + + {{wallet.walletStatus.connections}} + {{'COMPONENTS.SIDEBAR.SYNC.PEERS' | translate }} + + + + + {{ 'COMPONENTS.SIDEBAR.SYNC.CONNECTING' | translate }}... + + {{ 'COMPONENTS.SIDEBAR.SYNC.NOBLOCKS' | translate }}... + + + {{helpers.prettyCoins(wallet.walletStatus.latestBlockHeight)}} {{ 'COMPONENTS.SIDEBAR.SYNC.BLOCKS' | + translate }} + + + + + {{ 'COMPONENTS.SIDEBAR.SYNC.CONNECTING' | translate }}... + + {{ 'COMPONENTS.SIDEBAR.SYNC.NOBLOCKS' | translate }}... + + + {{ helpers.friendlyTimeEplased(wallet.walletStatus.latestBlockTime,dateNow)[0] }} + {{ helpers.friendlyTimeEplased(wallet.walletStatus.latestBlockTime,dateNow)[1] | translate }} + {{ 'COMPONENTS.SIDEBAR.SYNC.TIMESINCEBLOCK' | translate }} + + +
+
+ + + +
\ No newline at end of file diff --git a/src/app/components/sync-status/sync-status.component.spec.ts b/src/app/components/sync-status/sync-status.component.spec.ts new file mode 100644 index 00000000..3dea8098 --- /dev/null +++ b/src/app/components/sync-status/sync-status.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SyncStatusComponent } from './sync-status.component'; + +describe('SyncStatusComponent', () => { + let component: SyncStatusComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SyncStatusComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SyncStatusComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/sync-status/sync-status.component.ts b/src/app/components/sync-status/sync-status.component.ts new file mode 100644 index 00000000..f5db91e8 --- /dev/null +++ b/src/app/components/sync-status/sync-status.component.ts @@ -0,0 +1,89 @@ +import { Component, ChangeDetectorRef } from '@angular/core'; + +import { RpcService } from '../../providers/rpc.service'; +import { WalletService } from '../../providers/wallet.service'; +import Helpers from '../../helpers'; +import { EncryptionStatus } from '../../classes'; + +@Component({ + selector: 'sync-status', + templateUrl: './sync-status.component.html', +}) + +export class SyncStatusComponent { + + public helpers = Helpers; + public dateNow; + + constructor( + public rpc: RpcService, + public wallet: WalletService, + private cdRef: ChangeDetectorRef + ) { + + } + + ngAfterViewChecked() { + this.dateNow = new Date(); + this.cdRef.detectChanges(); + } + + get lockStatus() { + let iconClass = 'danger'; + let title = 'COMPONENTS.SIDEBAR.STATUS.UNENCRYPTED'; + let iconName = 'lock-open'; + + switch (this.wallet.walletStatus.encryption_status) { + case EncryptionStatus.LOCKED: + case EncryptionStatus.ENCRYPTING: + iconClass = 'success'; + title = 'COMPONENTS.SIDEBAR.STATUS.LOCKED'; + iconName = 'lock'; + break; + case EncryptionStatus.LOCKEDFORSTAKING: + iconClass = 'success'; + title = 'COMPONENTS.SIDEBAR.STATUS.UNLOCKEDSTAKING'; + iconName = 'unlock'; + break; + case EncryptionStatus.UNLOCKEDANONYMONLY: + iconClass = 'success'; + title = 'COMPONENTS.SIDEBAR.STATUS.UNLOCKEDANON'; + iconName = 'unlock'; + break; + case EncryptionStatus.UNLOCKED: + iconClass = 'danger'; + title = 'COMPONENTS.SIDEBAR.STATUS.UNLOCKED'; + iconName = 'unlock'; + break; + } + + return { + class: iconClass, + title: title, + icon: iconName + } + } + + get stakingStatus() { + let flag = this.wallet.stakingStatus.staking; + let iconClass = flag ? 'success' : 'danger'; + let title = flag ? 'COMPONENTS.SIDEBAR.STATUS.STAKING' : 'COMPONENTS.SIDEBAR.STATUS.NOTSTAKING'; + return { + class: iconClass, + title: title, + icon: 'coins' + } + } + + get masternodeStatus() { + let flag = this.wallet.masternode.running; + let iconClass = flag ? 'success' : 'danger'; + let title = flag ? 'COMPONENTS.SIDEBAR.STATUS.MASTERNODEON' : 'COMPONENTS.SIDEBAR.STATUS.MASTERNODEOFF' + return { + class: iconClass, + title: title, + icon: 'network-wired' + } + } + +} diff --git a/src/app/components/titlebar/titlebar.component.html b/src/app/components/titlebar/titlebar.component.html new file mode 100644 index 00000000..2a4d7789 --- /dev/null +++ b/src/app/components/titlebar/titlebar.component.html @@ -0,0 +1,76 @@ +
+ + + + +
+ +
+
+
+ + +
+
+ + + + + + +
+
+ + + +
+
+
\ No newline at end of file diff --git a/src/app/components/titlebar/titlebar.component.spec.ts b/src/app/components/titlebar/titlebar.component.spec.ts new file mode 100644 index 00000000..ef3196f0 --- /dev/null +++ b/src/app/components/titlebar/titlebar.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TitlebarComponent } from './titlebar.component'; + +describe('TitlebarComponent', () => { + let component: TitlebarComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TitlebarComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TitlebarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/titlebar/titlebar.component.ts b/src/app/components/titlebar/titlebar.component.ts new file mode 100644 index 00000000..b1558236 --- /dev/null +++ b/src/app/components/titlebar/titlebar.component.ts @@ -0,0 +1,362 @@ +import { Component, isDevMode } from '@angular/core'; +import { WalletService, DATASYNCTYPES } from '../../providers/wallet.service'; +import { Router } from '@angular/router'; +import { PromptService } from '../prompt/prompt.service'; +import { ElectronService } from '../../providers/electron.service'; +import { ErrorService } from '../../providers/error.service'; +import { RpcService } from '../../providers/rpc.service'; +import { NotificationService } from '../../providers/notification.service'; +import { TranslationService } from '../../providers/translation.service'; +import { EncryptionStatus } from '../../classes'; + +@Component({ + selector: 'title-bar', + templateUrl: './titlebar.component.html', + host: { + '(document:click)': 'documentClick($event)', + }, +}) +export class TitlebarComponent { + + menuActive = false; + menuHoverIndex = -1 + appWindow = this.electron.remote.getCurrentWindow(); + showWindowsMenu: boolean = false; + subEncryption; + subLanguage; + public EncryptionStatus = EncryptionStatus; + + constructor( + private prompt: PromptService, + private electron: ElectronService, + private rpc: RpcService, + public wallet: WalletService, + private router: Router, + private notification: NotificationService, + private errorService: ErrorService, + private translation: TranslationService + ) { + + } + + ngOnInit() { + if (this.electron.isElectron()) { + // if we are on windows use our angular menu + // otherwise build the menu natively and link + // actions through IPC + this.showWindowsMenu = window.process.platform === 'win32'; + if (!this.showWindowsMenu) { + this.connectMenu(); + this.buildMenu(); + } + } + } + + ngOnDestroy() { + if (this.subEncryption) this.subEncryption.unsubscribe(); + if (this.subLanguage) this.subLanguage.unsubscribe(); + } + + getMenus() { + let encryptionItems = []; + if (this.wallet.walletStatus.encryption_status === EncryptionStatus.UNENCRYPTED) + encryptionItems.push('MENU.ENCRYPT.ENCRYPT') + if (this.wallet.walletStatus.encryption_status !== EncryptionStatus.UNENCRYPTED) + encryptionItems.push('MENU.ENCRYPT.CHANGEPASS') + if (this.wallet.canUnlock()) + encryptionItems.push('MENU.ENCRYPT.UNLOCK') + if (this.wallet.canLock()) + encryptionItems.push('MENU.ENCRYPT.LOCK') + + const menus = [ + { + label: 'MENU.FILE.TITLE', + items: [ + 'MENU.FILE.BACKUPWALLET', + 'MENU.FILE.SIGNMESSAGE', + 'MENU.FILE.VERIFYMESSAGE', + 'SEPERATOR', + 'MENU.FILE.LOCALE', + 'SEPERATOR', + 'MENU.FILE.RESTARTCORE', + 'SEPERATOR', + 'MENU.FILE.EXIT', + ] + }, + { + label: 'MENU.ENCRYPT.TITLE', + items: encryptionItems + }, + { + label: 'MENU.TOOLS.TITLE', + items: [ + 'MENU.TOOLS.INFORMATION', + 'MENU.TOOLS.DEBUGCONSOLE', + 'MENU.TOOLS.PEERSLIST', + 'MENU.TOOLS.WALLETREPAIR', + ] + }, + { + label: 'MENU.HELP.TITLE', + items: [ + 'MENU.HELP.CHECKUPDATECORE', + 'MENU.HELP.CHECKUPDATEWALLET', + 'SEPERATOR', + 'MENU.HELP.ISSUE', + 'MENU.HELP.DISCORD', + 'SEPERATOR', + 'MENU.HELP.ABOUTCORE', + 'MENU.HELP.ABOUTALTITUDE' + ] + }, + ]; + + return menus; + } + + get isMaximized() { + if (this.appWindow.isMaximized()) return false; + return true; + } + + async buildMenu() { + if (isDevMode()) console.log("Rebuild menu"); + + let appMenu = new this.electron.remote.Menu(); + + const menus = this.getMenus(); + + for (let i = 0; i < menus.length; i++) { + let menu = menus[i]; + // create submenu + let submenu = []; + for (let j = 0; j < menu.items.length; j++) { + const item = menu.items[j]; + if (item === 'SEPERATOR') submenu.push({ type: 'separator' }) + else submenu.push({ + label: await this.translation.translate(item), + click(menuItem, currentWindow) { currentWindow.webContents.send(item) } + }) + } + // create menu item + const label = await this.translation.translate(menu.label) + const menuItem = new this.electron.remote.MenuItem({ + label: label, + role: 'window', + submenu: submenu + }) + appMenu.append(menuItem); + } + + this.electron.remote.Menu.setApplicationMenu(appMenu) + } + + connectMenu() { + // listen for encryption and language changes to redraw + this.subEncryption = this.wallet.encryptionStatusChanges.subscribe(() => { + this.buildMenu(); + }); + this.subLanguage = this.electron.languageChangedEvent.subscribe(() => { + this.buildMenu(); + }); + // connect IPC + this.electron.ipcRenderer.on('MENU.FILE.BACKUPWALLET', () => this.backupWallet()); + this.electron.ipcRenderer.on('MENU.FILE.SIGNMESSAGE', () => this.goToSignMessage()); + this.electron.ipcRenderer.on('MENU.FILE.VERIFYMESSAGE', () => this.goToVerifyMessage()); + this.electron.ipcRenderer.on('MENU.FILE.LOCALE', () => this.goToLocale()); + this.electron.ipcRenderer.on('MENU.FILE.RESTARTCORE', () => this.restartCore()); + this.electron.ipcRenderer.on('MENU.FILE.EXIT', () => this.close()); + + this.electron.ipcRenderer.on('MENU.ENCRYPT.ENCRYPT', () => this.encryptWallet()); + this.electron.ipcRenderer.on('MENU.ENCRYPT.CHANGEPASS', () => this.changePassphrase()); + this.electron.ipcRenderer.on('MENU.ENCRYPT.UNLOCK', () => this.unlockWallet()); + this.electron.ipcRenderer.on('MENU.ENCRYPT.LOCK', () => this.lockWallet()); + + this.electron.ipcRenderer.on('MENU.TOOLS.INFORMATION', () => this.goToInformation()); + this.electron.ipcRenderer.on('MENU.TOOLS.DEBUGCONSOLE', () => this.goToDebugConsole()); + this.electron.ipcRenderer.on('MENU.TOOLS.PEERSLIST', () => this.goToPeersList()); + this.electron.ipcRenderer.on('MENU.TOOLS.WALLETREPAIR', () => this.goToWalletRepair()); + + this.electron.ipcRenderer.on('MENU.HELP.CHECKUPDATECORE', () => this.checkUpdateCore()); + this.electron.ipcRenderer.on('MENU.HELP.CHECKUPDATEWALLET', () => this.checkUpdateWallet()); + this.electron.ipcRenderer.on('MENU.HELP.ABOUTCORE', () => this.goToAboutCore()); + this.electron.ipcRenderer.on('MENU.HELP.ABOUTALTITUDE', () => this.goToAboutAltitude()); + this.electron.ipcRenderer.on('MENU.HELP.DISCORD', () => this.openDiscord()); + this.electron.ipcRenderer.on('MENU.HELP.ISSUE', () => this.openIssues()); + } + + documentClick(event) { + if (event.target.className === "dropbtn") this.menuActive = !this.menuActive; + else this.menuActive = false; + } + + async backupWallet() { + const options = { + filters: [ + { name: 'Wallet Data', extensions: ['dat'] } + ] + } + this.electron.remote.dialog.showSaveDialog(options, async (filename, bookmark) => { + if (filename) { + this.notification.loading('NOTIFICATIONS.WALLETBACKINGUP'); + try { + await this.wallet.backupWallet(filename); + this.notification.notify('success', 'NOTIFICATIONS.WALLETBACKEDUP'); + } catch (ex) { + this.notification.dismissNotifications(); + this.errorService.diagnose(ex); + } + } + }); + } + + goToSignMessage() { + this.router.navigate(['/signmessage/0']); + } + + goToVerifyMessage() { + this.router.navigate(['/signmessage/1']); + } + + goToLocale() { + this.router.navigate(['/locale']); + } + + async encryptWallet() { + try { + const [nPass, confPass] = await this.prompt.encrypt(); + if (!nPass || !confPass) return this.notification.notify('error', 'NOTIFICATIONS.EMPTYFIELDS'); + if (nPass !== confPass) return this.notification.notify('error', 'NOTIFICATIONS.PASSPHRASEMISMATCH'); + + this.notification.loading('NOTIFICATIONS.WALLETENCRYPTING'); + + try { + await this.wallet.encryptWallet(nPass); + this.prompt.alert('COMPONENTS.PROMPT.ENCRYPTEDTITLE', 'COMPONENTS.PROMPT.ENCRYPTEDCONTENT', 'MISC.OKBUTTON'); + this.rpc.restartClient(); + } catch (ex) { + this.errorService.diagnose(ex); + } + this.notification.dismissNotifications() + + } catch (ex) { + // closed prompt + } + } + + async unlockWallet() { + try { + const [passphrase, stakingOnly] = await this.prompt.getPassphrase(true); + + try { + await this.wallet.unlock(passphrase, stakingOnly); + this.wallet.requestDataSync(DATASYNCTYPES.WALLET) + } catch (ex) { + this.errorService.diagnose(ex); + } + + } catch (ex) { + // closed prompt + } + } + + lockWallet() { + this.wallet.lockWallet(); + } + + async changePassphrase() { + try { + const [cPass, nPass, confPass] = await this.prompt.changePassphrase(); + if (!nPass || !cPass || !confPass) return this.notification.notify('error', 'NOTIFICATIONS.EMPTYFIELDS'); + if (nPass !== confPass) return this.notification.notify('error', 'NOTIFICATIONS.PASSPHRASEMISMATCH'); + + this.notification.loading('NOTIFICATIONS.CHANGINGPASSPHARASE'); + try { + await this.wallet.changePassphrase(cPass, nPass); + this.prompt.alert('COMPONENTS.PROMPT.ENCRYPTEDTITLE', 'COMPONENTS.PROMPT.ENCRYPTEDCONTENT', 'MISC.OKBUTTON'); + } catch (ex) { + this.errorService.diagnose(ex); + } + this.notification.dismissNotifications() + + } catch (ex) { + // closed prompt + } + } + + goToInformation() { + this.router.navigate(['/tools/0']); + } + + goToDebugConsole() { + this.router.navigate(['/tools/1']); + } + + goToPeersList() { + this.router.navigate(['/tools/2']); + } + + goToWalletRepair() { + this.router.navigate(['/tools/3']); + } + + goToAboutCore() { + this.router.navigate(['/about/0']); + } + + goToAboutAltitude() { + this.router.navigate(['/about/1']); + } + + openDiscord() { + this.electron.shell.openExternal('https://discord.gg/SHNjQBv'); + } + + openIssues() { + this.electron.shell.openExternal('https://github.com/TheLindaProjectInc/Altitude/issues'); + } + + checkUpdateCore() { + this.notification.notify('default', 'NOTIFICATIONS.CHECKINGUPDATE'); + this.electron.ipcRenderer.send('client-node', 'CHECKUPDATE'); + } + + async checkUpdateWallet() { + this.notification.loading('NOTIFICATIONS.CHECKINGUPDATE'); + try { + await this.electron.checkForWalletUpdate(false); + } catch (ex) { + this.notification.notify('error', 'NOTIFICATIONS.CHECKINGUPDATEFAILED'); + } + this.notification.dismissNotifications() + } + + restartCore() { + this.wallet.stopSyncService(); + this.rpc.restartClient(); + } + + minimize() { + this.appWindow.minimize(); + } + + resize() { + if (this.appWindow.isMaximized()) { + this.appWindow.unmaximize(); + this.appWindow.setSize(800, 600); + this.electron.ipcRenderer.send('settings', 'SETFULLSCREEN', true); + } else { + this.appWindow.maximize(); + this.electron.ipcRenderer.send('settings', 'SETFULLSCREEN', true); + } + } + + close() { + this.wallet.stopSyncService(); + this.electron.remote.app.quit() + } + + + + +} diff --git a/src/app/helpers.ts b/src/app/helpers.ts new file mode 100644 index 00000000..ba8f5d7f --- /dev/null +++ b/src/app/helpers.ts @@ -0,0 +1,123 @@ +import Big from 'big.js'; + +export default class Helpers { + + public static toSatoshi(amount: number | Big) { + try { + return (amount as Big).times(100000000); + } catch (ex) { + return Math.round(amount as number * 100000000); + } + } + + public static fromSatoshi(amount: number | Big) { + try { + return (amount as Big).div(100000000); + } catch (ex) { + return Math.round(amount as number / 100000000); + } + } + + public static roundCoins(coins: Big, decimals: number = 8): Big { + const parts = coins.toString().split("."); + if (parts.length === 2) { + const dec = Number("0." + parts[1]); + const len = parts[1].length; + if (len > decimals) { + const decString = dec.toFixed(decimals).toString().split(".")[1]; + return Big(parts[0] + '.' + decString); + } + } + return coins; + } + + public static prettyCoins(coins: Big, decimals?: number) { + if (coins) { + coins = this.roundCoins(coins, decimals); + let parts = coins.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); + if (parts.length > 1) return parts.join("."); + return parts[0]; + } + return 0; + } + + + public static getFee(numInputs: number, numOutputs: number, baseFee: number): number { + const totalBytes = this.getBytes(numInputs, numOutputs); + const feeMultiplier = Math.ceil(totalBytes / 1000); + return Math.round(baseFee * feeMultiplier * 1000) / 1000; + } + + public static getBytes(numInputs: number, numOutputs: number): number { + const baseSize = 44; + const outputSize = 34; + const inputSize = 148; + const inputBytes = inputSize * numInputs; + const outputBytes = numOutputs * outputSize; + return baseSize + inputBytes + outputBytes; + } + + public static formatTimeEplased(amount, now = new Date()) { + let s = Math.round(now.getTime() / 1000) - amount; + // check seconds + if (s < 60) return s + 's'; + // check minutes + let m = Math.floor(s / 60); + s = s - m * 60; + if (m < 60) return m + 'm ' + s + 's'; + // check hours + let h = Math.floor(m / 60); + m = m - h * 60; + return h + 'h ' + m + 'm ' + s + 's'; + } + + public static formatTime(s) { + // check seconds + if (s < 60) return s + 's'; + // check minutes + let m = Math.floor(s / 60); + s = s - m * 60; + if (m < 60) return m + 'm ' + s + 's'; + // check hours + let h = Math.floor(m / 60); + m = m - h * 60; + if (h < 24) return h + 'h ' + m + 'm ' + s + 's'; + let d = Math.floor(h / 24); + h = h - d * 24; + return d + 'd ' + h + 'h ' + m + 'm ' + s + 's'; + } + + public static friendlyTimeEplased(amount, now = new Date()) { + const seconds = Math.round(now.getTime() / 1000) - Math.round(amount / 1000); + const minutes = seconds / 60; + const hours = minutes / 60; + const days = hours / 24; + const months = days / 30.416; + const years = days / 365; + + if (seconds <= 45) + return [null, 'TIME.AFEWSECONDS']; + else if (seconds <= 90) + return [null, 'TIME.AMINUTE']; + else if (minutes <= 50) + return [Math.round(minutes), 'TIME.MINUTES']; + else if (hours <= 1.5) + return [null, 'TIME.ANHOUR']; + else if (hours <= 22) + return [Math.round(hours), 'TIME.HOURS']; + else if (hours <= 36) + return [null, 'TIME.ADAY']; + else if (days <= 25) + return [Math.round(days), 'TIME.DAYS']; + else if (months <= 1.5) + return [null, 'TIME.AMONTH']; + else if (months <= 11.5) + return [Math.round(months), 'TIME.MONTHS']; + else if (years <= 1.5) + return [null, 'TIME.AYEAR']; + else + return [Math.round(years), 'TIME.YEARS']; + } + +} diff --git a/src/app/icon-module.ts b/src/app/icon-module.ts new file mode 100644 index 00000000..7e2d9126 --- /dev/null +++ b/src/app/icon-module.ts @@ -0,0 +1,82 @@ + +import { library } from '@fortawesome/fontawesome-svg-core'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { + faReceipt, + faWallet, + faNetworkWired, + faColumns, + faWifi, + faClock, + faLayerGroup, + faLock, + faUnlock, + faSignInAlt, + faSignOutAlt, + faPiggyBank, + faExchangeAlt, + faCopy, + faTimes, + faPlus, + faCode, + faCoins, + faDatabase, + faCheckCircle, + faTimesCircle, + faLockOpen, + faAddressBook, + faArrowLeft, + faArrowRight, + faTrash, + faSave, + faHandPointer, + faToggleOff, + faToggleOn, + faArrowDown, + faArrowUp, + faSpinner, + faExclamationCircle, + faLink +} from '@fortawesome/free-solid-svg-icons'; + + +export function setupIcons() { + // only add used icons to avoid bloat + library.add( + faWallet, + faReceipt, + faNetworkWired, + faColumns, + faWifi, + faClock, + faLayerGroup, + faLock, + faUnlock, + faSignInAlt, + faSignOutAlt, + faPiggyBank, + faExchangeAlt, + faCopy, + faTimes, + faPlus, + faCode, + faCoins, + faDatabase, + faCheckCircle, + faTimesCircle, + faLockOpen, + faAddressBook, + faArrowLeft, + faArrowRight, + faTrash, + faSave, + faHandPointer, + faToggleOff, + faToggleOn, + faArrowDown, + faArrowUp, + faSpinner, + faExclamationCircle, + faLink + ); +} \ No newline at end of file diff --git a/src/app/pages/about/about.component.html b/src/app/pages/about/about.component.html new file mode 100644 index 00000000..876cc53b --- /dev/null +++ b/src/app/pages/about/about.component.html @@ -0,0 +1,15 @@ +
+ +
+ + +
+ +

+

+ +
\ No newline at end of file diff --git a/src/app/pages/about/about.component.spec.ts b/src/app/pages/about/about.component.spec.ts new file mode 100644 index 00000000..dc074613 --- /dev/null +++ b/src/app/pages/about/about.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import {AboutComponent } from './about.component'; + +describe('AboutComponent', () => { + let component: AboutComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AboutComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AboutComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/about/about.component.ts b/src/app/pages/about/about.component.ts new file mode 100644 index 00000000..8f3d99f2 --- /dev/null +++ b/src/app/pages/about/about.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +@Component({ + selector: 'app-about', + templateUrl: './about.component.html' +}) +export class AboutComponent { + sub; + tab = 0; + + constructor( + private route: ActivatedRoute + ) { } + + ngOnInit() { + this.sub = this.route.params.subscribe(params => { + this.tab = Number(params['tab']); + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + +} diff --git a/src/app/pages/dashboard/dashboard.component.html b/src/app/pages/dashboard/dashboard.component.html new file mode 100644 index 00000000..a508d956 --- /dev/null +++ b/src/app/pages/dashboard/dashboard.component.html @@ -0,0 +1,81 @@ +
+ +
+

Alert

+ {{wallet.walletStatus.errors}} +
+ +

{{ 'PAGES.DASHBOARD.ACCOUNTS' | translate }}

+ + +
+ + +
+ +
+ +
+ +

{{ 'PAGES.DASHBOARD.TRANSACTIONS' | translate }}

+ +
+
+
+
+ + + + + + +
+
+
{{trx.category}}
+
{{trx.timestamp | date:'MMM d, h:mm a'}}
+
{{trx.account || trx.address}}
+
+
+
+ {{trx.category!='Payment To Self'&&trx.amount>0?'+':''}}{{helpers.prettyCoins(trx.amount)}} Linda +
+
{{ 'MISC.FEE' | translate }}: {{helpers.prettyCoins(trx.fee)}} + Linda
+
+
+
+ +
+ + + +

{{ 'PAGES.DASHBOARD.CREATEACCOUNTTITLE' | translate }}

+ + +
\ No newline at end of file diff --git a/src/app/pages/dashboard/dashboard.component.spec.ts b/src/app/pages/dashboard/dashboard.component.spec.ts new file mode 100644 index 00000000..9c996c37 --- /dev/null +++ b/src/app/pages/dashboard/dashboard.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DashboardComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/dashboard/dashboard.component.ts b/src/app/pages/dashboard/dashboard.component.ts new file mode 100644 index 00000000..9dc2cb39 --- /dev/null +++ b/src/app/pages/dashboard/dashboard.component.ts @@ -0,0 +1,73 @@ +import { Component } from '@angular/core'; +import { WalletService, DATASYNCTYPES } from '../../providers/wallet.service'; +import helpers from '../../helpers'; +import { Router } from '@angular/router'; +import { NgxSmartModalService } from 'ngx-smart-modal'; +import { ErrorService } from '../../providers/error.service'; +import { NotificationService } from '../../providers/notification.service'; +import { ElectronService } from '../../providers/electron.service'; +import { ContextMenuService } from '../../components/context-menu/context-menu.service'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html' +}) +export class DashboardComponent { + public helpers = helpers; + newAccountLabel = ''; + hideEmptyAccounts = true; + + constructor( + public wallet: WalletService, + private router: Router, + public ngxModal: NgxSmartModalService, + private notification: NotificationService, + private errorService: ErrorService, + private electron: ElectronService, + private contextMenu: ContextMenuService + ) { + } + + displayTransactions() { + let trx = []; + for (let i = 0; i <= 10; i++) { + if (this.wallet.transactions[i]) + trx.push(this.wallet.transactions[i]); + } + return trx; + } + + manageAccount(account) { + this.router.navigate(['/manage-account', account.address]); + } + + showNewAccountModal() { + this.newAccountLabel = ''; + this.ngxModal.getModal('addAccountModal').open() + } + + async createNewAccount() { + this.ngxModal.getModal('addAccountModal').close(); + try { + await this.wallet.getNewAddress(this.newAccountLabel); + await this.wallet.requestDataSync(DATASYNCTYPES.ACCOUNTS); + this.notification.notify('success', 'NOTIFICATIONS.CREATEDNEWACCOUNT'); + } catch (ex) { + this.errorService.diagnose(ex); + } + } + + onRightClick(e, trx) { + const items = [ + { + name: 'PAGES.TRANSACTIONS.COPYBLOCKHASH', + func: () => this.electron.clipboard.writeText(trx.blockHash) + }, + { + name: 'PAGES.TRANSACTIONS.COPYTXID', + func: () => this.electron.clipboard.writeText(trx.txId) + } + ] + this.contextMenu.show(e, items) + } +} diff --git a/src/app/pages/explorer/explorer.component.html b/src/app/pages/explorer/explorer.component.html new file mode 100644 index 00000000..03b954eb --- /dev/null +++ b/src/app/pages/explorer/explorer.component.html @@ -0,0 +1,176 @@ +
+ +

{{ 'PAGES.EXPLORER.TITLE' | translate }}

+ +
+
+ {{ 'MISC.SEARCH' | translate }} + +
+
+ +

+ {{ 'PAGES.EXPLORER.BLOCKTITLE' | translate }} #{{currentBlock.height}} +

+ +

+ {{ 'PAGES.EXPLORER.TRANSACTIONTITLE' | translate }} + {{currentTransaction.txid}} +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'PAGES.EXPLORER.TABLE_SUMMARY' | translate }}
{{ 'PAGES.EXPLORER.TABLE_HEIGHT' | translate }}{{currentBlock.height}}
{{ 'PAGES.EXPLORER.TABLE_HASH' | translate }}{{currentBlock.hash}}
{{ 'PAGES.EXPLORER.TABLE_PREVHASH' | translate }}
{{ 'PAGES.EXPLORER.TABLE_NEXTHEIGHT' | translate }}
{{ 'PAGES.EXPLORER.TABLE_FLAGS' | translate }}{{currentBlock.flags}}
{{ 'PAGES.EXPLORER.TABLE_TIME' | translate }}{{currentBlock.time*1000 | date:'MMM d yyyy, h:mm:ss a'}}
{{ 'PAGES.EXPLORER.TABLE_TRANSACTIONS' | translate }} + {{currentBlock.tx.length}} +
+ +
{{ 'PAGES.EXPLORER.TABLE_MINT' | translate }}{{helpers.prettyCoins(currentBlock.mint)}} Linda
{{ 'PAGES.EXPLORER.TABLE_VERSION' | translate }}{{currentBlock.version}}
{{ 'PAGES.EXPLORER.TABLE_SIZE' | translate }}{{currentBlock.size}}
{{ 'PAGES.EXPLORER.TABLE_BLOCKTRUST' | translate }}{{currentBlock.blocktrust}}
{{ 'PAGES.EXPLORER.TABLE_CHAINTRUST' | translate }}{{currentBlock.chaintrust}}
{{ 'PAGES.EXPLORER.TABLE_BITS' | translate }}{{currentBlock.bits}}
{{ 'PAGES.EXPLORER.TABLE_NONCE' | translate }}{{currentBlock.nonce}}
{{ 'PAGES.EXPLORER.TABLE_MERKLEROOT' | translate }}{{currentBlock.merkleroot}}
{{ 'PAGES.EXPLORER.TABLE_MODIFIER' | translate }}{{currentBlock.modifier}}
{{ 'PAGES.EXPLORER.TABLE_PROOFHASH' | translate }}{{currentBlock.proofhash}}
{{ 'PAGES.EXPLORER.TABLE_SIGNATURE' | translate }}{{currentBlock.signature}}
{{ 'PAGES.EXPLORER.TABLE_DIFFICULTY' | translate }}{{currentBlock.difficulty}}
{{ 'PAGES.EXPLORER.TABLE_ENTROPYBIT' | translate }}{{currentBlock.entropybit}}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'PAGES.EXPLORER.TABLE_SUMMARY' | translate }}
{{ 'PAGES.EXPLORER.TABLE_HASH' | translate }}{{currentTransaction.txid}}
{{ 'PAGES.EXPLORER.TABLE_BLOCKHASH' | translate }}
{{ 'PAGES.EXPLORER.TABLE_CONFIRMATIONS' | translate }}{{currentTransaction.confirmations}}
{{ 'PAGES.EXPLORER.TABLE_TIME' | translate }}{{currentTransaction.time*1000 | date:'MMM d yyyy, h:mm:ss a'}}
{{ 'PAGES.EXPLORER.TABLE_VERSION' | translate }}{{currentTransaction.version}}
+ + + + + + + + + + + + + + + +
{{ 'PAGES.EXPLORER.TABLE_INPUTOUTPUT' | translate }}
+
+ {{ 'PAGES.EXPLORER.COINBASE' | translate }} + {{ addr }} + {{helpers.prettyCoins(vin.value)}} Linda +
+
+ + +
+ {{ 'PAGES.EXPLORER.NONSTANDARD' | translate }} + {{ addr }} + {{helpers.prettyCoins(vout.value)}} Linda +
+
+ +
\ No newline at end of file diff --git a/src/app/pages/explorer/explorer.component.spec.ts b/src/app/pages/explorer/explorer.component.spec.ts new file mode 100644 index 00000000..add0087f --- /dev/null +++ b/src/app/pages/explorer/explorer.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ExplorerComponent } from './explorer.component'; + +describe('ExplorerComponent', () => { + let component: ExplorerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ExplorerComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ExplorerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/explorer/explorer.component.ts b/src/app/pages/explorer/explorer.component.ts new file mode 100644 index 00000000..d9f7351d --- /dev/null +++ b/src/app/pages/explorer/explorer.component.ts @@ -0,0 +1,109 @@ +import { Component } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { ElectronService } from '../../providers/electron.service'; +import { WalletService } from '../../providers/wallet.service'; +import { ErrorService } from '../../providers/error.service'; +import { NotificationService } from '../../providers/notification.service'; +import Helpers from '../../helpers'; + +@Component({ + selector: 'app-explorer', + templateUrl: './explorer.component.html' +}) +export class ExplorerComponent { + + searchInput = ''; + + currentBlock; + currentTransaction; + + public helpers = Helpers; + + constructor( + private notification: NotificationService, + private wallet: WalletService, + private errorService: ErrorService + ) { + + } + + ngOnInit() { + this.loadLatest() + } + + async loadLatest() { + if (this.wallet.walletStatus.latestBlockTime) { + this.loadBlock(this.wallet.walletStatus.latestBlockHeight); + } else { + setTimeout(() => this.loadLatest(), 1000); + } + } + + async loadBlock(blockHeight: number, blockHash: string = "") { + try { + this.currentBlock = blockHash ? await this.wallet.getBlock(blockHash) : await this.wallet.getBlockByNumber(blockHeight); + } catch (ex) { + this.errorService.diagnose(ex); + } + } + + async loadTransaction(txId: string) { + try { + this.currentTransaction = await this.wallet.getTransaction(txId); + this.currentBlock = null; + this.loadTransactionInputs(); + } catch (ex) { + this.errorService.diagnose(ex); + } + } + + async search() { + if (!isNaN(Number(this.searchInput))) { + // is a block height + try { + const result = await this.wallet.getBlockByNumber(Number(this.searchInput)); + this.currentBlock = result; + } catch (ex) { + this.errorService.diagnose(ex); + } + } else { + //is block hash or transaction hash + try { + const result = await this.wallet.getBlock(this.searchInput); + this.currentBlock = result; + } catch (ex) { + if (ex.error && ex.error.error && ex.error.error.code === -5) + this.searchForTransaction() + else + this.errorService.diagnose(ex); + } + } + } + + async searchForTransaction() { + try { + const result = await this.wallet.getTransaction(this.searchInput); + this.currentBlock = null; + this.currentTransaction = result; + this.loadTransactionInputs(); + } catch (ex) { + if (ex.error && ex.error.error && ex.error.error.code === -5) + this.notification.notify("error", "PAGES.EXPLORER.SEARCHNORESULTS"); + else + this.errorService.diagnose(ex); + } + } + + loadTransactionInputs() { + // lookup input addresses + this.currentTransaction.vin.forEach(vin => { + if (vin.txid) { + this.wallet.getTransaction(vin.txid).then(inputTransaction => { + vin.addresses = inputTransaction.vout[vin.vout].scriptPubKey.addresses; + vin.value = inputTransaction.vout[vin.vout].value; + }, err => { }); + } + }) + } + +} diff --git a/src/app/pages/locale/languages.ts b/src/app/pages/locale/languages.ts new file mode 100644 index 00000000..001798a8 --- /dev/null +++ b/src/app/pages/locale/languages.ts @@ -0,0 +1,418 @@ +module.exports = { + "Afrikaans": { + "code": "af", + "local": "Afrikaans" + }, + "Albanian": { + "code": "sq", + "local": "shqiptar" + }, + "Amharic": { + "code": "am", + "local": "አማርኛ" + }, + "Arabic": { + "code": "ar", + "local": "عربى" + }, + "Armenian": { + "code": "hy", + "local": "հայերեն" + }, + "Azerbaijani": { + "code": "az", + "local": "Azərbaycan" + }, + "Basque": { + "code": "eu", + "local": "Euskal" + }, + "Belarusian": { + "code": "be", + "local": "беларускі" + }, + "Bengali": { + "code": "bn", + "local": "বাঙালি" + }, + "Bosnian": { + "code": "bs", + "local": "Bosanski" + }, + "Bulgarian": { + "code": "bg", + "local": "български" + }, + "Catalan": { + "code": "ca", + "local": "Català" + }, + "Cebuano": { + "code": "ceb", + "local": "Cebuano" + }, + "Chinese (Simplified)": { + "code": "zh-CN", + "local": "简体中文)" + }, + "Chinese (Traditional)": { + "code": "zh-TW", + "local": "中國傳統的)" + }, + "Corsican": { + "code": "co", + "local": "Corsu" + }, + "Croatian": { + "code": "hr", + "local": "Hrvatski" + }, + "Czech": { + "code": "cs", + "local": "čeština" + }, + "Danish": { + "code": "da", + "local": "dansk" + }, + "Dutch": { + "code": "nl", + "local": "Nederlands" + }, + "English": { + "code": "en", + "local": "English" + }, + "Esperanto": { + "code": "eo", + "local": "Esperanto" + }, + "Estonian": { + "code": "et", + "local": "Eesti keel" + }, + "Finnish": { + "code": "fi", + "local": "Suomalainen" + }, + "French": { + "code": "fr", + "local": "français" + }, + "Frisian": { + "code": "fy", + "local": "Frysk" + }, + "Galician": { + "code": "gl", + "local": "Galego" + }, + "Georgian": { + "code": "ka", + "local": "ქართული" + }, + "German": { + "code": "de", + "local": "Deutsche" + }, + "Greek": { + "code": "el", + "local": "Ελληνικά" + }, + "Gujarati": { + "code": "gu", + "local": "ગુજરાતી" + }, + "Haitian Creole": { + "code": "ht", + "local": "Kreyòl Ayisyen" + }, + "Hausa": { + "code": "ha", + "local": "Hausa" + }, + "Hawaiian": { + "code": "haw", + "local": "Ōlelo Hawaiʻi" + }, + "Hebrew": { + "code": "he", + "local": "עברית" + }, + "Hindi": { + "code": "hi", + "local": "हिंदी" + }, + "Hmong": { + "code": "hmn", + "local": "Hmoob" + }, + "Hungarian": { + "code": "hu", + "local": "Magyar" + }, + "Icelandic": { + "code": "is", + "local": "Íslensku" + }, + "Igbo": { + "code": "ig", + "local": "Igbo" + }, + "Indonesian": { + "code": "id", + "local": "bahasa Indonesia" + }, + "Irish": { + "code": "ga", + "local": "Gaeilge" + }, + "Italian": { + "code": "it", + "local": "italiano" + }, + "Japanese": { + "code": "ja", + "local": "日本人" + }, + "Javanese": { + "code": "jw", + "local": "Wong Jawa" + }, + "Kannada": { + "code": "kn", + "local": "ಕನ್ನಡ" + }, + "Kazakh": { + "code": "kk", + "local": "Қазақша" + }, + "Khmer": { + "code": "km", + "local": "ភាសាខ្មែរ" + }, + "Korean": { + "code": "ko", + "local": "한국어" + }, + "Kurdish": { + "code": "ku", + "local": "Kurdî" + }, + "Kyrgyz": { + "code": "ky", + "local": "Кыргызча" + }, + "Lao": { + "code": "lo", + "local": "ລາວ" + }, + "Latin": { + "code": "la", + "local": "Latine" + }, + "Latvian": { + "code": "lv", + "local": "Latviešu" + }, + "Lithuanian": { + "code": "lt", + "local": "Lietuviškai" + }, + "Luxembourgish": { + "code": "lb", + "local": "Lëtzebuergesch" + }, + "Macedonian": { + "code": "mk", + "local": "Македонски" + }, + "Malagasy": { + "code": "mg", + "local": "Malagasy" + }, + "Malay": { + "code": "ms", + "local": "Melayu" + }, + "Malayalam": { + "code": "ml", + "local": "മലയാളം" + }, + "Maltese": { + "code": "mt", + "local": "Malti" + }, + "Maori": { + "code": "mi", + "local": "Maori" + }, + "Marathi": { + "code": "mr", + "local": "मराठी" + }, + "Mongolian": { + "code": "mn", + "local": "Монгол хэл" + }, + "Myanmar (Burmese)": { + "code": "my", + "local": "မြန်မာ (ဗမာ)" + }, + "Nepali": { + "code": "ne", + "local": "नेपाली" + }, + "Norwegian": { + "code": "no", + "local": "norsk" + }, + "Nyanja (Chichewa)": { + "code": "ny", + "local": "Nyanja (Chichewa)" + }, + "Pashto": { + "code": "ps", + "local": "پښتو" + }, + "Persian": { + "code": "fa", + "local": "فارسی" + }, + "Polish": { + "code": "pl", + "local": "Polskie" + }, + "Portuguese (Portugal, Brazil)": { + "code": "pt", + "local": "Português (Portugal, Brasil)" + }, + "Punjabi": { + "code": "pa", + "local": "ਪੰਜਾਬੀ" + }, + "Romanian": { + "code": "ro", + "local": "Română" + }, + "Russian": { + "code": "ru", + "local": "русский" + }, + "Samoan": { + "code": "sm", + "local": "Samoa" + }, + "Scots Gaelic": { + "code": "gd", + "local": "Gàidhlig na h-Alba" + }, + "Serbian": { + "code": "sr", + "local": "Српски" + }, + "Sesotho": { + "code": "st", + "local": "Sesotho" + }, + "Shona": { + "code": "sn", + "local": "Shona" + }, + "Sindhi": { + "code": "sd", + "local": "سنڌي" + }, + "Sinhala (Sinhalese)": { + "code": "si", + "local": "සිංහල (සිංහල)" + }, + "Slovak": { + "code": "sk", + "local": "slovenský" + }, + "Slovenian": { + "code": "sl", + "local": "Slovenščina" + }, + "Somali": { + "code": "so", + "local": "Somali" + }, + "Spanish": { + "code": "es", + "local": "Español" + }, + "Sundanese": { + "code": "su", + "local": "Sunda" + }, + "Swahili": { + "code": "sw", + "local": "Kiswahili" + }, + "Swedish": { + "code": "sv", + "local": "svenska" + }, + "Tagalog (Filipino)": { + "code": "tl", + "local": "Tagalog (Filipino)" + }, + "Tajik": { + "code": "tg", + "local": "Тоҷикӣ" + }, + "Tamil": { + "code": "ta", + "local": "தமிழ்" + }, + "Telugu": { + "code": "te", + "local": "తెలుగు" + }, + "Thai": { + "code": "th", + "local": "ไทย" + }, + "Turkish": { + "code": "tr", + "local": "Türk" + }, + "Ukrainian": { + "code": "uk", + "local": "Українська" + }, + "Urdu": { + "code": "ur", + "local": "اردو" + }, + "Uzbek": { + "code": "uz", + "local": "O'zbek" + }, + "Vietnamese": { + "code": "vi", + "local": "Tiếng Việt" + }, + "Welsh": { + "code": "cy", + "local": "Cymraeg" + }, + "Xhosa": { + "code": "xh", + "local": "isiXhosa" + }, + "Yiddish": { + "code": "yi", + "local": "ייִדיש" + }, + "Yoruba": { + "code": "yo", + "local": "Yorùbá" + }, + "Zulu": { + "code": "zu", + "local": "Zulu" + } +} \ No newline at end of file diff --git a/src/app/pages/locale/locale.component.html b/src/app/pages/locale/locale.component.html new file mode 100644 index 00000000..250aeff6 --- /dev/null +++ b/src/app/pages/locale/locale.component.html @@ -0,0 +1,14 @@ +
+ +

{{ 'PAGES.LOCALE.TITLE' | translate }}

+ +
+ {{ 'MISC.SEARCH' | translate }} + +
+ + + +
\ No newline at end of file diff --git a/src/app/pages/locale/locale.component.spec.ts b/src/app/pages/locale/locale.component.spec.ts new file mode 100644 index 00000000..c011eae3 --- /dev/null +++ b/src/app/pages/locale/locale.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LocaleComponent } from './locale.component'; + +describe('LocaleComponent', () => { + let component: LocaleComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [LocaleComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LocaleComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/locale/locale.component.ts b/src/app/pages/locale/locale.component.ts new file mode 100644 index 00000000..4a894663 --- /dev/null +++ b/src/app/pages/locale/locale.component.ts @@ -0,0 +1,49 @@ +import { Component } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { ElectronService } from '../../providers/electron.service'; +var supportedLanguages = require('./languages'); + +@Component({ + selector: 'app-locale', + templateUrl: './locale.component.html' +}) +export class LocaleComponent { + + languages = []; + search = ''; + + constructor( + private translate: TranslateService, + private electron: ElectronService + ) { + + } + + ngOnInit() { + Object.keys(supportedLanguages).forEach(key => { + this.languages.push({ local: supportedLanguages[key].local, code: supportedLanguages[key].code }); + }); + } + + filter() { + let languages = []; + const search = this.search.toLowerCase(); + Object.keys(supportedLanguages).forEach(key => { + const local = supportedLanguages[key].local; + if (!search || local.toLowerCase().indexOf(search) > -1 || key.toLowerCase().indexOf(search) > -1) + languages.push({ local: local, code: supportedLanguages[key].code }); + }); + this.languages = languages; + } + + get currentLanguage() { + return this.translate.getDefaultLang(); + } + + setLangauge(language) { + if (this.currentLanguage !== language.code) { + this.electron.ipcRenderer.send('settings', 'SETLOCALE', language.code); + } + } + +} diff --git a/src/app/pages/manage-account/manage-account.component.html b/src/app/pages/manage-account/manage-account.component.html new file mode 100644 index 00000000..6fe4079d --- /dev/null +++ b/src/app/pages/manage-account/manage-account.component.html @@ -0,0 +1,34 @@ +
+ + + + + +
+
+
+ +
\ No newline at end of file diff --git a/src/app/pages/manage-account/manage-account.component.spec.ts b/src/app/pages/manage-account/manage-account.component.spec.ts new file mode 100644 index 00000000..8880e17d --- /dev/null +++ b/src/app/pages/manage-account/manage-account.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ManageAccountComponent } from './manage-account.component'; + +describe('ManageAddressComponent', () => { + let component: ManageAccountComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ManageAccountComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ManageAccountComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/manage-account/manage-account.component.ts b/src/app/pages/manage-account/manage-account.component.ts new file mode 100644 index 00000000..eee6194d --- /dev/null +++ b/src/app/pages/manage-account/manage-account.component.ts @@ -0,0 +1,85 @@ +import { Component } from '@angular/core'; +import { WalletService } from '../../providers/wallet.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import helpers from '../../helpers'; +import { ElectronService } from '../../providers/electron.service'; +import { ErrorService } from '../../providers/error.service'; +import { NotificationService } from '../../providers/notification.service'; + +declare let QRCode: any; + +@Component({ + selector: 'app-manage-account', + templateUrl: './manage-account.component.html', +}) + +export class ManageAccountComponent { + account; + sub; + public helpers = helpers; + + constructor( + private router: Router, + public wallet: WalletService, + private route: ActivatedRoute, + private electron: ElectronService, + private notification: NotificationService, + private errorService: ErrorService + ) { + + } + + ngOnInit() { + this.sub = this.route.params.subscribe(params => { + const address = params['address']; + for (let i = 0; i < this.wallet.accounts.length; i++) { + if (this.wallet.accounts[i].address === address) { + this.account = this.wallet.accounts[i]; + break; + } + } + if (!this.account) this.router.navigate(['/dashboard']); + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + ngAfterViewInit() { + this.showQrCode(); + } + + async copyAddress() { + if (this.account) { + this.electron.clipboard.writeText(this.account.address); + this.notification.notify('success', 'NOTIFICATIONS.ADDRESSCOPIEDCLIPBOARD'); + } + } + + renameAccount() { + if (this.account) { + try { + this.wallet.updateAddressAccount(this.account.mainAddress); + } catch (ex) { + this.errorService.diagnose(ex); + } + } + } + + showQrCode() { + if (document.getElementById('qrcode') && this.account) { + new QRCode("qrcode", { + text: this.account.address, + width: 128, + height: 128, + colorDark: "#000000", + colorLight: "#ffffff", + }); + } else { + setTimeout(() => this.showQrCode(), 500); + } + } + + +} diff --git a/src/app/pages/masternodes/masternodes.component.html b/src/app/pages/masternodes/masternodes.component.html new file mode 100644 index 00000000..3b78acc0 --- /dev/null +++ b/src/app/pages/masternodes/masternodes.component.html @@ -0,0 +1,136 @@ +
+ +
+ + +
+ +
+ +
{{ 'PAGES.MASTERNODES.NOTENABLEDTITLE' | translate }}
+

{{ 'PAGES.MASTERNODES.NOTENABLEDINSTR' | translate }}

+ + +
+
+
+ + +
+
+
{{mn.pubkey}}
+
{{mn.address}}
+
{{ 'PAGES.MASTERNODES.PROTOCOL' | translate }}: {{mn.protocolVersion}}
+
+
+
{{ 'PAGES.MASTERNODES.LASTSEEN' | translate }}: + {{helpers.formatTimeEplased(mn.lastTimeSeen,dateNow)}} + {{ + 'MISC.AGO' | + translate }}
+
{{ 'PAGES.MASTERNODES.ACTIVETIME' | translate }}: {{helpers.formatTime(mn.activeseconds,dateNow)}}
+
+
+
+
+ +
+
+
{{mn.address}}
+
+
+
{{ 'PAGES.MASTERNODES.LASTSEEN' | translate }}: N/A
+
{{ 'PAGES.MASTERNODES.ACTIVETIME' | translate }}: N/A
+
+
+
+ +
+ + +
+ +
+ + +
+
+ + + + + + + + + +
+

{{'MISC.SORTBY' | translate}}

+
+ + + + + + +
+

{{'MISC.SEARCH' | translate}}

+
+ +
+
+ + +
+
+ + +
+
+
{{mn.pubkey}}
+
{{mn.address}}
+
{{ 'PAGES.MASTERNODES.PROTOCOL' | translate }}: {{mn.protocolVersion}}
+
+
+
{{ 'PAGES.MASTERNODES.LASTSEEN' | translate }}: + {{helpers.formatTimeEplased(mn.lastTimeSeen,dateNow)}} + {{ + 'MISC.AGO' | + translate }}
+
{{ 'PAGES.MASTERNODES.ACTIVETIME' | translate }}: {{helpers.formatTime(mn.activeseconds,dateNow)}}
+
+
+
+ +
+ +
\ No newline at end of file diff --git a/src/app/pages/masternodes/masternodes.component.spec.ts b/src/app/pages/masternodes/masternodes.component.spec.ts new file mode 100644 index 00000000..bcf38349 --- /dev/null +++ b/src/app/pages/masternodes/masternodes.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MasternodesComponent } from './masternodes.component'; + +describe('MasternodesComponent', () => { + let component: MasternodesComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MasternodesComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MasternodesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/masternodes/masternodes.component.ts b/src/app/pages/masternodes/masternodes.component.ts new file mode 100644 index 00000000..79016470 --- /dev/null +++ b/src/app/pages/masternodes/masternodes.component.ts @@ -0,0 +1,181 @@ +import { Component, ChangeDetectorRef } from '@angular/core'; +import { WalletService } from '../../providers/wallet.service'; +import Helpers from '../../helpers'; +import { PromptService } from '../../components/prompt/prompt.service'; +import { NotifierService } from 'angular-notifier'; +import { ContextMenuService } from '../../components/context-menu/context-menu.service'; +import { ErrorService } from '../../providers/error.service'; +import { NotificationService } from '../../providers/notification.service'; + +@Component({ + selector: 'app-masternodes', + templateUrl: './masternodes.component.html' +}) +export class MasternodesComponent { + // make helpers accessible for html + helpers = Helpers; + // sport masternode list + desc = false; + sortField; + // filter masternode list + searchFilter = ''; + // filtered masternode list + items; + // my online masternode list + items_me; + // my offline masternode list + items_me_off; + // subscribe to masternode changes from wallet to update list + sub; + // which tab to show + tab = 0; + // cache now to avoid angular 'update has changed' errors when showing time eplased + dateNow; + + constructor( + public wallet: WalletService, + private cdRef: ChangeDetectorRef, + private prompt: PromptService, + private notifier: NotifierService, + private notification: NotificationService, + private contextMenu: ContextMenuService, + private errorService: ErrorService + ) { } + + ngAfterViewChecked() { + this.dateNow = new Date(); + this.cdRef.detectChanges(); + } + + ngOnInit() { + this.items = this.wallet.masternode.list; + this.getMyList(); + + this.sub = this.wallet.masternodeListUpdated.subscribe(() => { + this.items = this.wallet.masternode.list; + this.checkSort(); + this.filter(); + this.getMyList(); + }); + } + + getMyList() { + let items = []; + let itemsOffline = []; + let ipList = []; + // get ips for all masternodes in my masternode.conf file + this.wallet.masternode.config.forEach(mn => ipList.push(mn.address)) + this.wallet.masternode.list.forEach(mn => { + // check if i'm running a masternode. will have the 'status' field + if (mn.status !== undefined) items.push(mn); + else if (ipList.indexOf(mn.address) > -1) { // or check if it is in my masternode.conf file + ipList.splice(ipList.indexOf(mn.address), 1); + // add alias to masternode for context menu + for (let i = 0; i < this.wallet.masternode.config.length; i++) { + const mnConf = this.wallet.masternode.config[i]; + if (mnConf.address === mn.address) { + mn['alias'] = mnConf.alias + } + } + items.push(mn) + } + }) + this.wallet.masternode.config.forEach(mn => { + if (ipList.indexOf(mn.address) > -1) { + itemsOffline.push(mn); + } + }) + + this.items_me = items; + this.items_me_off = itemsOffline; + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + sort(field) { + this.sortField = field; + this.desc = !this.desc; + this.checkSort(); + } + + filter() { + let items = []; + this.searchFilter = this.searchFilter.toLowerCase(); + for (let i = 0; i < this.wallet.masternode.list.length; i++) { + const item = this.wallet.masternode.list[i]; + if ( + !this.searchFilter || + item.pubkey.toLowerCase().indexOf(this.searchFilter) > -1 || + item.address.toLowerCase().indexOf(this.searchFilter) > -1 || + item.protocolVersion.toString().indexOf(this.searchFilter) > -1 + ) + items.push(item); + } + this.items = items; + this.checkSort(); + } + + checkSort() { + if (this.sortField && this.items.length) { + this.items = [].concat(this.items).sort((a, b) => { + if (a[this.sortField] > b[this.sortField]) { + return !this.desc ? 1 : -1; + } else if (a[this.sortField] < b[this.sortField]) { + return this.desc ? 1 : -1; + } else { + return 0; + } + }) + } + } + + onRightClick(e, masternode) { + if (masternode.alias) { + const items = [{ + name: 'PAGES.MASTERNODES.STARTALIASBUTTON', + func: () => this.startAlias(masternode.alias) + }] + this.contextMenu.show(e, items) + } + } + + start() { + this.sendStart("start"); + } + + startAlias(alias: string) { + this.sendStart("start-alias", [alias]); + } + + startAll() { + this.sendStart("start-many"); + } + + async sendStart(cmd, params = []) { + try { + if (this.wallet.requireUnlock()) { + const [passphrase, stakingOnly] = await this.prompt.getPassphrase(); + params.push(passphrase); + } + + this.notification.loading('NOTIFICATIONS.STARTINGMASTERNODE'); + try { + const res = await this.wallet.masternodeCMD(cmd, params); + if (res.result === "failed") return this.notification.notify('error', res.errorMessage, false); + if (res.overall) return this.notification.notify('default', res.overall, false); + if (res.result === "successful") return this.notification.notify('success', res.alias + ' ' + res.result, false); + this.notification.notify('default', res, false); + } catch (ex) { + this.errorService.diagnose(ex); + } + this.notification.dismissNotifications() + + } catch (ex) { + // passphrase prompt closed + } + } + + +} diff --git a/src/app/pages/send/send.component.html b/src/app/pages/send/send.component.html new file mode 100644 index 00000000..7a393a91 --- /dev/null +++ b/src/app/pages/send/send.component.html @@ -0,0 +1,125 @@ +
+ +
+ +

{{ 'PAGES.SEND.COINCONTROL' | translate }}

+ +
+ + {{ 'PAGES.SEND.INPUTSAUTOMATIC' | translate }} + {{helpers.prettyCoins(getSelectedAmount())}} Linda +
+ +
+ + + +
+
+ +
+
+ +
+ {{ 'PAGES.SEND.PAYTO' | translate }} + + +
+
+ {{ 'PAGES.SEND.LABEL' | translate }} + +
+
+ {{ 'PAGES.SEND.AMOUNT' | translate }} + + +
+
+
+ + + +
+
+
{{ 'MISC.FEE' | translate }}: {{UI_fee}}
+
{{ 'PAGES.SEND.TOTAL' | translate }}: {{helpers.prettyCoins(UI_total)}}
+
+
+ + + + + +
+
+ + + +

{{ 'PAGES.SEND.SELECTINPUTSTITLE' | translate }}

+ +
+
+

{{ 'PAGES.SEND.SELECTED' | translate }}: {{helpers.prettyCoins(getSelectedAmount())}} Linda

+

{{ 'MISC.FEE' | translate }}: {{helpers.getFee(getSelectedQuantity(), recipients.length, wallet.fee)}}

+

{{ 'PAGES.SEND.AFTERFEE' | translate }}: {{helpers.prettyCoins(getSelectedAftFee())}} Linda

+
+
+

{{ 'PAGES.SEND.QUANTITY' | translate }}: {{getSelectedQuantity()}}

+

{{ 'PAGES.SEND.BYTES' | translate }}: {{helpers.getBytes(getSelectedQuantity(), recipients.length)}}

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
{{ 'PAGES.SEND.TABLECOLUMNS_AMOUNT' | translate }}{{ 'PAGES.SEND.TABLECOLUMNS_LABEL' | translate }}{{ 'PAGES.SEND.TABLECOLUMNS_ADDRESS' | translate }}{{ 'PAGES.SEND.TABLECOLUMNS_DATE' | translate }}{{ 'PAGES.SEND.TABLECOLUMNS_CONFIRMS' | translate }}
+ + + + {{inp.amount}}{{inp.account}}{{inp.address}}{{inp.blockTime | date:'MMM d, h:mm a'}}{{inp.confirmations}}
+
+ +
+ + + + +
\ No newline at end of file diff --git a/src/app/pages/send/send.component.spec.ts b/src/app/pages/send/send.component.spec.ts new file mode 100644 index 00000000..79eac9a6 --- /dev/null +++ b/src/app/pages/send/send.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SendComponent } from './send.component'; + +describe('SendComponent', () => { + let component: SendComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SendComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SendComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/send/send.component.ts b/src/app/pages/send/send.component.ts new file mode 100644 index 00000000..88edd1fe --- /dev/null +++ b/src/app/pages/send/send.component.ts @@ -0,0 +1,400 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { NgxSmartModalService } from 'ngx-smart-modal'; +import Big from 'big.js'; +import { WalletService, DATASYNCTYPES } from '../../providers/wallet.service'; +import Helpers from '../../helpers'; +import { NotifierService } from 'angular-notifier'; +import { PromptService } from '../../components/prompt/prompt.service'; +import { AddressBookService } from '../../components/address-book/address-book.service'; +import { ContextMenuService } from '../../components/context-menu/context-menu.service'; +import { ElectronService } from '../../providers/electron.service'; +import { ErrorService } from '../../providers/error.service'; +import { NotificationService } from '../../providers/notification.service'; +import { Input } from '../../classes'; + +@Component({ + selector: 'app-send', + templateUrl: './send.component.html', +}) +export class SendComponent implements OnInit, OnDestroy { + recipients = []; + changeAddress = ''; + enabledChangeAddress = false; + tableStyle = {}; + resizeTimeout; + tableInputs = []; + helpers = Helpers; + UI_selectedBalance = new Big(0); + UI_fee = 0; + UI_total = new Big(0); + + constructor( + private ngxModal: NgxSmartModalService, + public wallet: WalletService, + private notifier: NotifierService, + private prompt: PromptService, + private addressBook: AddressBookService, + private contextMenu: ContextMenuService, + public electron: ElectronService, + private errorService: ErrorService, + private notification: NotificationService, + ) { } + + ngOnInit(): void { + this.reset(); + window.addEventListener('resize', () => this.onResize()); + } + + ngOnDestroy(): void { + window.removeEventListener('resize', () => this.onResize()); + } + + onResize(): void { + if (!this.resizeTimeout) { + this.resizeTimeout = setTimeout(() => { + this.resizeTimeout = null + this.setTableDimensions(); + }, 200) + } + } + + setTableDimensions(): void { + const minHeight = 300; + let height = window.innerHeight / 2; + height = height > minHeight ? height : minHeight; + this.tableStyle = { + width: window.innerWidth - 28 * 2 - 16 * 2 + 'px', + height: height + 'px' + } + } + + toggleCoinControlFeatures(): void { + this.electron.ipcRenderer.send('settings', 'SETHIDECOINCONTROLFEATURES', !this.electron.settings.hideCoinControlFeatures); + } + + onRightClick(e, input: Input): void { + let items = []; + if (input.locked) { + items.push({ + name: 'PAGES.SEND.CONTEXTMENUUNLOCKINPUT', + func: () => this.lockUnspent(true, input) + }); + } else { + items.push({ + name: 'PAGES.SEND.CONTEXTMENULOCKINPUT', + func: () => this.lockUnspent(false, input) + }); + } + this.contextMenu.show(e, items) + } + + lockUnspent(unlock: boolean, input: Input): void { + try { + this.wallet.lockUnspent(unlock, input) + } catch (ex) { + this.errorService.diagnose(ex); + } + } + + getInputs(): Array { + let inputs = []; + this.wallet.accounts.forEach(acc => { + acc.addresses.forEach(addr => { + addr.spendableInputs().forEach(inp => { + inputs.push(inp) + }) + }) + }) + return inputs + } + + reset(): void { + this.recipients = [] + this.addRecipient(); + this.changeAddress = ''; + this.enabledChangeAddress = false; + this.getInputs().forEach(inp => inp.selected = false); + this.UI_selectedBalance = new Big(0); + this.UI_fee = 0; + this.UI_total = new Big(0); + } + + removeRecipient(index): void { + this.recipients.splice(index, 1); + } + + addRecipient(): void { + this.recipients.push({ + address: '', + amount: '', + label: '' + }); + } + + async getFromAddressBook(recp): Promise { + const addr = await this.addressBook.getAddress(); + if (addr) { + recp.address = addr.address; + recp.label = addr.label + } + } + + showSelectInputsModal(): void { + this.setTableDimensions(); + this.tableInputs = []; + this.wallet.accounts.forEach(acc => { + acc.addresses.forEach(addr => { + addr.allInputs().forEach(inp => { + this.tableInputs.push(inp) + }) + }) + }) + this.ngxModal.getModal('selectInputsModal').open() + } + + getSelectedAmount(): Big { + let amount = Big(0); + this.getInputs().forEach(inp => { + if (inp.selected) amount = amount.add(inp.amount) + }) + return amount; + } + + getSelectedAftFee(): Big { + return this.getSelectedAmount().sub(Helpers.getFee(this.getSelectedQuantity(), this.recipients.length, this.wallet.fee)) + } + + getSelectedQuantity(): number { + let selected = 0; + this.getInputs().forEach(inp => { + if (inp.selected) selected++ + }) + return selected; + } + + selectUnselectAll(): void { + const selected = this.getSelectedQuantity(); + const total = this.getInputs().length; + const spread = selected / total; + let select = true; + if (spread > 0.5) select = false + this.getInputs().forEach(inp => inp.selected = select) + } + + cancelSelectInputsModal(): void { + this.getInputs().forEach(inp => inp.selected = false) + this.ngxModal.getModal('selectInputsModal').close(); + } + + doneSelectInputsModal(): void { + this.ngxModal.getModal('selectInputsModal').close(); + this.UI_selectedBalance = this.getSelectedBalance(); + this.calculateOutput() + } + + calculateOutput(): void { + this.UI_fee = this.calculateFee(); + this.UI_total = this.getActualTotal(); + } + + useAvailable(recipient): void { + recipient.amount = 0; + recipient.amount = this.getSelectedBalance().sub(this.getExpectedTotal()); + recipient.amount = Big(recipient.amount).add(this.getBaseFee()).sub(this.calculateFee()); + this.calculateOutput(); + } + + getExpectedTotal(): Big { + let total = Big(this.getBaseFee()); + this.recipients.forEach(recipient => { + if (recipient.amount) total = total.add(recipient.amount); + }); + return Helpers.roundCoins(total); + } + + getActualTotal(): Big { + let total = Big(this.calculateFee()); + this.recipients.forEach(recipient => { + if (recipient.amount) total = total.add(recipient.amount); + }); + return Helpers.roundCoins(total); + } + + checkTransactionValid(): boolean { + if (this.getActualTotal().gt(this.getSelectedBalance())) { + this.notification.notify('error', 'NOTIFICATIONS.SENDINGEXCEEDSBALANCE'); + return false; + } + if (this.enabledChangeAddress && !this.changeAddress) { + this.notification.notify('error', 'NOTIFICATIONS.MISSINGCHANGEADDRESS'); + return false; + } + for (let i = 0; i < this.recipients.length; i++) { + if (!this.recipients[i].address) { + this.notification.notify('error', 'NOTIFICATIONS.MISSINGDESTINATIONADDRESS'); + return false; + } + if (!this.recipients[i].amount) { + this.notification.notify('error', 'NOTIFICATIONS.MISSINGAMOUNTTOSEND'); + return false; + } + } + return true; + } + + getBaseFee(): Big { + return Helpers.getFee(1, this.recipients.length, this.wallet.fee) + } + + calculateFee(): Big { + let total = Big(0); + this.recipients.forEach(recipient => { + if (recipient.amount) total = total.add(recipient.amount); + }); + if (total.gt(0)) { + const inputs = this.selectInputs(); + if (inputs.length) return Helpers.getFee(inputs.length, this.recipients.length, this.wallet.fee); + } + return this.getBaseFee() + } + + async send(): Promise { + if (!this.checkTransactionValid()) return; + let outputs = {}; + // get inputs + let inputs = this.selectInputs(); + + if (!inputs.length) + return this.notification.notify('error', 'NOTIFICATIONS.INSUFFICIENTBALANCE'); + + // get outputs + for (let i = 0; i < this.recipients.length; i++) { + outputs[this.recipients[i].address] = Number(this.recipients[i].amount); + } + // get fee + let fee = this.calculateFee(); + // get change address is any + let change = this.enabledChangeAddress ? this.changeAddress : null; + + try { + let passphrase, stakingOnly; + if (this.wallet.requireUnlock()) [passphrase, stakingOnly] = await this.prompt.getPassphrase(); + + this.notification.loading('NOTIFICATIONS.SENDINGTRANSACTION'); + try { + const res = await this.wallet.sendTransaction(inputs, outputs, fee, passphrase, change); + if (res.success) { + this.notification.notify('success', 'NOTIFICATIONS.TRANSACTIONSENT'); + // add and labeled addressed to address book + this.addRecipientsToAddressBook(); + // reset page + this.reset(); + } else { + this.notification.notify('error', res.message); + // load accounts + this.wallet.requestDataSync(DATASYNCTYPES.ACCOUNTS); + } + // load transactions + this.wallet.requestDataSync(DATASYNCTYPES.TRANSACTIONS); + } catch (ex) { + this.errorService.diagnose(ex); + } + this.notification.dismissNotifications(); + } catch (ex) { + // passphrase prompt closed + } + } + + addRecipientsToAddressBook() { + this.recipients.forEach(async recp => { + if (recp.label) { + // check we don't already have it + let alreadyHave = false; + for (let i = 0; i < this.wallet.accounts.length; i++) { + const acc = this.wallet.accounts[i]; + if (acc.address === recp.address && acc.name === recp.label) { + alreadyHave = true; + break; + } + } + if (!alreadyHave) { + try { + await this.wallet.addressBookAdd(recp.address, recp.label) + } catch (ex) { + // we don't care if this fails here + } + } + } + }) + } + + getInputOptions(): Array<{ txid: string, vout: number, balance: Big }> { + let utxos = []; + const manualSelect = this.getSelectedQuantity() > 0; + this.getInputs().forEach(inp => { + if (!manualSelect || inp.selected) + utxos.push({ + txid: inp.txid, + vout: inp.vout, + balance: inp.amount + }); + }) + return utxos; + } + + selectInputs(): Array<{ txid: string, vout: number }> { + const required = this.getExpectedTotal(); + const utxos = this.getInputOptions(); + + let selectedInputs = []; + + // check for exact match + for (let i = 0; i < utxos.length; i++) { + if ((utxos[i].balance.eq(required))) { + selectedInputs.push(utxos[i]); + break; + } + } + + if (!selectedInputs.length) { + for (let i = 0; i < 100; i++) { + let newCombination = []; + let tmpUtxos = utxos.slice(); + let tmpTotal = Big(0); + + while (tmpUtxos.length) { + let limit = tmpUtxos.length - 2; + if (limit < 0) limit = 0; + let index = tmpUtxos.length + while (index >= tmpUtxos.length) index = Math.round(Math.random() * limit); + tmpTotal = tmpTotal.add(tmpUtxos[index].balance); // update total + newCombination.push(tmpUtxos[index]); // add to combination + tmpUtxos.splice(index, 1); // remove from possible combinations + if (tmpTotal.gte(required) || !tmpUtxos.length) break; + } + + if (tmpTotal.eq(required)) { + selectedInputs = newCombination.slice(); + break; + } else if (tmpTotal.gt(required) && (!selectedInputs.length || newCombination.length < selectedInputs.length)) { + selectedInputs = newCombination.slice(); + } + } + } + + let inputs = []; + selectedInputs.forEach(input => { + inputs.push({ txid: input.txid, vout: input.vout }); + }) + + return inputs; + } + + getSelectedBalance(): Big { + let balance = new Big(0); + const inputs = this.getInputOptions(); + inputs.forEach(inp => balance = balance.add(inp.balance)); + return balance; + } + +} diff --git a/src/app/pages/signmessage/signmessage.component.html b/src/app/pages/signmessage/signmessage.component.html new file mode 100644 index 00000000..07dbd15e --- /dev/null +++ b/src/app/pages/signmessage/signmessage.component.html @@ -0,0 +1,77 @@ +
+ +
+ + +
+ + +
+

{{'PAGES.SIGNMESSAGE.SIGN_DESCRIPTION' | translate}}

+
+ + +
+ +
+ +
+ +

{{'PAGES.SIGNMESSAGE.SIGNATURE' | translate}}

+
+ +
+ +
+ + +
+ +
+ +
+

{{'PAGES.SIGNMESSAGE.VERIFY_DESCRIPTION' | translate}}

+
+ + +
+ +
+ +
+ +
+ +
+ +

+ {{ 'PAGES.SIGNMESSAGE.VERIFYSUCCESS' | translate }} +

+

+ {{ 'PAGES.SIGNMESSAGE.VERIFYFAIL' | translate }} +

+ +
+ + +
+ +
+ +
\ No newline at end of file diff --git a/src/app/pages/signmessage/signmessage.component.spec.ts b/src/app/pages/signmessage/signmessage.component.spec.ts new file mode 100644 index 00000000..c64f74dd --- /dev/null +++ b/src/app/pages/signmessage/signmessage.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SignMessageComponent } from './signmessage.component'; + +describe('SignMessageComponent', () => { + let component: SignMessageComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SignMessageComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SignMessageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/signmessage/signmessage.component.ts b/src/app/pages/signmessage/signmessage.component.ts new file mode 100644 index 00000000..53da4d7a --- /dev/null +++ b/src/app/pages/signmessage/signmessage.component.ts @@ -0,0 +1,113 @@ +import { Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { NotifierService } from 'angular-notifier'; +import { WalletService } from '../../providers/wallet.service'; +import { PromptService } from '../../components/prompt/prompt.service'; +import { ErrorService } from '../../providers/error.service'; +import { AddressBookService } from '../../components/address-book/address-book.service'; +import { NotificationService } from '../../providers/notification.service'; + +@Component({ + selector: 'app-signmessage', + templateUrl: './signmessage.component.html', +}) + +export class SignMessageComponent { + + sub; + tab = 0; + sign = { + address: '', + message: '', + signature: '' + } + verify = { + address: '', + message: '', + signature: '', + result: null + } + + constructor( + private route: ActivatedRoute, + private notifier: NotifierService, + private wallet: WalletService, + private prompt: PromptService, + private addressBook: AddressBookService, + private errorService: ErrorService, + private notification: NotificationService, + ) { + + } + + ngOnInit() { + this.sub = this.route.params.subscribe(params => { + this.tab = Number(params['tab']); + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + sign_reset() { + this.sign.address = ''; + this.sign.message = ''; + this.sign.signature = ''; + } + + async getFromAddressBook(sign) { + const addr = await this.addressBook.getAddress(false); + if (addr && sign) this.sign.address = addr.address; + if (addr && !sign) this.verify.address = addr.address; + } + + async signMessage() { + if (!this.sign.address || !this.sign.message) + return this.notification.notify('error', 'NOTIFICATIONS.EMPTYFIELDS'); + + try { + let passphrase, stakingOnly; + if (this.wallet.requireUnlock()) [passphrase, stakingOnly] = await this.prompt.getPassphrase(); + + this.notification.loading('NOTIFICATIONS.SIGNINGMESSAGE'); + try { + const result = await this.wallet.signMessage(this.sign.address, this.sign.message, passphrase); + this.sign.signature = result + this.notification.notify('success', 'NOTIFICATIONS.SIGNEDMESSAGE'); + } catch (ex) { + this.errorService.diagnose(ex); + } + } catch (ex) { + // passphrase prompt closed + } + } + + verify_reset() { + this.verify.address = ''; + this.verify.message = ''; + this.verify.signature = ''; + this.verify.result = null; + } + + async verifyMessage() { + this.verify.result = null; + + if (!this.verify.address || !this.verify.message || !this.verify.signature) + return this.notification.notify('error', 'NOTIFICATIONS.EMPTYFIELDS'); + + this.notification.loading('NOTIFICATIONS.VERIFYINGMESSAGE'); + try { + let result = await this.wallet.verifyMessage(this.verify.address, this.verify.message, this.verify.signature); + if (result === true) this.verify.result = true; + else this.verify.result = false; + } catch (ex) { + this.errorService.diagnose(ex); + } + this.notification.dismissNotifications() + + } + + +} + diff --git a/src/app/pages/staking/staking.component.html b/src/app/pages/staking/staking.component.html new file mode 100644 index 00000000..0b2c5a95 --- /dev/null +++ b/src/app/pages/staking/staking.component.html @@ -0,0 +1,52 @@ +
+ + +
+

{{ 'PAGES.STAKING.NOTENABLEDTITLE' | translate }}

+

{{ 'PAGES.STAKING.NOTENABLEDINFO' | translate }}

+

{{ 'PAGES.STAKING.NOTENABLEDINSTR' | translate }}

+
+ + +
+

{{ 'PAGES.STAKING.NOTSTAKINGTITLE' | translate }}

+

{{ 'PAGES.STAKING.NOTSTAKINGINFO' | translate }}

+

{{ 'PAGES.STAKING.NOTSTAKINGINSTR' | translate }}

+ +
+ + +
+ +
+

{{ 'PAGES.STAKING.STAKINGTITLE' | translate }}

+

{{ 'PAGES.STAKING.EXPECTEDRETURN' | translate }}: {{wallet.stakingStatus.expectedTime}} + {{wallet.stakingStatus.expectedType}}

+

{{ 'PAGES.STAKING.YOURWEIGHT' | translate }}: {{helpers.prettyCoins(wallet.getWeight())}}

+

{{ 'PAGES.STAKING.NETWORKWEIGHT' | translate }}: {{helpers.prettyCoins(wallet.getNetWeight())}}

+ +
+ +

{{ 'PAGES.STAKING.INPUTSTITLE' | translate }}

+ + +
+
+ + +
+
+
{{input.account || input.address}}
+
{{ 'PAGES.STAKING.MATURE' | translate }}: {{input.matureTime | date:'MMM d, y, h:mm a'}}
+
+
+
+ {{helpers.prettyCoins(input.amount)}} Linda +
+
+
+
+ +
+ +
\ No newline at end of file diff --git a/src/app/pages/staking/staking.component.spec.ts b/src/app/pages/staking/staking.component.spec.ts new file mode 100644 index 00000000..f4abcafd --- /dev/null +++ b/src/app/pages/staking/staking.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StakingComponent } from './staking.component'; + +describe('StakingComponent', () => { + let component: StakingComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StakingComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StakingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/staking/staking.component.ts b/src/app/pages/staking/staking.component.ts new file mode 100644 index 00000000..d1f3683d --- /dev/null +++ b/src/app/pages/staking/staking.component.ts @@ -0,0 +1,84 @@ +import { Component } from '@angular/core'; +import { WalletService, DATASYNCTYPES } from '../../providers/wallet.service'; +import Helpers from '../../helpers'; +import { PromptService } from '../../components/prompt/prompt.service'; +import { ErrorService } from '../../providers/error.service'; +import { NotificationService } from '../../providers/notification.service'; +import { Input } from '../../classes'; + +@Component({ + selector: 'app-staking', + templateUrl: './staking.component.html', +}) +export class StakingComponent { + public helpers = Helpers; + stakingInputs = []; + + sub; + + constructor( + public wallet: WalletService, + private prompt: PromptService, + private notification: NotificationService, + private errorService: ErrorService + ) { + } + + ngOnInit() { + this.getPossibleInputs(); + this.sub = this.wallet.accountsUpdated.subscribe(() => this.getPossibleInputs()); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + async unlockForStaking() { + try { + const [passphrase, stakingOnly] = await this.prompt.getPassphrase(); + + this.notification.loading('NOTIFICATIONS.WALLETUNLOCKING'); + try { + await this.wallet.unlock(passphrase, true); + this.wallet.requestDataSync(DATASYNCTYPES.WALLET) + } catch (ex) { + this.errorService.diagnose(ex); + } + this.notification.dismissNotifications() + + } catch (ex) { + // passphrase prompt closed + } + } + + getPossibleInputs() { + let inputList = []; + this.wallet.accounts.forEach(acc => { + if (acc.balance.gt(0)) { + acc.addresses.forEach(addr => { + addr.spendableInputs().forEach(input => { + if (input.amount.gt(0)) inputList.push(input) + }) + }) + } + }) + this.stakingInputs = inputList.sort((a: Input, b: Input) => { + var m1 = this.isMature(a); + var m2 = this.isMature(b); + var a1 = a.amount.toFixed(); + var a2 = b.amount.toFixed(); + if (m1 < m2) return 1; + if (m1 > m2) return -1; + if (a1 < a2) return -1; + if (a1 > a2) return 1; + return 0; + }); + } + + + isMature(input: Input): boolean { + if (input.matureTime < new Date()) return true; + else return false; + } + +} \ No newline at end of file diff --git a/src/app/pages/tools/tools.component.html b/src/app/pages/tools/tools.component.html new file mode 100644 index 00000000..5176c5dc --- /dev/null +++ b/src/app/pages/tools/tools.component.html @@ -0,0 +1,182 @@ +
+ +
+ + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

{{ 'PAGES.TOOLS.ABOUT.GENERALTITLE' | translate }}

+
{{ 'PAGES.TOOLS.ABOUT.COREVERSION' | translate }}:{{wallet.walletStatus.version}}
{{ 'PAGES.TOOLS.ABOUT.PROTOCOLVERSION' | translate }}:{{wallet.walletStatus.protocolversion}}
{{ 'PAGES.TOOLS.ABOUT.WALLETVERSION' | translate }}:{{wallet.walletStatus.walletversion}}
+

{{ 'PAGES.TOOLS.ABOUT.NETWORKTITLE' | translate }}

+
{{ 'PAGES.TOOLS.ABOUT.NUMBERCONNECTIONS' | translate }}:{{wallet.walletStatus.connections}} (In: {{getPeersSpread()[0]}} / Out: {{getPeersSpread()[1]}})
{{ 'PAGES.TOOLS.ABOUT.NUMBERMASTERNODES' | translate }}:{{wallet.masternode.list.length}}
+

{{ 'PAGES.TOOLS.ABOUT.BLOCKCHAINTITLE' | translate }}

+
{{ 'PAGES.TOOLS.ABOUT.NUMBERBLOCKS' | translate }}:{{wallet.walletStatus.latestBlockHeight}}
{{ 'PAGES.TOOLS.ABOUT.BESTBLOCKTTIME' | translate }}:{{wallet.walletStatus.latestBlockTime | date:'MMM d, yyyy h:mm:ss a'}}
+
+ + +
+ +
{{ 'PAGES.TOOLS.DEBUG.CONSOLEINFO' | translate }}
+ +
{{ 'PAGES.TOOLS.DEBUG.CONSOLEWARNING' | translate }}
+ +
+
+ {{cmd.ts | date:'h:mm:ss a'}} + + +
{{cmd.data | json}}
+
{{cmd.data}}
+
+
+ +
+ + +
+
+ + +
+ +
+
+ + +
+
+
{{peer.addr}}
+
{{peer.subver}}
+
{{ 'PAGES.TOOLS.PEERS.PING' | translate }}: {{prettyPing(peer.pingtime)}}
+
+
+
{{ 'PAGES.TOOLS.PEERS.PROTOCOL' | translate }}: {{peer.version}}
+
{{ 'PAGES.TOOLS.PEERS.BANSCORE' | translate }}: {{peer.banscore}}
+
{{ 'PAGES.TOOLS.PEERS.HEIGHT' | translate }}: {{peer.startingheight}}
+
+
+
{{ 'PAGES.TOOLS.PEERS.SENDREC' | translate }}: + {{prettyDataTransfer(peer.bytessent)}}/{{prettyDataTransfer(peer.bytesrecv)}}
+
{{ 'PAGES.TOOLS.PEERS.LASTSENDREC' | translate }}: + {{helpers.formatTimeEplased(peer.lastsend,dateNow)}}/{{helpers.formatTimeEplased(peer.lastrecv,dateNow)}}
+
{{ 'PAGES.TOOLS.PEERS.CONTIME' | translate }}: {{helpers.formatTimeEplased(peer.conntime,dateNow)}}
+
+
+
+ + +
+ + +
+

{{'PAGES.TOOLS.REPAIR.INFO' | translate}}

+

{{'PAGES.TOOLS.REPAIR.INFOEXTERNAL' | translate}}

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + {{'PAGES.TOOLS.REPAIR.SALVAGEINFO' | translate}}
+ + {{'PAGES.TOOLS.REPAIR.RESCANINFO' | translate}}
+ + {{'PAGES.TOOLS.REPAIR.RECOVER1INFO' | translate}}
+ + {{'PAGES.TOOLS.REPAIR.RECOVER2INFO' | translate}}
+ + {{'PAGES.TOOLS.REPAIR.UPGRADEWALLETINFO' | translate}}
+ + {{'PAGES.TOOLS.REPAIR.REBUILDINDEXINFO' | translate}}
+
+ +
\ No newline at end of file diff --git a/src/app/pages/tools/tools.component.spec.ts b/src/app/pages/tools/tools.component.spec.ts new file mode 100644 index 00000000..0af9ffb1 --- /dev/null +++ b/src/app/pages/tools/tools.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ToolsComponent } from './tools.component'; + +describe('ToolsComponent', () => { + let component: ToolsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ToolsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ToolsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/tools/tools.component.ts b/src/app/pages/tools/tools.component.ts new file mode 100644 index 00000000..3eedd128 --- /dev/null +++ b/src/app/pages/tools/tools.component.ts @@ -0,0 +1,144 @@ +import { Component, OnInit, ElementRef, ViewChild, ChangeDetectorRef } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { WalletService } from '../../providers/wallet.service'; +import Helpers from '../../helpers'; +import { RpcService } from '../../providers/rpc.service'; +import { ElectronService, ClientStatus } from '../../providers/electron.service'; + +@Component({ + selector: 'app-tools', + templateUrl: './tools.component.html' +}) +export class ToolsComponent implements OnInit { + + @ViewChild('scrollingBlock') private myScrollContainer: ElementRef; + helpers = Helpers + sub; + tab = 0; + + rpcCommand = ""; + rpcHistory = []; + myCommands = []; + myCommandIndex = -1; + + dateNow + + repairCommands = ['-salvagewallet', '-rescan', '-zapwallettxes=1', '-zapwallettxes=2', '-upgradewallet', '-reindex']; + + constructor( + private route: ActivatedRoute, + private rpc: RpcService, + public wallet: WalletService, + private electron: ElectronService, + private cdRef: ChangeDetectorRef + ) { } + + ngAfterViewChecked() { + this.dateNow = new Date(); + this.cdRef.detectChanges(); + } + + ngOnInit() { + this.sub = this.route.params.subscribe(params => { + this.tab = Number(params['tab']); + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + rpcKeyUp(e) { + if (this.myCommandIndex < this.myCommands.length) this.myCommandIndex++; + this.rpcCommand = this.myCommands[this.myCommandIndex]; + } + + rpcKeyDown(e) { + if (this.myCommandIndex > -1) this.myCommandIndex--; + this.rpcCommand = this.myCommands[this.myCommandIndex]; + } + + async sendRPC() { + if (this.rpcCommand) { + try { + this.rpcHistory.push({ ts: new Date(), send: true, data: this.rpcCommand, json: false }); + this.myCommands.splice(0, 0, this.rpcCommand); + let params = this.rpcCommand.split(" "); + const method = params.shift(); + params = this.parseRPCParams(params); + console.log(params) + const res: any = await this.rpc.callServer(method, params); + let isJson = false; + if (res.result) isJson = typeof (res.result) === 'object'; + this.rpcHistory.push({ ts: new Date(), send: false, data: res.result || res.error, json: isJson }); + } catch (ex) { + let err = ex.statusText; + if (ex.error.error) err = `${ex.error.error.message} (code ${ex.error.error.code})`; + this.rpcHistory.push({ ts: new Date(), send: false, data: err, json: false }); + } + this.rpcCommand = ""; + // scroll to bottom of output once it has rendered + setTimeout(() => { + this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight; + }, 50); + } + } + + parseRPCParams(params: Array) { + let parsedParams = []; + params.forEach(param => { + if (param.toString().toLowerCase() === 'true') parsedParams.push(true) + else if (param.toString().toLowerCase() === 'false') parsedParams.push(false) + else if (!isNaN(Number(param))) parsedParams.push(Number(param)); + else { + try { + parsedParams.push(JSON.parse(param.replace(/'/g, ""))) + } catch (ex) { + parsedParams.push(param); + } + } + }) + return parsedParams; + } + + clearRPCHistory() { + this.rpcHistory = []; + } + + getPeersSpread() { + let inbound = 0; + let outbound = 0; + this.wallet.peers.forEach(peer => { + if (peer.inbound) inbound++; + else outbound++; + }) + return [inbound, outbound]; + } + + prettyDataTransfer(amount) { + // check bytes + if (amount < 1000) return amount + ' B'; + // check kb + amount = Math.round(amount / 1000); + if (amount < 1000) return amount + ' KB'; + // check mb + amount = Math.round(amount / 1000); + if (amount < 1000) return amount + ' MB'; + // check gb + amount = Math.round(amount / 1000); + if (amount < 1000) return amount + ' GB'; + } + + prettyPing(amount) { + return Math.round(amount * 1000) + 'ms'; + } + + canRunRepair() { + return this.rpc.clientStatus !== ClientStatus.RUNNINGEXTERNAL; + } + + repairWallet(cmd) { + this.rpc.restartClient([this.repairCommands[cmd]]); + } + +} \ No newline at end of file diff --git a/src/app/pages/transactions/transactions.component.html b/src/app/pages/transactions/transactions.component.html new file mode 100644 index 00000000..43e98dd7 --- /dev/null +++ b/src/app/pages/transactions/transactions.component.html @@ -0,0 +1,32 @@ +
+ +

{{'PAGES.TRANSACTIONS.TITLE' | translate}}

+ + +
+
+
+ + + + + + +
+
+
{{trx.category}}
+
{{trx.timestamp | date:'MMM d, h:mm a'}}
+
{{trx.account || trx.address}}
+
+
+
+ {{trx.category!='Payment To Self'&&trx.amount>0?'+':''}}{{helpers.prettyCoins(trx.amount)}} Linda +
+
{{ 'MISC.FEE' | translate }}: {{helpers.prettyCoins(trx.fee)}} + Linda
+
+
+
+ +
\ No newline at end of file diff --git a/src/app/pages/transactions/transactions.component.spec.ts b/src/app/pages/transactions/transactions.component.spec.ts new file mode 100644 index 00000000..b7cf5cf6 --- /dev/null +++ b/src/app/pages/transactions/transactions.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TransactionsComponent } from './transactions.component'; + +describe('TransactionsComponent', () => { + let component: TransactionsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TransactionsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TransactionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/transactions/transactions.component.ts b/src/app/pages/transactions/transactions.component.ts new file mode 100644 index 00000000..50e44aa6 --- /dev/null +++ b/src/app/pages/transactions/transactions.component.ts @@ -0,0 +1,62 @@ +import { Component } from '@angular/core'; +import { WalletService } from '../../providers/wallet.service'; +import Helpers from '../../helpers'; +import { ChangeEvent } from 'ngx-virtual-scroller'; +import { ErrorService } from '../../providers/error.service'; +import { ContextMenuService } from '../../components/context-menu/context-menu.service'; +import { ElectronService } from '../../providers/electron.service'; + +@Component({ + selector: 'app-transactions', + templateUrl: './transactions.component.html', +}) + +export class TransactionsComponent { + public helpers = Helpers; + transactions = []; + skip = 10; + loading = false; + + constructor( + public wallet: WalletService, + private errorService: ErrorService, + private contextMenu: ContextMenuService, + private electron: ElectronService + ) { + } + + ngOnDestroy() { + if (this.wallet.transactions.length > 10) { + const toRemove = this.wallet.transactions.length - 10; + this.wallet.transactions.splice(10, toRemove); + } + } + + async fetchMore(event: ChangeEvent) { + if (this.loading || event.end !== this.wallet.transactions.length - 1) return; + this.loading = true; + try { + await this.wallet.getTransactions(10, this.skip); + this.skip += 10; + } catch (ex) { + this.errorService.diagnose(ex); + } + this.loading = false; + } + + onRightClick(e, trx) { + const items = [ + { + name: 'PAGES.TRANSACTIONS.COPYBLOCKHASH', + func: () => this.electron.clipboard.writeText(trx.blockHash) + }, + { + name: 'PAGES.TRANSACTIONS.COPYTXID', + func: () => this.electron.clipboard.writeText(trx.txId) + } + ] + this.contextMenu.show(e, items) + } + + +} diff --git a/src/app/providers/electron.service.ts b/src/app/providers/electron.service.ts new file mode 100644 index 00000000..fd0e729b --- /dev/null +++ b/src/app/providers/electron.service.ts @@ -0,0 +1,148 @@ +import { Injectable, isDevMode, EventEmitter, Output } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +// If you import a module but never use any of the imported values other than as TypeScript types, +// the resulting javascript file will look as if you never imported the module at all. +import { ipcRenderer, remote, clipboard, shell } from 'electron'; +import { HttpClient } from '@angular/common/http'; +import * as compareVersions from 'compare-versions'; +var supportedLanguages = require('../pages/locale/languages'); + +@Injectable() +export class ElectronService { + + ipcRenderer: typeof ipcRenderer; + remote: typeof remote; + clipboard: typeof clipboard; + shell: typeof shell; + + settings: any = {}; + + @Output() clientStatusEvent: EventEmitter = new EventEmitter(); + @Output() RCPStatusEvent: EventEmitter = new EventEmitter(); + @Output() CredentialsEvent: EventEmitter = new EventEmitter(); + @Output() checkUpdateEvent: EventEmitter = new EventEmitter(); + @Output() languageChangedEvent: EventEmitter = new EventEmitter(); + + constructor( + private http: HttpClient, + private translate: TranslateService, + ) { + // Conditional imports + if (this.isElectron()) { + this.ipcRenderer = window.require('electron').ipcRenderer; + this.remote = window.require('electron').remote; + this.clipboard = window.require('electron').clipboard; + this.shell = window.require('electron').shell; + + this.getDeviceLangauge(); + this.connectClientNodeIPC(); + this.connectSettingsIPC(); + + if (!isDevMode()) + this.checkForWalletUpdate().then(() => { }, err => { }); + } + } + + isElectron = () => { + return window && window.process && window.process.type; + } + + connectClientNodeIPC() { + // listen for client + this.ipcRenderer.on('client-node', (event, cmd, data) => { + if (isDevMode()) console.log('Received IPC:client-node', cmd, data); + switch (cmd) { + case 'CREDENTIALS': + this.CredentialsEvent.emit(data); + break; + case 'STATUS': + this.clientStatusEvent.emit(data); + break; + case 'RPC': + this.RCPStatusEvent.emit(data); + break; + case 'CHECKUPDATE': + this.checkUpdateEvent.emit({ type: 'core', hasUpdate: data }); + break; + } + }); + // ask for credentials + this.ipcRenderer.send('client-node', 'CREDENTIALS'); + // ask for client status + this.ipcRenderer.send('client-node', 'STATUS'); + // ask for rpc status + this.ipcRenderer.send('client-node', 'RPC'); + } + + connectSettingsIPC() { + // listen for client + this.ipcRenderer.on('settings', (event, cmd, data) => { + if (isDevMode()) console.log('Received IPC:settings', cmd, data); + switch (cmd) { + case 'GET': + this.settings = data; + this.setLanguage(); + break; + } + }); + // ask for settings + this.ipcRenderer.send('settings', 'GET'); + } + + getDeviceLangauge() { + this.translate.setDefaultLang('en'); + const localLanguage = navigator.language.toLowerCase(); + const localLangaugeSplit = localLanguage.split("-")[0]; + Object.keys(supportedLanguages).forEach(key => { + const supportedLanguage = supportedLanguages[key].code.toLowerCase(); + if (supportedLanguage === localLanguage || supportedLanguage === localLangaugeSplit) { + if (isDevMode()) console.log("Detected local langauge", key); + this.translate.setDefaultLang(supportedLanguages[key].code); + } + }); + } + + setLanguage() { + if (this.translate.getDefaultLang() !== this.settings.locale) { + if (isDevMode()) console.log("Setting language to", this.settings.locale) + this.translate.setDefaultLang(this.settings.locale); + this.languageChangedEvent.emit(); + } + } + + public checkForWalletUpdate(showSkip = true) { + return new Promise((resolve, reject) => { + const walletUpdateUrl = 'https://api.github.com/repos/thelindaprojectinc/altitude/releases/latest'; + this.http.get(walletUpdateUrl).subscribe(remoteData => { + const appVersion = this.remote.app.getVersion(); + if ((!showSkip || this.settings.skipWalletUpdate !== remoteData.tag_name) && compareVersions(remoteData.tag_name, appVersion) > 0) { + this.checkUpdateEvent.emit({ type: 'wallet', version: remoteData.tag_name, showSkip: showSkip }); + resolve(true); + } else { + resolve(false); + } + }, err => { + reject(err); + }); + }) + } + +} + +export enum ClientStatus { + INITIALISING, + CHECKEXISTS, + DOWNLOADCLIENT, + UPDATEAVAILABLE, + STARTING, + RUNNING, + RUNNINGEXTERNAL, + STOPPED, + NOCREDENTIALS, + INVALIDHASH, + DOWNLOADFAILED, + UNSUPPORTEDPLATFORM, + SHUTTINGDOWN, + RESTARTING, + CLOSEDUNEXPECTED +} \ No newline at end of file diff --git a/src/app/providers/error.service.ts b/src/app/providers/error.service.ts new file mode 100644 index 00000000..420c3bb9 --- /dev/null +++ b/src/app/providers/error.service.ts @@ -0,0 +1,35 @@ +import { Injectable, isDevMode } from '@angular/core'; +import { NotificationService } from './notification.service'; +import log from 'electron-log'; + +@Injectable() +export class ErrorService { + + constructor( + private notification: NotificationService, + ) { + } + + public diagnose(ex: any): void { + if (isDevMode()) console.log('ErrorService', ex); + + if (ex.statusText && ex.statusText === "Unknown Error") { + // ex.statusText !== "Unknown Error" denotes a problem connecting to the + // client this error is handled and notifed to the user in the rpc service + } else if (ex.error && ex.error.error) { + const msg = `(${ex.error.error.code}) ${ex.error.error.message.replace('Error:', '').trim()}`; + this.notification.notify('error', msg, false); + } else if (ex.rpcNotReady) { + // ex.rpcNotReady is returned when we try to call the RPC before it's + // ready we can ignore this error + } else if (ex.rpcTimeout) { + // ex.rpcTimeout is returned when the RPC fails to respond in time + // this is usually during sync and heavy loads so we can ignore this error + } else { + log.error('ErrorService', 'New error', ex); + this.notification.notify('error', 'NOTIFICATIONS.GENERICERROR'); + } + } + + +} \ No newline at end of file diff --git a/src/app/providers/notification.service.ts b/src/app/providers/notification.service.ts new file mode 100644 index 00000000..7c2eb5c6 --- /dev/null +++ b/src/app/providers/notification.service.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@angular/core'; +import { NotifierService } from 'angular-notifier'; +import { TranslationService } from './translation.service'; + +@Injectable() +export class NotificationService { + + dismissableNotificationList = []; + + constructor( + private notifier: NotifierService, + private translation: TranslationService + ) { + } + + public async notify(type: string, translation: string, translate: boolean = true): Promise { + this.dismissNotifications(); + this.notifier.notify(type, translate ? await this.translation.translate(translation) : translation); + } + + public dismissNotifications() { + this.dismissableNotificationList.forEach(id => { + this.notifier.hide(id); + }) + this.dismissableNotificationList = []; + } + + public async loading(translation: string, translate: boolean = true): Promise { + + const id = new Date().getTime(); + this.dismissableNotificationList.push(id); + + setTimeout(async () => { + if (this.dismissableNotificationList.indexOf(id) > -1) { + this.notifier.notify('default', translate ? await this.translation.translate(translation) : translation); + } + }, 500); + } + +} \ No newline at end of file diff --git a/src/app/providers/rpc.service.ts b/src/app/providers/rpc.service.ts new file mode 100644 index 00000000..991d40be --- /dev/null +++ b/src/app/providers/rpc.service.ts @@ -0,0 +1,526 @@ +import { Injectable, isDevMode, Output, EventEmitter } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import Big from 'big.js'; +import { ElectronService, ClientStatus } from './electron.service'; +import { PromptService } from '../components/prompt/prompt.service'; + +@Injectable() +export class RpcService { + private port: number; + private username: string; + private password: string; + private encryptionStatus = 'Unencrypted'; + private confirmations = 10; + private masternodePort = 33820; + + public clientStatus: ClientStatus; + public RPCReady = false + public RPCWarmupMessage = ''; + private hasRPCCredentials = false; + + private readonly unlockTimeout = 31000000; + + constructor( + private http: HttpClient, + private electron: ElectronService, + private prompt: PromptService + ) { + if (electron.isElectron()) this.setupListeners() + else console.log("Not running in electron. cannot connect IPC"); + } + + setupListeners() { + // listen for RPC credentials + this.electron.CredentialsEvent.subscribe(creds => { + this.setCredentials(creds.rpcUser, creds.rpcPassword, creds.rpcPort); + }); + // electron for client status + this.electron.clientStatusEvent.subscribe((status: ClientStatus) => { + this.clientStatus = status; + if (status === ClientStatus.CLOSEDUNEXPECTED) this.notifyClientCloseUnexpected(); + }); + // electron for RPC status + this.electron.RCPStatusEvent.subscribe((status: { ready: boolean, message: string }) => { + this.RPCReady = status.ready; + this.RPCWarmupMessage = status.message + }); + } + + public restartClient(commands = null) { + this.hasRPCCredentials = false; + this.RPCReady = false; + this.electron.ipcRenderer.send('client-node', 'RESTART', commands); + } + + private setCredentials(username: string, password: string, port: number) { + this.hasRPCCredentials = true; + this.username = username; + this.password = password; + this.port = port; + } + + public async requestData(method, params = []) { + let data: any; + switch (method) { + case RPCMethods.ENCRYPT: + data = await this.callServer("encryptwallet", params); + break; + case RPCMethods.CHANGEPASSPHRASE: + data = await this.callServer("walletpassphrasechange", params); + break; + case RPCMethods.GETWALLET: + data = await this.getWalletInfo(); + break; + case RPCMethods.GETACCOUNTS: + data = await this.getAccounts(); + break; + case RPCMethods.GETTRANSACTIONS: + data = await this.getTransactions(params); + break; + case RPCMethods.GETSTAKING: + data = await this.callServer("getstakinginfo"); + break; + case RPCMethods.UPDATELABEL: + data = await this.callServer("setaccount", params); + break; + case RPCMethods.NEWADDRESS: + data = await this.callServer("getaccountaddress", params); + break; + case RPCMethods.UNLOCK: + data = await this.unlockWallet(params[0], this.unlockTimeout, params[1]); + break; + case RPCMethods.LOCK: + await this.callServer("walletlock"); + data = { result: { success: true } }; + break; + case RPCMethods.LOCKUNSPENT: + data = await this.callServer("lockunspent", params); + break; + case RPCMethods.CREATETRANSACTION: + data = await this.createTransaction(params); + break; + case RPCMethods.BACKUPWALLET: + data = await this.callServer("backupwallet", params); + break; + case RPCMethods.GETLATESTBLOCK: + data = await this.getLatestBlock(); + break; + case RPCMethods.MASTERNODESTART: + data = await this.callServer("masternode", ['start', ...params]) + break; + case RPCMethods.MASTERNODESTARTALIAS: + data = await this.callServer("masternode", ['start-alias', ...params]) + break; + case RPCMethods.MASTERNODESTARTMANY: + data = await this.callServer("masternode", ['start-many', ...params]) + break; + case RPCMethods.MASTERNODESTATUS: + data = await this.masternodeStatus(); + break; + case RPCMethods.MASTERNODESTATUSALL: + data = await this.callServer("masternode", ['status-all']); + break; + case RPCMethods.MASTERNODELISTCONF: + data = await this.callServer("masternode", ['list-conf']); + break; + case RPCMethods.SIGNMESSAGE: + data = await this.signMessage(params); + break; + case RPCMethods.VERIFYMESSAGE: + data = await this.callServer("verifymessage", params); + break; + case RPCMethods.PEERS: + data = await this.callServer("getpeerinfo"); + break; + case RPCMethods.ADDRESSBOOKLIST: + data = await this.callServer("listaddressbook"); + break; + case RPCMethods.ADDRESSBOOKADD: + data = await this.callServer("addressbookadd", params); + break; + case RPCMethods.ADDRESSBOOKREMOVE: + data = await this.callServer("addressbookremove", params); + break; + case RPCMethods.GETBLOCK: + data = await this.callServer("getblock", params); + break; + case RPCMethods.GETBLOCKBYNUMBER: + data = await this.callServer("getblockbynumber", params); + break; + case RPCMethods.GETTRANSACTION: + data = await this.callServer("gettransaction", params); + break; + } + return data.result ? data.result : {}; + } + + private async unlockWallet(passphrase, timeout, stakingOnly = false) { + try { + const lockdata: any = await this.callServer("walletpassphrase", [passphrase, timeout, stakingOnly]); + return lockdata; + } catch (ex) { + // if we called unlock when our wallet is already unlock or + // unencrypted just ignore it + if (ex.error.error.code === -15 || ex.error.error.code === -17) + return {} + else + throw ex + } + } + + private async signMessage(params) { + const [address, message, passphrase] = params; + try { + await this.unlockWallet(passphrase, 5); + const signdata: any = await this.callServer("signmessage", [address, message]); + this.checkUnlock(passphrase); + return signdata; + } catch (ex) { + this.checkUnlock(passphrase); + throw ex; + } + } + + private async getLatestBlock() { + let result = { height: 0, time: 0 }; + let data: any = await this.callServer('getbestblockhash'); + data = await this.callServer('getblock', [data.result]); + result.height = data.result.height; + result.time = data.result.time; + return { result }; + } + + private async getAccounts() { + // get addresses + let addresses: any = await this.callServer("listreceivedbyaddress", [0, true]); + // get address groupings + let groups: any = await this.callServer("listaddressgroupings"); + // get all unspent + let unspents: any = await this.callServer("listunspent", [1, 9999999, [], true]); + // assemble accounts + let accounts = []; + for (let i = 0; i < groups.result.length; i++) { + let grp = groups.result[i]; + let newAccount = []; + for (let j = 0; j < grp.length; j++) { + let newAddress = { + address: grp[j][0], + amount: grp[j][1], + account: grp[j][2], + unspents: [] + } + if (newAddress.account && newAccount.length) accounts.push([newAddress]); + else newAccount.push(newAddress); + // removing matching address in address list + for (let k = 0; k < addresses.result.length; k++) { + if (addresses.result[k].address === newAddress.address) { + addresses.result.splice(k, 1); + break; + } + } + } + accounts.push(newAccount); + } + // add remaining addresses from address list + addresses.result.forEach(address => { + if (address.account !== "(change)" || (address.account === "(change)" && address.amount !== "0")) { + accounts.push([{ + address: address.address, + amount: address.amount, + account: address.account, + unspents: [] + }]); + } + }); + // match unspent to address + for (let i = 0; i < unspents.result.length; i++) { + let unspent = unspents.result[i]; + for (let j = 0; j < accounts.length; j++) { + let acc = accounts[j]; + let foundAddr = false; + for (let k = 0; k < acc.length; k++) { + let addr = acc[k]; + if (addr.address === unspent.address) { + addr.unspents.push({ + amount: unspent.amount, + blockTime: unspent.time, + confirmations: unspent.confirmations, + scriptPubKey: unspent.scriptPubKey, + txid: unspent.txid, + vout: unspent.vout, + locked: unspent.locked + }); + unspents.result.splice(i--, 1); + foundAddr = true; + break; + } + } + if (foundAddr) break; + } + } + + // remove empty change addresses + for (let i = 0; i < accounts.length; i++) { + let acc = accounts[i]; + for (let j = 0; j < acc.length; j++) { + let addr = acc[j]; + if (addr.account === '(change)' && !addr.unspents.length) { + acc.splice(j--, 1); + } + } + if (!acc.length) accounts.splice(i--, 1); + } + + return { result: accounts }; + } + + private async getWalletInfo() { + let data: any = await this.callServer("getinfo"); + + this.encryptionStatus = data.result.encryption_status + + return data; + } + + private async createTransaction(params) { + let [inputs, outputs, fee, passphrase, changeAddress] = params; + try { + // get unspents + let unspents: any = await this.callServer("listunspent", [1, 9999999, [], true]); + unspents = unspents.result; + // safety check inputs + let sendingBalance = Big(0); + for (let i = 0; i < inputs.length; i++) { + let input = inputs[i]; + let foundMatch = false; + for (let j = 0; j < unspents.length; j++) { + let unspent = unspents[j]; + if (input.txid === unspent.txid && input.vout === unspent.vout) { + if (unspent.confirmations < 1) { + return { result: { success: false, error: "NOTIFICATIONS.MINIMUMCONFIRMATIONS" } }; + } + foundMatch = true; + sendingBalance = sendingBalance.add(Big(unspent.amount)); + break; + } + } + if (!foundMatch) return { result: { success: false, error: "NOTIFICATIONS.TRANSACTIONMISMATCH" } }; + } + // get total receving + let recevingBalance = Big(fee); + Object.keys(outputs).forEach(key => { + recevingBalance = recevingBalance.add(Big(outputs[key])); + }) + // safety check + if (sendingBalance.lt(recevingBalance)) { + return { result: { success: false, error: "NOTIFICATIONS.TRANSACTIONMISMATCH" } }; + } + // calculate change + let change = Number(sendingBalance.minus(recevingBalance).toString()); + + // unlock wallet + await this.unlockWallet(passphrase, 5); + // create change address + if (change > 0) { + if (!changeAddress) { + let changeRequest: any = await this.callServer("getnewaddress", ['(change)']); + changeAddress = changeRequest.result; + } + outputs[changeAddress] = change; + } + // create raw transaction + let raw: any = await this.callServer("createrawtransaction", [inputs, outputs]); + raw = raw.result; + // sign raw transaction + let signed: any = await this.callServer("signrawtransaction", [raw]); + this.checkUnlock(passphrase); + signed = signed.result.hex; + // send raw transaction + await this.callServer("sendrawtransaction", [signed]); + return { result: { success: true } }; + } catch (ex) { + this.checkUnlock(passphrase); + throw ex; + } + } + + private checkUnlock(passphrase) { + try { + if (this.encryptionStatus === 'LockedForStaking') + this.unlockWallet(passphrase, this.unlockTimeout, true) + else if (this.encryptionStatus === 'Unlocked') + this.unlockWallet(passphrase, this.unlockTimeout) + } catch (ex) { + + } + } + + private async getTransactions(params) { + let outputs = new Array(); + let count = params[0] || 10; + let from = params[1] || 0; + + // load all transactions + let data: any = await this.callServer('listtransactions', ['*', count, from]); + // get address + data.result.forEach(tx => { + outputs.push(new Transaction(tx)) + }) + + // group payments to self + outputs.forEach((output, index) => { + for (let i = index + 1; i < outputs.length; i++) { + if ( + output.address === outputs[i].address && + output.timestamp === outputs[i].timestamp && + Big(output.amount.replace("-", "")).eq(Big(outputs[i].amount.replace("-", ""))) + ) { + output.amount = output.amount.replace("-", ""); + output.category = "Payment To Self"; + output.fee = output.fee || outputs[i].fee; + outputs.splice(i, 1); + break; + } + } + }) + + return { result: outputs }; + } + + private async masternodeStatus() { + // check initialised + let init: any = await this.callServer("masternode", ['isInit']); + return { result: { initRequired: !init.result } }; + } + + private get isRPCReady() { + return this.RPCReady && this.hasRPCCredentials && (this.clientStatus === ClientStatus.RUNNING || this.clientStatus === ClientStatus.RUNNINGEXTERNAL) + } + + public callServer(method, params = []) { + return new Promise((resolve, reject) => { + if (!this.isRPCReady) reject({ rpcNotReady: true }); + else { + let start = new Date().getTime(); + let url = `http://${this.username}:${this.password}@127.0.0.1:${this.port}/`; + let payload = { jsonrpc: '1.0', id: 'Tunnel', method: method, params: params }; + let sub; + + // reject if request takes more than 10 seconds + // this is usually due to an rpc lockup during sync + const requestTimedOut = () => { + if (sub) sub.unsubscribe(); + reject({ rpcTimeout: true }); + } + let requestTimeout = setTimeout(requestTimedOut, 10000); + + sub = this.http.post(url, payload) + .subscribe(data => { + let time = new Date().getTime() - start + 'ms'; + if (isDevMode()) console.log('CallServer', time, method, data); + clearTimeout(requestTimeout); + resolve(data); + }, err => { + let time = new Date().getTime() - start + 'ms'; + if (isDevMode()) console.error('CallServer', time, method, err); + this.checkClientStopped(err); + clearTimeout(requestTimeout); + reject(err); + }); + } + }) + } + + async checkClientStopped(err) { + // if we lost connection to external client. notify user + if (this.clientStatus === ClientStatus.RUNNINGEXTERNAL && err.statusText === "Unknown Error") { + this.clientStatus = ClientStatus.STOPPED; + try { + await this.prompt.alert('COMPONENTS.PROMPT.CLIENTSTOPPEDTITLE', 'COMPONENTS.PROMPT.CLIENTSTOPPEDINFO', 'COMPONENTS.PROMPT.CLIENTSTOPPEDBUTTONSTART', 'COMPONENTS.PROMPT.CLIENTSTOPPEDBUTTONEXIT'); + // start internal client + this.restartClient(); + } catch (ex) { + // chose to stop wallet + this.electron.remote.app.quit() + } + } + } + + async notifyClientCloseUnexpected() { + try { + await this.prompt.alert('COMPONENTS.PROMPT.CLIENTCLOSEDUNEXPECTEDTITLE', 'COMPONENTS.PROMPT.CLIENTCLOSEDUNEXPECTEDINFO', 'COMPONENTS.PROMPT.CLIENTCLOSEDUNEXPECTEDBUTTONSTART', 'COMPONENTS.PROMPT.CLIENTSTOPPEDBUTTONEXIT'); + // restart internal client + this.restartClient(); + } catch (ex) { + // chose to stop wallet + this.electron.remote.app.quit() + } + } +} + +export class Transaction { + account: string; + address: string; + category: string; + amount: string; + fee: number; + confirmations: number + blockHash: string; + blockIndex: number; + blockTime: number; + txId: string; + timestamp: number; + + constructor(data: any) { + this.account = data.account; + this.address = data.address; + this.category = data.category; + this.amount = data.amount.toString(); + this.fee = data.fee; + this.confirmations = data.confirmations; + this.blockHash = data.blockhash; + this.blockIndex = data.blockindex; + this.blockTime = data.blocktime; + this.txId = data.txid; + this.timestamp = data.time; + // santise category + if (this.category === "send") this.category = "Payment" + if (this.category === "generate") this.category = "Mined" + if (this.category === "receive") this.category = "Received" + if (this.category === "immature") this.category = "Immature" + if (this.category === "orphan") this.category = "Orphan" + } +} + +export enum RPCMethods { + ENCRYPT, + CHANGEPASSPHRASE, + GETWALLET, + GETACCOUNTS, + GETTRANSACTIONS, + GETTOTALS, + GETSTAKING, + UPDATELABEL, + NEWADDRESS, + UNLOCK, + LOCK, + LOCKUNSPENT, + CREATETRANSACTION, + GETLATESTBLOCK, + MASTERNODESTART, + MASTERNODESTARTMANY, + MASTERNODESTARTALIAS, + MASTERNODESTATUS, + MASTERNODESTATUSALL, + MASTERNODELISTCONF, + BACKUPWALLET, + SIGNMESSAGE, + VERIFYMESSAGE, + PEERS, + ADDRESSBOOKLIST, + ADDRESSBOOKADD, + ADDRESSBOOKREMOVE, + GETBLOCK, + GETBLOCKBYNUMBER, + GETTRANSACTION +} \ No newline at end of file diff --git a/src/app/providers/translation.service.ts b/src/app/providers/translation.service.ts new file mode 100644 index 00000000..7be0488e --- /dev/null +++ b/src/app/providers/translation.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; + +@Injectable() +export class TranslationService { + + constructor( + private translateService: TranslateService, + ) { + } + + public async translate(key): Promise { + return new Promise((resolve) => { + this.translateService.get(key).subscribe((res: string) => { + resolve(res) + }); + }) + } + +} \ No newline at end of file diff --git a/src/app/providers/wallet.service.ts b/src/app/providers/wallet.service.ts new file mode 100644 index 00000000..ddfb926f --- /dev/null +++ b/src/app/providers/wallet.service.ts @@ -0,0 +1,649 @@ +import { Injectable, Output, EventEmitter } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import Big from 'big.js'; + +import { RPCMethods, RpcService } from './rpc.service'; +import Helpers from '../helpers'; +import { ElectronService } from './electron.service'; +import { ErrorService } from './error.service'; +import { + Account, + Address, + AddressBookItem, + Input, + MasternodeStatus, + Peer, + StakingStatus, + Transaction, + WalletStatus, + EncryptionStatus +} from '../classes'; + +@Injectable() +export class WalletService { + // Linda parameters + readonly masternodeCollateral = 2000000; + readonly fee = 0.001; + readonly masternodeConfirms = 10; + readonly matureTime = 24; + readonly confirmations = 10; + + // syncing flag + running: boolean; + + // timers + conversionSyncTimer; + syncServiceTimer; + + transactions: Array; + accounts: Array; + + // wallet state + walletStatus: WalletStatus; + stakingStatus: StakingStatus; + masternode: MasternodeStatus; + // peers list + peers: Array;; + // address book + addressBook: Array; + + // data syncs + dataSyncs = [ + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.WALLET, fn: () => this.syncWallet() }, + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.ACCOUNTS, fn: () => this.syncAccounts() }, + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.STAKING, fn: () => this.syncStaking() }, + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.LATESTBLOCK, fn: () => this.syncLatestBlock() }, + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.MASTERNODE, fn: (dataSync) => this.getMasternodeInfo(dataSync) }, + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.TRANSACTIONS, fn: () => this.syncTransactions() }, + { timestamp: 0, interval: 10000, async: false, showLoading: false, running: false, name: DATASYNCTYPES.MASTERNODELIST, fn: () => this.getMasternodeList() }, + { timestamp: 0, interval: 10000, async: false, showLoading: false, running: false, name: DATASYNCTYPES.PEERSLIST, fn: () => this.getPeersList() }, + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.ADDRESSBOOK, fn: () => this.getAddressBook() }, + { timestamp: 0, interval: 10000, async: true, showLoading: false, running: false, name: DATASYNCTYPES.MASTERNODELISTCONF, fn: (dataSync) => this.getMasternodeListConf(dataSync) }, + ]; + + @Output() accountsUpdated: EventEmitter = new EventEmitter(); + @Output() masternodeListUpdated: EventEmitter = new EventEmitter(); + @Output() encryptionStatusChanges: EventEmitter = new EventEmitter(); + + constructor( + private http: HttpClient, + private rpc: RpcService, + private electron: ElectronService, + private errorService: ErrorService + ) { + this.resetState(); + if (electron.isElectron()) this.setupListeners() + } + + resetState() { + this.running = false; + this.transactions = new Array(); + this.accounts = new Array(); + this.walletStatus = new WalletStatus(); + this.stakingStatus = new StakingStatus(); + this.masternode = new MasternodeStatus(); + this.peers = new Array(); + this.addressBook = new Array(); + } + + setupListeners() { + // electron for RPC status + this.electron.RCPStatusEvent.subscribe((status: { ready: boolean, message: string }) => { + if (status.ready) this.startSyncService(); + else this.stopSyncService(); + }); + } + + get balance(): Big { + let balance = Big(0); + this.accounts.forEach(acc => balance = balance.add(acc.balance)); + if (this.masternode.running) + balance = balance.add(this.masternodeCollateral) + + return balance; + } + + public requestDataSync(type: DATASYNCTYPES) { + for (let i = 0; i < this.dataSyncs.length; i++) { + let dataSync = this.dataSyncs[i]; + if (dataSync.name === type && !dataSync.running) { + dataSync.running = true; + this.runDataSync(dataSync) + } + } + return null; + } + + public stopSyncService() { + if (this.running) { + this.running = false; + if (this.syncServiceTimer) clearTimeout(this.syncServiceTimer); + if (this.conversionSyncTimer) clearTimeout(this.conversionSyncTimer); + // reset all timestamps so they will re-sync when the core is available + this.dataSyncs.forEach(ds => { + ds.timestamp = 0; + if (ds.name === DATASYNCTYPES.MASTERNODELISTCONF) ds.interval = 10000; + if (ds.name === DATASYNCTYPES.MASTERNODE) ds.interval = 10000; + }); + } + } + + public startSyncService() { + if (!this.running) { + this.running = true; + this.runSyncService(); + this.syncConverstion(); + } + } + + // sync data + private async runDataSync(dataSync) { + try { + await dataSync.fn(dataSync); + } catch (ex) { + this.errorService.diagnose(ex); + } + this.resetDataSync(dataSync); + } + + private async runSyncService() { + if (this.running) { + // run async loaders + let promises = []; + for (let i = 0; i < this.dataSyncs.length; i++) { + let dataSync = this.dataSyncs[i]; + if (!dataSync.running && dataSync.async && this.doRunDataSync(dataSync)) { + promises.push(this.runDataSync(dataSync)); + } + } + await Promise.all(promises); + + // run sync loaders + for (let i = 0; i < this.dataSyncs.length; i++) { + let dataSync = this.dataSyncs[i]; + if (!dataSync.running && !dataSync.async && this.doRunDataSync(dataSync)) { + await this.runDataSync(dataSync); + } + } + + this.syncServiceTimer = setTimeout(() => this.runSyncService(), 1000); + } + } + + private doRunDataSync(dataSync): boolean { + let diff = new Date().getTime() - dataSync.timestamp; + if (!dataSync.timestamp || (dataSync.interval > 0 && diff > dataSync.interval)) { + if (diff > 30 * 60 * 1000) dataSync.showLoading = true; + else dataSync.showLoading = false; + dataSync.running = true; + return true; + } + return false; + } + + private resetDataSync(dataSync) { + dataSync.showLoading = false; + dataSync.running = false; + dataSync.timestamp = this.running ? new Date().getTime() : 0; + } + + private async syncWallet() { + let data: any = await this.rpc.requestData(RPCMethods.GETWALLET); + if (!data.error) { + // on linux and osx we need to notify the title bar this has + // changed so it can redraw it + let encryptionChanged = this.walletStatus.encryption_status !== data.encryption_status + + this.walletStatus.version = data.version; + this.walletStatus.unlocked_until = data.unlocked_until; + this.walletStatus.protocolversion = data.protocolversion; + this.walletStatus.walletversion = data.walletversion; + this.walletStatus.connections = data.connections; + this.walletStatus.encryption_status = data.encryption_status; + this.walletStatus.errors = data.errors; + + if (encryptionChanged) this.encryptionStatusChanges.emit() + } + } + + private async syncAccounts() { + let accountList: any = await this.rpc.requestData(RPCMethods.GETACCOUNTS); + let newAccountList = new Array(); + // flag all address as to remove + this.accounts.forEach(acc => { + acc.addresses.forEach(addr => addr.removeFromAccount = true) + }) + // add and update accounts from server + accountList.forEach(acc => { + let account = new Account(); + acc.forEach(addr => { + account.addresses.push(new Address(addr, this.matureTime)); + }) + newAccountList.push(account); + // check if have match + let hasMatch = false; + for (let i = 0; i < this.accounts.length; i++) { + if (this.accounts[i].addresses[0] && this.accounts[i].addresses[0].address === account.addresses[0].address) { + this.accounts[i].syncAddresses(account.addresses); + hasMatch = true; + break; + } + } + if (!hasMatch) + this.accounts.push(account); + }) + + // remove any accounts that aren't in the new list from the server + for (let i = 0; i < this.accounts.length; i++) { + let hasMatch = false; + for (let j = 0; j < newAccountList.length; j++) { + if (this.accounts[i].name === newAccountList[j].name) { + hasMatch = true; + break; + } + } + if (!hasMatch) this.accounts.splice(i--, 1); + else this.accounts[i].removeRenamedAddresses(); // remove any addresses that have been renamed + } + this.accountsUpdated.emit(); + } + + private async syncTransactions() { + let transactionData: any = await this.rpc.requestData(RPCMethods.GETTRANSACTIONS, [10]) + if (transactionData && transactionData.length) { + transactionData.forEach(trans => { + let serverTrx = new Transaction(trans); + let hasMatch = false; + for (let i = 0; i < this.transactions.length; i++) { + let localTrx = this.transactions[i]; + if (localTrx.txId === serverTrx.txId && localTrx.blockIndex === localTrx.blockIndex) { + hasMatch = true; + // update confirmations + localTrx.confirmations = serverTrx.confirmations; + localTrx.category = serverTrx.category; + } + } + if (!hasMatch) this.transactions.push(serverTrx) + }) + this.transactions.sort((a, b) => { return b.timestamp.getTime() - a.timestamp.getTime(); }) + } + } + + private async syncStaking() { + let stakingData: any = await this.rpc.requestData(RPCMethods.GETSTAKING); + this.stakingStatus.weight = stakingData.weight; + this.stakingStatus.netStakeWeight = stakingData.netstakeweight; + this.stakingStatus.enabled = stakingData.enabled; + this.stakingStatus.staking = stakingData.staking; + this.getStakingTime(stakingData.expectedtime); + } + + private async syncLatestBlock() { + let blockData: any = await this.rpc.requestData(RPCMethods.GETLATESTBLOCK); + this.walletStatus.latestBlockHeight = blockData.height; + this.walletStatus.latestBlockTime = blockData.time * 1000; + } + + private async getMasternodeInfo(dataSync) { + let data: any = await this.rpc.requestData(RPCMethods.MASTERNODESTATUS); + this.masternode.setup = !data.initRequired; + } + + private async getMasternodeList() { + this.masternode.list = await this.rpc.requestData(RPCMethods.MASTERNODESTATUSALL); + this.masternodeListUpdated.emit(); + } + + private async getMasternodeListConf(dataSync) { + this.masternode.config = await this.rpc.requestData(RPCMethods.MASTERNODELISTCONF); + dataSync.interval = -1; + this.masternodeListUpdated.emit(); + } + + private async getPeersList() { + this.peers = await this.rpc.requestData(RPCMethods.PEERS); + } + + private async getAddressBook() { + let res = await this.rpc.requestData(RPCMethods.ADDRESSBOOKLIST); + if (!res.error) this.addressBook = res + } + + private syncConverstion() { + /* this.http.get(`https://api.coingecko.com/api/v3/coins/linda`) + .subscribe((data: any) => { + this.market = new MarketData(data); + }); + this.conversionSyncTimer = setTimeout(() => this.syncConverstion(), 1000 * 60 * 60) */ + } + // end sync data + + // tunnel methods + public addressBookAdd(address: string, label: string): Promise { + return new Promise(async (resolve, reject) => { + try { + for (let i = 0; i < this.addressBook.length; i++) { + if (this.addressBook[i].address === address) return true; + } + await this.rpc.requestData(RPCMethods.ADDRESSBOOKADD, [address, label]); + // add address to addressbook + this.addressBook.push({ address: address, account: label }); + resolve(); + } catch (ex) { + reject(ex); + } + }) + } + + public addressBookRemove(address: string): Promise { + return new Promise(async (resolve, reject) => { + try { + await this.rpc.requestData(RPCMethods.ADDRESSBOOKREMOVE, [address]); + // remove address to addressbook + for (let i = 0; i < this.addressBook.length; i++) { + if (this.addressBook[i].address === address) { + this.addressBook.splice(i, 1); + break; + } + } + resolve(); + } catch (ex) { + reject(ex); + } + }) + } + + public getTransactions(count, skip): Promise { + return new Promise(async (resolve, reject) => { + try { + let transactionData: any = await this.rpc.requestData(RPCMethods.GETTRANSACTIONS, [count, skip]) + if (transactionData && transactionData.length) { + transactionData.forEach(trans => { + let serverTrx = new Transaction(trans); + let hasMatch = false; + for (let i = 0; i < this.transactions.length; i++) { + let localTrx = this.transactions[i]; + if (localTrx.txId === serverTrx.txId && localTrx.blockIndex === localTrx.blockIndex) { + hasMatch = true; + localTrx.confirmations = serverTrx.confirmations; // update confirmations + } + } + if (!hasMatch) this.transactions.push(serverTrx) + }) + } + resolve(); + } catch (ex) { + reject(ex); + } + }) + } + + public getBlock(hash: string): Promise { + return this.rpc.requestData(RPCMethods.GETBLOCK, [hash]); + } + + public getBlockByNumber(height: number): Promise { + return this.rpc.requestData(RPCMethods.GETBLOCKBYNUMBER, [height]); + } + + public getTransaction(hash: string): Promise { + return this.rpc.requestData(RPCMethods.GETTRANSACTION, [hash]); + } + + public signMessage(address: string, message: string, passphrase: string): Promise { + return this.rpc.requestData(RPCMethods.SIGNMESSAGE, [address, message, passphrase]); + } + + public verifyMessage(address: string, message: string, signature: string): Promise { + return this.rpc.requestData(RPCMethods.VERIFYMESSAGE, [address, signature, message]); + } + + public backupWallet(location: string): Promise { + return this.rpc.requestData(RPCMethods.BACKUPWALLET, [location]); + } + + public changePassphrase(current: string, passphrase: string): Promise { + return this.rpc.requestData(RPCMethods.CHANGEPASSPHRASE, [current, passphrase]); + } + + public encryptWallet(passphrase: string): Promise { + return new Promise(async (resolve, reject) => { + try { + await this.rpc.requestData(RPCMethods.ENCRYPT, [passphrase]); + this.walletStatus.encryption_status = EncryptionStatus.ENCRYPTING; + this.encryptionStatusChanges.emit() + resolve() + } catch (ex) { + reject(ex); + } + }) + } + + public sendTransaction(inputs: any, outputs: any, fee: number, passphrase: string, changeAddress: string): Promise { + return this.rpc.requestData(RPCMethods.CREATETRANSACTION, [inputs, outputs, fee, passphrase, changeAddress]); + } + + public updateAddressAccount(address: Address): Promise { + return this.rpc.requestData(RPCMethods.UPDATELABEL, [address.address, address.newAccount]); + } + + public getNewAddress(account: string): Promise { + return this.rpc.requestData(RPCMethods.NEWADDRESS, [account]); + } + + public unlock(passphrase: string, stakingOnly: boolean = true): Promise { + return this.rpc.requestData(RPCMethods.UNLOCK, [passphrase, stakingOnly]); + } + + public lockWallet(): void { + // we'll handle the lock wallet error here so it's cleaner + // the UI will never need to handle these errors + try { + this.walletStatus.encryption_status = EncryptionStatus.LOCKED; + this.stakingStatus.staking = false; + this.encryptionStatusChanges.emit() + this.rpc.requestData(RPCMethods.LOCK); + } catch (ex) { + this.errorService.diagnose(ex); + } + } + + public lockUnspent(unlock: boolean, input: Input): Promise { + return new Promise(async (resolve, reject) => { + try { + let res = await this.rpc.requestData(RPCMethods.LOCKUNSPENT, [unlock, [{ txid: input.txid, vout: input.vout }]]); + if (res === true) input.locked = !unlock; + if (input.locked) input.selected = false; + resolve() + } catch (ex) { + reject(ex); + } + }) + } + + public masternodeCMD(type: string, params?: Array): Promise { + switch (type) { + case 'start': + return this.rpc.requestData(RPCMethods.MASTERNODESTART, params); + case 'start-alias': + return this.rpc.requestData(RPCMethods.MASTERNODESTARTALIAS, params); + case 'start-many': + return this.rpc.requestData(RPCMethods.MASTERNODESTARTMANY, params); + } + } + + // end tunnel methods + + // public methods + public requireUnlock() { + switch (this.walletStatus.encryption_status) { + case EncryptionStatus.LOCKED: + case EncryptionStatus.LOCKEDFORSTAKING: + case EncryptionStatus.UNLOCKEDANONYMONLY: + return true; + case EncryptionStatus.UNLOCKED: + case EncryptionStatus.UNENCRYPTED: + return false; + } + } + + public canLock() { + switch (this.walletStatus.encryption_status) { + case EncryptionStatus.LOCKED: + case EncryptionStatus.UNENCRYPTED: + return false; + case EncryptionStatus.LOCKEDFORSTAKING: + case EncryptionStatus.UNLOCKEDANONYMONLY: + case EncryptionStatus.UNLOCKED: + return true; + } + } + + public canUnlock() { + switch (this.walletStatus.encryption_status) { + case EncryptionStatus.UNLOCKED: + case EncryptionStatus.UNENCRYPTED: + return false; + case EncryptionStatus.LOCKED: + case EncryptionStatus.LOCKEDFORSTAKING: + case EncryptionStatus.UNLOCKEDANONYMONLY: + return true; + } + } + + public get staking() { + switch (this.walletStatus.encryption_status) { + case EncryptionStatus.UNLOCKED: + case EncryptionStatus.UNENCRYPTED: + case EncryptionStatus.LOCKEDFORSTAKING: + return true; + case EncryptionStatus.LOCKED: + case EncryptionStatus.UNLOCKEDANONYMONLY: + return false; + } + } + + public getTrxProgress(trx) { + let progress = Math.round(trx.confirmations / this.confirmations * 100); + let indicator = { + "right": "0", + } + if (progress === 0) { + indicator["background"] = "none"; + } else if (progress < 100) { + indicator["right"] = 100 - progress + "%"; + } + return indicator; + } + + public getAccounts(hideEmpty: boolean = false) { + let accList = new Array(); + this.accounts.forEach(acc => { + if (acc.name !== 'Unnamed' || acc.balance > 0 || !hideEmpty) + accList.push(acc); + }) + if (hideEmpty && !accList.length && this.accounts.length) accList.push(this.accounts[0]); + + // sort balance descending then name + return accList.sort((a: Account, b) => { + var o1 = a.balance; + var o2 = b.balance; + var p1 = a.name.toLowerCase(); + var p2 = b.name.toLowerCase(); + if (o1 < o2) return 1; + if (o1 > o2) return -1; + if (p1 < p2) return -1; + if (p1 > p2) return 1; + return 0; + }) + + } + + public getStakingTime(returnTime: number) { + if (!returnTime) { + this.stakingStatus.expectedTime = 0; + this.stakingStatus.expectedType = ''; + return; + } + + // check seconds + if (returnTime > 60) { + returnTime = returnTime / 60; + } else { + this.stakingStatus.expectedTime = returnTime; + this.stakingStatus.expectedType = 'seconds'; + return; + } + // check minutes + if (returnTime > 60) { + returnTime = returnTime / 60; + } else { + this.stakingStatus.expectedTime = Math.floor(returnTime); + this.stakingStatus.expectedType = 'minutes'; + return; + } + // check hours + if (returnTime > 60) { + returnTime = returnTime / 24; + } else { + this.stakingStatus.expectedTime = Math.floor(returnTime); + this.stakingStatus.expectedType = 'hours'; + return; + } + + // return days + this.stakingStatus.expectedTime = Math.floor(returnTime); + this.stakingStatus.expectedType = 'days'; + } + + public getWeight() { + if (this.stakingStatus) { + return Math.floor(Helpers.fromSatoshi(this.stakingStatus.weight) as number); + } + return 0; + } + + public getNetWeight() { + if (this.stakingStatus) { + return Math.floor(Helpers.fromSatoshi(this.stakingStatus.netStakeWeight) as number); + } + return 0; + } + // end public methods +} + +export enum DATASYNCTYPES { + WALLET, + ACCOUNTS, + TRANSACTIONS, + STAKING, + LATESTBLOCK, + MASTERNODE, + MASTERNODELIST, + MASTERNODELISTCONF, + PEERSLIST, + ADDRESSBOOK +} + +export class MarketData { + rank: number = 0; + change_24hr: number = 0; + change_7day: number = 0; + change_14day: number = 0; + marketCap: number = 0; + totalSupply: number = 0; + price: number = 0; + + + constructor(marketData?: any) { + if (marketData) { + this.rank = marketData.market_cap_rank; + this.change_24hr = Math.round(Number(marketData.market_data.price_change_percentage_24h) * 100) / 100; + this.change_7day = Math.round(Number(marketData.market_data.price_change_percentage_7d) * 100) / 100; + this.change_14day = Math.round(Number(marketData.market_data.price_change_percentage_14d) * 100) / 100; + this.marketCap = Math.round(marketData.market_data.market_cap.usd); + this.price = marketData.market_data.current_price.usd; + this.totalSupply = Math.round(Number(marketData.market_data.circulating_supply)); + } + } +} \ No newline at end of file diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/assets/jdenticon.js b/src/assets/jdenticon.js new file mode 100644 index 00000000..21e76866 --- /dev/null +++ b/src/assets/jdenticon.js @@ -0,0 +1,1339 @@ +/** + * Jdenticon 2.1.0 + * http://jdenticon.com + * + * Built: 2018-04-15T17:32:59.846Z + * + * Copyright (c) 2014-2018 Daniel Mester Pirttijärvi + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/*jslint bitwise: true */ + +(function (global, name, factory) { + var jQuery = global["jQuery"], + jdenticon = factory(global, jQuery); + + // START patch to work with angular 7 + global[name] = jdenticon; + setInterval(() => global[name](), 250); + // END patch to work with angular 7 +})(this, "jdenticon", function (global, jQuery) { + "use strict"; + +/** + * Creates a new element and adds it to the specified parent. + * @param {Element} parentNode + * @param {string} name + * @param {...*} keyValuePairs + */ +function SvgElement_append(parentNode, name, keyValuePairs) { + var el = document.createElementNS("http://www.w3.org/2000/svg", name); + + for (var i = 2; i + 1 < arguments.length; i += 2) { + el.setAttribute(arguments[i], arguments[i + 1]); + } + + parentNode.appendChild(el); +} + +/** + * Renderer producing SVG output. + * @private + * @constructor + */ +function SvgElement(element) { + // Don't use the clientWidth and clientHeight properties on SVG elements + // since Firefox won't serve a proper value of these properties on SVG + // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811) + // Instead use 100px as a hardcoded size (the svg viewBox will rescale + // the icon to the correct dimensions) + this.size = Math.min( + (Number(element.getAttribute("width")) || 100), + (Number(element.getAttribute("height")) || 100) + ); + this._el = element; + + // Clear current SVG child elements + while (element.firstChild) { + element.removeChild(element.firstChild); + } + + // Set viewBox attribute to ensure the svg scales nicely. + element.setAttribute("viewBox", "0 0 " + this.size + " " + this.size); + element.setAttribute("preserveAspectRatio", "xMidYMid meet"); +} +SvgElement.prototype = { + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ + setBackground: function (fillColor, opacity) { + if (opacity) { + SvgElement_append(this._el, "rect", + "width", "100%", + "height", "100%", + "fill", fillColor, + "opacity", opacity); + } + }, + /** + * Appends a path to the SVG element. + * @param {string} color Fill color on format #xxxxxx. + * @param {string} dataString The SVG path data string. + */ + append: function (color, dataString) { + SvgElement_append(this._el, "path", + "fill", color, + "d", dataString); + } +}; + + + +/** + * Renderer producing SVG output. + * @private + * @constructor + */ +function SvgWriter(size) { + this.size = size; + this._s = + ''; +} +SvgWriter.prototype = { + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ + setBackground: function (fillColor, opacity) { + if (opacity) { + this._s += ''; + } + }, + /** + * Writes a path to the SVG string. + * @param {string} color Fill color on format #rrggbb. + * @param {string} dataString The SVG path data string. + */ + append: function (color, dataString) { + this._s += + ''; + }, + /** + * Gets the rendered image as an SVG string. + */ + toString: function () { + return this._s + ""; + } +}; + + + +var dom = { + /** @const */ + ICON_TYPE_SVG: 1, + + /** @const */ + ICON_TYPE_CANVAS: 2, + + /** @const */ + HASH_ATTRIBUTE: "title", + + /** @const */ + VALUE_ATTRIBUTE: "identicon-canvas", + + supportsQuerySelectorAll: typeof document !== "undefined" && "querySelectorAll" in document, + + getIdenticonType: dom_getIdenticonType +}; + +/** @const */ +dom.ICON_SELECTOR = "[" + dom.HASH_ATTRIBUTE +"],[" + dom.VALUE_ATTRIBUTE +"]"; + +function dom_getIdenticonType(el) { + if (el) { + var tagName = el["tagName"]; + + if (/svg/i.test(tagName)) { + return dom.ICON_TYPE_SVG; + } + + if (/canvas/i.test(tagName) && "getContext" in el) { + return dom.ICON_TYPE_CANVAS; + } + } +} + + + + +/** + * Computes a SHA1 hash for any value and returns it as a hexadecimal string. + * @param {string} message + */ +function sha1(message) { + /** + * Converts an array of 32-bit unsigned numbers to a hexadecimal string in big endian format. + * @param {Array} words + */ + function wordsToHexString(words) { + var hashOctets = []; + for (var i = 0; i < words.length; i++) { + var val = words[i]; + + for (var shift = 28; shift >= 0; shift -= 4) { + var octet = (val >>> shift) & 0xf; + hashOctets.push(octet.toString(16)); + } + } + + return hashOctets.join(""); + } + + /** + * Converts the specified message to a sequence of UTF8 encoded and padded 64 byte blocks. + * @param {string} message Any value that will be padded to 64 byte blocks. + */ + function getBlocks(message) { + var percentEncoded = encodeURI(message), + binaryMessage = [], + binaryMessageLength = 0, + i, b, + + blocks = [], + + BLOCK_SIZE_BYTES = 64, + BLOCK_SIZE_WORDS = BLOCK_SIZE_BYTES >>> 2, + MESSAGE_LENGTH_SIZE_BYTES = 8; + + // UTF8 encode message + for (i = 0; i < percentEncoded.length; i++) { + if (percentEncoded[i] == "%") { + b = parseHex(percentEncoded, i + 1, 2); + i += 2; + } + else { + b = percentEncoded.charCodeAt(i); + } + binaryMessage[binaryMessageLength++] = b; + } + + // Trailing '1' bit + binaryMessage[binaryMessageLength++] = 0x80; + + function getWordBlock(startIndex, byteCount) { + var words = []; + var wordIndex = -1; + + for (var i = 0; i < byteCount; i++) { + wordIndex = (i / 4) | 0; + words[wordIndex] = (words[wordIndex] || 0) + + (binaryMessage[startIndex + i] << ((3 - (i & 3)) * 8)); + } + + while (++wordIndex < BLOCK_SIZE_WORDS) { + words[wordIndex] = 0; + } + + return words; + } + + // Full blocks + for (i = 0; i + BLOCK_SIZE_BYTES <= binaryMessageLength; i+= BLOCK_SIZE_BYTES) { + blocks.push(getWordBlock(i, BLOCK_SIZE_BYTES)); + } + + // Final block(s) + // Rest of message + var lastBlockDataLength = binaryMessageLength - i; + + var block = getWordBlock(i, lastBlockDataLength); + + // If there is no room for the message size in this block, + // return the block and put the size in the following block. + if (lastBlockDataLength + MESSAGE_LENGTH_SIZE_BYTES > BLOCK_SIZE_BYTES) { + // Message size goes in next block + blocks.push(block); + block = getWordBlock(0, 0); + } + + var messageSizeBits = binaryMessageLength * 8 - 8; + block[BLOCK_SIZE_WORDS - 1] = messageSizeBits; + blocks.push(block); + + return blocks; + } + + /** + * Rotates the value a specified number of bits to the left. + * @param {number} value Value to rotate + * @param {number} shift Bit count to shift. + */ + function rotl(value, shift) { + return (value << shift) | (value >>> (32 - shift)); + } + + /** + * Computes a SHA1 hash for the specified array of 64 byte blocks. + * @param {Array>} blocks + */ + function computeHash(blocks) { + var a = 0x67452301, + b = 0xefcdab89, + c = 0x98badcfe, + d = 0x10325476, + e = 0xc3d2e1f0, + hash = [a, b, c, d, e]; + + for (var i = 0; i < blocks.length; i++) { + var w = blocks[i]; + + for (var t = 16; t < 80; t++) { + w[t] = rotl(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1); + } + + for (var t = 0; t < 80; t++) { + var f = + // Ch + t < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 : + + // Parity + t < 40 ? (b ^ c ^ d) + 0x6ed9eba1 : + + // Maj + t < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc : + + // Parity + (b ^ c ^ d) + 0xca62c1d6; + + var T = rotl(a, 5) + f + e + w[t]; + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = T | 0; + } + + hash[0] = a = ((hash[0] + a) | 0); + hash[1] = b = ((hash[1] + b) | 0); + hash[2] = c = ((hash[2] + c) | 0); + hash[3] = d = ((hash[3] + d) | 0); + hash[4] = e = ((hash[4] + e) | 0); + } + + return hash; + } + + return wordsToHexString(computeHash(getBlocks(message))); +} + + + + +/** + * Renderer redirecting drawing commands to a canvas context. + * @param {number=} size + * @private + * @constructor + */ +function CanvasRenderer(ctx, size) { + var width = ctx.canvas.width, + height = ctx.canvas.height; + + ctx.save(); + + this._ctx = ctx; + + if (size) { + this.size = size; + } + else { + this.size = Math.min(width, height); + + ctx.translate( + ((width - this.size) / 2) | 0, + ((height - this.size) / 2) | 0); + } + + ctx.clearRect(0, 0, this.size, this.size); +} +CanvasRenderer.prototype = { + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + setBackground: function (fillColor) { + var ctx = this._ctx, + size = this.size; + + ctx.fillStyle = color.toCss3(fillColor); + ctx.fillRect(0, 0, size, size); + }, + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} fillColor Fill color on format #rrggbb[aa]. + */ + beginShape: function (fillColor) { + this._ctx.fillStyle = color.toCss3(fillColor); + this._ctx.beginPath(); + }, + /** + * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas. + */ + endShape: function () { + this._ctx.fill(); + }, + /** + * Adds a polygon to the rendering queue. + * @param points An array of Point objects. + */ + addPolygon: function (points) { + var ctx = this._ctx, i; + ctx.moveTo(points[0].x, points[0].y); + for (i = 1; i < points.length; i++) { + ctx.lineTo(points[i].x, points[i].y); + } + ctx.closePath(); + }, + /** + * Adds a circle to the rendering queue. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle: function (point, diameter, counterClockwise) { + var ctx = this._ctx, + radius = diameter / 2; + ctx.moveTo(point.x + radius, point.y + radius); + ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise); + ctx.closePath(); + }, + /** + * Called when the icon has been completely drawn. + */ + finish: function () { + this._ctx.restore(); + } +}; + + + + +function decToHex(v) { + v |= 0; // Ensure integer value + return v < 0 ? "00" : + v < 16 ? "0" + v.toString(16) : + v < 256 ? v.toString(16) : + "ff"; +} + +function hueToRgb(m1, m2, h) { + h = h < 0 ? h + 6 : h > 6 ? h - 6 : h; + return decToHex(255 * ( + h < 1 ? m1 + (m2 - m1) * h : + h < 3 ? m2 : + h < 4 ? m1 + (m2 - m1) * (4 - h) : + m1)); +} + +/** + * Functions for converting colors to hex-rgb representations. + * @private + */ +var color = { + /** + * @param {number} r Red channel [0, 255] + * @param {number} g Green channel [0, 255] + * @param {number} b Blue channel [0, 255] + */ + rgb: function (r, g, b) { + return "#" + decToHex(r) + decToHex(g) + decToHex(b); + }, + /** + * @param {string} color Color value to parse. Curently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported. + */ + parse: function (color) { + if (/^#[0-9a-f]{3,8}$/i.test(color)) { + if (color.length < 6) { + var r = color[1], + g = color[2], + b = color[3], + a = color[4] || ""; + return "#" + r + r + g + g + b + b + a + a; + } + if (color.length == 7 || color.length > 8) { + return color; + } + } + }, + /** + * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA" + */ + toCss3: function (hexColor) { + var a = parseHex(hexColor, 7, 2); + if (isNaN(a)) { + return hexColor; + } + var r = parseHex(hexColor, 1, 2), + g = parseHex(hexColor, 3, 2), + b = parseHex(hexColor, 5, 2); + return "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")"; + }, + /** + * @param h Hue [0, 1] + * @param s Saturation [0, 1] + * @param l Lightness [0, 1] + */ + hsl: function (h, s, l) { + // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color + if (s == 0) { + var partialHex = decToHex(l * 255); + return "#" + partialHex + partialHex + partialHex; + } + else { + var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s, + m1 = l * 2 - m2; + return "#" + + hueToRgb(m1, m2, h * 6 + 2) + + hueToRgb(m1, m2, h * 6) + + hueToRgb(m1, m2, h * 6 - 2); + } + }, + // This function will correct the lightness for the "dark" hues + correctedHsl: function (h, s, l) { + // The corrector specifies the perceived middle lightnesses for each hue + var correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ], + corrector = correctors[(h * 6 + 0.5) | 0]; + + // Adjust the input lightness relative to the corrector + l = l < 0.5 ? l * corrector * 2 : corrector + (l - 0.5) * (1 - corrector) * 2; + + return color.hsl(h, s, l); + } +}; + + + + +function observer(updateCallback) { + if (typeof MutationObserver != "undefined") { + var mutationObserver = new MutationObserver(function onmutation(mutations) { + for (var mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) { + var mutation = mutations[mutationIndex]; + var addedNodes = mutation.addedNodes; + + for (var addedNodeIndex = 0; addedNodes && addedNodeIndex < addedNodes.length; addedNodeIndex++) { + var addedNode = addedNodes[addedNodeIndex]; + + // Skip other types of nodes than element nodes, since they might not support + // the querySelectorAll method => runtime error. + if (addedNode.nodeType == Node.ELEMENT_NODE) { + if (dom.getIdenticonType(addedNode)) { + updateCallback(addedNode); + } + else { + var icons = addedNode.querySelectorAll(dom.ICON_SELECTOR); + for (var iconIndex = 0; iconIndex < icons.length; iconIndex++) { + updateCallback(icons[iconIndex]); + } + } + } + } + + if (mutation.type == "attributes" && dom.getIdenticonType(mutation.target)) { + updateCallback(mutation.target); + } + } + }); + + mutationObserver.observe(document.body, { + "childList": true, + "attributes": true, + "attributeFilter": [dom.VALUE_ATTRIBUTE, dom.HASH_ATTRIBUTE, "width", "height"], + "subtree": true + }); + } +} + + + +var shapes = { + center: [ + /** @param {Graphics} g */ + function (g, cell, index) { + var k = cell * 0.42; + g.addPolygon([ + 0, 0, + cell, 0, + cell, cell - k * 2, + cell - k, cell, + 0, cell + ]); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var w = 0 | (cell * 0.5), + h = 0 | (cell * 0.8); + g.addTriangle(cell - w, 0, w, h, 2); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var s = 0 | (cell / 3); + g.addRectangle(s, s, cell - s, cell - s); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var inner = cell * 0.1, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 6 ? 1 : + cell < 8 ? 2 : + (0 | (cell * 0.25)); + + inner = + inner > 1 ? (0 | inner) : // large icon => truncate decimals + inner > 0.5 ? 1 : // medium size icon => fixed width + inner; // small icon => anti-aliased border + + g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var m = 0 | (cell * 0.15), + s = 0 | (cell * 0.5); + g.addCircle(cell - s - m, cell - s - m, s); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var inner = cell * 0.1, + outer = inner * 4; + + // Align edge to nearest pixel in large icons + if (outer > 3) { + outer = 0 | outer; + } + + g.addRectangle(0, 0, cell, cell); + g.addPolygon([ + outer, outer, + cell - inner, outer, + outer + (cell - outer - inner) / 2, cell - inner + ], true); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + g.addPolygon([ + 0, 0, + cell, 0, + cell, cell * 0.7, + cell * 0.4, cell * 0.4, + cell * 0.7, cell, + 0, cell + ]); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + g.addRectangle(0, 0, cell, cell / 2); + g.addRectangle(0, cell / 2, cell / 2, cell / 2); + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var inner = cell * 0.14, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 4 ? 1 : + cell < 6 ? 2 : + (0 | (cell * 0.35)); + + inner = + cell < 8 ? inner : // small icon => anti-aliased border + (0 | inner); // large icon => truncate decimals + + g.addRectangle(0, 0, cell, cell); + g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var inner = cell * 0.12, + outer = inner * 3; + + g.addRectangle(0, 0, cell, cell); + g.addCircle(outer, outer, cell - inner - outer, true); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var m = cell * 0.25; + g.addRectangle(0, 0, cell, cell); + g.addRhombus(m, m, cell - m, cell - m, true); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var m = cell * 0.4, s = cell * 1.2; + if (!index) { + g.addCircle(m, m, s); + } + } + ], + + outer: [ + /** @param {Graphics} g */ + function (g, cell, index) { + g.addTriangle(0, 0, cell, cell, 0); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + g.addTriangle(0, cell / 2, cell, cell / 2, 0); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + g.addRhombus(0, 0, cell, cell); + }, + /** @param {Graphics} g */ + function (g, cell, index) { + var m = cell / 6; + g.addCircle(m, m, cell - 2 * m); + } + ] +}; + + + +/** + * Parses a substring of the hash as a number. + * @param {number} startPosition + * @param {number=} octets + * @noinline + */ +function parseHex(hash, startPosition, octets) { + return parseInt(hash.substr(startPosition, octets), 16); +} + + + +/** + * Prepares a measure to be used as a measure in an SVG path, by + * rounding the measure to a single decimal. This reduces the file + * size of the generated SVG with more than 50% in some cases. + */ +function svgValue(value) { + return ((value * 10 + 0.5) | 0) / 10; +} + +/** + * Represents an SVG path element. + * @private + * @constructor + */ +function SvgPath() { + /** + * This property holds the data string (path.d) of the SVG path. + */ + this.dataString = ""; +} +SvgPath.prototype = { + /** + * Adds a polygon with the current fill color to the SVG path. + * @param points An array of Point objects. + */ + addPolygon: function (points) { + var dataString = "M" + svgValue(points[0].x) + " " + svgValue(points[0].y); + for (var i = 1; i < points.length; i++) { + dataString += "L" + svgValue(points[i].x) + " " + svgValue(points[i].y); + } + this.dataString += dataString + "Z"; + }, + /** + * Adds a circle with the current fill color to the SVG path. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle: function (point, diameter, counterClockwise) { + var sweepFlag = counterClockwise ? 0 : 1, + svgRadius = svgValue(diameter / 2), + svgDiameter = svgValue(diameter); + + this.dataString += + "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) + + "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " " + svgDiameter + ",0" + + "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " " + (-svgDiameter) + ",0"; + } +}; + + + + +/** + * Renderer producing SVG output. + * @private + * @constructor + * @param {SvgElement|SvgWriter} target + */ +function SvgRenderer(target) { + this._pathsByColor = { }; + this._target = target; + this.size = target.size; +} +SvgRenderer.prototype = { + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + setBackground: function (fillColor) { + var match = /^(#......)(..)?/.exec(fillColor), + opacity = match[2] ? parseHex(match[2], 0) / 255 : 1; + this._target.setBackground(match[1], opacity); + }, + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} color Fill color on format #xxxxxx. + */ + beginShape: function (color) { + this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath()); + }, + /** + * Marks the end of the currently drawn shape. + */ + endShape: function () { }, + /** + * Adds a polygon with the current fill color to the SVG. + * @param points An array of Point objects. + */ + addPolygon: function (points) { + this._path.addPolygon(points); + }, + /** + * Adds a circle with the current fill color to the SVG. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle: function (point, diameter, counterClockwise) { + this._path.addCircle(point, diameter, counterClockwise); + }, + /** + * Called when the icon has been completely drawn. + */ + finish: function () { + for (var color in this._pathsByColor) { + this._target.append(color, this._pathsByColor[color].dataString); + } + } +}; + + + + +/** + * Provides helper functions for rendering common basic shapes. + * @private + * @constructor + */ +function Graphics(renderer) { + this._renderer = renderer; + this._transform = Transform.noTransform; +} +Graphics.prototype = { + /** + * Adds a polygon to the underlying renderer. + * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ] + * @param {boolean=} invert Specifies if the polygon will be inverted. + */ + addPolygon: function (points, invert) { + var di = invert ? -2 : 2, + transform = this._transform, + transformedPoints = [], + i; + + for (i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) { + transformedPoints.push(transform.transformPoint(points[i], points[i + 1])); + } + + this._renderer.addPolygon(transformedPoints); + }, + + /** + * Adds a polygon to the underlying renderer. + * Source: http://stackoverflow.com/a/2173084 + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} size The size of the ellipse. + * @param {boolean=} invert Specifies if the ellipse will be inverted. + */ + addCircle: function (x, y, size, invert) { + var p = this._transform.transformPoint(x, y, size, size); + this._renderer.addCircle(p, size, invert); + }, + + /** + * Adds a rectangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle. + * @param {number} w The width of the rectangle. + * @param {number} h The height of the rectangle. + * @param {boolean=} invert Specifies if the rectangle will be inverted. + */ + addRectangle: function (x, y, w, h, invert) { + this.addPolygon([ + x, y, + x + w, y, + x + w, y + h, + x, y + h + ], invert); + }, + + /** + * Adds a right triangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} w The width of the triangle. + * @param {number} h The height of the triangle. + * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle. + * @param {boolean=} invert Specifies if the triangle will be inverted. + */ + addTriangle: function (x, y, w, h, r, invert) { + var points = [ + x + w, y, + x + w, y + h, + x, y + h, + x, y + ]; + points.splice(((r || 0) % 4) * 2, 2); + this.addPolygon(points, invert); + }, + + /** + * Adds a rhombus to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} w The width of the rhombus. + * @param {number} h The height of the rhombus. + * @param {boolean=} invert Specifies if the rhombus will be inverted. + */ + addRhombus: function (x, y, w, h, invert) { + this.addPolygon([ + x + w / 2, y, + x + w, y + h / 2, + x + w / 2, y + h, + x, y + h / 2 + ], invert); + } +}; + + + + +/** + * Gets a set of identicon color candidates for a specified hue and config. + */ +function colorTheme(hue, config) { + hue = config.hue(hue); + return [ + // Dark gray + color.correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)), + // Mid color + color.correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)), + // Light gray + color.correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)), + // Light color + color.correctedHsl(hue, config.colorSaturation, config.colorLightness(1)), + // Dark color + color.correctedHsl(hue, config.colorSaturation, config.colorLightness(0)) + ]; +} + + + +/** + * Represents a point. + * @private + * @constructor + */ +function Point(x, y) { + this.x = x; + this.y = y; +}; + + + + +/** + * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, + * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly. + * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle. + * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle. + * @param {number} size The size of the transformed rectangle. + * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad + * @private + * @constructor + */ +function Transform(x, y, size, rotation) { + this._x = x; + this._y = y; + this._size = size; + this._rotation = rotation; +} +Transform.prototype = { + /** + * Transforms the specified point based on the translation and rotation specification for this Transform. + * @param {number} x x-coordinate + * @param {number} y y-coordinate + * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + */ + transformPoint: function (x, y, w, h) { + var right = this._x + this._size, + bottom = this._y + this._size; + return this._rotation === 1 ? new Point(right - y - (h || 0), this._y + x) : + this._rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) : + this._rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) : + new Point(this._x + x, this._y + y); + } +}; +Transform.noTransform = new Transform(0, 0, 0, 0); + + + + +/** + * Draws an identicon to a specified renderer. + */ +function iconGenerator(renderer, hash, x, y, size, padding, config) { + var undefined; + + // Set background color + if (config.backColor) { + renderer.setBackground(config.backColor); + } + + // Calculate padding and round to nearest integer + padding = (0.5 + size * (padding === undefined ? 0.08 : padding)) | 0; + size -= padding * 2; + + var graphics = new Graphics(renderer); + + // Calculate cell size and ensure it is an integer + var cell = 0 | (size / 4); + + // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon + x += 0 | (padding + size / 2 - cell * 2); + y += 0 | (padding + size / 2 - cell * 2); + + function renderShape(colorIndex, shapes, index, rotationIndex, positions) { + var r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0, + shape = shapes[parseHex(hash, index, 1) % shapes.length], + i; + + renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]); + + for (i = 0; i < positions.length; i++) { + graphics._transform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4); + shape(graphics, cell, i); + } + + renderer.endShape(); + } + + // AVAILABLE COLORS + var hue = parseHex(hash, -7) / 0xfffffff, + + // Available colors for this icon + availableColors = colorTheme(hue, config), + + // The index of the selected colors + selectedColorIndexes = [], + index; + + function isDuplicate(values) { + if (values.indexOf(index) >= 0) { + for (var i = 0; i < values.length; i++) { + if (selectedColorIndexes.indexOf(values[i]) >= 0) { + return true; + } + } + } + } + + for (var i = 0; i < 3; i++) { + index = parseHex(hash, 8 + i, 1) % availableColors.length; + if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo + isDuplicate([2, 3])) { // Disallow light gray and light color combo + index = 1; + } + selectedColorIndexes.push(index); + } + + // ACTUAL RENDERING + // Sides + renderShape(0, shapes.outer, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]); + // Corners + renderShape(1, shapes.outer, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]); + // Center + renderShape(2, shapes.center, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]); + + renderer.finish(); +}; + + + + + + +/** + * Gets the normalized current Jdenticon color configuration. Missing fields have default values. + */ +function getCurrentConfig() { + var configObject = jdenticon["config"] || global["jdenticon_config"] || { }, + lightnessConfig = configObject["lightness"] || { }, + + // In versions < 2.1.0 there was no grayscale saturation - + // saturation was the color saturation. + saturation = configObject["saturation"] || { }, + colorSaturation = "color" in saturation ? saturation["color"] : saturation, + grayscaleSaturation = saturation["grayscale"], + + backColor = configObject["backColor"]; + + /** + * Creates a lightness range. + */ + function lightness(configName, defaultRange) { + var range = lightnessConfig[configName]; + + // Check if the lightness range is an array-like object. This way we ensure the + // array contain two values at the same time. + if (!(range && range.length > 1)) { + range = defaultRange; + } + + /** + * Gets a lightness relative the specified value in the specified lightness range. + */ + return function (value) { + value = range[0] + value * (range[1] - range[0]); + return value < 0 ? 0 : value > 1 ? 1 : value; + }; + } + + /** + * Gets a hue allowed by the configured hue restriction, + * provided the originally computed hue. + */ + function hueFunction(originalHue) { + var hueConfig = configObject["hues"], hue; + + // Check if 'hues' is an array-like object. This way we also ensure that + // the array is not empty, which would mean no hue restriction. + if (hueConfig && hueConfig.length > 0) { + // originalHue is in the range [0, 1] + // Multiply with 0.999 to change the range to [0, 1) and then truncate the index. + hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)]; + } + + return typeof hue == "number" ? + + // A hue was specified. We need to convert the hue from + // degrees on any turn - e.g. 746° is a perfectly valid hue - + // to turns in the range [0, 1). + ((((hue / 360) % 1) + 1) % 1) : + + // No hue configured => use original hue + originalHue; + } + + return { + hue: hueFunction, + colorSaturation: typeof colorSaturation == "number" ? colorSaturation : 0.5, + grayscaleSaturation: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0, + colorLightness: lightness("color", [0.4, 0.8]), + grayscaleLightness: lightness("grayscale", [0.3, 0.9]), + backColor: color.parse(backColor) + } +} + +/** + * Inputs a value that might be a valid hash string for Jdenticon and returns it + * if it is determined valid, otherwise a falsy value is returned. + */ +function getValidHash(hashCandidate) { + return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate; +} + +/** + * Computes a hash for the specified value. Currnently SHA1 is used. This function + * always returns a valid hash. + */ +function computeHash(value) { + return sha1(value == null ? "" : "" + value); +} + +/** + * Updates the identicon in the specified canvas or svg elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered. Can be a CSS selector or a DOM element of the type SVG or CANVAS. + * @param {string=} hash - Optional hash to be rendered. If not specified, the hash specified by the data-jdenticon-hash is used. + * @param {number=} padding - Optional padding in percents. Extra padding might be added to center the rendered identicon. + */ +function update(el, hash, padding) { + if (typeof(el) === "string") { + if (dom.supportsQuerySelectorAll) { + var elements = document.querySelectorAll(el); + for (var i = 0; i < elements.length; i++) { + update(elements[i], hash, padding); + } + } + return; + } + + var iconType = dom.getIdenticonType(el); + if (!iconType) { + return; + } + + // Hash selection. The result from getValidHash or computeHash is + // accepted as a valid hash. + hash = + // 1. Explicit valid hash + getValidHash(hash) || + + // 2. Explicit value (`!= null` catches both null and undefined) + hash != null && computeHash(hash) || + + // 3. `data-jdenticon-hash` attribute + getValidHash(el.getAttribute(dom.HASH_ATTRIBUTE)) || + + // 4. `data-jdenticon-value` attribute. + // We want to treat an empty attribute as an empty value. + // Some browsers return empty string even if the attribute + // is not specified, so use hasAttribute to determine if + // the attribute is specified. + el.hasAttribute(dom.VALUE_ATTRIBUTE) && computeHash(el.getAttribute(dom.HASH_ATTRIBUTE)); + + if (!hash) { + // No hash specified. Don't render an icon. + return; + } + + var renderer = iconType == dom.ICON_TYPE_SVG ? + new SvgRenderer(new SvgElement(el)) : + new CanvasRenderer(el.getContext("2d")); + + // Draw icon + iconGenerator(renderer, hash, 0, 0, renderer.size, padding, getCurrentConfig()); +} + +/** + * Draws an identicon to a context. + * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0). + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + */ +function drawIcon(ctx, hashOrValue, size, padding) { + if (!ctx) { + throw new Error("No canvas specified."); + } + + var renderer = new CanvasRenderer(ctx, size); + iconGenerator(renderer, + getValidHash(hashOrValue) || computeHash(hashOrValue), + 0, 0, size, padding || 0, getCurrentConfig()); +} + +/** + * Draws an identicon as an SVG string. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {number=} padding - Optional padding in percents. Extra padding might be added to center the rendered identicon. + * @returns {string} SVG string + */ +function toSvg(hashOrValue, size, padding) { + var writer = new SvgWriter(size); + var renderer = new SvgRenderer(writer); + iconGenerator(renderer, + getValidHash(hashOrValue) || computeHash(hashOrValue), + 0, 0, size, padding, getCurrentConfig()); + return writer.toString(); +} + +/** + * Updates all canvas elements with the data-jdenticon-hash attribute. + */ +function jdenticon() { + if (dom.supportsQuerySelectorAll) { + update(dom.ICON_SELECTOR); + } +} + +/** + * This function is called once upon page load. + */ +function jdenticonStartup() { + var replaceMode = (jdenticon["config"] || global["jdenticon_config"] || { })["replaceMode"]; + if (replaceMode != "never") { + jdenticon(); + + if (replaceMode == "observe") { + observer(update); + } + } +} + +// Public API +jdenticon["drawIcon"] = drawIcon; +jdenticon["toSvg"] = toSvg; +jdenticon["update"] = update; +jdenticon["version"] = "2.1.0"; + +// Basic jQuery plugin +if (jQuery) { + jQuery["fn"]["jdenticon"] = function (hashOrValue, padding) { + this["each"](function (index, el) { + update(el, hashOrValue, padding); + }); + return this; + }; +} + +// Schedule to render all identicons on the page once it has been loaded. +if (typeof setTimeout === "function") { + setTimeout(jdenticonStartup, 0); +} + + + + + return jdenticon; +}); \ No newline at end of file diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 00000000..53ff5555 Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/assets/qrcode.js b/src/assets/qrcode.js new file mode 100644 index 00000000..5507c154 --- /dev/null +++ b/src/assets/qrcode.js @@ -0,0 +1,614 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see http://www.d-project.com/ + * @see http://jeromeetienne.github.com/jquery-qrcode/ + */ +var QRCode; + +(function () { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + this.parsedData = []; + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = []; + var code = this.data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + this.parsedData.push(byteArray); + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData); + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191); + this.parsedData.unshift(187); + this.parsedData.unshift(239); + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length; + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8); + } + } + }; + + function QRCodeModel(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} + return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row=7){this.setupTypeNumber(test);} + if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} + this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} + return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} + for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} + for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} + this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex>>bitIndex)&1)==1);} + var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} + this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} + row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;itotalDataCount*8){throw new Error("code length overflow. (" + +buffer.getLengthInBits() + +">" + +totalDataCount*8 + +")");} + if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} + while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} + while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD1,8);} + return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r=0)?modPoly.get(modIndex):0;}} + var totalCodeCount=0;for(var i=0;i=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} + return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} + return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} + return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i5){lostPoint+=(3+sameCount-5);}}} + for(var row=0;row=256){n-=255;} + return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} + if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} + this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; + + function _isSupportCanvas() { + return typeof CanvasRenderingContext2D != "undefined"; + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid() { + var android = false; + var sAgent = navigator.userAgent; + + if (/android/i.test(sAgent)) { // android + android = true; + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]); + } + } + + return android; + } + + var svgDrawer = (function() { + + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + + this.clear(); + + function makeSVG(tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); + return el; + } + + var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); + _el.appendChild(svg); + + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG("use", {"x": String(col), "y": String(row)}); + child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") + svg.appendChild(child); + } + } + } + }; + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) + this._el.removeChild(this._el.lastChild); + }; + return Drawing; + })(); + + var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; + + // Drawing in DOM by using Table tag + var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + var aHTML = ['']; + + for (var row = 0; row < nCount; row++) { + aHTML.push(''); + + for (var col = 0; col < nCount; col++) { + aHTML.push(''); + } + + aHTML.push(''); + } + + aHTML.push('
'); + _el.innerHTML = aHTML.join(''); + + // Fix the margin values as real size. + var elTable = _el.childNodes[0]; + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; + } + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = ''; + }; + + return Drawing; + })() : (function () { // Drawing in Canvas + function _onMakeImage() { + this._elImage.src = this._elCanvas.toDataURL("image/png"); + this._elImage.style.display = "block"; + this._elCanvas.style.display = "none"; + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio; + var drawImage = CanvasRenderingContext2D.prototype.drawImage; + CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (("nodeName" in image) && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor; + } + } else if (typeof dw == "undefined") { + arguments[1] *= factor; + arguments[2] *= factor; + arguments[3] *= factor; + arguments[4] *= factor; + } + + drawImage.apply(this, arguments); + }; + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI(fSuccess, fFail) { + var self = this; + self._fFail = fFail; + self._fSuccess = fSuccess; + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement("img"); + var fOnError = function() { + self._bSupportDataURI = false; + + if (self._fFail) { + self._fFail.call(self); + } + }; + var fOnSuccess = function() { + self._bSupportDataURI = true; + + if (self._fSuccess) { + self._fSuccess.call(self); + } + }; + + el.onabort = fOnError; + el.onerror = fOnError; + el.onload = fOnSuccess; + el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. + return; + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self); + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self); + } + }; + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false; + this._android = _getAndroid(); + + this._htOption = htOption; + this._elCanvas = document.createElement("canvas"); + this._elCanvas.width = htOption.width; + this._elCanvas.height = htOption.height; + el.appendChild(this._elCanvas); + this._el = el; + this._oContext = this._elCanvas.getContext("2d"); + this._bIsPainted = false; + this._elImage = document.createElement("img"); + this._elImage.alt = "Scan me!"; + this._elImage.style.display = "none"; + this._el.appendChild(this._elImage); + this._bSupportDataURI = null; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage; + var _oContext = this._oContext; + var _htOption = this._htOption; + + var nCount = oQRCode.getModuleCount(); + var nWidth = _htOption.width / nCount; + var nHeight = _htOption.height / nCount; + var nRoundedWidth = Math.round(nWidth); + var nRoundedHeight = Math.round(nHeight); + + _elImage.style.display = "none"; + this.clear(); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col); + var nLeft = col * nWidth; + var nTop = row * nHeight; + _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.lineWidth = 1; + _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.fillRect(nLeft, nTop, nWidth, nHeight); + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ); + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ); + } + } + + this._bIsPainted = true; + }; + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage); + } + }; + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted; + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); + this._bIsPainted = false; + }; + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber; + } + + return Math.floor(nNumber * 1000) / 1000; + }; + + return Drawing; + })(); + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber(sText, nCorrectLevel) { + var nType = 1; + var length = _getUTF8Length(sText); + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0; + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L : + nLimit = QRCodeLimitLength[i][0]; + break; + case QRErrorCorrectLevel.M : + nLimit = QRCodeLimitLength[i][1]; + break; + case QRErrorCorrectLevel.Q : + nLimit = QRCodeLimitLength[i][2]; + break; + case QRErrorCorrectLevel.H : + nLimit = QRCodeLimitLength[i][3]; + break; + } + + if (length <= nLimit) { + break; + } else { + nType++; + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error("Too long data"); + } + + return nType; + } + + function _getUTF8Length(sText) { + var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); + return replacedText.length + (replacedText.length != sText ? 3 : 0); + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width : 256, + height : 256, + typeNumber : 4, + colorDark : "#000000", + colorLight : "#ffffff", + correctLevel : QRErrorCorrectLevel.H + }; + + if (typeof vOption === 'string') { + vOption = { + text : vOption + }; + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i]; + } + } + + if (typeof el == "string") { + el = document.getElementById(el); + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer; + } + + this._android = _getAndroid(); + this._el = el; + this._oQRCode = null; + this._oDrawing = new Drawing(this._el, this._htOption); + + if (this._htOption.text) { + this.makeCode(this._htOption.text); + } + }; + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); + this._oQRCode.addData(sText); + this._oQRCode.make(); + this._el.title = sText; + this._oDrawing.draw(this._oQRCode); + this.makeImage(); + }; + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { + this._oDrawing.makeImage(); + } + }; + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear(); + }; + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel; +})(); diff --git a/src/assets/styles/button.scss b/src/assets/styles/button.scss new file mode 100644 index 00000000..8a9f3291 --- /dev/null +++ b/src/assets/styles/button.scss @@ -0,0 +1,111 @@ +button { + &:hover, + &:active, + &:focus { + outline: none; + } +} + +.btn { + height: 35px; + min-width: 100px; + -webkit-border-radius: 25px; + border-radius: 25px; + cursor: pointer; + border-color: transparent; + color: $font-primary; + text-align: center; + background: none; + padding: 0 10px; + margin: 2px; + transition: background-color 0.15s ease-in-out, color 0.05s ease-in-out; + &.btn-link { + text-align: left; + font-size: initial; + padding: 0; + margin: 0; + border: none !important; + min-width: 0; + height: auto; + } + &.btn-sm { + font-size: 12px; + min-width: 0; + height: 25px; + } + &.btn-default { + color: $font-primary; + border: 2px solid $font-primary; + &:hover { + animation: glow-default 2s ease-in infinite; + color: $background-primary; + background-color: $font-primary; + } + } + &.btn-primary { + color: $color-primary; + border: 2px solid $color-primary; + &:hover { + animation: glow-primary 2s ease-in infinite; + color: $font-primary; + background-color: $color-primary; + } + } + &.btn-success { + color: $color-success; + border: 2px solid $color-success; + &:hover { + animation: glow-success 2s ease-in infinite; + color: $font-primary; + background-color: $color-success; + } + } + &.btn-danger { + color: $color-danger; + border: 2px solid $color-danger; + &:hover { + animation: glow-danger 2s ease-in infinite; + color: $font-primary; + background-color: $color-danger; + } + } + &.btn-icon { + min-width: 10px; + } + &[disabled] { + cursor: default; + filter: brightness(50%); + } +} + +@keyframes glow-primary { + 35% { + border-color: lighten($color: $color-primary, $amount: 5%); + background: lighten($color: $color-primary, $amount: 5%); + box-shadow: 0 0 20px lighten($color: rgba($color-primary, .4), $amount: 5%); + } +} + +@keyframes glow-success { + 35% { + border-color: lighten($color: $color-success, $amount: 5%); + background: lighten($color: $color-success, $amount: 5%); + box-shadow: 0 0 20px lighten($color: rgba($color-success, .4), $amount: 5%); + } +} + +@keyframes glow-danger { + 35% { + border-color: lighten($color: $color-danger, $amount: 5%); + background: lighten($color: $color-danger, $amount: 5%); + box-shadow: 0 0 20px lighten($color: rgba($color-danger, .4), $amount: 5%); + } +} + +@keyframes glow-default { + 35% { + border-color: lighten($color: $font-primary, $amount: 5%); + background: lighten($color: $font-primary, $amount: 5%); + box-shadow: 0 0 20px lighten($color: rgba($font-primary, .4), $amount: 5%); + } +} \ No newline at end of file diff --git a/src/assets/styles/checkbox.scss b/src/assets/styles/checkbox.scss new file mode 100644 index 00000000..3313a87a --- /dev/null +++ b/src/assets/styles/checkbox.scss @@ -0,0 +1,47 @@ +input[type="checkbox" i] { + position: absolute; // take it out of document flow + opacity: 0; // hide it + &+label { + position: relative; + cursor: pointer; + padding: 0; + } // Box. + &+label:before { + content: ''; + margin-right: 10px; + display: inline-block; + vertical-align: text-top; + border-radius: 99px; + width: 20px; + height: 20px; + background: white; + } // Box hover + &:hover+label:before { + background: $color-primary; + } // Box focus + &:focus+label:before { + box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12); + } // Box checked + &:checked+label:before { + background: $color-primary; + } // Disabled state label. + &:disabled+label { + color: #b8b8b8; + cursor: auto; + } // Disabled box. + &:disabled+label:before { + box-shadow: none; + background: #ddd; + } // Checkmark. Could be replaced with an image + &:checked+label:after { + content: ''; + position: absolute; + left: 5px; + top: 9px; + background: white; + width: 2px; + height: 2px; + box-shadow: 2px 0 0 white, 4px 0 0 white, 4px -2px 0 white, 4px -4px 0 white, 4px -6px 0 white, 4px -8px 0 white; + transform: rotate(45deg); + } +} \ No newline at end of file diff --git a/src/assets/styles/clientStatus.scss b/src/assets/styles/clientStatus.scss new file mode 100644 index 00000000..a7e5d5f5 --- /dev/null +++ b/src/assets/styles/clientStatus.scss @@ -0,0 +1,128 @@ +.clienstatus-backdrop { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + flex-direction: column; + background: rgba(0, 0, 0, 0.8); + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; +} + +#clienstatus-loading { + display: block; + position: relative; + left: 50%; + top: 50%; + width: 150px; + height: 150px; + margin: 0 0 0 -75px; + border: 3px solid #F00; +} + +#clienstatus-loading:after { + content: ""; + position: absolute; + border: 3px solid #0F0; + left: 15px; + right: 15px; + top: 15px; + bottom: 15px; +} + +#clienstatus-loading:before { + content: ""; + position: absolute; + border: 3px solid #00F; + left: 5px; + right: 5px; + top: 5px; + bottom: 5px; +} + +#clienstatus-loading { + border: 3px solid transparent; + border-top-color: #4D658D; + border-bottom-color: #4D658D; + border-radius: 50%; + -webkit-animation: loader 2s linear infinite; + -moz-animation: loader 2s linear infinite; + -o-animation: loader 2s linear infinite; + animation: loader 2s linear infinite; +} + +#clienstatus-loading:before { + border: 3px solid transparent; + border-top-color: #D4CC6A; + border-bottom-color: #D4CC6A; + border-radius: 50%; + -webkit-animation: loader 3s linear infinite; + -moz-animation: loader 2s linear infinite; + -o-animation: loader 2s linear infinite; + animation: loader 3s linear infinite; +} + +#clienstatus-loading:after { + border: 3px solid transparent; + border-top-color: #fe6c01; + border-bottom-color: #fe6c01; + border-radius: 50%; + -webkit-animation: loader 1.5s linear infinite; + animation: loader 1.5s linear infinite; + -moz-animation: loader 2s linear infinite; + -o-animation: loader 2s linear infinite; +} + +@-webkit-keyframes loaders { + 0% { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes loader { + 0% { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +#content-wrapper { + color: #FFF; + position: fixed; + left: 0; + top: 20px; + width: 100%; + height: 100%; +} + +#header { + width: 800px; + margin: 0 auto; + text-align: center; + height: 100px; + background-color: #666; +} + +#content { + width: 800px; + height: 1000px; + margin: 0 auto; + text-align: center; + background-color: #888; +} \ No newline at end of file diff --git a/src/assets/styles/contextMenu.scss b/src/assets/styles/contextMenu.scss new file mode 100644 index 00000000..07990a4a --- /dev/null +++ b/src/assets/styles/contextMenu.scss @@ -0,0 +1,17 @@ +.context-menu { + display: none; + position: absolute; + left: 0; + top: 0; + &.visible { + display: block; + z-index: 1050; + } + .dropdown { + height: 0; + } + .dropdown-content { + display: block; + top: 0; + } +} \ No newline at end of file diff --git a/src/assets/styles/modal.scss b/src/assets/styles/modal.scss new file mode 100644 index 00000000..426e4846 --- /dev/null +++ b/src/assets/styles/modal.scss @@ -0,0 +1,55 @@ +ngx-smart-modal { + .nsm-dialog { + max-width: 100%; + justify-content: center; + } + h1 { + margin-top: .5em; + margin-bottom: 1em; + } + .nsm-content { + background-color: $background-primary; + min-width: 400px; + } + .nsm-body, + form { + display: flex; + flex-direction: column; + } + form { + textarea, + input:not([type]), + input[type="email" i], + input[type="number" i], + input[type="password" i], + input[type="tel" i], + input[type="url" i], + input[type="text" i] { + margin-bottom: 5px; + } + } + .nsm-dialog-btn-close { + color: $font-primary; + } + .modal-buttons-end { + display: flex; + justify-content: flex-end; + margin-top: 2em; + } + .modal-buttons { + display: flex; + justify-content: space-between; + margin-top: 2em; + } + .alert-modal { + .nsm-content { + width: 400px; + } + } +} + +.address-book { + .nsm-content { + width: 100%; + } +} \ No newline at end of file diff --git a/src/assets/styles/tables.scss b/src/assets/styles/tables.scss new file mode 100644 index 00000000..e57472df --- /dev/null +++ b/src/assets/styles/tables.scss @@ -0,0 +1,76 @@ +.table-wrapper { + overflow: auto +} + +.table { + width: 100%; + border-spacing: 0; + border: .5px solid; + thead { + th { + border-bottom: 1px solid; + padding: 15px 5px; + border-top: .5px solid; + &:first-child { + border-left: 1px solid; + } + &:last-child { + border-right: 1px solid; + } + } + } + td { + border-bottom: .5px solid; + padding: 5px; + &.actions { + text-align: center; + } + textarea, + input:not([type]), + input[type="email" i], + input[type="number" i], + input[type="password" i], + input[type="tel" i], + input[type="url" i], + input[type="text" i] { + border: none; + } + } +} + +.table-explorer { + text-align: left; + word-break: break-word; + margin-bottom: 20px; + th { + border-bottom: .5px solid; + padding: 5px; + } + th:first-child { + min-width: 110px; + } + .vinvout { + padding: 5px; + display: flex; + align-items: center; + .badge { + margin-left: 5px + } + } +} + +.table-repair { + .btn { + width: 170px; + } +} + +.table-tools { + width: 100%; + .title { + min-width: 60px; + h4 { + margin: 1em 0; + } + } +} \ No newline at end of file diff --git a/src/assets/styles/tabs.scss b/src/assets/styles/tabs.scss new file mode 100644 index 00000000..593bfe3a --- /dev/null +++ b/src/assets/styles/tabs.scss @@ -0,0 +1,37 @@ +.tabs { + border-bottom: 1px solid darken($color: $font-primary, $amount: 40%); + margin-bottom: 20px; + position: fixed; + right: 20px; + left: 270px; + background: $background-primary; + z-index: 10; + margin-top: -10px; + button { + background: none; + color: darken($color: $font-primary, $amount: 40%); + border: none; + padding: 10px; + cursor: pointer; + &:hover, + &:active, + &:focus { + color: darken($color: $font-primary, $amount: 20%); + border-bottom: 1px solid darken($color: $font-primary, $amount: 20%); + padding-bottom: 9px; + } + &.active { + color: $font-primary; + border-bottom: 1px solid $font-primary; + padding-bottom: 9px; + } + } + &.not-fixed { + position: initial; + margin-top: 0; + } +} + +.tab-content { + margin-top: 50px +} \ No newline at end of file diff --git a/src/assets/styles/titlebar.scss b/src/assets/styles/titlebar.scss new file mode 100644 index 00000000..ad2bb9a7 --- /dev/null +++ b/src/assets/styles/titlebar.scss @@ -0,0 +1,170 @@ +.titlebar { + z-index: 100; + position: fixed; + right: -1px; + top: -1px; + display: block; + height: 32px; + padding: 0; + -webkit-app-region: drag; + background: $background-primary +} + +.titlebar-controls { + float: right; + text-align: left; +} + +.titlebar:after, +.titlebar-controls:after { + content: ' '; + display: table; + clear: both; +} + +.titlebar-minimize, +.titlebar-resize, +.titlebar-close { + float: left; + width: 45px; + height: 31px; + margin: 1px 1px 0 0; + text-align: center; + line-height: 29px; + -webkit-transition: background-color .2s; + -moz-transition: background-color .2s; + -ms-transition: background-color .2s; + -o-transition: background-color .2s; + transition: background-color .2s; + -webkit-app-region: no-drag; +} + +.titlebar-minimize svg, +.titlebar-resize svg.maximize-svg, +.titlebar-resize svg.fullscreen-svg, +.titlebar-close svg { + width: 10px; + height: 10px; + shape-rendering: crispEdges; +} + +.titlebar-close svg polygon { + -webkit-transition: fill .2s; + -moz-transition: fill .2s; + -ms-transition: fill .2s; + -o-transition: fill .2s; + transition: fill .2s; +} + +.titlebar:not(.fullscreen) svg.maximize-svg { + display: none; +} + +.titlebar.fullscreen svg.fullscreen-svg { + display: none; +} + +.titlebar-minimize:hover, +.titlebar-resize:hover, +.titlebar-fullscreen:hover { + background-color: rgba(255, 255, 255, 0.1); +} + +.titlebar-light .titlebar-minimize:hover, +.titlebar-light .titlebar-resize:hover, +.titlebar-light .titlebar-fullscreen:hover { + background-color: rgba(0, 0, 0, 0.1); +} + +.titlebar-close:hover { + background-color: rgba(232, 17, 35, 0.9); +} + +.titlebar-close:hover svg polygon { + fill: rgba(255, 255, 255, 1); +} + +.titlebar-light .titlebar-close:hover { + fill: rgba(0, 0, 0, 1); +} + +.titlebar-light svg polygon, +.titlebar-light svg rect, +.titlebar-light svg>path { + fill: rgba(255, 255, 255, 1); +} + +.titlebar-light .titlebar-close:hover { + background-color: rgba(232, 17, 35, 0.9); +} + +.titlebar-menu { + position: fixed; + left: 0; + top: 0; + z-index: 100; + display: flex; + hr { + border-color: rgba(255, 255, 255, .1); + margin: 2px 6px; + } + .dropdown { + height: 32px; + display: flex; + .dropbtn { + -webkit-transition: fill .2s; + -moz-transition: fill .2s; + -ms-transition: fill .2s; + -o-transition: fill .2s; + transition: fill .2s; + padding: 0 8px; + font-size: 14px; + border: none; + color: $font-primary; + background-color: inherit; + &:hover, + &:active { + background-color: rgba(255, 255, 255, 0.1) + } + } + } + &.selected { + .dropdown:hover, + .dropdown.hover { + .dropbtn { + background-color: rgba(255, 255, 255, 0.1) + } + .dropdown-content { + display: block; + } + } + } + .dropdown-content { + display: none; + top: 32px; + background: $background-accent; + position: absolute; + min-width: 160px; + box-shadow: 0px 2px 3px 1px rgba(0, 0, 0, 0.5); + z-index: 1; + padding: 5px 0; + button { + float: none; + font-size: 14px; + color: $font-primary; + white-space: nowrap; + padding: 5px 20px; + display: block; + text-align: left; + background: none; + border: none; + margin: 0; + width: 100%; + &:hover, + &:active, + &:focus { + background-color: $background-primary; + } + } + } +} \ No newline at end of file diff --git a/src/assets/styles/variables.scss b/src/assets/styles/variables.scss new file mode 100644 index 00000000..e3faac71 --- /dev/null +++ b/src/assets/styles/variables.scss @@ -0,0 +1,6 @@ +$color-primary: #fe6c01; +$color-success:#28a745; +$color-danger:#dc3545; +$font-primary:white; +$background-primary:#151727; +$background-accent:#1d1f36; \ No newline at end of file diff --git a/src/environments/environment.dev.ts b/src/environments/environment.dev.ts new file mode 100644 index 00000000..7953ebf8 --- /dev/null +++ b/src/environments/environment.dev.ts @@ -0,0 +1,9 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `index.ts`, but if you do +// `ng build --env=prod` then `index.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +export const AppConfig = { + production: false, + environment: 'DEV' +}; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 00000000..047b3fce --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,4 @@ +export const AppConfig = { + production: true, + environment: 'PROD' +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 00000000..ca0b6a9c --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,4 @@ +export const AppConfig = { + production: false, + environment: 'LOCAL' +}; diff --git a/src/index.html b/src/index.html new file mode 100644 index 00000000..524330f8 --- /dev/null +++ b/src/index.html @@ -0,0 +1,25 @@ + + + + + + Altitude + + + + + + + + + + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 00000000..6ad7b100 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,15 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { AppConfig } from './environments/environment'; + +if (AppConfig.production) { + enableProdMode(); +} + +platformBrowserDynamic() + .bootstrapModule(AppModule, { + preserveWhitespaces: false + }) + .catch(err => console.error(err)); diff --git a/src/polyfills-test.ts b/src/polyfills-test.ts new file mode 100644 index 00000000..332646f5 --- /dev/null +++ b/src/polyfills-test.ts @@ -0,0 +1,3 @@ +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; + diff --git a/src/polyfills.ts b/src/polyfills.ts new file mode 100644 index 00000000..d3e73dd8 --- /dev/null +++ b/src/polyfills.ts @@ -0,0 +1,84 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + + +/** Evergreen browsers require these. **/ +// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. +import 'core-js/es7/reflect'; + + +/** + * Required to support Web Animations `@angular/platform-browser/animations`. + * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + */ + +// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame +// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick +// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + +/* +* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js +* with the following flag, it will bypass `zone.js` patch for IE/Edge +*/ +// (window as any).__Zone_enable_cross_context_check = true; + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js/dist/zone-mix'; // Included with Angular CLI. + +/** + * You can load zone-patch-electron to allow electron native APIs + * (Such as dialog/shortcut/menu/getFileIcon/shell/session/ + * desktopCapturer/onEvent) in ngZone + */ +// import 'zone.js/dist/zone-patch-electron'; // add zone-patch-electron to patch Electron native API + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/src/styles.scss b/src/styles.scss new file mode 100644 index 00000000..30f6fcb0 --- /dev/null +++ b/src/styles.scss @@ -0,0 +1,654 @@ +/* You can add global styles to this file, and also import other style files */ + +@import "~ngx-smart-modal/ngx-smart-modal"; +@import "./assets/styles/variables"; +@import "./assets/styles/button"; +@import "./assets/styles/modal"; +@import "./assets/styles/titlebar"; +@import "./assets/styles/clientStatus.scss"; +@import "./assets/styles/tabs.scss"; +@import "./assets/styles/tables.scss"; +@import "./assets/styles/contextMenu.scss"; +@import "./assets/styles/checkbox.scss"; +html, +body { + overflow: hidden; + margin: 0; + padding: 0; + background-color: $background-primary; +} + +body { + --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; + display: flex; + color: $font-primary; + flex-direction: column; + padding-top: 31px; + -webkit-app-region: drag; +} + +button, +a { + -webkit-app-region: no-drag; +} + +.wrapper { + position: absolute; + top: 31px; + bottom: 9px; + right: 0; + left: 0; + margin-left: 250px; + flex: 1; +} + +.block { + display: block; +} + +.pointer { + cursor: pointer; +} + +h1 { + font-size: 1.5em; +} + +h2 { + font-size: 1.25em; + .subtitle { + font-size: .75em + } +} + +a { + -webkit-user-drag: none; +} + +.success { + color: $color-success; +} + +.danger { + color: $color-danger; +} + +.primary { + color: $color-primary; +} + +.flex { + display: flex; +} + +.right { + float: right; +} + +.content { + overflow: auto; + height: 100%; + padding-top: 10px; + padding-left: 20px; + padding-right: 20px; + position: sticky; +} + +.sidebar { + position: fixed; + bottom: 0; + top: 0; + width: 250px; + min-width: 250px; + background: $background-accent; + display: flex; + flex-direction: column; + justify-content: space-between; + .sidebar-top { + display: flex; + flex-direction: column; + align-items: center; + width: 250px; + min-width: 250px; + } + .logo { + height: 125px; + padding-top: 20px; + } + h3 { + color: $color-primary; + font-weight: normal; + margin: 0; + font-size: 16px; + } + .balance-currency { + font-size: 10px; + } + ul { + width: 100%; + padding: 0; + list-style: none; + list-style-image: none; + a { + color: $font-primary; + display: block; + padding: 10px 20px; + text-decoration: none; + &:hover, + &:active, + &.active { + background: $background-primary; + color: $color-primary; + } + fa-icon { + margin-right: 10px; + } + } + } + .wallet-sync { + display: flex; + flex: 1; + flex-direction: column; + padding: 10px; + justify-content: flex-end; + font-size: 14px; + align-items: flex-start; + line-height: 20px; + width: 100%; + fa-icon { + margin-right: 5px; + } + } + .wallet-status { + width: 100%; + padding-bottom: 10px; + fa-icon { + margin: 5px; + &:first-child { + margin-left: 10px; + } + } + } +} + +// Accounts +.accounts { + display: flex; + flex-wrap: wrap; +} + +.account { + background-color: $background-accent; + min-width: 300px; + border-radius: 6px; + margin: 10px; + flex-grow: 1; + position: relative; + overflow: hidden; + z-index: 1; + cursor: pointer; + .account-inner { + width: 100%; + float: left; + z-index: 1; + position: relative; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + } + .account-identicon { + padding-right: 15px; + } + .account-name { + display: flex; + align-items: center; + padding: 10px; + padding-bottom: 0; + h5 { + padding: 0 10px; + margin: 0; + font-weight: 700; + letter-spacing: 1px; + text-transform: uppercase; + } + } + .account-balance { + padding: 0 10px; + margin: 0px; + color: $color-primary; + font-size: 16px; + line-height: 1.8; + span { + font-size: 12px; + } + } + .account-address { + padding: 10px; + padding-top: 0; + margin: 0px; + font-size: 10px; + font-weight: normal; + line-height: 1.8; + } + .wave { + height: 100%; + width: 100%; + position: relative; + background: lighten($color: $background-primary, $amount: 10%); + z-index: -1; + } + .wave:before, + .wave:after { + content: ""; + display: block; + position: absolute; + background: lighten($color: $background-primary, $amount: 20%); + background: -moz-linear-gradient(top, lighten($color: $background-primary, $amount: 20%) 0%, rgba(lighten($color: $background-primary, $amount: 35%), 0.3) 100%); + background: -webkit-gradient(left top, left bottom, color-stop(0%, lighten($color: $background-primary, $amount: 20%)), color-stop(100%, rgba(lighten($color: $background-primary, $amount: 35%), 0.3))); + background: -webkit-linear-gradient(top, lighten($color: $background-primary, $amount: 20%) 0%, rgba(lighten($color: $background-primary, $amount: 35%), 0.3) 100%); + background: -o-linear-gradient(top, lighten($color: $background-primary, $amount: 20%) 0%, rgba(lighten($color: $background-primary, $amount: 35%), 0.3) 100%); + background: -ms-linear-gradient(top, lighten($color: $background-primary, $amount: 20%) 0%, rgba(lighten($color: $background-primary, $amount: 35%), 0.3) 100%); + background: linear-gradient(to bottom, lighten($color: $background-primary, $amount: 20%) 0%, rgba(lighten($color: $background-primary, $amount: 35%), 0.3) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c10e1a', endColorstr='#f1404c', GradientType=0); + -webkit-border-radius: 50% 50%; + -moz-border-radius: 50% 50%; + border-radius: 50% 50%; + } + .wave:after { + height: 200%; + width: 100%; + left: 35%; + top: 20%; + opacity: 0.8; + } + .wave:before { + height: 360px; + width: 360px; + left: -5%; + top: -70%; + } +} + +.account-identicon { + display: flex; + justify-content: flex-end; + canvas { + background: $background-primary; + border-radius: 99px; + padding: 6px; + } +} + +// Transactions +.transactions { + width: 100%; + padding-bottom: 10px; + .transaction { + height: 92px; + display: flex; + align-items: center; + border-bottom: 1px solid $background-primary; + position: relative; + .icon { + padding: 15px; + } + .detail { + flex: 1; + padding: 10px 0; + } + .value { + padding: 10px; + padding-left: 0; + text-align: right; + .small { + font-size: 12px; + } + } + &.confirmed { + background: $background-accent; + } + } + .progress { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: -1; + &.unconfirmed { + transition: right 2s; + background: -webkit-linear-gradient(left, $background-accent 30%, lighten($color: $background-accent, $amount: 10%) 80%, $background-accent 100%) repeat; + -webkit-background-size: 50% 100%; + -webkit-animation-name: moving-gradient; + -webkit-animation-duration: 3s; + -webkit-animation-iteration-count: infinite; + -webkit-animation-timing-function: linear; + } + &.confirmed { + background: $background-accent; + } + } + tr { + background: $background-accent; + -webkit-transition: background-image 1s ease-in-out; + transition: background-image 1s ease-in-out; + } + h5 { + padding: 0 10px; + margin: 0px; + line-height: 1.8; + } + h6 { + padding: 0 10px; + margin: 0px; + font-size: 14px; + font-weight: 400; + line-height: 1.8; + } +} + +@-webkit-keyframes moving-gradient { + 0% { + background-position: left bottom; + } + 100% { + background-position: right bottom; + } +} + +// maanage account +.manage-account-wrapper { + display: flex; + flex: 1; + justify-content: center; + align-items: center; + padding-top: 20px; + .account-identicon { + margin-right: 20px; + canvas { + background: $background-accent !important; + } + } + .account-name { + display: flex; + align-items: center; + fa-icon { + font-size: 24px; + } + input { + background: none; + border: none; + color: white; + margin-left: 10px; + font-size: 24px; + &:focus { + outline: none; + } + } + } + h2, + h4 { + margin: 5px 0; + } + h2 { + color: $color-primary; + span { + font-size: 14px + } + } +} + +.manage-account-actions { + display: flex; + align-items: center; + justify-content: center; + padding: 20px; + padding-bottom: 30px; +} + +.qrcode-wrapper { + display: flex; + justify-content: center; + #qrcode { + padding: 10px; + background: white; + border-radius: 4px; + width: 129px; + } +} + +// inputs +textarea, +input:not([type]), +input[type="email" i], +input[type="number" i], +input[type="password" i], +input[type="tel" i], +input[type="url" i], +input[type="text" i] { + border: 1px solid white; + border-radius: 99px; + padding: 10px 20px; + color: white; + background: none; + &:focus, + &:active { + outline: none; + } + &[disabled] { + background: rgba(0, 0, 0, 0.3); + } +} + +// checkbox +// forms +.form-inline { + display: flex; + align-items: center; + padding: 5px; + textarea, + input:not([type]), + input[type="email" i], + input[type="number" i], + input[type="password" i], + input[type="tel" i], + input[type="url" i], + input[type="text" i] { + flex: 1; + margin-left: 5px; + } + span { + min-width: 80px; + } +} + +// titlebar +// send +.toolbar-bottom { + position: fixed; + bottom: 0; + left: 250px; + right: 0; + padding: 10px; + background: $background-primary; + input:not([type]), + input[type="email" i], + input[type="number" i], + input[type="password" i], + input[type="tel" i], + input[type="url" i], + input[type="text" i] { + flex: 1; + } +} + +.send-recipients { + margin-bottom: 150px; +} + +.send-recipient { + position: relative; + background: $background-accent; + border-radius: 6px; + padding: 10px; + margin-bottom: 5px; + padding-top: 35px; + .close { + position: absolute; + right: 0; + top: 0; + } +} + +.send-source { + background: $background-accent; + border-radius: 6px; + padding: 10px; + margin-bottom: 50px; + h4 { + margin-top: 1em; + } +} + +.inputs-list { + table { + border-spacing: 0; + width: 100%; + th { + background: $background-primary; + padding: 5px; + } + td { + padding: 5px; + text-align: center; + fa-icon { + margin-left: -10px; + } + } + tbody { + td:nth-child(4) { + font-size: 12px + } + } + } +} + +.inputs-header { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + padding: 5px; + p { + margin: 5px + } +} + +.inputs-header-wrapper { + border: 1px solid white; + border-radius: 6px; + margin-bottom: 10px; +} + +.send-summary { + text-align: right; + h5:first-child { + margin-top: 0; + } +} + +.notification-box { + background: $background-accent; + border-radius: 6px; + padding: 10px; +} + +.information-table { + margin-top: 1em; + text-align: left; + h4 { + margin-top: 10px; + margin-bottom: 5px; + } +} + +//debug console +.rpc-commands { + margin-bottom: 70px; + font-family: monospace; + fa-icon { + margin-right: 10px; + } + .line { + display: flex; + padding: 3px 0; + } + pre { + white-space: pre-wrap; + word-break: break-word; + margin: 0; + } + .timestamp { + min-width: 90px; + } +} + +// scrollbar +::-webkit-scrollbar { + width: .4em; +} + +::-webkit-scrollbar, +::-webkit-scrollbar-thumb { + overflow: visible; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, .2); +} + +.cover-bar { + position: absolute; + background: $background-primary; + height: 100%; + top: 0; + right: 0; + width: .4em; + -webkit-transition: all .5s; + opacity: 1; + z-index: 1; +} + +.page:hover .cover-bar { + opacity: 0; + visibility: hidden; + -webkit-transition: all .5s; +} + +.badge { + border-radius: 99px; + font-size: 12px; + padding: 2px 4px; + text-align: center; + &.primary { + background: $color-primary; + color: inherit !important; + } +} + +.alerts { + padding: 10px; + border-radius: 5px; + background: $color-danger; + h1 { + margin: 0; + } +} \ No newline at end of file diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 00000000..16317897 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,20 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json new file mode 100644 index 00000000..fbae189a --- /dev/null +++ b/src/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "module": "es2015", + "baseUrl": "", + "types": [] + }, + "exclude": [ + "**/*.spec.ts" + ] +} diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json new file mode 100644 index 00000000..eb2aca62 --- /dev/null +++ b/src/tsconfig.spec.json @@ -0,0 +1,24 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "module": "commonjs", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts", + "polyfills-test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ], + "exclude": [ + "dist", + "release", + "node_modules" + ] +} diff --git a/src/typings.d.ts b/src/typings.d.ts new file mode 100644 index 00000000..78708ff3 --- /dev/null +++ b/src/typings.d.ts @@ -0,0 +1,11 @@ +/* SystemJS module definition */ +declare var nodeModule: NodeModule; +interface NodeModule { + id: string; +} + +declare var window: Window; +interface Window { + process: any; + require: any; +} diff --git a/tsconfig-serve.json b/tsconfig-serve.json new file mode 100644 index 00000000..4cabacf1 --- /dev/null +++ b/tsconfig-serve.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "resolveJsonModule": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "es2016", + "es2015", + "dom" + ] + }, + "include": [ + "main.ts" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts" + ] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..e04aaff8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "resolveJsonModule": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "es2016", + "es2015", + "dom" + ] + }, + "include": [ + "main.ts", + "src/**/*" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..ae580808 --- /dev/null +++ b/tslint.json @@ -0,0 +1,136 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "deprecation": { + "severity": "warn" + }, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs/Rx" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "component-selector": [ + true, + "element", + "app", + "kebab-case" + ], + "no-output-on-prefix": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..386a0773 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,8649 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"7zip-bin@~4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-4.1.0.tgz#33eff662a5c39c0c2061170cc003c5120743fff0" + integrity sha512-AsnBZN3a8/JcNt+KPkGGODaA4c7l3W5+WpeKgGSbstSLxqWtTXqd1ieJGBQ8IFCtRg8DmmKUcSkIkUc0A4p3YA== + +"@angular-devkit/architect@0.11.4": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.11.4.tgz#f0cc3b4f1dd0128f6b41d3bb760bcf4c324cd063" + integrity sha512-2zi6S9tPlk52vyqN67IvFoeNgd0uxtrPlwl3TdvJ3wrH7sYGJnkQ+EzAE7cKUGWAV989BbNtx2YxhRDHnN21Fg== + dependencies: + "@angular-devkit/core" "7.1.4" + rxjs "6.3.3" + +"@angular-devkit/build-angular@0.11.4": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.11.4.tgz#795084e29c66a71da15227cf2ac29794aa807c7c" + integrity sha512-5WQAQB4heDqAotqjU3Tl8Ons0S/e16dKwVkQFdqfKPyBgmu4CyUH35eTV+i6i7un1Elg65U5GnA4MiUtApqVyw== + dependencies: + "@angular-devkit/architect" "0.11.4" + "@angular-devkit/build-optimizer" "0.11.4" + "@angular-devkit/build-webpack" "0.11.4" + "@angular-devkit/core" "7.1.4" + "@ngtools/webpack" "7.1.4" + ajv "6.5.3" + autoprefixer "9.3.1" + circular-dependency-plugin "5.0.2" + clean-css "4.2.1" + copy-webpack-plugin "4.5.4" + file-loader "2.0.0" + glob "7.1.3" + istanbul "0.4.5" + istanbul-instrumenter-loader "3.0.1" + karma-source-map-support "1.3.0" + less "3.8.1" + less-loader "4.1.0" + license-webpack-plugin "2.0.2" + loader-utils "1.1.0" + mini-css-extract-plugin "0.4.4" + minimatch "3.0.4" + opn "5.3.0" + parse5 "4.0.0" + portfinder "1.0.17" + postcss "7.0.5" + postcss-import "12.0.0" + postcss-loader "3.0.0" + raw-loader "0.5.1" + rxjs "6.3.3" + sass-loader "7.1.0" + semver "5.5.1" + source-map-loader "0.2.4" + source-map-support "0.5.9" + speed-measure-webpack-plugin "1.2.3" + stats-webpack-plugin "0.7.0" + style-loader "0.23.1" + stylus "0.54.5" + stylus-loader "3.0.2" + terser-webpack-plugin "1.1.0" + tree-kill "1.2.0" + webpack "4.23.1" + webpack-dev-middleware "3.4.0" + webpack-dev-server "3.1.10" + webpack-merge "4.1.4" + webpack-sources "1.3.0" + webpack-subresource-integrity "1.1.0-rc.6" + optionalDependencies: + node-sass "4.10.0" + +"@angular-devkit/build-optimizer@0.11.4": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.11.4.tgz#d96b0e16a76f3825f173220a2de5f376fc5abaee" + integrity sha512-tAAWWFCcl918Q1JivlLvLFer8Qm4/THWbEneMwk5fQvG6/NgJLoa3itP/MCUq4qL6YHmp2DWkdWnWfRQCgHeFA== + dependencies: + loader-utils "1.1.0" + source-map "0.5.6" + typescript "3.1.6" + webpack-sources "1.2.0" + +"@angular-devkit/build-webpack@0.11.4": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.11.4.tgz#1397b21b6187eab0641830ece4c3b9faba00855e" + integrity sha512-4nEDXSbv3oDu27Rw5s2DMKmcOZYVAt76bryVF2SycSkDq3eAIiqmgw3G3CJJ4LTulXzDpaIpk02MvgbYkX+hvw== + dependencies: + "@angular-devkit/architect" "0.11.4" + "@angular-devkit/core" "7.1.4" + rxjs "6.3.3" + +"@angular-devkit/core@7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.1.4.tgz#4d903fd2ecc259b716ae76da19695d03993e583c" + integrity sha512-3cBVHjSQjMyE/mIyOX82ekdybNRQlN+kUfmdZS6oVW9aV48vdxcVbEGdl8t1H4enMf89u8kXiAAET9jFaqWopg== + dependencies: + ajv "6.5.3" + chokidar "2.0.4" + fast-json-stable-stringify "2.0.0" + rxjs "6.3.3" + source-map "0.7.3" + +"@angular-devkit/schematics@7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.1.4.tgz#d2828fb86b5453395fab12a36779d0fd9fbdadc2" + integrity sha512-+rn3ppcC3grsi9vV2uUIYh/5mUBEJ+JRCKW11BJoUqLMeu8W7h+vbVonyfwJXsk3FSTf9ZY0C7F7UqggRS3cWw== + dependencies: + "@angular-devkit/core" "7.1.4" + rxjs "6.3.3" + +"@angular/cli@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-7.1.4.tgz#f07ee4e979ec202bf2fd91a665e3d2d6c065bbe1" + integrity sha512-SruaZsmyq3+ymMPeMJSzhytvgtvzyzb1q58pUYX+vZjff2aMYOo0TVxJALwTOPIABICTqUTZmujbLG9uxVgxFA== + dependencies: + "@angular-devkit/architect" "0.11.4" + "@angular-devkit/core" "7.1.4" + "@angular-devkit/schematics" "7.1.4" + "@schematics/angular" "7.1.4" + "@schematics/update" "0.11.4" + inquirer "6.2.0" + opn "5.3.0" + semver "5.5.1" + symbol-observable "1.2.0" + +"@angular/common@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-7.1.4.tgz#a89f43e87317dee80b7664225442aaeca6c83547" + integrity sha512-oQPCilcf1H/OXmt4z6PfGoCSb1YPRBAXGs/KRBARm3tYan2r5CmV0BFwpWXWQrEMt8YQqqLiBQUQ64d8+VFm8Q== + dependencies: + tslib "^1.9.0" + +"@angular/compiler-cli@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-7.1.4.tgz#2a65ed98a189fb066d7e3dc6d98eff0918b3ff62" + integrity sha512-fyEY58A53pmVEuhfyU1z1TAi1n5rOK5cCjhFnUUnnESQFEW/aQYOl0ZL6LDsMSYfa78fkDw4Nc0DytvZ1ymVMw== + dependencies: + canonical-path "1.0.0" + chokidar "^1.4.2" + convert-source-map "^1.5.1" + dependency-graph "^0.7.2" + magic-string "^0.25.0" + minimist "^1.2.0" + reflect-metadata "^0.1.2" + shelljs "^0.8.1" + source-map "^0.6.1" + tslib "^1.9.0" + yargs "9.0.1" + +"@angular/compiler@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-7.1.4.tgz#fc0f8ddd2d1b6e1a4aafab2af7949bbd05bc527c" + integrity sha512-AvYXtjEJ27Rhv4c27DXNEa58Lit63jdydzbz7VuyFhNU+FwDUK2DC4gZe0nWZsf7HUniJezVRFkECDCZQeSKCQ== + dependencies: + tslib "^1.9.0" + +"@angular/core@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-7.1.4.tgz#ad899985290957bbb9ac5c47c62ae5a72ccf5d00" + integrity sha512-36uWLrmmlzf8JKaq2A5F2tPQEHvFSsbTQWOT559Drp1tzM2uSA7PysNHv5TXUshDn5i54S2EQFm4bj2YPp4Hzg== + dependencies: + tslib "^1.9.0" + +"@angular/forms@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-7.1.4.tgz#f3491264c27968d8da017fdc5b1178c46f4a4b83" + integrity sha512-YB2lDRe7aMsaO5ZlbeFZGH+uTQOcpotFDKCmTckpefRJ7id6TlUSBYdYRH80qOQfPJGpsnqQvLZkL24UMasKtQ== + dependencies: + tslib "^1.9.0" + +"@angular/http@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/http/-/http-7.1.4.tgz#03568b174cf8caaa6fa84a4f0e5ced5f68dfb6c3" + integrity sha512-Lrjb99sHu0Cv7MBbVLev1I1Fe+DJcwG4v7juZB/5nE5opKmbQo3Lfqvt2dVrMOxHeju9ReFznEnuGNMK6+m6pQ== + dependencies: + tslib "^1.9.0" + +"@angular/language-service@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-7.1.4.tgz#59303e719937f774d9266a5e5f498ba254e0fe7b" + integrity sha512-Pvrk3W3+6XfrmpCRcTumfyplv6AQJXKfDdPFSbhdpHJlpdcQRo6TckA85Yln5/CXZSAiPaZeiejQt2OogrIRLg== + +"@angular/platform-browser-dynamic@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.1.4.tgz#e76a5a267caf27d17bf46d16f009cd9c68a8dfd3" + integrity sha512-LtFd6XIz98BKjxrCRbaz2y0XSmVQSTzrvpAyNzKnzHAMn+4XpIpnzyV3Y6DeHolIBwLjFHFzGKMBwOHOwME4RQ== + dependencies: + tslib "^1.9.0" + +"@angular/platform-browser@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-7.1.4.tgz#1d6cbaedb565d8b92fb0e227b2f4a599dd5ec217" + integrity sha512-lIFBKo6Uqty7qYDI9T8quFCUzUpGBgpzvDe14aAHFwZCft9rMS1J7PB1F26/dy2RBQE8tUyN2zp2xZQnYAhMcA== + dependencies: + tslib "^1.9.0" + +"@angular/router@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-7.1.4.tgz#b618a7b3d474bc443b5f8269e04b093a9619800d" + integrity sha512-5VVVcRsmuKrIWPnh5zF1ExXmIpCx2tlisJ7YTS2FFDXnqrZ9i2QgaxyJuyZE+Btg3t7LPF4tkhRQpjauNiHJYA== + dependencies: + tslib "^1.9.0" + +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/generator@^7.0.0", "@babel/generator@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.2.tgz#18c816c70962640eab42fe8cae5f3947a5c65ccc" + integrity sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg== + dependencies: + "@babel/types" "^7.2.2" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" + integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489" + integrity sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA== + +"@babel/template@^7.0.0", "@babel/template@^7.1.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" + integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.2.2" + "@babel/types" "^7.2.2" + +"@babel/traverse@^7.0.0": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" + integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.2.2" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.2.3" + "@babel/types" "^7.2.2" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.10" + +"@babel/types@^7.0.0", "@babel/types@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e" + integrity sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + +"@fortawesome/angular-fontawesome@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@fortawesome/angular-fontawesome/-/angular-fontawesome-0.3.0.tgz#380492f186469ce03d6fdbb3ec719810f771bf62" + integrity sha512-wXvyPI7GidoNiqeMz2re9iemUMFH4zBmuv94CfXlaanQ8+kMP/fYs/k69PLVN1KsebQY4kRA9GHmc1U1ndBkJg== + dependencies: + tslib "^1.9.0" + +"@fortawesome/fontawesome-common-types@^0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.12.tgz#42baa71f97ca06faeb0b6718fa5ed20c5eefdf07" + integrity sha512-ISLNpEx6fhJTYYkvBeo/4DHeL5EIA+VybJoOOnH67m6uXt6V6VFizdEN4qchHagNIeZfzI0LnA22gk0wbVPv/g== + +"@fortawesome/fontawesome-svg-core@^1.2.12": + version "1.2.12" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.12.tgz#9732617b1e484435f6946645d7f9ad248f12c437" + integrity sha512-cqTfa3vZ+Z9UYQnmLfCOwyLnf0Xcoxkmm/BSaI29Yikzu9zIeD4es7lBZMDqLOXYSEQC+rCr8caxFlGJcJVA+w== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.12" + +"@fortawesome/free-solid-svg-icons@^5.6.3": + version "5.6.3" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.6.3.tgz#1d7f6669ccd6a1ea673699e41f7e32c81401a260" + integrity sha512-ld8Gfp1KrncOpFRheThUDlD6/Ro9ZJGqfCEMXlO/x1Cg7ltLc5iYDG7yxDowLcmFY2BGSmxIIU3ZMW5FVTrfwQ== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.12" + +"@ngtools/webpack@7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-7.1.4.tgz#632ece6ed8e05fe743554cc935be36a653376f01" + integrity sha512-8A15TPJzg3g7yI70QvBzJ253P32WAgCVre9nMaDdd22UmlbvN8Ke4RuQY7vYVTECLL+bWpFJEFXL+ThzCRUgeA== + dependencies: + "@angular-devkit/core" "7.1.4" + enhanced-resolve "4.1.0" + rxjs "6.3.3" + tree-kill "1.2.0" + webpack-sources "1.2.0" + +"@ngx-translate/core@11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-11.0.1.tgz#cecefad41f06368f5859dac48fec8fcc4485615f" + integrity sha512-nBCa1ZD9fAUY/3eskP3Lql2fNg8OMrYIej1/5GRsfcutx9tG/5fZLCv9m6UCw1aS+u4uK/vXjv1ctG/FdMvaWg== + dependencies: + tslib "^1.9.0" + +"@ngx-translate/http-loader@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@ngx-translate/http-loader/-/http-loader-4.0.0.tgz#8a555248ad4b7d513460fcec9da25b0447962f1d" + integrity sha512-x8LumqydWD7eX9yQTAVeoCM9gFUIGVTUjZqbxdAUavAA3qVnk9wCQux7iHLPXpydl8vyQmLoPQR+fFU+DUDOMA== + dependencies: + tslib "^1.9.0" + +"@schematics/angular@7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.1.4.tgz#cec4a5b793e54bd624018b6b5b4b917c467d22a5" + integrity sha512-4QVSmvQtOELek+FDq+k2ROeH9YrRrPJ6jWK179+qOruKSd4uTgEti/jy+fS0rfr52kDSGdDhz7XTh/QvQB89fg== + dependencies: + "@angular-devkit/core" "7.1.4" + "@angular-devkit/schematics" "7.1.4" + typescript "3.1.6" + +"@schematics/update@0.11.4": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.11.4.tgz#47407cff57dba8ffc6826e1328fefd526fab2721" + integrity sha512-InfsMJtdWwoqCPmtlJeXBwRPPgIXUzpzIkCCcayRe9gy6PkPUIlOjfgEZ4Mqm/HR46lqsI8xwZfUK7SLV//a2g== + dependencies: + "@angular-devkit/core" "7.1.4" + "@angular-devkit/schematics" "7.1.4" + "@yarnpkg/lockfile" "1.1.0" + ini "1.3.5" + pacote "9.1.1" + rxjs "6.3.3" + semver "5.5.1" + semver-intersect "1.4.0" + +"@tweenjs/tween.js@^17.1.0": + version "17.2.0" + resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-17.2.0.tgz#21f89b709bafc4b303adae7a83b4f35a0d9e4796" + integrity sha1-IfibcJuvxLMDra56g7TzWg2eR5Y= + +"@types/jasmine@*", "@types/jasmine@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.3.4.tgz#492cc70364f6dee047887b4fa2135bedd41fb143" + integrity sha512-543S+ZCJfN4jKWzRkptbJqTY2vc4h7+lPVqU2hXb1XFofDcUxNANAimdZPYaH6/yhezVAsNeujoZjAFU06bfmA== + +"@types/jasminewd2@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/jasminewd2/-/jasminewd2-2.0.6.tgz#2f57a8d9875a6c9ef328a14bd070ba14a055ac39" + integrity sha512-2ZOKrxb8bKRmP/po5ObYnRDgFE4i+lQiEB27bAMmtMWLgJSqlIDqlLx6S0IRorpOmOPRQ6O80NujTmQAtBkeNw== + dependencies: + "@types/jasmine" "*" + +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + +"@types/node@^6.0.46": + version "6.14.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-6.14.2.tgz#40b3dbb1221c7d66802cbcc32fe3b85e54569c77" + integrity sha512-JWB3xaVfsfnFY8Ofc9rTB/op0fqqTSqy4vBcVk1LuRJvta7KTX+D//fCkiTMeLGhdr2EbFZzQjC97gvmPilk9Q== + +"@types/node@^8.0.24": + version "8.10.39" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.39.tgz#e7e87ad00364dd7bc485c940926345b8ec1a26ca" + integrity sha512-rE7fktr02J8ybFf6eysife+WF+L4sAHWzw09DgdCebEu+qDwMvv4zl6Bc+825ttGZP73kCKxa3dhJOoGJ8+5mA== + +"@types/q@^0.0.32": + version "0.0.32" + resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5" + integrity sha1-vShOV8hPEyXacCur/IKlMoGQwMU= + +"@types/selenium-webdriver@^3.0.0": + version "3.0.14" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.14.tgz#0b20a2370e6b1b8322c9c3dfcaa409e6c7c0c0a9" + integrity sha512-4GbNCDs98uHCT/OMv40qQC/OpoPbYn9XdXeTiFwHBBFO6eJhYEPUu2zDKirXSbHlvDV8oZ9l8EQ+HrEx/YS9DQ== + +"@types/tween.js@^16.6.1": + version "16.9.0" + resolved "https://registry.yarnpkg.com/@types/tween.js/-/tween.js-16.9.0.tgz#af25067f86e15d2cba89b26776fc273ff7f55650" + integrity sha512-N47wexTYhyaiJv+uY63v/PVFPAzRVv7NFXNfv/G6SZJntHPiBd42MdTXWgbz3tsMWzur6uhgcALybuDAVy03tg== + +"@webassemblyjs/ast@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.10.tgz#0cfc61d61286240b72fc522cb755613699eea40a" + integrity sha512-wTUeaByYN2EA6qVqhbgavtGc7fLTOx0glG2IBsFlrFG51uXIGlYBTyIZMf4SPLo3v1bgV/7lBN3l7Z0R6Hswew== + dependencies: + "@webassemblyjs/helper-module-context" "1.7.10" + "@webassemblyjs/helper-wasm-bytecode" "1.7.10" + "@webassemblyjs/wast-parser" "1.7.10" + +"@webassemblyjs/floating-point-hex-parser@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.10.tgz#ee63d729c6311a85863e369a473f9983f984e4d9" + integrity sha512-gMsGbI6I3p/P1xL2UxqhNh1ga2HCsx5VBB2i5VvJFAaqAjd2PBTRULc3BpTydabUQEGlaZCzEUQhLoLG7TvEYQ== + +"@webassemblyjs/helper-api-error@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.10.tgz#bfcb3bbe59775357475790a2ad7b289f09b2f198" + integrity sha512-DoYRlPWtuw3yd5BOr9XhtrmB6X1enYF0/54yNvQWGXZEPDF5PJVNI7zQ7gkcKfTESzp8bIBWailaFXEK/jjCsw== + +"@webassemblyjs/helper-buffer@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.10.tgz#0a8c624c67ad0b214d2e003859921a1988cb151b" + integrity sha512-+RMU3dt/dPh4EpVX4u5jxsOlw22tp3zjqE0m3ftU2tsYxnPULb4cyHlgaNd2KoWuwasCQqn8Mhr+TTdbtj3LlA== + +"@webassemblyjs/helper-code-frame@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.10.tgz#0ab7e22fad0241a173178c73976fc0edf50832ce" + integrity sha512-UiytbpKAULOEab2hUZK2ywXen4gWJVrgxtwY3Kn+eZaaSWaRM8z/7dAXRSoamhKFiBh1uaqxzE/XD9BLlug3gw== + dependencies: + "@webassemblyjs/wast-printer" "1.7.10" + +"@webassemblyjs/helper-fsm@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.10.tgz#0915e7713fbbb735620a9d3e4fa3d7951f97ac64" + integrity sha512-w2vDtUK9xeSRtt5+RnnlRCI7wHEvLjF0XdnxJpgx+LJOvklTZPqWkuy/NhwHSLP19sm9H8dWxKeReMR7sCkGZA== + +"@webassemblyjs/helper-module-context@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.10.tgz#9beb83f72740f5ac8075313b5cac5e796510f755" + integrity sha512-yE5x/LzZ3XdPdREmJijxzfrf+BDRewvO0zl8kvORgSWmxpRrkqY39KZSq6TSgIWBxkK4SrzlS3BsMCv2s1FpsQ== + +"@webassemblyjs/helper-wasm-bytecode@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.10.tgz#797b1e734bbcfdea8399669cdc58308ef1c7ffc0" + integrity sha512-u5qy4SJ/OrxKxZqJ9N3qH4ZQgHaAzsopsYwLvoWJY6Q33r8PhT3VPyNMaJ7ZFoqzBnZlCcS/0f4Sp8WBxylXfg== + +"@webassemblyjs/helper-wasm-section@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.10.tgz#c0ea3703c615d7bc3e3507c3b7991c8767b2f20e" + integrity sha512-Ecvww6sCkcjatcyctUrn22neSJHLN/TTzolMGG/N7S9rpbsTZ8c6Bl98GpSpV77EvzNijiNRHBG0+JO99qKz6g== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/helper-buffer" "1.7.10" + "@webassemblyjs/helper-wasm-bytecode" "1.7.10" + "@webassemblyjs/wasm-gen" "1.7.10" + +"@webassemblyjs/ieee754@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.10.tgz#62c1728b7ef0f66ef8221e2966a0afd75db430df" + integrity sha512-HRcWcY+YWt4+s/CvQn+vnSPfRaD4KkuzQFt5MNaELXXHSjelHlSEA8ZcqT69q0GTIuLWZ6JaoKar4yWHVpZHsQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.10.tgz#167e0bb4b06d7701585772a73fba9f4df85439f6" + integrity sha512-og8MciYlA8hvzCLR71hCuZKPbVBfLQeHv7ImKZ4nlyxrYbG7uJHYtHiHu6OV9SqrGuD03H/HtXC4Bgdjfm9FHw== + dependencies: + "@xtuc/long" "4.2.1" + +"@webassemblyjs/utf8@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.10.tgz#b6728f5b6f50364abc155be029f9670e6685605a" + integrity sha512-Ng6Pxv6siyZp635xCSnH3mKmIFgqWPCcGdoo0GBYgyGdxu7cUj4agV7Uu1a8REP66UYUFXJLudeGgd4RvuJAnQ== + +"@webassemblyjs/wasm-edit@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.10.tgz#83fe3140f5a58f5a30b914702be9f0e59a399092" + integrity sha512-e9RZFQlb+ZuYcKRcW9yl+mqX/Ycj9+3/+ppDI8nEE/NCY6FoK8f3dKBcfubYV/HZn44b+ND4hjh+4BYBt+sDnA== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/helper-buffer" "1.7.10" + "@webassemblyjs/helper-wasm-bytecode" "1.7.10" + "@webassemblyjs/helper-wasm-section" "1.7.10" + "@webassemblyjs/wasm-gen" "1.7.10" + "@webassemblyjs/wasm-opt" "1.7.10" + "@webassemblyjs/wasm-parser" "1.7.10" + "@webassemblyjs/wast-printer" "1.7.10" + +"@webassemblyjs/wasm-gen@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.10.tgz#4de003806ae29c97ab3707782469b53299570174" + integrity sha512-M0lb6cO2Y0PzDye/L39PqwV+jvO+2YxEG5ax+7dgq7EwXdAlpOMx1jxyXJTScQoeTpzOPIb+fLgX/IkLF8h2yw== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/helper-wasm-bytecode" "1.7.10" + "@webassemblyjs/ieee754" "1.7.10" + "@webassemblyjs/leb128" "1.7.10" + "@webassemblyjs/utf8" "1.7.10" + +"@webassemblyjs/wasm-opt@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.10.tgz#d151e31611934a556c82789fdeec41a814993c2a" + integrity sha512-R66IHGCdicgF5ZliN10yn5HaC7vwYAqrSVJGjtJJQp5+QNPBye6heWdVH/at40uh0uoaDN/UVUfXK0gvuUqtVg== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/helper-buffer" "1.7.10" + "@webassemblyjs/wasm-gen" "1.7.10" + "@webassemblyjs/wasm-parser" "1.7.10" + +"@webassemblyjs/wasm-parser@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.10.tgz#0367be7bf8f09e3e6abc95f8e483b9206487ec65" + integrity sha512-AEv8mkXVK63n/iDR3T693EzoGPnNAwKwT3iHmKJNBrrALAhhEjuPzo/lTE4U7LquEwyvg5nneSNdTdgrBaGJcA== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/helper-api-error" "1.7.10" + "@webassemblyjs/helper-wasm-bytecode" "1.7.10" + "@webassemblyjs/ieee754" "1.7.10" + "@webassemblyjs/leb128" "1.7.10" + "@webassemblyjs/utf8" "1.7.10" + +"@webassemblyjs/wast-parser@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.10.tgz#058f598b52f730b23fc874d4775b6286b6247264" + integrity sha512-YTPEtOBljkCL0VjDp4sHe22dAYSm3ZwdJ9+2NTGdtC7ayNvuip1wAhaAS8Zt9Q6SW9E5Jf5PX7YE3XWlrzR9cw== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/floating-point-hex-parser" "1.7.10" + "@webassemblyjs/helper-api-error" "1.7.10" + "@webassemblyjs/helper-code-frame" "1.7.10" + "@webassemblyjs/helper-fsm" "1.7.10" + "@xtuc/long" "4.2.1" + +"@webassemblyjs/wast-printer@1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.10.tgz#d817909d2450ae96c66b7607624d98a33b84223b" + integrity sha512-mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/wast-parser" "1.7.10" + "@xtuc/long" "4.2.1" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" + integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== + +"@yarnpkg/lockfile@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +JSONStream@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + +accepts@~1.3.4, accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== + dependencies: + acorn "^5.0.0" + +acorn@^5.0.0, acorn@^5.6.2: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +adm-zip@^0.4.9: + version "0.4.13" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.13.tgz#597e2f8cc3672151e1307d3e95cddbc75672314a" + integrity sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" + integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== + dependencies: + humanize-ms "^1.2.1" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= + +ajv@6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9" + integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^5.0.0, ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ajv@^6.1.0, ajv@^6.5.5: + version "6.6.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d" + integrity sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +angular-notifier@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/angular-notifier/-/angular-notifier-4.1.1.tgz#127e6c50acab9fe70e784d0e7f4996860f8f93a0" + integrity sha512-QrL5cW3GDjONy6Ack+HIgd3tUf93ztkPT6C551/pqOaE69Ad2YDem+JyBLnlLKBnCFUxhKkSVnv/Ak2HsOrBxQ== + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-colors@^3.0.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +app-builder-bin@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-2.6.1.tgz#aa97f82d341dfa6f1269d78955482d619cc613ed" + integrity sha512-W0l85O+s6lOaziWqAhszPfwiG0s15FvMBP9j9i/bknsMccUkwN60u4Cy7yYtf6akCUDuJenLqpTX4/xvkq1egw== + +app-builder-lib@20.38.4, app-builder-lib@~20.38.3: + version "20.38.4" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-20.38.4.tgz#71a515d01f4f2bd48a67495804f659a46c35303c" + integrity sha512-JbuAJQBndcCW6BJVIb2tPjM5wiuIjz2LUlbyVxNIawM2wFKUBV9kr0N3RNBJFxcrCEuA9oprMUCoymJdrMUVfA== + dependencies: + "7zip-bin" "~4.1.0" + app-builder-bin "2.6.1" + async-exit-hook "^2.0.1" + bluebird-lst "^1.0.6" + builder-util "9.6.1" + builder-util-runtime "8.1.0" + chromium-pickle-js "^0.2.0" + debug "^4.1.0" + ejs "^2.6.1" + electron-osx-sign "0.4.11" + electron-publish "20.38.3" + fs-extra-p "^7.0.0" + hosted-git-info "^2.7.1" + is-ci "^2.0.0" + isbinaryfile "^3.0.3" + js-yaml "^3.12.0" + lazy-val "^1.0.3" + minimatch "^3.0.4" + normalize-package-data "^2.4.0" + plist "^3.0.1" + read-config-file "3.2.0" + sanitize-filename "^1.6.1" + semver "^5.6.0" + temp-file "^3.3.2" + +app-root-path@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a" + integrity sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo= + +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== + dependencies: + default-require-extensions "^2.0.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + integrity sha1-GdOGodntxufByF04iu28xW0zYC0= + +async-exit-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3" + integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +async@1.x, async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@2.6.1, async@^2.0.0, async@^2.5.0, async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.3.1.tgz#71b622174de2b783d5fd99f9ad617b7a3c78443e" + integrity sha512-DY9gOh8z3tnCbJ13JIWaeQsoYncTGdsrgCceBaQSIL4nvdrLxgbRSBPevg2XbX7u4QCSfLheSJEEIUUSlkbx6Q== + dependencies: + browserslist "^4.3.3" + caniuse-lite "^1.0.30000898" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.5" + postcss-value-parser "^3.3.1" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.6.0, aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-generator@^6.18.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.18.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@^1.0.2, base64-js@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +blocking-proxy@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-1.0.1.tgz#81d6fd1fe13a4c0d6957df7f91b75e98dac40cb2" + integrity sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA== + dependencies: + minimist "^1.2.0" + +bluebird-lst@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.6.tgz#89bc4de0a357373605c8781f293f7b06d454f869" + integrity sha512-CBWFoPuUPpcvMUxfyr8DKdI5d4kjxFl1h39+VbKxP3KJWJHEsLtuT4pPLkjpxCGU6Ask21tvbnftWXdqIxYldQ== + dependencies: + bluebird "^3.5.2" + +bluebird@^3.3.0, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" + integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.18.3, body-parser@^1.16.1: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^0.1.2: + version "0.1.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6" + integrity sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY= + dependencies: + expand-range "^0.1.0" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.3.3: + version "4.3.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.6.tgz#0f9d9081afc66b36f477c6bdf3813f784f42396a" + integrity sha512-kMGKs4BTzRWviZ8yru18xBpx+CyHG9eqgRbj9XbE3IMgtczf4aiA0Y1YCpVdvUieKGZ03kolSPXqTcscBCb9qw== + dependencies: + caniuse-lite "^1.0.30000921" + electron-to-chromium "^1.3.92" + node-releases "^1.1.1" + +browserstack@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/browserstack/-/browserstack-1.5.1.tgz#e2dfa66ffee940ebad0a07f7e00fd4687c455d66" + integrity sha512-O8VMT64P9NOLhuIoD4YngyxBURefaSdR4QdhG8l6HZ9VxtU7jc3m6jLufFwKA5gaf7fetfB2TnRJnMxyob+heg== + dependencies: + https-proxy-agent "^2.2.1" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0, buffer-from@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builder-util-runtime@8.1.0, builder-util-runtime@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.1.0.tgz#dd7fca995d48ceee7580b4851ca057566c94601e" + integrity sha512-s1mlJ28mv+56Iebh6c9aXjVe11O3Z0cDTwAGeB0PCcUzHA37fDxGgS8ZGoYNMZP+rBHj21d/od1wuYofTVLaQg== + dependencies: + bluebird-lst "^1.0.6" + debug "^4.1.0" + fs-extra-p "^7.0.0" + sax "^1.2.4" + +builder-util@9.6.1, builder-util@~9.6.0: + version "9.6.1" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-9.6.1.tgz#4625620b1535fe40dcacb178d24fe56d0d7c8957" + integrity sha512-8MljKTjeV+A+LLVexuWEV3EpWbiUcsHHrB4Bg2qNo/3dC+vTo6g/27+W3Ij7Ij1UTobSkNBstFieWijXJCco9A== + dependencies: + "7zip-bin" "~4.1.0" + app-builder-bin "2.6.1" + bluebird-lst "^1.0.6" + builder-util-runtime "^8.1.0" + chalk "^2.4.1" + debug "^4.1.0" + fs-extra-p "^7.0.0" + is-ci "^2.0.0" + js-yaml "^3.12.0" + source-map-support "^0.5.9" + stat-mode "^0.2.2" + temp-file "^3.3.2" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +cacache@^10.0.4: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + integrity sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA== + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cacache@^11.0.1, cacache@^11.0.2, cacache@^11.2.0: + version "11.3.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f" + integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA== + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + figgy-pudding "^3.1.0" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.0" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^4.0.0, camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + +caniuse-lite@^1.0.30000898, caniuse-lite@^1.0.30000921: + version "1.0.30000923" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000923.tgz#148f9bda508024b5ce957b463ae2e8302b451bb2" + integrity sha512-j5ur7eeluOFjjPUkydtXP4KFAsmH3XaQNch5tvWSO+dLHYt5PE+VgJZLWtbVOodfWij6m6zas28T4gB/cLYq1w== + +canonical-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/canonical-path/-/canonical-path-1.0.0.tgz#fcb470c23958def85081856be7a86e904f180d1d" + integrity sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg== + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + 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" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chokidar@2.0.4, chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.3, chokidar@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chokidar@^1.4.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= + 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" + +chownr@^1.0.1, chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== + dependencies: + tslib "^1.9.0" + +chromium-pickle-js@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" + integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-dependency-plugin@5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz#da168c0b37e7b43563fb9f912c1c007c213389ef" + integrity sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA== + +circular-json@^0.5.5: + version "0.5.9" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" + integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" + integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== + dependencies: + source-map "~0.6.0" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-deep@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713" + integrity sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ== + dependencies: + for-own "^1.0.0" + is-plain-object "^2.0.4" + kind-of "^6.0.0" + shallow-clone "^1.0.0" + +clone@^2.1.1, clone@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +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" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +codelyzer@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-4.5.0.tgz#a65ddeeeca2894653253a89bfa229118ff9f59b1" + integrity sha512-oO6vCkjqsVrEsmh58oNlnJkRXuA30hF8cdNAQV9DytEalDwyOFRvHMnlKFzmOStNerOmPGZU9GAHnBo4tGvtiQ== + dependencies: + app-root-path "^2.1.0" + css-selector-tokenizer "^0.7.0" + cssauron "^1.4.0" + semver-dsl "^1.0.1" + source-map "^0.5.7" + sprintf-js "^1.1.1" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@~0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd" + integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0= + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +colors@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= + +colors@^1.1.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +combine-lists@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6" + integrity sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y= + dependencies: + lodash "^4.5.0" + +combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.12.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== + +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compare-version@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" + integrity sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA= + +compare-versions@^3.2.1, compare-versions@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" + integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1, component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +compressible@~2.0.14: + version "2.0.15" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212" + integrity sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw== + dependencies: + mime-db ">= 1.36.0 < 2" + +compression@^1.5.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" + integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.14" + debug "2.6.9" + on-headers "~1.0.1" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@1.6.2, concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +connect-history-api-fallback@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a" + integrity sha1-sGhzk0vF40T+9hGhlqb6rgruAVo= + +connect@^3.6.0: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +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" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +copy-webpack-plugin@4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.4.tgz#f2b2782b3cd5225535c3dc166a80067e7d940f27" + integrity sha512-0lstlEyj74OAtYMrDxlNZsU7cwFijAI3Ofz2fD6Mpo9r4xCv4yegfa3uHIKvZY1NSuOtE9nvG6TAhJ+uz9gDaQ== + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + globby "^7.1.1" + is-glob "^4.0.0" + loader-utils "^1.1.0" + minimatch "^3.0.4" + p-limit "^1.0.0" + serialize-javascript "^1.4.0" + +core-js@2.6.1, core-js@^2.2.0, core-js@^2.4.0, core-js@^2.5.7: + version "2.6.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" + integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg== + +core-js@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65" + integrity sha1-+rg/uwstjchfpjbEudNMdUIMbWU= + +core-util-is@1.0.2, 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" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +css-parse@1.7.x: + version "1.7.0" + resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.7.0.tgz#321f6cf73782a6ff751111390fc05e2c657d8c9b" + integrity sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs= + +css-selector-tokenizer@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d" + integrity sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA== + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +cssauron@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssauron/-/cssauron-1.4.0.tgz#a6602dff7e04a8306dc0db9a551e92e8b5662ad8" + integrity sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg= + dependencies: + through X.X.X + +cssesc@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" + integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +date-format@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8" + integrity sha1-YV6CjiM90aubua4JUODOzPpuytg= + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +debug@*, debug@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + dependencies: + ms "^2.1.1" + +debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0, debug@=3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.0.0, debug@^3.1.0, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg== + dependencies: + xregexp "4.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +default-gateway@^2.6.0: + version "2.7.2" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f" + integrity sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ== + dependencies: + execa "^0.10.0" + ip-regex "^2.1.0" + +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= + dependencies: + strip-bom "^3.0.0" + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag= + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +dependency-graph@^0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.7.2.tgz#91db9de6eb72699209d88aea4c1fd5221cac1c49" + integrity sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ== + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-node@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@^3.1.0, diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +dmg-builder@6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-6.5.3.tgz#95afe3deab33fd874f68d299bc71b481e94f5312" + integrity sha512-ZNl4GFBg6rdFplnuoK56iftxh/qgM7rXJUxgl21eK4WsjxgQwtQ0REZo+pDSL4OzVeyOO8MMNWSNQcCsBLiDyA== + dependencies: + app-builder-lib "~20.38.3" + bluebird-lst "^1.0.6" + builder-util "~9.6.0" + fs-extra-p "^7.0.0" + iconv-lite "^0.4.24" + js-yaml "^3.12.0" + parse-color "^1.0.0" + sanitize-filename "^1.6.1" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +dom-serialize@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +dotenv-expand@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-4.2.0.tgz#def1f1ca5d6059d24a766e587942c21106ce1275" + integrity sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU= + +dotenv@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" + integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125" + integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +ejs@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" + integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== + +electron-builder@20.38.4: + version "20.38.4" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-20.38.4.tgz#67727529ffb87e7fdd78b3a84ea0d6c22bf04ec2" + integrity sha512-WHOr3Rz2wktxV5TqmRL6woO9/wrIZeRfJPSEXOhgfgLskE5Sp2Aer0zAF7lHNqXuG6JhU+0I9IYFAxa73MTs9w== + dependencies: + app-builder-lib "20.38.4" + bluebird-lst "^1.0.6" + builder-util "9.6.1" + builder-util-runtime "8.1.0" + chalk "^2.4.1" + dmg-builder "6.5.3" + fs-extra-p "^7.0.0" + is-ci "^2.0.0" + lazy-val "^1.0.3" + read-config-file "3.2.0" + sanitize-filename "^1.6.1" + update-notifier "^2.5.0" + yargs "^12.0.5" + +electron-download@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-4.1.1.tgz#02e69556705cc456e520f9e035556ed5a015ebe8" + integrity sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg== + dependencies: + debug "^3.0.0" + env-paths "^1.0.0" + fs-extra "^4.0.1" + minimist "^1.2.0" + nugget "^2.0.1" + path-exists "^3.0.0" + rc "^1.2.1" + semver "^5.4.1" + sumchecker "^2.0.2" + +electron-json-storage@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/electron-json-storage/-/electron-json-storage-4.1.5.tgz#72b0e15efe2e04cc42542e3408986c2be9e2b906" + integrity sha512-7Ptks1xqvXl+iGfrsY3lsVLjO0ybMceRCGJBRTHX5ci07p+gUi7dtOws6y/2nDRjbUGrapScms9ovV1LP8I4TQ== + dependencies: + async "^2.0.0" + lockfile "^1.0.4" + lodash "^4.0.1" + mkdirp "^0.5.1" + rimraf "^2.5.1" + +electron-log@^2.2.17: + version "2.2.17" + resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-2.2.17.tgz#e71e2ebb949fc96ded7cdb99eeee7202e48981d2" + integrity sha512-v+Af5W5z99ehhaLOfE9eTSXUwjzh2wFlQjz51dvkZ6ZIrET6OB/zAZPvsuwT6tm3t5x+M1r+Ed3U3xtPZYAyuQ== + +electron-osx-sign@0.4.11: + version "0.4.11" + resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz#8377732fe7b207969f264b67582ee47029ce092f" + integrity sha512-VVd40nrnVqymvFrY9ZkOYgHJOvexHHYTR3di/SN+mjJ0OWhR1I8BRVj3U+Yamw6hnkZZNKZp52rqL5EFAAPFkQ== + dependencies: + bluebird "^3.5.0" + compare-version "^0.1.2" + debug "^2.6.8" + isbinaryfile "^3.0.2" + minimist "^1.2.0" + plist "^3.0.1" + +electron-publish@20.38.3: + version "20.38.3" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-20.38.3.tgz#7c162904f728ba2bbf2640bc3620b65ce1061ce3" + integrity sha512-Qomq253NT5DfjUZgFSx6p+gheU5YhM6zZ67fTtBZvwyk0v8HwxNXfa8fZT7h+1c3BwEmjusTbmjZRNW/XZBXFA== + dependencies: + bluebird-lst "^1.0.6" + builder-util "~9.6.0" + builder-util-runtime "^8.1.0" + chalk "^2.4.1" + fs-extra-p "^7.0.0" + lazy-val "^1.0.3" + mime "^2.4.0" + +electron-reload@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/electron-reload/-/electron-reload-1.4.0.tgz#00154268c936fa17b496fdb1728434c747e1d29a" + integrity sha512-pluNocZ9LqIeKmUzUSEHa+vT1+dG5923zXez4iwEhWqC2hydALPKvu+kJJzkdYRJv5z15S8waDthyrMyKd5MCQ== + dependencies: + chokidar "^2.0.4" + +electron-to-chromium@^1.3.92: + version "1.3.96" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.96.tgz#25770ec99b8b07706dedf3a5f43fa50cb54c4f9a" + integrity sha512-ZUXBUyGLeoJxp4Nt6G/GjBRLnyz8IKQGexZ2ndWaoegThgMGFO1tdDYID5gBV32/1S83osjJHyfzvanE/8HY4Q== + +electron@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/electron/-/electron-4.0.0.tgz#6ccb40cc8bf2d49954dcea73b97ae7ad12ee04b3" + integrity sha512-3XPG/3IXlvnT1oe1K6zEushoD0SKbP8xwdrL10EWGe6k2iOV4hSHqJ8vWnR8yZ7VbSXmBRfomEFDNAo/q/cwKw== + dependencies: + "@types/node" "^8.0.24" + electron-download "^4.1.0" + extract-zip "^1.0.3" + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +encodeurl@~1.0.1, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" + integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" + integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.1.tgz#b60281c35484a70ee0351ea0ebff83ec8c9522a2" + integrity sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w== + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + +enhanced-resolve@4.1.0, enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +env-paths@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" + integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA= + +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= + +errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.4.3: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-promise@^4.0.3: + version "4.2.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" + integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg== + +es6-promise@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" + integrity sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y= + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + +estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-braces@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" + integrity sha1-SIsdHSRRyz06axks/AMPRMWFX+o= + dependencies: + array-slice "^0.2.3" + array-unique "^0.2.1" + braces "^0.1.2" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044" + integrity sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ= + dependencies: + is-number "^0.1.1" + repeat-string "^0.2.2" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +express@^4.16.2: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.1, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extract-zip@^1.0.3: + version "1.6.7" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" + integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= + dependencies: + concat-stream "1.6.2" + debug "2.6.9" + mkdirp "0.5.1" + yauzl "2.4.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@2.0.0, fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastparse@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" + integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg= + dependencies: + websocket-driver ">=0.5.1" + +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= + dependencies: + pend "~1.2.0" + +figgy-pudding@^3.1.0, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-loader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-2.0.0.tgz#39749c82f020b9e85901dcff98e8004e6401cfde" + integrity sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ== + dependencies: + loader-utils "^1.0.2" + schema-utils "^1.0.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fileset@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== + +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +follow-redirects@^1.0.0: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +for-in@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE= + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.1, form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-access@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" + integrity sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o= + dependencies: + null-check "^1.0.0" + +fs-extra-p@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-7.0.0.tgz#da9a72df71dc77fb938162025a5fc658713c98ab" + integrity sha512-5tg5jBOd0xIXjwj4PDnafOXL5TyPVzjxLby4DPKev53wurEXp7IsojBaD4Lj5M5w7jxw0pbkEU0fFEPmcKoMnA== + dependencies: + bluebird-lst "^1.0.6" + fs-extra "^7.0.0" + +fs-extra@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.0.0, fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +fstream@^1.0.0, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + 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" + wide-align "^1.1.0" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +genfun@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" + integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + 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" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + 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" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@7.0.x: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo= + 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" + +glob@7.1.3, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +globals@^11.1.0: + version "11.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" + integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globule@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" + integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + +google-translate@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/google-translate/-/google-translate-2.2.0.tgz#bfba67d5317f2243bb1962fb0dfdff25ee108d78" + integrity sha512-k9MuJIRUAhEpdd732mKWxONOmpA8gX4bJtwsOQCEwFVcm+V0eIGBq4uMWw69Lu9GvJO77w+STma5rh4W+62p+g== + dependencies: + async "2.6.1" + he "1.1.1" + request "2.87.0" + underscore "1.9.1" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +handle-thing@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" + integrity sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ= + +handlebars@^4.0.1, handlebars@^4.0.11: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^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" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@5.x.x: + version "5.0.4" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da" + integrity sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w== + +hoek@6.x.x: + version "6.1.2" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.2.tgz#99e6d070561839de74ee427b61aa476bd6bddfd6" + integrity sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q== + +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +http-cache-semantics@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.4.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8" + integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w== + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-proxy-middleware@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz#0987e6bb5a5606e5a69168d8f967a87f15dd8aab" + integrity sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q== + dependencies: + http-proxy "^1.16.2" + is-glob "^4.0.0" + lodash "^4.17.5" + micromatch "^3.1.9" + +http-proxy@^1.13.0, http-proxy@^1.16.2: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@1.3.5, ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" + integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +internal-ip@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-3.0.1.tgz#df5c99876e1d2eb2ea2d74f520e3f669a00ece27" + integrity sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q== + dependencies: + default-gateway "^2.6.0" + ipaddr.js "^1.5.2" + +interpret@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= + +ipaddr.js@^1.5.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.1.tgz#fa4b79fa47fd3def5e3b159825161c0a519c9427" + integrity sha1-+kt5+kf9Pe9eOxWYJRYcClGclCc= + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +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" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +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" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + 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" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +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" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + +is-number@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" + integrity sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY= + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +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" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isbinaryfile@^3.0.0, isbinaryfile@^3.0.2, isbinaryfile@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isemail@3.x.x: + version "3.2.0" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" + integrity sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg== + dependencies: + punycode "2.x.x" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-api@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.0.6.tgz#cd7b33ee678f6c01531d05f5e567ebbcd25f8ecc" + integrity sha512-8W5oeAGWXhtTJjAyVfvavOLVyZCTNCKsyF6GON/INKlBdO7uJ/bv3qnPj5M6ERKzmMCJS1kntnjjGuJ86fn3rQ== + dependencies: + async "^2.6.1" + compare-versions "^3.2.1" + fileset "^2.0.3" + istanbul-lib-coverage "^2.0.1" + istanbul-lib-hook "^2.0.1" + istanbul-lib-instrument "^3.0.0" + istanbul-lib-report "^2.0.2" + istanbul-lib-source-maps "^2.0.1" + istanbul-reports "^2.0.1" + js-yaml "^3.12.0" + make-dir "^1.3.0" + once "^1.4.0" + +istanbul-instrumenter-loader@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz#9957bd59252b373fae5c52b7b5188e6fde2a0949" + integrity sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w== + dependencies: + convert-source-map "^1.5.0" + istanbul-lib-instrument "^1.7.3" + loader-utils "^1.1.0" + schema-utils "^0.3.0" + +istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + +istanbul-lib-coverage@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" + integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== + +istanbul-lib-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72" + integrity sha512-ufiZoiJ8CxY577JJWEeFuxXZoMqiKpq/RqZtOAYuQLvlkbJWscq9n3gc4xrCGH9n4pW0qnTxOz1oyMmVtk8E1w== + dependencies: + append-transform "^1.0.0" + +istanbul-lib-instrument@^1.7.3: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul-lib-instrument@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" + integrity sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ== + dependencies: + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + istanbul-lib-coverage "^2.0.1" + semver "^5.5.0" + +istanbul-lib-report@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535" + integrity sha512-rJ8uR3peeIrwAxoDEbK4dJ7cqqtxBisZKCuwkMtMv0xYzaAnsAi3AHrHPAAtNXzG/bcCgZZ3OJVqm1DTi9ap2Q== + dependencies: + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + supports-color "^5.4.0" + +istanbul-lib-source-maps@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e" + integrity sha512-30l40ySg+gvBLcxTrLzR4Z2XTRj3HgRCA/p2rnbs/3OiTaoj054gAbuP5DcLOtwqmy4XW8qXBHzrmP2/bQ9i3A== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + rimraf "^2.6.2" + source-map "^0.6.1" + +istanbul-reports@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7" + integrity sha512-CT0QgMBJqs6NJLF678ZHcquUAZIoBIUNzdJrRJfpkI9OnzG6MkUfHxbJC3ln981dMswC7/B1mfX3LNkhgJxsuw== + dependencies: + handlebars "^4.0.11" + +istanbul@0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +jasmine-core@3.3.0, jasmine-core@^3.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.3.0.tgz#dea1cdc634bc93c7e0d4ad27185df30fa971b10e" + integrity sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA== + +jasmine-core@~2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e" + integrity sha1-vMl5rh+f0FcB5F5S5l06XWPxok4= + +jasmine-spec-reporter@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz#1d632aec0341670ad324f92ba84b4b32b35e9e22" + integrity sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg== + dependencies: + colors "1.1.2" + +jasmine@2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.8.0.tgz#6b089c0a11576b1f16df11b80146d91d4e8b8a3e" + integrity sha1-awicChFXax8W3xG4AUbZHU6Lij4= + dependencies: + exit "^0.1.2" + glob "^7.0.6" + jasmine-core "~2.8.0" + +jasminewd2@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/jasminewd2/-/jasminewd2-2.2.0.tgz#e37cf0b17f199cce23bea71b2039395246b4ec4e" + integrity sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4= + +joi@^13.0.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f" + integrity sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q== + dependencies: + hoek "5.x.x" + isemail "3.x.x" + topo "3.x.x" + +js-base64@^2.1.8: + version "2.5.0" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.0.tgz#42255ba183ab67ce59a0dee640afdc00ab5ae93e" + integrity sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +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" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jszip@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37" + integrity sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ== + dependencies: + core-js "~2.3.0" + es6-promise "~3.0.2" + lie "~3.1.0" + pako "~1.0.2" + readable-stream "~2.0.6" + +karma-chrome-launcher@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" + integrity sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w== + dependencies: + fs-access "^1.0.0" + which "^1.2.1" + +karma-coverage-istanbul-reporter@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.0.4.tgz#402ae4ed6eadb9d9dafbd408ffda17897c0d003a" + integrity sha512-xJS7QSQIVU6VK9HuJ/ieE5yynxKhjCCkd96NLY/BX/HXsx0CskU9JJiMQbd4cHALiddMwI4OWh1IIzeWrsavJw== + dependencies: + istanbul-api "^2.0.5" + minimatch "^3.0.4" + +karma-jasmine-html-reporter@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.4.0.tgz#1abbd30d4509a8c82b96707ae7d2fa4da459ca19" + integrity sha512-0wxhwA8PLPpICZ4o2GRnPi67hf3JhfQm5WCB8nElh4qsE6wRNOTtrqooyBPNqI087Xr2SBhxLg5fU+BJ/qxRrw== + +karma-jasmine@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-2.0.1.tgz#26e3e31f2faf272dd80ebb0e1898914cc3a19763" + integrity sha512-iuC0hmr9b+SNn1DaUD2QEYtUxkS1J+bSJSn7ejdEexs7P8EYvA1CWkEdrDQ+8jVH3AgWlCNwjYsT1chjcNW9lA== + dependencies: + jasmine-core "^3.3" + +karma-source-map-support@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.3.0.tgz#36dd4d8ca154b62ace95696236fae37caf0a7dde" + integrity sha512-HcPqdAusNez/ywa+biN4EphGz62MmQyPggUsDfsHqa7tSe4jdsxgvTKuDfIazjL+IOxpVWyT7Pr4dhAV+sxX5Q== + dependencies: + source-map-support "^0.5.5" + +karma@3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/karma/-/karma-3.1.4.tgz#3890ca9722b10d1d14b726e1335931455788499e" + integrity sha512-31Vo8Qr5glN+dZEVIpnPCxEGleqE0EY6CtC2X9TagRV3rRQ3SNrvfhddICkJgUK3AgqpeKSZau03QumTGhGoSw== + dependencies: + bluebird "^3.3.0" + body-parser "^1.16.1" + chokidar "^2.0.3" + colors "^1.1.0" + combine-lists "^1.0.0" + connect "^3.6.0" + core-js "^2.2.0" + di "^0.0.1" + dom-serialize "^2.2.0" + expand-braces "^0.1.1" + flatted "^2.0.0" + glob "^7.1.1" + graceful-fs "^4.1.2" + http-proxy "^1.13.0" + isbinaryfile "^3.0.0" + lodash "^4.17.5" + log4js "^3.0.0" + mime "^2.3.1" + minimatch "^3.0.2" + optimist "^0.6.1" + qjobs "^1.1.4" + range-parser "^1.2.0" + rimraf "^2.6.0" + safe-buffer "^5.0.1" + socket.io "2.1.1" + source-map "^0.6.1" + tmp "0.0.33" + useragent "2.3.0" + +killable@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + +lazy-val@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc" + integrity sha512-pjCf3BYk+uv3ZcPzEVM0BFvO9Uw58TmlrU0oG5tTrr9Kcid3+kdKxapH8CjdYmVa2nO5wOoZn2rdvZx2PKj/xg== + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +less-loader@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.1.0.tgz#2c1352c5b09a4f84101490274fd51674de41363e" + integrity sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg== + dependencies: + clone "^2.1.1" + loader-utils "^1.1.0" + pify "^3.0.0" + +less@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/less/-/less-3.8.1.tgz#f31758598ef5a1930dd4caefa9e4340641e71e1d" + integrity sha512-8HFGuWmL3FhQR0aH89escFNBQH/nEiYPP2ltDFdQw2chE28Yx2E3lhAIq9Y2saYwLSwa699s4dBVEfCY8Drf7Q== + dependencies: + clone "^2.1.2" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + mime "^1.4.1" + mkdirp "^0.5.0" + promise "^7.1.1" + request "^2.83.0" + source-map "~0.6.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +license-webpack-plugin@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-2.0.2.tgz#9d34b521cb7fca8527945310b05be6ef0248b687" + integrity sha512-GsomZw5VoT20ST8qH2tOjBgbyhn6Pgs9M94g0mbvfBIV1VXufm1iKY+4dbgfTObj1Mp6nSRE3Zf74deOZr0KwA== + dependencies: + webpack-sources "^1.2.0" + +lie@~3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4= + dependencies: + immediate "~3.0.5" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" + integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== + +loader-utils@1.1.0, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lockfile@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" + integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== + dependencies: + signal-exit "^3.0.2" + +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + +lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.mergewith@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" + integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== + +lodash.tail@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664" + integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ= + +lodash@^4.0.0, lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.5.0, lodash@~4.17.10: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +log4js@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-3.0.6.tgz#e6caced94967eeeb9ce399f9f8682a4b2b28c8ff" + integrity sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ== + dependencies: + circular-json "^0.5.5" + date-format "^1.2.0" + debug "^3.1.0" + rfdc "^1.1.2" + streamroller "0.7.0" + +loglevel@^1.4.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" + integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +magic-string@^0.25.0: + version "0.25.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.1.tgz#b1c248b399cd7485da0fe7385c2fc7011843266e" + integrity sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg== + dependencies: + sourcemap-codec "^1.4.1" + +make-dir@^1.0.0, make-dir@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-error@^1.1.1: + version "1.3.5" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" + integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== + +make-fetch-happen@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083" + integrity sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ== + dependencies: + agentkeepalive "^3.4.1" + cacache "^11.0.1" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + lru-cache "^4.1.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" + integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + +meow@^3.1.0, meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + 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" + +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +"mime-db@>= 1.36.0 < 2", mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19: + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== + dependencies: + mime-db "~1.37.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.3.1, mime@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" + integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mini-css-extract-plugin@0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.4.tgz#c10410a004951bd3cedac1da69053940fccb625d" + integrity sha512-o+Jm+ocb0asEngdM6FsZWtZsRzA8koFUudIDwYUfl94M3PejPHG7Vopw5hN9V8WsMkSFpm3tZP3Fesz89EyrfQ== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + integrity sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4= + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.0.0, ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.10.0, nan@^2.9.2: + version "2.12.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" + integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +neo-async@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + +ngx-smart-modal@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ngx-smart-modal/-/ngx-smart-modal-7.1.0.tgz#133a59f90b09fb789e83e397e77a7eeb955e87f9" + integrity sha512-rQKHN1ekAM9UoyrfIh04deZ6jjO8X3u3g5/uDNp/Dg0GRvpwcq411x/VimRuyojQlAEHorbKJ2YcEN+i/ymAyw== + +ngx-virtual-scroller@^1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/ngx-virtual-scroller/-/ngx-virtual-scroller-1.0.16.tgz#63d0b32764c573a74a468b602a2d02c8ae7ad9b9" + integrity sha512-8HahzMbkRAULb/7y8EqmBx/c8Iw8qqDlEGvwlIyryg6Rsk/2TGIG35Z8w1KFaiW+10JulvewFaRByaLkrKiSiA== + dependencies: + "@tweenjs/tween.js" "^17.1.0" + "@types/tween.js" "^16.6.1" + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-fetch-npm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" + integrity sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw== + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + +node-forge@0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" + integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-libs-browser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.2.tgz#93c17fba5eec8650ad908de5433fa8763baebe4d" + integrity sha512-j1gEV/zX821yxdWp/1vBMN0pSUjuH9oGUdLCb4PfUko6ZW7KdRs3Z+QGGwDUhYtSpQvdVVyLd2V0YvLsmdg5jQ== + dependencies: + semver "^5.3.0" + +node-sass@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.10.0.tgz#dcc2b364c0913630945ccbf7a2bbf1f926effca4" + integrity sha512-fDQJfXszw6vek63Fe/ldkYXmRYK/QS6NbvM3i5oEo9ntPDy4XX7BcKZyTKv+/kSSxRtXXc7l+MSwEmYc0CSy6Q== + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.clonedeep "^4.3.2" + lodash.mergewith "^4.6.0" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.10.0" + node-gyp "^3.8.0" + npmlog "^4.0.0" + request "^2.88.0" + sass-graph "^2.2.4" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +"nopt@2 || 3", nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== + +npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" + integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA== + dependencies: + hosted-git-info "^2.6.0" + osenv "^0.1.5" + semver "^5.5.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.12, npm-packlist@^1.1.6: + version "1.1.12" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" + integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-pick-manifest@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40" + integrity sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA== + dependencies: + figgy-pudding "^3.5.1" + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-registry-fetch@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz#aa7d9a7c92aff94f48dba0984bdef4bd131c88cc" + integrity sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw== + dependencies: + JSONStream "^1.3.4" + bluebird "^3.5.1" + figgy-pudding "^3.4.1" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + npm-package-arg "^6.1.0" + +npm-run-all@4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nugget@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nugget/-/nugget-2.0.1.tgz#201095a487e1ad36081b3432fa3cada4f8d071b0" + integrity sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA= + dependencies: + debug "^2.1.3" + minimist "^1.1.0" + pretty-bytes "^1.0.2" + progress-stream "^1.1.0" + request "^2.45.0" + single-line-log "^1.1.2" + throttleit "0.0.2" + +null-check@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" + integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +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" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== + +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +obuf@^1.0.0, obuf@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c= + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opn@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" + integrity sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g== + dependencies: + is-wsl "^1.1.0" + +opn@^5.1.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" + integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== + dependencies: + is-wsl "^1.1.0" + +optimist@^0.6.1, optimist@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-locale@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" + integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== + dependencies: + execa "^0.10.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4, osenv@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-limit@^1.0.0, p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pacote@9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.1.1.tgz#25091f75a25021de8be8d34cc6408728fca3579b" + integrity sha512-f28Rq5ozzKAA9YwIKw61/ipwAatUZseYmVssDbHHaexF0wRIVotapVEZPAjOT7Eu3LYVqEp0NVpNizoAnYBUaA== + dependencies: + bluebird "^3.5.2" + cacache "^11.2.0" + figgy-pudding "^3.5.1" + get-stream "^4.1.0" + glob "^7.1.3" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + minimatch "^3.0.4" + minipass "^2.3.5" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.12" + npm-pick-manifest "^2.1.0" + npm-registry-fetch "^3.8.0" + osenv "^0.1.5" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^5.0.1" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.6.0" + ssri "^6.0.1" + tar "^4.4.6" + unique-filename "^1.1.1" + which "^1.3.1" + +pako@~1.0.2, pako@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.7.tgz#2473439021b57f1516c82f58be7275ad8ef1bb27" + integrity sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ== + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-color@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-color/-/parse-color-1.0.0.tgz#7b748b95a83f03f16a94f535e52d7f3d94658619" + integrity sha1-e3SLlag/A/FqlPU15S1/PZRlhhk= + dependencies: + color-convert "~0.5.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +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" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pidtree@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b" + integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + 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" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +plist@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" + integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ== + dependencies: + base64-js "^1.2.3" + xmlbuilder "^9.0.7" + xmldom "0.1.x" + +portfinder@1.0.17: + version "1.0.17" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.17.tgz#a8a1691143e46c4735edefcf4fbcccedad26456a" + integrity sha512-syFcRIRzVI1BoEFOCaAiizwDolh1S1YXSodsVhncbhjzjZQulhczNRbqnUl9N31Q4dKGOXsNDqxC2BWBgSMqeQ== + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +portfinder@^1.0.9: + version "1.0.20" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" + integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw== + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-import@12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.0.tgz#149f96a4ef0b27525c419784be8517ebd17e92c5" + integrity sha512-3KqKRZcaZAvxbY8DVLdd81tG5uKzbUQuiWIvy0o0fzEC42bKacqPYFWbfCQyw6L4LWUaqPz/idvIdbhpgQ32eQ== + dependencies: + postcss "^7.0.1" + postcss-value-parser "^3.2.3" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-load-config@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484" + integrity sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ== + dependencies: + cosmiconfig "^4.0.0" + import-cwd "^2.0.0" + +postcss-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss@7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.5.tgz#70e6443e36a6d520b0fd4e7593fcca3635ee9f55" + integrity sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.5.0" + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.5: + version "7.0.7" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.7.tgz#2754d073f77acb4ef08f1235c36c5721a7201614" + integrity sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.5.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +pretty-bytes@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84" + integrity sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ= + dependencies: + get-stdin "^4.0.1" + meow "^3.1.0" + +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" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress-stream@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-1.2.0.tgz#2cd3cfea33ba3a89c9c121ec3347abe9ab125f77" + integrity sha1-LNPP6jO6OonJwSHsM0er6asSX3c= + dependencies: + speedometer "~0.1.2" + through2 "~0.2.3" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +protoduck@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" + integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== + dependencies: + genfun "^5.0.0" + +protractor@5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.4.1.tgz#011a99e38df7aa45d22455b889ffbb13a6ce0bd9" + integrity sha512-ORey5ewQMYiXQxcQohsqEiKYOg/r5yJoJbt0tuROmmgajdg/CA3gTOZNIFJncUVMAJIk5YFqBBLUjKVmQO6tfA== + dependencies: + "@types/node" "^6.0.46" + "@types/q" "^0.0.32" + "@types/selenium-webdriver" "^3.0.0" + blocking-proxy "^1.0.0" + browserstack "^1.5.1" + chalk "^1.1.3" + glob "^7.0.3" + jasmine "2.8.0" + jasminewd2 "^2.1.0" + optimist "~0.6.0" + q "1.4.1" + saucelabs "^1.5.0" + selenium-webdriver "3.6.0" + source-map-support "~0.4.0" + webdriver-js-extender "2.1.0" + webdriver-manager "^12.0.6" + +proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0, pump@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@2.x.x, punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +q@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" + integrity sha1-VXBbzZPF82c1MMLCy8DCs63cKG4= + +q@^1.4.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qjobs@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.5.2, qs@~6.5.1, qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef" + integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg== + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +raw-loader@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" + integrity sha1-DD0L6u2KAclm2Xh793goElKpeao= + +rc@^1.0.1, rc@^1.1.6, rc@^1.2.1, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= + dependencies: + pify "^2.3.0" + +read-config-file@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-3.2.0.tgz#50a2756a9a128ab9dcbe087e2724c512e3d0ccd1" + integrity sha512-i1QRc5jy4sHm9YBGb6ArA5SU1mDrc5wu2mnm3r9gPnm+LVZhBGbpTCKqAXyvV4TJHnBR3Yaaww+9b3DyRZcfww== + dependencies: + ajv "^6.5.5" + ajv-keywords "^3.2.0" + bluebird-lst "^1.0.6" + dotenv "^6.1.0" + dotenv-expand "^4.2.0" + fs-extra-p "^7.0.0" + js-yaml "^3.12.0" + json5 "^2.1.0" + lazy-val "^1.0.3" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= + dependencies: + 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.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +reflect-metadata@^0.1.2: + version "0.1.12" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" + integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== + +regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" + integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" + integrity sha1-x6jTI2BoNiBZp+RlH8aITosftK4= + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request@2.87.0: + version "2.87.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" + integrity sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +request@^2.45.0, request@^2.83.0, request@^2.87.0, request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2: + version "1.9.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" + integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= + +rfdc@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.2.tgz#e6e72d74f5dc39de8f538f65e00c36c18018e349" + integrity sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA== + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= + +rxjs@6.3.3, rxjs@^6.1.0: + version "6.3.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" + integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sanitize-filename@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" + integrity sha1-YS2hyWRz+gLczaktzVtKsWSmdyo= + dependencies: + truncate-utf8-bytes "^1.0.0" + +sass-graph@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sass-loader@7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.1.0.tgz#16fd5138cb8b424bf8a759528a1972d72aad069d" + integrity sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w== + dependencies: + clone-deep "^2.0.1" + loader-utils "^1.0.1" + lodash.tail "^4.1.1" + neo-async "^2.5.0" + pify "^3.0.0" + semver "^5.5.0" + +saucelabs@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.5.0.tgz#9405a73c360d449b232839919a86c396d379fd9d" + integrity sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ== + dependencies: + https-proxy-agent "^2.2.1" + +sax@0.5.x: + version "0.5.8" + resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" + integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE= + +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + integrity sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8= + dependencies: + ajv "^5.0.0" + +schema-utils@^0.4.4, schema-utils@^0.4.5: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" + integrity sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q== + dependencies: + jszip "^3.1.3" + rimraf "^2.5.4" + tmp "0.0.30" + xml2js "^0.4.17" + +selfsigned@^1.9.1: + version "1.10.4" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd" + integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw== + dependencies: + node-forge "0.7.5" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +semver-dsl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/semver-dsl/-/semver-dsl-1.0.1.tgz#d3678de5555e8a61f629eed025366ae5f27340a0" + integrity sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA= + dependencies: + semver "^5.3.0" + +semver-intersect@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/semver-intersect/-/semver-intersect-1.4.0.tgz#bdd9c06bedcdd2fedb8cd352c3c43ee8c61321f3" + integrity sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ== + dependencies: + semver "^5.0.0" + +"semver@2 || 3 || 4 || 5", semver@^5.0.0, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +semver@5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw== + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +serialize-javascript@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" + integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== + +serve-index@^1.7.2: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallow-clone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571" + integrity sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA== + dependencies: + is-extendable "^0.1.1" + kind-of "^5.0.0" + mixin-object "^2.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shelljs@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" + integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +single-line-log@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/single-line-log/-/single-line-log-1.1.2.tgz#c2f83f273a3e1a16edb0995661da0ed5ef033364" + integrity sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q= + dependencies: + string-width "^1.0.1" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +smart-buffer@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3" + integrity sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" + integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs= + +socket.io-client@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" + integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.2.0" + to-array "0.1.4" + +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" + integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" + integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA== + dependencies: + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +sockjs-client@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" + integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.19: + version "0.3.19" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" + integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.0.1" + +socks-proxy-agent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473" + integrity sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw== + dependencies: + agent-base "~4.2.0" + socks "~2.2.0" + +socks@~2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.2.tgz#f061219fc2d4d332afb4af93e865c84d3fa26e2b" + integrity sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q== + dependencies: + ip "^1.1.5" + smart-buffer "^4.0.1" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-list-map@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" + integrity sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY= + +source-map-loader@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.4.tgz#c18b0dc6e23bf66f6792437557c569a11e072271" + integrity sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ== + dependencies: + async "^2.5.0" + loader-utils "^1.1.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@0.5.9, source-map-support@^0.5.5, source-map-support@^0.5.6, source-map-support@^0.5.9, source-map-support@~0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.4.0: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.1.x: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= + dependencies: + amdefine ">=0.0.4" + +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + +source-map@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +source-map@^0.4.2, source-map@~0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + +sourcemap-codec@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz#c63ea927c029dd6bd9a2b7fa03b3fec02ad56e9f" + integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg== + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== + +spdy-transport@^2.0.18: + version "2.1.1" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.1.1.tgz#c54815d73858aadd06ce63001e7d25fa6441623b" + integrity sha512-q7D8c148escoB3Z7ySCASadkegMmUZW8Wb/Q1u0/XBgDKMO880rLQDj8Twiew/tYi7ghemKUi/whSYOwE17f5Q== + dependencies: + debug "^2.6.8" + detect-node "^2.0.3" + hpack.js "^2.1.6" + obuf "^1.1.1" + readable-stream "^2.2.9" + safe-buffer "^5.0.1" + wbuf "^1.7.2" + +spdy@^3.4.1: + version "3.4.7" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc" + integrity sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw= + dependencies: + debug "^2.6.8" + handle-thing "^1.2.5" + http-deceiver "^1.2.7" + safe-buffer "^5.0.1" + select-hose "^2.0.0" + spdy-transport "^2.0.18" + +speed-measure-webpack-plugin@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.3.tgz#de170b5cefbfa1c039d95e639edd3ad50cfc7c48" + integrity sha512-p+taQ69VkRUXYMoZOx2nxV/Tz8tt79ahctoZJyJDHWP7fEYvwFNf5Pd73k5kZ6auu0pTsPNLEUwWpM8mCk85Zw== + dependencies: + chalk "^2.0.1" + +speedometer@~0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" + integrity sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0= + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" + integrity sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + integrity sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ== + dependencies: + safe-buffer "^5.1.1" + +ssri@^6.0.0, ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stat-mode@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" + integrity sha1-5sgLYjEj19gM8TLOU480YokHJQI= + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stats-webpack-plugin@0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/stats-webpack-plugin/-/stats-webpack-plugin-0.7.0.tgz#ccffe9b745de8bbb155571e063f8263fc0e2bc06" + integrity sha512-NT0YGhwuQ0EOX+uPhhUcI6/+1Sq/pMzNuSCBVT4GbFl/ac6I/JZefBcjlECNfAb1t3GOx5dEj1Z7x0cAxeeVLQ== + dependencies: + lodash "^4.17.4" + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== + dependencies: + readable-stream "^2.0.1" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamroller@0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.7.0.tgz#a1d1b7cf83d39afb0d63049a5acbf93493bdf64b" + integrity sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ== + dependencies: + date-format "^1.2.0" + debug "^3.1.0" + mkdirp "^0.5.1" + readable-stream "^2.3.0" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string.prototype.padend@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" + integrity sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + +string_decoder@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +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" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + +stylus-loader@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6" + integrity sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA== + dependencies: + loader-utils "^1.0.2" + lodash.clonedeep "^4.5.0" + when "~3.6.x" + +stylus@0.54.5: + version "0.54.5" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" + integrity sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk= + dependencies: + css-parse "1.7.x" + debug "*" + glob "7.0.x" + mkdirp "0.5.x" + sax "0.5.x" + source-map "0.1.x" + +sumchecker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-2.0.2.tgz#0f42c10e5d05da5d42eea3e56c3399a37d6c5b3e" + integrity sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4= + dependencies: + debug "^2.2.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e" + integrity sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA== + +tar@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4, tar@^4.4.6: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +temp-file@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/temp-file/-/temp-file-3.3.2.tgz#69b6daf1bbe23231d0a5d03844e3d96f3f531aaa" + integrity sha512-FGKccAW0Mux9hC/2bdUIe4bJRv4OyVo4RpVcuplFird1V/YoplIFbnPZjfzbJSf/qNvRZIRB9/4n/RkI0GziuQ== + dependencies: + async-exit-hook "^2.0.1" + bluebird-lst "^1.0.6" + fs-extra-p "^7.0.0" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +terser-webpack-plugin@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.1.0.tgz#cf7c25a1eee25bf121f4a587bb9e004e3f80e528" + integrity sha512-61lV0DSxMAZ8AyZG7/A4a3UPlrbOBo8NIQ4tJzLPAdGOQ+yoNC7l5ijEow27lBAL2humer01KLS6bGIMYQxKoA== + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.8.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +terser@^3.8.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.13.1.tgz#a02e8827fb9705fe7b609c31093d010b28cea8eb" + integrity sha512-ogyZye4DFqOtMzT92Y3Nxxw8OvXmL39HOALro4fc+EUYFFF9G/kk0znkvwMz6PPYgBtdKAodh3FPR70eugdaQA== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + source-map-support "~0.5.6" + +throttleit@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" + integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f" + integrity sha1-6zKE2k6jEbbMis42U3SKUqvyWj8= + dependencies: + readable-stream "~1.1.9" + xtend "~2.1.1" + +"through@>=2.2.7 <3", through@X.X.X, through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" + integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + dependencies: + setimmediate "^1.0.4" + +tmp@0.0.30: + version "0.0.30" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" + integrity sha1-ckGdSovn1s51FI/YsyTlk6cRwu0= + dependencies: + os-tmpdir "~1.0.1" + +tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +topo@3.x.x: + version "3.0.3" + resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" + integrity sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ== + dependencies: + hoek "6.x.x" + +tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== + dependencies: + punycode "^1.4.1" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tree-kill@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.0.tgz#5846786237b4239014f05db156b643212d4c6f36" + integrity sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg== + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== + dependencies: + glob "^7.1.2" + +truncate-utf8-bytes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" + integrity sha1-QFkjkJWS1W94pYGENLC3hInKXys= + dependencies: + utf8-byte-length "^1.0.1" + +ts-node@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + +tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tslint@5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.0.tgz#47f2dba291ed3d580752d109866fb640768fca36" + integrity sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ== + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.27.2" + +tsutils@^2.27.2: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68" + integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA== + +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + +uglifyjs-webpack-plugin@^1.2.4: + version "1.3.0" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de" + integrity sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw== + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + schema-utils "^0.4.5" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +underscore@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.0, unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg== + dependencies: + imurmurhash "^0.1.4" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== + +update-notifier@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" + integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== + dependencies: + querystringify "^2.0.0" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +useragent@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" + integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw== + dependencies: + lru-cache "4.1.x" + tmp "0.0.x" + +utf8-byte-length@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" + integrity sha1-9F8VDExm7uloGGUFq5P8u4rWv2E= + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1, uuid@^3.1.0, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +wait-on@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.2.0.tgz#c83924df0fc42a675c678324c49c769d378bcb85" + integrity sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg== + dependencies: + core-js "^2.5.7" + joi "^13.0.0" + minimist "^1.2.0" + request "^2.88.0" + rx "^4.1.0" + +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wbuf@^1.1.0, wbuf@^1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +web-animations-js@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/web-animations-js/-/web-animations-js-2.3.1.tgz#3a6d9bc15196377a90f8e2803fa5262165b04510" + integrity sha1-Om2bwVGWN3qQ+OKAP6UmIWWwRRA= + +webdriver-js-extender@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz#57d7a93c00db4cc8d556e4d3db4b5db0a80c3bb7" + integrity sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ== + dependencies: + "@types/selenium-webdriver" "^3.0.0" + selenium-webdriver "^3.0.1" + +webdriver-manager@12.1.0, webdriver-manager@^12.0.6: + version "12.1.0" + resolved "https://registry.yarnpkg.com/webdriver-manager/-/webdriver-manager-12.1.0.tgz#f6601e52de5f0c97fc7024c889eeb2416f2f1d9d" + integrity sha512-oEc5fmkpz6Yh6udhwir5m0eN5mgRPq9P/NU5YWuT3Up5slt6Zz+znhLU7q4+8rwCZz/Qq3Fgpr/4oao7NPCm2A== + dependencies: + adm-zip "^0.4.9" + chalk "^1.1.1" + del "^2.2.0" + glob "^7.0.3" + ini "^1.3.4" + minimist "^1.2.0" + q "^1.4.1" + request "^2.87.0" + rimraf "^2.5.2" + semver "^5.3.0" + xml2js "^0.4.17" + +webpack-core@^0.6.8: + version "0.6.9" + resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2" + integrity sha1-/FcViMhVjad76e+23r3Fo7FyvcI= + dependencies: + source-list-map "~0.1.7" + source-map "~0.4.1" + +webpack-dev-middleware@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890" + integrity sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA== + dependencies: + memory-fs "~0.4.1" + mime "^2.3.1" + range-parser "^1.0.3" + webpack-log "^2.0.0" + +webpack-dev-server@3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.10.tgz#507411bee727ee8d2fdffdc621b66a64ab3dea2b" + integrity sha512-RqOAVjfqZJtQcB0LmrzJ5y4Jp78lv9CK0MZ1YJDTaTmedMZ9PU9FLMQNrMCfVu8hHzaVLVOJKBlGEHMN10z+ww== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.0.0" + compression "^1.5.2" + connect-history-api-fallback "^1.3.0" + debug "^3.1.0" + del "^3.0.0" + express "^4.16.2" + html-entities "^1.2.0" + http-proxy-middleware "~0.18.0" + import-local "^2.0.0" + internal-ip "^3.0.1" + ip "^1.1.5" + killable "^1.0.0" + loglevel "^1.4.1" + opn "^5.1.0" + portfinder "^1.0.9" + schema-utils "^1.0.0" + selfsigned "^1.9.1" + serve-index "^1.7.2" + sockjs "0.3.19" + sockjs-client "1.3.0" + spdy "^3.4.1" + strip-ansi "^3.0.0" + supports-color "^5.1.0" + webpack-dev-middleware "3.4.0" + webpack-log "^2.0.0" + yargs "12.0.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.4.tgz#0fde38eabf2d5fd85251c24a5a8c48f8a3f4eb7b" + integrity sha512-TmSe1HZKeOPey3oy1Ov2iS3guIZjWvMT2BBJDzzT5jScHTjVC3mpjJofgueEzaEd6ibhxRDD6MIblDr8tzh8iQ== + dependencies: + lodash "^4.17.5" + +webpack-sources@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.2.0.tgz#18181e0d013fce096faf6f8e6d41eeffffdceac2" + integrity sha512-9BZwxR85dNsjWz3blyxdOhTgtnQvv3OEs5xofI0wPYTwu5kaWxS08UuD1oI7WLBLpRO+ylf0ofnXLXWmGb2WMw== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@1.3.0, webpack-sources@^1.1.0, webpack-sources@^1.2.0, webpack-sources@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-subresource-integrity@1.1.0-rc.6: + version "1.1.0-rc.6" + resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.6.tgz#37f6f1264e1eb378e41465a98da80fad76ab8886" + integrity sha512-Az7y8xTniNhaA0620AV1KPwWOqawurVVDzQSpPAeR5RwNbL91GoBSJAAo9cfd+GiFHwsS5bbHepBw1e6Hzxy4w== + dependencies: + webpack-core "^0.6.8" + +webpack@4.23.1: + version "4.23.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.23.1.tgz#db7467b116771ae020c58bdfe2a0822785bb8239" + integrity sha512-iE5Cu4rGEDk7ONRjisTOjVHv3dDtcFfwitSxT7evtYj/rANJpt1OuC/Kozh1pBa99AUBr1L/LsaNB+D9Xz3CEg== + dependencies: + "@webassemblyjs/ast" "1.7.10" + "@webassemblyjs/helper-module-context" "1.7.10" + "@webassemblyjs/wasm-edit" "1.7.10" + "@webassemblyjs/wasm-parser" "1.7.10" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.1.0" + uglifyjs-webpack-plugin "^1.2.4" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + +websocket-driver@>=0.5.1: + version "0.7.0" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + integrity sha1-DK+dLXVdk67gSdS90NP+LMoqJOs= + dependencies: + http-parser-js ">=0.4.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +when@~3.6.x: + version "3.6.4" + resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" + integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1, which@^1.1.1, which@^1.2.1, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xml2js@^0.4.17: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + +xmlbuilder@^9.0.7, xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + +xmldom@0.1.x: + version "0.1.27" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" + integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= + dependencies: + object-keys "~0.4.0" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= + dependencies: + camelcase "^3.0.0" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= + dependencies: + camelcase "^4.1.0" + +yargs@12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" + integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ== + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" + +yargs@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" + integrity sha1-UqzCP+7Kw0BCB47njAwAf1CF20w= + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + +yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +yauzl@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU= + dependencies: + fd-slicer "~1.0.1" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= + +zone.js@0.8.26: + version "0.8.26" + resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.8.26.tgz#7bdd72f7668c5a7ad6b118148b4ea39c59d08d2d" + integrity sha512-W9Nj+UmBJG251wkCacIkETgra4QgBo/vgoEkb4a2uoLzpQG7qF9nzwoLXWU5xj3Fg2mxGvEDh47mg24vXccYjA==