From 2ef0f04ac24ffeaeb3a22681d3962b9a4426bf07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Fri, 8 Sep 2017 14:04:36 +0200 Subject: [PATCH 01/32] core: Remove `core:upload-complete` event. XHRUpload and Tus were relying on `core:upload-complete` to determine when their uploads had all finished, but `core:upload-complete` could fire before all XHR `onload` handlers were called. Then, because XHRUpload and Tus would resolve their `handleUpload` promises at that point, the `core:success` event could fire *before* all `core:upload-success` events had fired, and before the plugins properly handled responses. In particular, some files may not have `.uploadURL` properties when `core:success` is fired: https://community.transloadit.com/t/unable-to-get-to-work-the-awss3-plugin/14477/16 I think, that the XHR `onprogress` event would fire first at 100%, and then the `onload` handler fired at some point later (after the response was parsed or whatever the browser does to it). This could cause the `core:upload-complete` event to fire before responses were handled by Uppy. The XHRUpload and Tus plugins now use the Promises that they were already creating to wait for uploads to complete. This way they will always have handled responses before handing over control to postprocessors and before the `core:success` event is fired. Since `core:upload-complete` is now unused, I just removed it for now. --- src/core/Core.js | 7 ------- src/plugins/Tus10.js | 14 +++++--------- src/plugins/XHRUpload.js | 14 +++++--------- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/core/Core.js b/src/core/Core.js index 85ac26b15..68ad030d6 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -525,13 +525,6 @@ class Uppy { }) this.calculateTotalProgress() - - if (this.getState().totalProgress === 100) { - const completeFiles = Object.keys(updatedFiles).filter((file) => { - return updatedFiles[file].progress.uploadComplete - }) - this.emit('core:upload-complete', completeFiles.length) - } }) this.on('core:update-meta', (data, fileID) => { diff --git a/src/plugins/Tus10.js b/src/plugins/Tus10.js index 071cd2388..0e855405d 100644 --- a/src/plugins/Tus10.js +++ b/src/plugins/Tus10.js @@ -324,16 +324,16 @@ module.exports = class Tus10 extends Plugin { } uploadFiles (files) { - files.forEach((file, index) => { + return Promise.all(files.map((file, index) => { const current = parseInt(index, 10) + 1 const total = files.length if (!file.isRemote) { - this.upload(file, current, total) + return this.upload(file, current, total) } else { - this.uploadRemote(file, current, total) + return this.uploadRemote(file, current, total) } - }) + })) } handleUpload (fileIDs) { @@ -345,11 +345,7 @@ module.exports = class Tus10 extends Plugin { this.core.log('Tus is uploading...') const filesToUpload = fileIDs.map((fileID) => this.core.getFile(fileID)) - this.uploadFiles(filesToUpload) - - return new Promise((resolve) => { - this.core.once('core:upload-complete', resolve) - }) + return this.uploadFiles(filesToUpload) } actions () { diff --git a/src/plugins/XHRUpload.js b/src/plugins/XHRUpload.js index 9f706bc91..2c6281479 100644 --- a/src/plugins/XHRUpload.js +++ b/src/plugins/XHRUpload.js @@ -176,16 +176,16 @@ module.exports = class XHRUpload extends Plugin { } selectForUpload (files) { - files.forEach((file, i) => { + return Promise.all(files.map((file, i) => { const current = parseInt(i, 10) + 1 const total = files.length if (file.isRemote) { - this.uploadRemote(file, current, total) + return this.uploadRemote(file, current, total) } else { - this.upload(file, current, total) + return this.upload(file, current, total) } - }) + })) // if (this.opts.bundle) { // uploaders.push(this.upload(files, 0, files.length)) @@ -208,11 +208,7 @@ module.exports = class XHRUpload extends Plugin { return this.core.state.files[fileID] } - this.selectForUpload(files) - - return new Promise((resolve) => { - this.core.once('core:upload-complete', resolve) - }) + return this.selectForUpload(files).then(() => null) } install () { From 83f514232e428fab44ea88a801552bcb0790db80 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Fri, 8 Sep 2017 15:21:48 -0400 Subject: [PATCH 02/32] bind `info` --- src/core/Core.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Core.js b/src/core/Core.js index 85ac26b15..2ec220729 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -71,6 +71,7 @@ class Uppy { this.updateMeta = this.updateMeta.bind(this) this.initSocket = this.initSocket.bind(this) this.log = this.log.bind(this) + this.info = this.info.bind(this) this.addFile = this.addFile.bind(this) this.removeFile = this.removeFile.bind(this) this.calculateProgress = this.calculateProgress.bind(this) From 7dfae9d24c4aa15ae4661c1ab8d153639c53c1bf Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Fri, 8 Sep 2017 15:23:44 -0400 Subject: [PATCH 03/32] support multiple elements in `findDOMElement` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @goto-bus-stop potential danger point. introduced to support multiple dashboard open triggers #326 Maybe we should always return an array and just use the first element where multiple elements don’t make sense --- src/core/Utils.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index 16c28cae9..70a5719dc 100644 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -516,7 +516,12 @@ function isDOMElement (obj) { */ function findDOMElement (element) { if (typeof element === 'string') { - return document.querySelector(element) + const elements = [].slice.call(document.querySelectorAll(element)) + if (elements.length > 1) { + return elements + } + return elements[0] + // return document.querySelector(element) } if (typeof element === 'object' && isDOMElement(element)) { From c77c6a103d23055a5b154a7f2025f0769862c879 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Fri, 8 Sep 2017 15:24:30 -0400 Subject: [PATCH 04/32] hideModal/showModal --> show/hide, isOpen, DashboardUI --> Dashboard --- src/plugins/Dashboard/Dashboard.js | 2 +- src/plugins/Dashboard/index.js | 47 ++++++++++++++++++------------ src/plugins/StatusBar/index.js | 4 +-- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/plugins/Dashboard/Dashboard.js b/src/plugins/Dashboard/Dashboard.js index d81cec6ee..857da16b4 100644 --- a/src/plugins/Dashboard/Dashboard.js +++ b/src/plugins/Dashboard/Dashboard.js @@ -69,7 +69,7 @@ module.exports = function Dashboard (props) { type="button" aria-label="${props.i18n('closeModal')}" title="${props.i18n('closeModal')}" - onclick=${props.hideModal}>${closeIcon()} + onclick=${props.hide}>${closeIcon()}
diff --git a/src/plugins/Dashboard/index.js b/src/plugins/Dashboard/index.js index afe8eb09e..1a6b189ec 100644 --- a/src/plugins/Dashboard/index.js +++ b/src/plugins/Dashboard/index.js @@ -14,8 +14,8 @@ const { defaultTabIcon } = require('./icons') module.exports = class DashboardUI extends Plugin { constructor (core, opts) { super(core, opts) - this.id = 'DashboardUI' - this.title = 'Dashboard UI' + this.id = 'Dashboard' + this.title = 'Dashboard' this.type = 'orchestrator' const defaultLocale = { @@ -66,8 +66,8 @@ module.exports = class DashboardUI extends Plugin { this.translator = new Translator({locale: this.locale}) this.containerWidth = this.translator.translate.bind(this.translator) - this.hideModal = this.hideModal.bind(this) - this.showModal = this.showModal.bind(this) + this.hide = this.hide.bind(this) + this.show = this.show.bind(this) this.addTarget = this.addTarget.bind(this) this.actions = this.actions.bind(this) @@ -143,7 +143,11 @@ module.exports = class DashboardUI extends Plugin { })}) } - hideModal () { + isOpen () { + return !this.core.getState().modal.isHidden || false + } + + hide () { const modal = this.core.getState().modal this.core.setState({ @@ -157,7 +161,7 @@ module.exports = class DashboardUI extends Plugin { window.scrollTo(0, this.savedDocumentScrollPosition) } - showModal () { + show () { const modal = this.core.getState().modal this.core.setState({ @@ -185,19 +189,23 @@ module.exports = class DashboardUI extends Plugin { // Close the Modal on esc key press handleEscapeKeyPress (event) { if (event.keyCode === 27) { - this.hideModal() + this.hide() } } handleClickOutside () { - if (this.opts.closeModalOnClickOutside) this.hideModal() + if (this.opts.closeModalOnClickOutside) this.hide() } initEvents () { // Modal open button const showModalTrigger = findDOMElement(this.opts.trigger) if (!this.opts.inline && showModalTrigger) { - showModalTrigger.addEventListener('click', this.showModal) + if (Array.isArray(showModalTrigger)) { + showModalTrigger.forEach(trigger => trigger.addEventListener('click', this.show)) + } else { + showModalTrigger.addEventListener('click', this.show) + } } if (!this.opts.inline && !showModalTrigger) { @@ -215,7 +223,11 @@ module.exports = class DashboardUI extends Plugin { removeEvents () { const showModalTrigger = findDOMElement(this.opts.trigger) if (!this.opts.inline && showModalTrigger) { - showModalTrigger.removeEventListener('click', this.showModal) + if (Array.isArray(showModalTrigger)) { + showModalTrigger.forEach(trigger => trigger.removeEventListener('click', this.show)) + } else { + showModalTrigger.removeEventListener('click', this.show) + } } this.removeDragDropListener() @@ -259,7 +271,7 @@ module.exports = class DashboardUI extends Plugin { } handleDrop (files) { - this.core.log('All right, someone dropped something...') + this.core.log('[Dashboard] Files were droppeded') files.forEach((file) => { this.core.addFile({ @@ -300,7 +312,6 @@ module.exports = class DashboardUI extends Plugin { inProgressFilesArray.push(files[file]) }) - // total size and uploaded size let totalSize = 0 let totalUploadedSize = 0 inProgressFilesArray.forEach((file) => { @@ -326,7 +337,7 @@ module.exports = class DashboardUI extends Plugin { } const pauseUpload = (fileID) => { - this.core.emit.emit('core:upload-pause', fileID) + this.core.emit('core:upload-pause', fileID) } const cancelUpload = (fileID) => { @@ -343,9 +354,9 @@ module.exports = class DashboardUI extends Plugin { this.core.emit('dashboard:file-card') } - const info = (text, type, duration) => { - this.core.info(text, type, duration) - } + // const info = (text, type, duration) => { + // this.core.info(text, type, duration) + // } const resumableUploads = this.core.state.capabilities.resumableUploads || false @@ -362,7 +373,7 @@ module.exports = class DashboardUI extends Plugin { autoProceed: this.core.opts.autoProceed, hideUploadButton: this.opts.hideUploadButton, id: this.id, - hideModal: this.hideModal, + hide: this.hide, handleClickOutside: this.handleClickOutside, showProgressDetails: this.opts.showProgressDetails, inline: this.opts.inline, @@ -375,7 +386,7 @@ module.exports = class DashboardUI extends Plugin { resumeAll: this.resumeAll, addFile: this.core.addFile, removeFile: this.core.removeFile, - info: info, + info: this.core.info, note: this.opts.note, metaFields: state.metaFields, resumableUploads: resumableUploads, diff --git a/src/plugins/StatusBar/index.js b/src/plugins/StatusBar/index.js index 53907e73b..e08bf47d8 100644 --- a/src/plugins/StatusBar/index.js +++ b/src/plugins/StatusBar/index.js @@ -11,8 +11,8 @@ const prettyBytes = require('prettier-bytes') module.exports = class StatusBarUI extends Plugin { constructor (core, opts) { super(core, opts) - this.id = 'StatusBarUI' - this.title = 'StatusBar UI' + this.id = 'StatusBar' + this.title = 'StatusBar' this.type = 'progressindicator' // set default options From d4e5daa6302ccaa9e416a30ae829210210b711ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Sat, 9 Sep 2017 14:08:41 +0200 Subject: [PATCH 05/32] xhrupload,tus: Use `promise-settle` --- package-lock.json | 67 +++++++++++++++++++++------------------- package.json | 1 + src/plugins/Tus10.js | 3 +- src/plugins/XHRUpload.js | 3 +- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e627d8db..a5786cf92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,16 @@ "integrity": "sha1-9vGlzl05caSt6RoR0i1MRZrNN18=", "dev": true }, + "JSONStream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", + "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "dev": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, "abbrev": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", @@ -1445,9 +1455,9 @@ "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", "dev": true, "requires": { + "JSONStream": "1.3.1", "combine-source-map": "0.7.2", "defined": "1.0.0", - "JSONStream": "1.3.1", "through2": "2.0.3", "umd": "3.0.1" } @@ -1734,6 +1744,7 @@ "integrity": "sha1-BQjMHnv0wVIxLC+lI+Z2wLC5IxE=", "dev": true, "requires": { + "JSONStream": "1.3.1", "assert": "1.4.1", "browser-pack": "6.0.2", "browser-resolve": "1.11.2", @@ -1755,7 +1766,6 @@ "https-browserify": "0.0.1", "inherits": "2.0.3", "insert-module-globals": "7.0.1", - "JSONStream": "1.3.1", "labeled-stream-splicer": "2.0.0", "module-deps": "4.1.1", "os-browserify": "0.1.2", @@ -4907,14 +4917,6 @@ } } }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, "string-width": { "version": "1.0.2", "bundled": true, @@ -4925,6 +4927,14 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, "stringstream": { "version": "0.0.5", "bundled": true, @@ -6186,10 +6196,10 @@ "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", "dev": true, "requires": { + "JSONStream": "1.3.1", "combine-source-map": "0.7.2", "concat-stream": "1.5.2", "is-buffer": "1.1.5", - "JSONStream": "1.3.1", "lexical-scope": "1.2.0", "process": "0.11.10", "through2": "2.0.3", @@ -6679,16 +6689,6 @@ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", "dev": true }, - "JSONStream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", - "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", - "dev": true, - "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" - } - }, "jsprim": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", @@ -7697,6 +7697,7 @@ "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", "dev": true, "requires": { + "JSONStream": "1.3.1", "browser-resolve": "1.11.2", "cached-path-relative": "1.0.1", "concat-stream": "1.5.2", @@ -7704,7 +7705,6 @@ "detective": "4.5.0", "duplexer2": "0.1.4", "inherits": "2.0.3", - "JSONStream": "1.3.1", "parents": "1.0.1", "readable-stream": "2.2.11", "resolve": "1.3.3", @@ -9320,6 +9320,11 @@ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true }, + "promise-settle": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promise-settle/-/promise-settle-0.3.0.tgz", + "integrity": "sha1-tO/VcqHrdM95T4KM00naQKCOTpY=" + }, "propagate": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", @@ -10973,14 +10978,6 @@ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", "dev": true }, - "string_decoder": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", - "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", - "requires": { - "safe-buffer": "5.0.1" - } - }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -11035,6 +11032,14 @@ "function-bind": "1.1.0" } }, + "string_decoder": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", + "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", + "requires": { + "safe-buffer": "5.0.1" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", @@ -11831,6 +11836,7 @@ "integrity": "sha1-tanJAgJD8McORnW+yCI7xifkFc4=", "dev": true, "requires": { + "JSONStream": "1.3.1", "assert": "1.4.1", "browser-pack": "6.0.2", "browser-resolve": "1.11.2", @@ -11852,7 +11858,6 @@ "https-browserify": "0.0.1", "inherits": "2.0.3", "insert-module-globals": "7.0.1", - "JSONStream": "1.3.1", "labeled-stream-splicer": "2.0.0", "module-deps": "4.1.1", "os-browserify": "0.1.2", diff --git a/package.json b/package.json index 52bd3f599..d43b94c4f 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "nanoraf": "3.0.1", "on-load": "3.2.0", "prettier-bytes": "1.0.4", + "promise-settle": "^0.3.0", "socket.io-client": "2.0.1", "tus-js-client": "1.4.3", "url-parse": "1.1.9", diff --git a/src/plugins/Tus10.js b/src/plugins/Tus10.js index 0e855405d..b85df6b01 100644 --- a/src/plugins/Tus10.js +++ b/src/plugins/Tus10.js @@ -1,5 +1,6 @@ const Plugin = require('./Plugin') const tus = require('tus-js-client') +const settle = require('promise-settle') const UppySocket = require('../core/UppySocket') const Utils = require('../core/Utils') require('whatwg-fetch') @@ -324,7 +325,7 @@ module.exports = class Tus10 extends Plugin { } uploadFiles (files) { - return Promise.all(files.map((file, index) => { + return settle(files.map((file, index) => { const current = parseInt(index, 10) + 1 const total = files.length diff --git a/src/plugins/XHRUpload.js b/src/plugins/XHRUpload.js index 2c6281479..f6acb3859 100644 --- a/src/plugins/XHRUpload.js +++ b/src/plugins/XHRUpload.js @@ -1,4 +1,5 @@ const Plugin = require('./Plugin') +const settle = require('promise-settle') const UppySocket = require('../core/UppySocket') const Utils = require('../core/Utils') @@ -176,7 +177,7 @@ module.exports = class XHRUpload extends Plugin { } selectForUpload (files) { - return Promise.all(files.map((file, i) => { + return settle(files.map((file, i) => { const current = parseInt(i, 10) + 1 const total = files.length From 6b6ce35927165403b81eefb036b547042a3a8986 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Sun, 10 Sep 2017 21:35:10 -0400 Subject: [PATCH 06/32] add `findDOMElements ` that always returns an array of DOM elements --- src/core/Utils.js | 19 +++++++++++++------ src/plugins/Dashboard/index.js | 8 ++++---- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index 70a5719dc..9a2d23594 100644 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -516,12 +516,7 @@ function isDOMElement (obj) { */ function findDOMElement (element) { if (typeof element === 'string') { - const elements = [].slice.call(document.querySelectorAll(element)) - if (elements.length > 1) { - return elements - } - return elements[0] - // return document.querySelector(element) + return document.querySelector(element) } if (typeof element === 'object' && isDOMElement(element)) { @@ -529,6 +524,17 @@ function findDOMElement (element) { } } +/** + * Find one or more DOM elements. + * + * @param {string} selector + * @return {Array|null} + */ +function findAllDOMElements (selector) { + const elements = [].slice.call(document.querySelectorAll(selector)) + return elements.length > 0 ? elements : null +} + function getSocketHost (url) { // get the host domain var regex = /^(?:https?:\/\/|\/\/)?(?:[^@\n]+@)?(?:www\.)?([^\n]+)/ @@ -580,6 +586,7 @@ module.exports = { copyToClipboard, prettyETA, findDOMElement, + findAllDOMElements, getSocketHost, emitSocketProgress } diff --git a/src/plugins/Dashboard/index.js b/src/plugins/Dashboard/index.js index 1a6b189ec..0c36f8a0f 100644 --- a/src/plugins/Dashboard/index.js +++ b/src/plugins/Dashboard/index.js @@ -4,7 +4,7 @@ const dragDrop = require('drag-drop') const Dashboard = require('./Dashboard') const StatusBar = require('../StatusBar') const Informer = require('../Informer') -const { findDOMElement } = require('../../core/Utils') +const { findAllDOMElements } = require('../../core/Utils') const prettyBytes = require('prettier-bytes') const { defaultTabIcon } = require('./icons') @@ -199,7 +199,7 @@ module.exports = class DashboardUI extends Plugin { initEvents () { // Modal open button - const showModalTrigger = findDOMElement(this.opts.trigger) + const showModalTrigger = findAllDOMElements(this.opts.trigger) if (!this.opts.inline && showModalTrigger) { if (Array.isArray(showModalTrigger)) { showModalTrigger.forEach(trigger => trigger.addEventListener('click', this.show)) @@ -221,7 +221,7 @@ module.exports = class DashboardUI extends Plugin { } removeEvents () { - const showModalTrigger = findDOMElement(this.opts.trigger) + const showModalTrigger = findAllDOMElements(this.opts.trigger) if (!this.opts.inline && showModalTrigger) { if (Array.isArray(showModalTrigger)) { showModalTrigger.forEach(trigger => trigger.removeEventListener('click', this.show)) @@ -271,7 +271,7 @@ module.exports = class DashboardUI extends Plugin { } handleDrop (files) { - this.core.log('[Dashboard] Files were droppeded') + this.core.log('[Dashboard] Files were dropped') files.forEach((file) => { this.core.addFile({ From 47dab77dea75edf691963c25f499b6104578eb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Mon, 11 Sep 2017 10:41:30 +0200 Subject: [PATCH 07/32] Update lockfile --- package-lock.json | 1092 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 1016 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index a5786cf92..1ae26db2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,12 @@ "through": "2.3.8" } }, + "abab": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", + "integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=", + "dev": true + }, "abbrev": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", @@ -69,6 +75,23 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=" }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", @@ -199,6 +222,15 @@ "integrity": "sha1-YzXYZclkDQ+tmQBOWnkjIjjpLfo=", "dev": true }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "requires": { + "default-require-extensions": "1.0.0" + } + }, "aproba": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", @@ -245,6 +277,12 @@ "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", "dev": true }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, "array-filter": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", @@ -657,6 +695,17 @@ "babel-template": "6.25.0" } }, + "babel-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-20.0.3.tgz", + "integrity": "sha1-5KA7E9wQOJ4UD8ZF0J/8TO0wFnE=", + "dev": true, + "requires": { + "babel-core": "6.13.2", + "babel-plugin-istanbul": "4.1.4", + "babel-preset-jest": "20.0.3" + } + }, "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", @@ -691,6 +740,34 @@ "babel-types": "6.25.0" } }, + "babel-plugin-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.4.tgz", + "integrity": "sha1-GN3oS/POMp/d8/QQP66SFFbY5Yc=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "istanbul-lib-instrument": "1.8.0", + "test-exclude": "4.1.1" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + } + } + }, + "babel-plugin-jest-hoist": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz", + "integrity": "sha1-r+3IU70/jcNUjqZx++adA8wsF2c=", + "dev": true + }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", @@ -1030,6 +1107,15 @@ "babel-plugin-transform-regenerator": "6.24.1" } }, + "babel-preset-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz", + "integrity": "sha1-y6yq3stdaJyh4d4TYOv8ZoYsF4o=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "20.0.3" + } + }, "babel-register": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.9.0.tgz", @@ -1891,6 +1977,15 @@ "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", "dev": true }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, + "requires": { + "node-int64": "0.4.0" + } + }, "buble": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/buble/-/buble-0.12.5.tgz", @@ -2235,6 +2330,12 @@ "readdirp": "2.1.0" } }, + "ci-info": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.1.tgz", + "integrity": "sha512-vHDDF/bP9RYpTWtUhpJRhCFdvvp3iDWvEbuDbWgvjUrNGV1MXJrE0MPcwGtEled04m61iwdBLUIHZtDgzWS4ZQ==", + "dev": true + }, "cipher-base": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", @@ -2643,6 +2744,12 @@ "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", "dev": true }, + "content-type-parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", + "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", + "dev": true + }, "convert-source-map": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", @@ -2823,6 +2930,21 @@ "source-map": "0.5.6" } }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", + "dev": true + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "dev": true, + "requires": { + "cssom": "0.3.2" + } + }, "ctype": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", @@ -2948,6 +3070,15 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "requires": { + "strip-bom": "2.0.0" + } + }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -3097,6 +3228,12 @@ "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", "dev": true }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, "diffie-hellman": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", @@ -3465,6 +3602,15 @@ "has-binary2": "1.0.2" } }, + "errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "dev": true, + "requires": { + "prr": "0.0.0" + } + }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", @@ -3590,6 +3736,27 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "escodegen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", + "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "dev": true, + "requires": { + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.5.6" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + } + } + }, "escope": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", @@ -3667,6 +3834,12 @@ "integrity": "sha1-06aKr8cZFjnn7kQec0hzkCY1QpI=", "dev": true }, + "eslint-plugin-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-20.0.3.tgz", + "integrity": "sha1-7BXrpqwKtEpn6/bgJnLKnX58uik=", + "dev": true + }, "eslint-plugin-promise": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.4.2.tgz", @@ -3777,6 +3950,15 @@ "create-hash": "1.1.3" } }, + "exec-sh": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", + "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", + "dev": true, + "requires": { + "merge": "1.2.0" + } + }, "exit-hook": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", @@ -3925,6 +4107,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "dev": true, + "requires": { + "bser": "2.0.0" + } + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -3962,6 +4153,16 @@ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", "dev": true }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "7.1.1", + "minimatch": "3.0.4" + } + }, "fill-range": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", @@ -4061,15 +4262,6 @@ "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" }, - "for-each": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", - "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", - "dev": true, - "requires": { - "is-function": "1.0.1" - } - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -5845,6 +6037,29 @@ } } }, + "handlebars": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", + "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.28" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, "har-schema": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", @@ -5990,6 +6205,15 @@ "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", "dev": true }, + "html-encoding-sniffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", + "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", + "dev": true, + "requires": { + "whatwg-encoding": "1.0.1" + } + }, "htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", @@ -6301,6 +6525,15 @@ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", "dev": true }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "1.1.1" + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", @@ -6352,12 +6585,6 @@ "number-is-nan": "1.0.1" } }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", - "dev": true - }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", @@ -6594,6 +6821,490 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "istanbul-api": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.14.tgz", + "integrity": "sha1-JbxXAffGgMD//5E95G42GaOm5oA=", + "dev": true, + "requires": { + "async": "2.5.0", + "fileset": "2.0.3", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-hook": "1.0.7", + "istanbul-lib-instrument": "1.8.0", + "istanbul-lib-report": "1.1.1", + "istanbul-lib-source-maps": "1.2.1", + "istanbul-reports": "1.1.2", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "once": "1.4.0" + }, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + } + } + }, + "istanbul-lib-coverage": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", + "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", + "dev": true, + "requires": { + "append-transform": "0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz", + "integrity": "sha1-ZvbJQhzJ7EcE928tsIS6kHiitTI=", + "dev": true, + "requires": { + "babel-generator": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.18.0", + "istanbul-lib-coverage": "1.1.1", + "semver": "5.4.1" + }, + "dependencies": { + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", + "integrity": "sha512-tvF+YmCmH4thnez6JFX06ujIA19WPa9YUiwjc1uALF2cv5dmE3It8b5I8Ob7FHJ70H9Y5yF+TDkVa/mcADuw1Q==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz", + "integrity": "sha512-mukVvSXCn9JQvdJl8wP/iPhqig0MRtuWuD4ZNKo6vB2Ik//AmhAKe3QnPN02dmkRe3lTudFk3rzoHhwU4hb94w==", + "dev": true, + "requires": { + "debug": "2.6.4", + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "rimraf": "2.6.1", + "source-map": "0.5.6" + } + }, + "istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha1-D7Lj9qqZIr085F0F2KtNXo4HvU8=", + "dev": true, + "requires": { + "handlebars": "4.0.10" + } + }, + "jest": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-20.0.4.tgz", + "integrity": "sha1-PdJgwpidba1nix6cxNkZRPbWAqw=", + "dev": true, + "requires": { + "jest-cli": "20.0.4" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "jest-cli": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-20.0.4.tgz", + "integrity": "sha1-5TKxnYiuW8bEF+iwWTpv6VSx3JM=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "callsites": "2.0.0", + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "is-ci": "1.0.10", + "istanbul-api": "1.1.14", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-instrument": "1.8.0", + "istanbul-lib-source-maps": "1.2.1", + "jest-changed-files": "20.0.3", + "jest-config": "20.0.4", + "jest-docblock": "20.0.3", + "jest-environment-jsdom": "20.0.3", + "jest-haste-map": "20.0.5", + "jest-jasmine2": "20.0.4", + "jest-message-util": "20.0.3", + "jest-regex-util": "20.0.3", + "jest-resolve-dependencies": "20.0.3", + "jest-runtime": "20.0.4", + "jest-snapshot": "20.0.3", + "jest-util": "20.0.3", + "micromatch": "2.3.11", + "node-notifier": "5.1.2", + "pify": "2.3.0", + "slash": "1.0.0", + "string-length": "1.0.1", + "throat": "3.2.0", + "which": "1.2.14", + "worker-farm": "1.5.0", + "yargs": "7.1.0" + } + }, + "node-notifier": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", + "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", + "dev": true, + "requires": { + "growly": "1.3.0", + "semver": "5.4.1", + "shellwords": "0.1.0", + "which": "1.2.14" + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "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" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + } + } + } + }, + "jest-changed-files": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-20.0.3.tgz", + "integrity": "sha1-k5TVzGXEOEBhSb7xv01Sto4D4/g=", + "dev": true + }, + "jest-config": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-20.0.4.tgz", + "integrity": "sha1-43kwqyIXyRNgXv8T5712PsSPruo=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "glob": "7.1.1", + "jest-environment-jsdom": "20.0.3", + "jest-environment-node": "20.0.3", + "jest-jasmine2": "20.0.4", + "jest-matcher-utils": "20.0.3", + "jest-regex-util": "20.0.3", + "jest-resolve": "20.0.4", + "jest-validate": "20.0.3", + "pretty-format": "20.0.3" + } + }, + "jest-diff": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-20.0.3.tgz", + "integrity": "sha1-gfKI/Z5nXw+yPHXxwrGURf5YZhc=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "diff": "3.3.1", + "jest-matcher-utils": "20.0.3", + "pretty-format": "20.0.3" + } + }, + "jest-docblock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-20.0.3.tgz", + "integrity": "sha1-F76phDQswz2DxQ++FUXqDvqkRxI=", + "dev": true + }, + "jest-environment-jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz", + "integrity": "sha1-BIqKwS7iJfcZBBdxODS7mZeH3pk=", + "dev": true, + "requires": { + "jest-mock": "20.0.3", + "jest-util": "20.0.3", + "jsdom": "9.12.0" + } + }, + "jest-environment-node": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-20.0.3.tgz", + "integrity": "sha1-1Ii8RhKvLCRumG6K52caCZFj1AM=", + "dev": true, + "requires": { + "jest-mock": "20.0.3", + "jest-util": "20.0.3" + } + }, + "jest-haste-map": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-20.0.5.tgz", + "integrity": "sha512-0IKAQjUvuZjMCNi/0VNQQF74/H9KB67hsHJqGiwTWQC6XO5Azs7kLWm+6Q/dwuhvDUvABDOBMFK2/FwZ3sZ07Q==", + "dev": true, + "requires": { + "fb-watchman": "2.0.0", + "graceful-fs": "4.1.11", + "jest-docblock": "20.0.3", + "micromatch": "2.3.11", + "sane": "1.6.0", + "worker-farm": "1.5.0" + } + }, + "jest-jasmine2": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz", + "integrity": "sha1-/MWxQReA2RHQQpAu8YWehS5g1eE=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-matchers": "20.0.3", + "jest-message-util": "20.0.3", + "jest-snapshot": "20.0.3", + "once": "1.4.0", + "p-map": "1.1.1" + } + }, + "jest-matcher-utils": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz", + "integrity": "sha1-s6a443yld4A7CDKpixZPRLeBVhI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "pretty-format": "20.0.3" + } + }, + "jest-matchers": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-20.0.3.tgz", + "integrity": "sha1-ymnbHDLbWm9wf6XgQBq7VXAN/WA=", + "dev": true, + "requires": { + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-message-util": "20.0.3", + "jest-regex-util": "20.0.3" + } + }, + "jest-message-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-20.0.3.tgz", + "integrity": "sha1-auwoRDBvyw5udNV5bBAG2W/dgxw=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "micromatch": "2.3.11", + "slash": "1.0.0" + } + }, + "jest-mock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-20.0.3.tgz", + "integrity": "sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk=", + "dev": true + }, + "jest-regex-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-20.0.3.tgz", + "integrity": "sha1-hburXRM+RGJbGfr4xqpRItCF12I=", + "dev": true + }, + "jest-resolve": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-20.0.4.tgz", + "integrity": "sha1-lEiz6La6/BVHlETGSZBFt//ll6U=", + "dev": true, + "requires": { + "browser-resolve": "1.11.2", + "is-builtin-module": "1.0.0", + "resolve": "1.3.3" + } + }, + "jest-resolve-dependencies": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz", + "integrity": "sha1-bhSntxevDyyzZnxUneQK8Bexcjo=", + "dev": true, + "requires": { + "jest-regex-util": "20.0.3" + } + }, + "jest-runtime": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-20.0.4.tgz", + "integrity": "sha1-osgCIZxCA/dU3xQE5JAYYWnRJNg=", + "dev": true, + "requires": { + "babel-core": "6.13.2", + "babel-jest": "20.0.3", + "babel-plugin-istanbul": "4.1.4", + "chalk": "1.1.3", + "convert-source-map": "1.5.0", + "graceful-fs": "4.1.11", + "jest-config": "20.0.4", + "jest-haste-map": "20.0.5", + "jest-regex-util": "20.0.3", + "jest-resolve": "20.0.4", + "jest-util": "20.0.3", + "json-stable-stringify": "1.0.1", + "micromatch": "2.3.11", + "strip-bom": "3.0.0", + "yargs": "7.1.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "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" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + } + } + } + }, + "jest-snapshot": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-20.0.3.tgz", + "integrity": "sha1-W4R+GtsaTZCFKn+fElCG4YfHZWY=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-util": "20.0.3", + "natural-compare": "1.4.0", + "pretty-format": "20.0.3" + } + }, + "jest-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-20.0.3.tgz", + "integrity": "sha1-DAf32A2C9OWmfG+LnD/n9lz9Mq0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "jest-message-util": "20.0.3", + "jest-mock": "20.0.3", + "jest-validate": "20.0.3", + "leven": "2.1.0", + "mkdirp": "0.5.1" + } + }, + "jest-validate": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-20.0.3.tgz", + "integrity": "sha1-0M/R3k9XnymEhJJcKA+PHZTsPKs=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "jest-matcher-utils": "20.0.3", + "leven": "2.1.0", + "pretty-format": "20.0.3" + } + }, "js-base64": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", @@ -6623,6 +7334,41 @@ "dev": true, "optional": true }, + "jsdom": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", + "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", + "dev": true, + "requires": { + "abab": "1.0.3", + "acorn": "4.0.13", + "acorn-globals": "3.1.0", + "array-equal": "1.0.0", + "content-type-parser": "1.0.1", + "cssom": "0.3.2", + "cssstyle": "0.2.37", + "escodegen": "1.9.0", + "html-encoding-sniffer": "1.0.1", + "nwmatcher": "1.4.1", + "parse5": "1.5.1", + "request": "2.81.0", + "sax": "1.2.2", + "symbol-tree": "3.2.2", + "tough-cookie": "2.3.2", + "webidl-conversions": "4.0.2", + "whatwg-encoding": "1.0.1", + "whatwg-url": "4.8.0", + "xml-name-validator": "2.0.1" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", @@ -6988,6 +7734,12 @@ "invert-kv": "1.0.0" } }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -7154,6 +7906,24 @@ } } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", @@ -7421,6 +8191,15 @@ "vlq": "0.2.2" } }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.4" + } + }, "map-async": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/map-async/-/map-async-0.1.1.tgz", @@ -7555,6 +8334,12 @@ } } }, + "merge": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", + "dev": true + }, "merge-descriptors": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", @@ -8146,6 +8931,12 @@ } } }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, "node-notifier": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-4.6.0.tgz", @@ -8421,6 +9212,12 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "nwmatcher": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.1.tgz", + "integrity": "sha1-eumwew6oBNt+JfBctf5Al9TklJ8=", + "dev": true + }, "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", @@ -8438,12 +9235,6 @@ "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" }, - "object-inspect": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.2.2.tgz", - "integrity": "sha1-yCEV5PzIiK6hTWTCLk8X9qcNXlo=", - "dev": true - }, "object-keys": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", @@ -8692,6 +9483,27 @@ "object-assign": "4.1.1" } }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "p-map": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", + "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=", + "dev": true + }, "package-json": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.2.1.tgz", @@ -8758,6 +9570,12 @@ "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", "dev": true }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "dev": true + }, "parsejson": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", @@ -9287,6 +10105,27 @@ "resolved": "https://registry.npmjs.org/prettier-bytes/-/prettier-bytes-1.0.4.tgz", "integrity": "sha1-mUsCqkb2mcULYle1+qp/4lV+YtY=" }, + "pretty-format": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-20.0.3.tgz", + "integrity": "sha1-Ag41ClYKH+GpjcO+tsz/s4beixQ=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1", + "ansi-styles": "3.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + } + } + }, "pretty-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", @@ -9331,6 +10170,12 @@ "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=", "dev": true }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, "ps-tree": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", @@ -10047,15 +10892,6 @@ "onetime": "1.1.0" } }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "requires": { - "through": "2.3.8" - } - }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -10127,6 +10963,47 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" }, + "sane": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-1.6.0.tgz", + "integrity": "sha1-lhDEUjB6E10pwf3+JUcDQYDEZ3U=", + "dev": true, + "requires": { + "anymatch": "1.3.0", + "exec-sh": "0.2.1", + "fb-watchman": "1.9.2", + "minimatch": "3.0.4", + "minimist": "1.2.0", + "walker": "1.0.7", + "watch": "0.10.0" + }, + "dependencies": { + "bser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", + "integrity": "sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk=", + "dev": true, + "requires": { + "node-int64": "0.4.0" + } + }, + "fb-watchman": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", + "integrity": "sha1-okz0eCf4LTj7Waaa1wt247auc4M=", + "dev": true, + "requires": { + "bser": "1.0.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "sass": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/sass/-/sass-0.5.0.tgz", @@ -11021,17 +11898,6 @@ "function-bind": "1.1.0" } }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.7.0", - "function-bind": "1.1.0" - } - }, "string_decoder": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", @@ -11120,6 +11986,12 @@ "whet.extend": "0.9.9" } }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, "syntax-error": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", @@ -11216,41 +12088,6 @@ } } }, - "tape": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.6.3.tgz", - "integrity": "sha1-Y353WB6ass4XV36b1M5PV1gG2LY=", - "dev": true, - "requires": { - "deep-equal": "1.0.1", - "defined": "1.0.0", - "for-each": "0.3.2", - "function-bind": "1.1.0", - "glob": "7.1.1", - "has": "1.0.1", - "inherits": "2.0.3", - "minimist": "1.2.0", - "object-inspect": "1.2.2", - "resolve": "1.1.7", - "resumer": "0.0.0", - "string.prototype.trim": "1.1.2", - "through": "2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } - } - }, "tar": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", @@ -11262,6 +12099,19 @@ "inherits": "2.0.3" } }, + "test-exclude": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", + "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -11278,6 +12128,12 @@ "object-path": "0.9.2" } }, + "throat": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", + "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -11349,6 +12205,12 @@ "os-tmpdir": "1.0.2" } }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", @@ -11401,6 +12263,12 @@ "punycode": "1.4.1" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, "transform-filter": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/transform-filter/-/transform-filter-0.1.1.tgz", @@ -11815,6 +12683,21 @@ "indexof": "0.0.1" } }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.11" + } + }, + "watch": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", + "integrity": "sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw=", + "dev": true + }, "watchify": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.7.0.tgz", @@ -11922,6 +12805,12 @@ "integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes=", "dev": true }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, "weinre": { "version": "2.0.0-pre-I0Z7U9OV", "resolved": "https://registry.npmjs.org/weinre/-/weinre-2.0.0-pre-I0Z7U9OV.tgz", @@ -11933,11 +12822,46 @@ "underscore": "1.7.0" } }, + "whatwg-encoding": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", + "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", + "dev": true, + "requires": { + "iconv-lite": "0.4.13" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + } + } + }, "whatwg-fetch": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" }, + "whatwg-url": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", + "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "dev": true, + "requires": { + "tr46": "0.0.3", + "webidl-conversions": "3.0.1" + }, + "dependencies": { + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + } + } + }, "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", @@ -11991,6 +12915,16 @@ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, + "worker-farm": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.0.tgz", + "integrity": "sha512-DHRiUggxtbruaTwnLDm2/BRDKZIoOYvrgYUj5Bam4fU6Gtvc0FaEyoswFPBjMXAweGW2H4BDNIpy//1yXXuaqQ==", + "dev": true, + "requires": { + "errno": "0.1.4", + "xtend": "4.0.1" + } + }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -12057,6 +12991,12 @@ "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=", "dev": true }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", + "dev": true + }, "xml2js": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", From 76e1d0e60077f2bb56200fcca0e8289c4c019c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Mon, 11 Sep 2017 11:01:58 +0200 Subject: [PATCH 08/32] website: Use minified bundle for `disc` --- bin/build-bundle | 20 -------------------- bin/build-bundle-locales | 21 --------------------- bin/disc.js | 31 +++++++++++++++++++++++++++++++ package.json | 3 +-- 4 files changed, 32 insertions(+), 43 deletions(-) delete mode 100755 bin/build-bundle delete mode 100755 bin/build-bundle-locales create mode 100644 bin/disc.js diff --git a/bin/build-bundle b/bin/build-bundle deleted file mode 100755 index 750e17ac1..000000000 --- a/bin/build-bundle +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -o pipefail -set -o errexit -set -o nounset -# set -o xtrace - -# Set magic variables for current file & dir -__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -__file="${__dir}/$(basename "${BASH_SOURCE[0]}")" -__base="$(basename ${__file} .sh)" - -SRC="src/index.js" -OUT="${OUT:-uppy.js}" -OUTDIR="dist" - -FLAGS="-t [ babelify ] --standalone Uppy" - -mkdir -p "${OUTDIR}" - -browserify ${@:-} $SRC $FLAGS > $OUTDIR/$OUT diff --git a/bin/build-bundle-locales b/bin/build-bundle-locales deleted file mode 100755 index 6722c37c3..000000000 --- a/bin/build-bundle-locales +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -set -o pipefail -set -o errexit -set -o nounset -# set -o xtrace - -# Set magic variables for current file & dir -__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -__file="${__dir}/$(basename "${BASH_SOURCE[0]}")" -__base="$(basename ${__file} .sh)" - -OUTDIR="dist/locales" - -FLAGS="-t [ babelify ]" - -mkdir -p "${OUTDIR}" - -for file in ./src/locales/*.js; do - # echo "$file"; - node_modules/.bin/browserify $file $FLAGS > $OUTDIR/${file##*/}; -done diff --git a/bin/disc.js b/bin/disc.js new file mode 100644 index 000000000..bcea64ed2 --- /dev/null +++ b/bin/disc.js @@ -0,0 +1,31 @@ +const fs = require('fs') +const path = require('path') +const { PassThrough } = require('stream') +const browserify = require('browserify') +const babelify = require('babelify') +const minifyify = require('minifyify') +const disc = require('disc') + +const outputPath = path.join(__dirname, '../website/src/disc.html') + +const bundler = browserify(path.join(__dirname, '../src/index.js'), { + fullPaths: true, + standalone: 'Uppy' +}) + +bundler.plugin(minifyify, { map: false }) +bundler.transform(babelify) + +bundler.bundle() + .pipe(disc()) + .pipe(prepend('---\nlayout: false\n---\n')) + .pipe(fs.createWriteStream(outputPath)) + .on('error', (err) => { + throw err + }) + +function prepend (text) { + const stream = new PassThrough() + stream.write(text) + return stream +} diff --git a/package.json b/package.json index 267cb516d..cb4cad804 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,6 @@ "build:css": "node ./bin/build-css.js", "build:gzip": "node ./bin/gzip.js", "size": "echo 'JS Bundle mingz:' && cat ./dist/uppy.min.js | gzip | wc -c && echo 'CSS Bundle mingz:' && cat ./dist/uppy.min.css | gzip | wc -c", - "build:bundle:fullpath": "env OUT=uppy-fp.js ./bin/build-bundle --full-paths", "build:js": "npm-run-all build:bundle build:lib", "build:lib": "babel --version && babel src --source-maps -d lib", "build": "npm-run-all --parallel build:js build:css --serial build:gzip size", @@ -133,7 +132,7 @@ "web:clean": "cd website && ./node_modules/.bin/hexo clean", "web:deploy": "npm-run-all web:install web:disc web:build && ./bin/web-deploy", "web:generated-docs": "cd website && node node_modules/documentation/bin/documentation.js readme ../src/index.js --readme-file=src/docs/api.md --section 'Uppy Core & Plugins' -q --github -c doc-order.json", - "web:disc": "npm run build:bundle:fullpath && discify dist/uppy-fp.js --output website/src/_disc.html && echo '---\nlayout: false\n---\n' |cat - website/src/_disc.html > website/src/disc.html && rm website/src/_disc.html", + "web:disc": "node ./bin/disc.js", "web:install": "cd website && npm install", "web:bundle:update:watch": "onchange 'dist/**/*.css' 'dist/**/*.js' --initial --verbose -- node website/update.js", "web:examples:watch": "cd website && node build-examples.js watch", From 31d2e2379119ce5206d7178aa77fab562231edb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Fri, 1 Sep 2017 13:17:58 +0200 Subject: [PATCH 09/32] core: Implement `id` option, ref #256 --- src/core/Core.js | 1 + src/plugins/RestoreFiles/ServiceWorker.js | 33 ++++++++++++------- .../RestoreFiles/ServiceWorkerStore.js | 11 +++++-- src/plugins/RestoreFiles/index.js | 12 ++++--- website/src/docs/uppy.md | 17 +++++++++- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/core/Core.js b/src/core/Core.js index 68ad030d6..13e900eff 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -34,6 +34,7 @@ class Uppy { // set default options const defaultOptions = { + id: 'uppy', autoProceed: true, debug: false, restrictions: { diff --git a/src/plugins/RestoreFiles/ServiceWorker.js b/src/plugins/RestoreFiles/ServiceWorker.js index fb133df15..16e29eadb 100644 --- a/src/plugins/RestoreFiles/ServiceWorker.js +++ b/src/plugins/RestoreFiles/ServiceWorker.js @@ -1,12 +1,19 @@ /* globals clients */ -const fileCache = {} +const fileCache = Object.create(null) + +function getCache (name) { + if (!fileCache[name]) { + fileCache[name] = Object.create(null) + } + return fileCache[name] +} self.addEventListener('install', (event) => { console.log('Installing Uppy Service Worker...') event.waitUntil(Promise.resolve() - .then(() => self.skipWaiting())) + .then(() => self.skipWaiting())) }) self.addEventListener('activate', (event) => { @@ -21,30 +28,34 @@ function sendMessageToAllClients (msg) { }) } -function addFile (file) { - fileCache[file.id] = file +function addFile (store, file) { + getCache(store)[file.id] = file console.log('Added file to service worker cache:', file) } -function removeFile (fileID) { - delete fileCache[fileID] +function removeFile (store, fileID) { + delete getCache(store)[fileID] console.log('Removed file from service worker cache:', fileID) } -function getFiles () { - sendMessageToAllClients({ type: 'ALL_FILES', files: fileCache }) +function getFiles (store) { + sendMessageToAllClients({ + type: 'ALL_FILES', + store, + files: getCache(store) + }) } self.addEventListener('message', (event) => { switch (event.data.type) { case 'ADD_FILE': - addFile(event.data.data) + addFile(event.data.store, event.data.data) break case 'REMOVE_FILE': - removeFile(event.data.data) + removeFile(event.data.store, event.data.data) break case 'GET_FILES': - getFiles() + getFiles(event.data.store) break } }) diff --git a/src/plugins/RestoreFiles/ServiceWorkerStore.js b/src/plugins/RestoreFiles/ServiceWorkerStore.js index b353d7966..47c1113c0 100644 --- a/src/plugins/RestoreFiles/ServiceWorkerStore.js +++ b/src/plugins/RestoreFiles/ServiceWorkerStore.js @@ -1,7 +1,7 @@ const isSupported = 'serviceWorker' in navigator class ServiceWorkerStore { - constructor (core) { + constructor (core, opts) { this.core = core this.ready = new Promise((resolve, reject) => { // service worker stuff @@ -9,6 +9,7 @@ class ServiceWorkerStore { resolve() }) }) + this.name = opts.storeName } list () { @@ -20,6 +21,9 @@ class ServiceWorkerStore { console.log('Loading stored blobs from Service Worker') const onMessage = (event) => { + if (event.data.store !== this.name) { + return + } switch (event.data.type) { case 'ALL_FILES': defer.resolve(event.data.files) @@ -32,7 +36,8 @@ class ServiceWorkerStore { navigator.serviceWorker.addEventListener('message', onMessage) navigator.serviceWorker.controller.postMessage({ - type: 'GET_FILES' + type: 'GET_FILES', + data: { store: this.name } }) }) @@ -44,6 +49,7 @@ class ServiceWorkerStore { navigator.serviceWorker.controller.postMessage({ type: 'ADD_FILE', data: { + store: this.name, id: file.id, data: file.data } @@ -55,6 +61,7 @@ class ServiceWorkerStore { return this.ready.then(() => { navigator.serviceWorker.controller.postMessage({ type: 'REMOVE_FILE', + store: this.name, data: fileID }) }) diff --git a/src/plugins/RestoreFiles/index.js b/src/plugins/RestoreFiles/index.js index 0a5e70b85..29042de07 100644 --- a/src/plugins/RestoreFiles/index.js +++ b/src/plugins/RestoreFiles/index.js @@ -25,9 +25,11 @@ module.exports = class RestoreFiles extends Plugin { // merge default options with the ones set by user this.opts = Object.assign({}, defaultOptions, opts) - // const Store = this.opts.serviceWorker ? ServiceWorkerStore : IndexedDBStore - this.ServiceWorkerStore = this.opts.serviceWorker ? new ServiceWorkerStore(core) : false - this.IndexedDBStore = new IndexedDBStore(core) + this.ServiceWorkerStore = null + if (this.opts.serviceWorker) { + this.ServiceWorkerStore = new ServiceWorkerStore(core, { storeName: core.opts.id }) + } + this.IndexedDBStore = new IndexedDBStore(core, { storeName: core.opts.id }) this.saveFilesStateToLocalStorage = this.saveFilesStateToLocalStorage.bind(this) this.loadFilesStateFromLocalStorage = this.loadFilesStateFromLocalStorage.bind(this) @@ -37,7 +39,7 @@ module.exports = class RestoreFiles extends Plugin { } loadFilesStateFromLocalStorage () { - const savedState = localStorage.getItem('uppyState') + const savedState = localStorage.getItem(`uppyState:${this.core.opts.id}`) if (savedState) { this.core.log('Recovered some state from Local Storage') @@ -50,7 +52,7 @@ module.exports = class RestoreFiles extends Plugin { currentUploads: this.core.state.currentUploads, files: this.core.state.files }) - localStorage.setItem('uppyState', files) + localStorage.setItem(`uppyState:${this.core.opts.id}`, files) } loadFileBlobsFromServiceWorker () { diff --git a/website/src/docs/uppy.md b/website/src/docs/uppy.md index eb820b7bf..d360b88ce 100644 --- a/website/src/docs/uppy.md +++ b/website/src/docs/uppy.md @@ -11,6 +11,7 @@ Core module that orchistrated everything in Uppy, exposing `state`, `events` and ```js const uppy = Uppy({ + id: 'uppy', autoProceed: true, restrictions: { maxFileSize: false, @@ -25,6 +26,20 @@ const uppy = Uppy({ }) ``` +### `id: 'uppy'` + +A site-wide unique ID for the instance. +If multiple Uppy instances are being used, for example on two different pages, an `id` should be specified. +This allows Uppy to store information in `localStorage` without colliding with other Uppy instances. + +Note that this ID should be persistent across page reloads and navigation--it shouldn't be a random number that's different every time Uppy is loaded. +For example, if one Uppy instance is used to upload user avatars, and another to add photos to a blog post, you might use: + +```js +const avatarUploader = Uppy({ id: 'avatar' }) +const photoUploader = Uppy({ id: 'post' }) +``` + ### `autoProceed: true` Starts upload automatically after the first file is selected. @@ -222,7 +237,7 @@ uppy.updateMeta('myfileID', {resize: 1500}) ### `uppy.reset()` -Stop all uploads in progress and clear file selection, set progress to 0. Basically, return things to the way they were before any user input. +Stop all uploads in progress and clear file selection, set progress to 0. Basically, return things to the way they were before any user input. ### `uppy.close()` From e65348a8fc56e4b2d1a55a9077bbbbe5cde760e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Fri, 1 Sep 2017 13:19:08 +0200 Subject: [PATCH 10/32] restore: Namespace serviceWorker action types --- src/plugins/RestoreFiles/ServiceWorker.js | 8 ++++---- src/plugins/RestoreFiles/ServiceWorkerStore.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/RestoreFiles/ServiceWorker.js b/src/plugins/RestoreFiles/ServiceWorker.js index 16e29eadb..adf11b236 100644 --- a/src/plugins/RestoreFiles/ServiceWorker.js +++ b/src/plugins/RestoreFiles/ServiceWorker.js @@ -40,7 +40,7 @@ function removeFile (store, fileID) { function getFiles (store) { sendMessageToAllClients({ - type: 'ALL_FILES', + type: 'uppy/ALL_FILES', store, files: getCache(store) }) @@ -48,13 +48,13 @@ function getFiles (store) { self.addEventListener('message', (event) => { switch (event.data.type) { - case 'ADD_FILE': + case 'uppy/ADD_FILE': addFile(event.data.store, event.data.data) break - case 'REMOVE_FILE': + case 'uppy/REMOVE_FILE': removeFile(event.data.store, event.data.data) break - case 'GET_FILES': + case 'uppy/GET_FILES': getFiles(event.data.store) break } diff --git a/src/plugins/RestoreFiles/ServiceWorkerStore.js b/src/plugins/RestoreFiles/ServiceWorkerStore.js index 47c1113c0..79f13b9ce 100644 --- a/src/plugins/RestoreFiles/ServiceWorkerStore.js +++ b/src/plugins/RestoreFiles/ServiceWorkerStore.js @@ -25,7 +25,7 @@ class ServiceWorkerStore { return } switch (event.data.type) { - case 'ALL_FILES': + case 'uppy/ALL_FILES': defer.resolve(event.data.files) navigator.serviceWorker.removeEventListener('message', onMessage) break @@ -36,7 +36,7 @@ class ServiceWorkerStore { navigator.serviceWorker.addEventListener('message', onMessage) navigator.serviceWorker.controller.postMessage({ - type: 'GET_FILES', + type: 'uppy/GET_FILES', data: { store: this.name } }) }) @@ -47,7 +47,7 @@ class ServiceWorkerStore { put (file) { return this.ready.then(() => { navigator.serviceWorker.controller.postMessage({ - type: 'ADD_FILE', + type: 'uppy/ADD_FILE', data: { store: this.name, id: file.id, @@ -60,7 +60,7 @@ class ServiceWorkerStore { delete (fileID) { return this.ready.then(() => { navigator.serviceWorker.controller.postMessage({ - type: 'REMOVE_FILE', + type: 'uppy/REMOVE_FILE', store: this.name, data: fileID }) From 03cb1b47d8c743c603e704a5a333e74cbe36a11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Mon, 11 Sep 2017 12:13:55 +0200 Subject: [PATCH 11/32] changelog: tick off Uppy instance IDs --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a768b0cce..b32c987cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,7 +86,7 @@ What we need to do to release Uppy 1.0 - [ ] core: research !important styles to be immune to any environment/page. Maybe use smth like `postcss-safe-important`. Or increase specificity (with .Uppy) (@arturi) - [ ] test: add https://github.com/pa11y/pa11y for automated accessibility testing (@arturi) - [ ] test: add tests for `npm install uppy` and running in different browsers, the real world use case (@arturi) -- [ ] core: Uppy ID per instance +- [x] core: Uppy ID per instance (@goto-bus-stop) - [ ] core: allow setting custom `id` for plugins: https://github.com/transloadit/uppy/pull/328#issuecomment-328242214 (@arturi) - [ ] core: move `setPluginState` to Plugin class ? (@goto-bus-stop) - [ ] add `FormEncapsulator`: a plugin that is used in conjunction with any other acquirer, responsible for injecting any result (like from Transloadit plugin) back into the form (jquery-sdk includes the whole Assembly Status JSON in a hidden field i think) From 61c055df080215f4bb462e19e8501f30ed8216a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Mon, 11 Sep 2017 12:15:29 +0200 Subject: [PATCH 12/32] =?UTF-8?q?docs:=20--=20=E2=86=92=20em=20dash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/src/docs/uppy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/docs/uppy.md b/website/src/docs/uppy.md index d360b88ce..38fbf176c 100644 --- a/website/src/docs/uppy.md +++ b/website/src/docs/uppy.md @@ -32,7 +32,7 @@ A site-wide unique ID for the instance. If multiple Uppy instances are being used, for example on two different pages, an `id` should be specified. This allows Uppy to store information in `localStorage` without colliding with other Uppy instances. -Note that this ID should be persistent across page reloads and navigation--it shouldn't be a random number that's different every time Uppy is loaded. +Note that this ID should be persistent across page reloads and navigation—it shouldn't be a random number that's different every time Uppy is loaded. For example, if one Uppy instance is used to upload user avatars, and another to add photos to a blog post, you might use: ```js From 51fb7f5c49aa53d2b848f0c1c64dd9d48db35826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Mon, 11 Sep 2017 14:20:52 +0200 Subject: [PATCH 13/32] deps: Update tus-js-client `tus-js-client` v1.4.4 and up will resume an upload when you reuse the `tus.Upload` instance, where previously it wouldn't. --- package-lock.json | 147 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 141 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ae26db2d..23a42625f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2041,6 +2041,14 @@ "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", "dev": true }, + "buffer-from": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.1.tgz", + "integrity": "sha1-V7GLHaChnsBvM4N6UnWiQjUb114=", + "requires": { + "is-array-buffer-x": "1.4.0" + } + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -6130,6 +6138,19 @@ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, + "has-symbol-support-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz", + "integrity": "sha512-JkaetveU7hFbqnAC1EV1sF4rlojU2D4Usc5CmS69l6NfmPDnpnFUegzFg33eDkkpNCxZ0mQp65HwUDrNFS/8MA==" + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "requires": { + "has-symbol-support-x": "1.4.1" + } + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -6483,6 +6504,16 @@ "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", "dev": true }, + "is-array-buffer-x": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/is-array-buffer-x/-/is-array-buffer-x-1.4.0.tgz", + "integrity": "sha512-0GQe5QPJBh9Lmt+PFP9O2BQvwQ1cMPohgL9vRuNIjb5cYi9HeeJESCJeG8lHziniVR+3VolF8YRz6LlfgNpb0A==", + "requires": { + "has-to-string-tag-x": "1.4.1", + "is-object-like-x": "1.5.1", + "to-string-tag-x": "1.4.1" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -6585,6 +6616,18 @@ "number-is-nan": "1.0.1" } }, + "is-function-x": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-function-x/-/is-function-x-3.1.1.tgz", + "integrity": "sha512-klx9TzyFpj8D1aNMSHi6y0+inn2gOmtPQQkVkxTVv5Oa8YNWFJJ5QpIe09p79zHxeJ5FzyA7Ms2vQH2PLXt4OQ==", + "requires": { + "has-to-string-tag-x": "1.4.1", + "is-primitive": "2.0.0", + "normalize-space-x": "1.3.3", + "replace-comments-x": "1.0.3", + "to-string-tag-x": "1.4.1" + } + }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", @@ -6631,6 +6674,15 @@ "lodash.isfinite": "3.3.2" } }, + "is-object-like-x": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/is-object-like-x/-/is-object-like-x-1.5.1.tgz", + "integrity": "sha512-AtUeYE4Xs8EbuHuG6yBHiLdIlWRPPFidcIs3JE6PJZ/mzUQFOK8X5J1OA+3cVi0rlrdUCjiX52obtCV2hxs+HA==", + "requires": { + "is-function-x": "3.1.1", + "is-primitive": "2.0.0" + } + }, "is-online": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-online/-/is-online-5.0.0.tgz", @@ -6691,8 +6743,7 @@ "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, "is-property": { "version": "1.0.2", @@ -6750,6 +6801,11 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.4.tgz", + "integrity": "sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=" + }, "is-svg": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", @@ -6762,8 +6818,7 @@ "is-symbol": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" }, "is-typedarray": { "version": "1.0.0", @@ -8059,6 +8114,11 @@ "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", "dev": true }, + "lodash.isnull": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnull/-/lodash.isnull-3.0.0.tgz", + "integrity": "sha1-+vvlnqHcon7teGU0A53YTC4HxW4=" + }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -9088,6 +9148,15 @@ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, + "normalize-space-x": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/normalize-space-x/-/normalize-space-x-1.3.3.tgz", + "integrity": "sha512-9q953GogZSw2Ba1Pj3rI9T3xIPq5PtQBXEX2T/nKCaRuj8scAicXCsYMBKfKDtohTWaKGrZmBF9h53GJzfZ8TQ==", + "requires": { + "trim-x": "1.0.3", + "white-space-x": "2.0.3" + } + }, "normalize-url": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", @@ -10795,6 +10864,14 @@ "is-finite": "1.0.2" } }, + "replace-comments-x": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/replace-comments-x/-/replace-comments-x-1.0.3.tgz", + "integrity": "sha512-9i7cX4w+QmkEAelyYVofBP+lLgJZkZ40imH9txxOQVX5F12vDccF+paHIQpDB2LNZY4gjkGbljintKCjUcflow==", + "requires": { + "is-string": "1.0.4" + } + }, "request": { "version": "2.81.0", "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", @@ -12228,6 +12305,23 @@ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, + "to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/to-string-tag-x/-/to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-hPekHIGkkJowH45vGmYHLYe335PUnY0XAHa1tomdRpNVZT8wDsbWAbykRvJ81YKjyeBVN4smoNMLtJOWrQj7ZA==", + "requires": { + "lodash.isnull": "3.0.0", + "validate.io-undefined": "1.0.3" + } + }, + "to-string-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/to-string-x/-/to-string-x-1.4.1.tgz", + "integrity": "sha512-63i4+t2/xWQCTYTTSFvQJcQzlXAL+0xLSJhOARh6XyDfv2AI5oKcQIVUQ9HwrbeHVLZ1fH+vWnoVLQpQIH/HaQ==", + "requires": { + "is-symbol": "1.0.1" + } + }, "to-utf8": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz", @@ -12291,6 +12385,15 @@ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", "dev": true }, + "trim-left-x": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/trim-left-x/-/trim-left-x-1.3.5.tgz", + "integrity": "sha512-aAp+6wECRhtaGWp44PKbxilvjY+kFPJ2RRweEtleLAZ9hYtM7DL1ShEPl/KF6lu6lAYb8xISF/h9egGjiJpZFQ==", + "requires": { + "to-string-x": "1.4.1", + "white-space-x": "2.0.3" + } + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -12303,6 +12406,24 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "trim-right-x": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/trim-right-x/-/trim-right-x-1.3.3.tgz", + "integrity": "sha512-a0Moq+2fFdRXcVjqtDgxtDYx3bRTvsLMmwiK9vEVWuc8Y557oZjA3A6eJ0UcyNEa8DE57KMFSRGPUzrLLDJukg==", + "requires": { + "to-string-x": "1.4.1", + "white-space-x": "2.0.3" + } + }, + "trim-x": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/trim-x/-/trim-x-1.0.3.tgz", + "integrity": "sha512-+fXcHQ+pV3uL/wmuFZGL2uWh4hO7maqPf/534GyV4HAtVe/JE0IX4dFWNgYwGwqMvWztBSW6jrqQSslLggQbOg==", + "requires": { + "trim-left-x": "1.3.5", + "trim-right-x": "1.3.3" + } + }, "tryit": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", @@ -12325,11 +12446,13 @@ } }, "tus-js-client": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-1.4.3.tgz", - "integrity": "sha1-5DN16aGkK2+o2pbPWas4vqQLwdk=", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-1.4.4.tgz", + "integrity": "sha1-l5Ry9K4oq81o790iRfzuuMW2Hmc=", "requires": { + "buffer-from": "0.1.1", "extend": "3.0.1", + "lodash.throttle": "4.1.1", "resolve-url": "0.2.1" } }, @@ -12641,6 +12764,11 @@ "spdx-expression-parse": "1.0.4" } }, + "validate.io-undefined": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/validate.io-undefined/-/validate.io-undefined-1.0.3.tgz", + "integrity": "sha1-fif8uzFbhB54JDQxiXZxkp4gt/Q=" + }, "vary": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz", @@ -12883,6 +13011,11 @@ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, + "white-space-x": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/white-space-x/-/white-space-x-2.0.3.tgz", + "integrity": "sha512-An6uHDfZizY0t7x8iyY8nLej1lnqyaFSyTKjwwqS0VIhvV4tof6a+Et4uJVFlZh7HUAOgKoZfm5hFzl/D4xDgw==" + }, "wide-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", diff --git a/package.json b/package.json index 267cb516d..07446575f 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "prettier-bytes": "1.0.4", "promise-settle": "^0.3.0", "socket.io-client": "2.0.1", - "tus-js-client": "1.4.3", + "tus-js-client": "^1.4.4", "url-parse": "1.1.9", "whatwg-fetch": "2.0.3", "yo-yo": "1.4.0", From dc1ac4f314957d9ad26af6a27032f148d4f0c881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Mon, 11 Sep 2017 15:31:53 +0200 Subject: [PATCH 14/32] core: Add `getID()` method. --- src/core/Core.js | 4 ++++ src/core/Core.test.js | 8 ++++++++ src/plugins/RestoreFiles/index.js | 4 ++-- website/src/docs/uppy.md | 4 ++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/core/Core.js b/src/core/Core.js index 13e900eff..a08f9d8da 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -598,6 +598,10 @@ class Uppy { } } + getID () { + return this.opts.id + } + /** * Registers a plugin with Core * diff --git a/src/core/Core.test.js b/src/core/Core.test.js index a031ab283..57dc7d50a 100644 --- a/src/core/Core.test.js +++ b/src/core/Core.test.js @@ -42,6 +42,14 @@ describe('src/Core', () => { expect(core.constructor.name).toEqual('Uppy') }) + it('should have a string `id` option that defaults to "uppy"', () => { + const core = Core() + expect(core.getID()).toEqual('uppy') + + const core2 = Core({ id: 'profile' }) + expect(core2.getID()).toEqual('profile') + }) + describe('plugins', () => { it('should add a plugin to the plugin stack', () => { const core = Core() diff --git a/src/plugins/RestoreFiles/index.js b/src/plugins/RestoreFiles/index.js index 29042de07..534cca27f 100644 --- a/src/plugins/RestoreFiles/index.js +++ b/src/plugins/RestoreFiles/index.js @@ -27,9 +27,9 @@ module.exports = class RestoreFiles extends Plugin { this.ServiceWorkerStore = null if (this.opts.serviceWorker) { - this.ServiceWorkerStore = new ServiceWorkerStore(core, { storeName: core.opts.id }) + this.ServiceWorkerStore = new ServiceWorkerStore(core, { storeName: core.getID() }) } - this.IndexedDBStore = new IndexedDBStore(core, { storeName: core.opts.id }) + this.IndexedDBStore = new IndexedDBStore(core, { storeName: core.getID() }) this.saveFilesStateToLocalStorage = this.saveFilesStateToLocalStorage.bind(this) this.loadFilesStateFromLocalStorage = this.loadFilesStateFromLocalStorage.bind(this) diff --git a/website/src/docs/uppy.md b/website/src/docs/uppy.md index 38fbf176c..e8899c8a1 100644 --- a/website/src/docs/uppy.md +++ b/website/src/docs/uppy.md @@ -144,6 +144,10 @@ uppy.use(DragDrop, {target: 'body'}) Initializes everything after setup. Must be called before calling `.upload()` or using Uppy in any meaningful way. +### `uppy.getID()` + +Get the uppy instance ID, see the [`id` option](#id-39-uppy-39). + ### `uppy.addFile(fileObject)` Add a new file to Uppy’s internal state. From 981a331c10f7318abb1a329677bc25a0c3e14e82 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Sep 2017 09:45:43 -0400 Subject: [PATCH 15/32] =?UTF-8?q?allow=20=E2=80=9Cselector=E2=80=9D=20to?= =?UTF-8?q?=20be=20a=20DOM=20element=20in=20`findAllDOMElements`=20too?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/Utils.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index 9a2d23594..2857293ad 100644 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -527,12 +527,18 @@ function findDOMElement (element) { /** * Find one or more DOM elements. * - * @param {string} selector + * @param {string} element * @return {Array|null} */ -function findAllDOMElements (selector) { - const elements = [].slice.call(document.querySelectorAll(selector)) - return elements.length > 0 ? elements : null +function findAllDOMElements (element) { + if (typeof element === 'string') { + const elements = [].slice.call(document.querySelectorAll(element)) + return elements.length > 0 ? elements : null + } + + if (typeof element === 'object' && isDOMElement(element)) { + return element + } } function getSocketHost (url) { From 6ecaad1bc60b9eeb89890f59c8d105ab7f8b7c10 Mon Sep 17 00:00:00 2001 From: Richard Willars Date: Thu, 7 Sep 2017 16:35:52 +0100 Subject: [PATCH 16/32] Rename isOnline with updateOnlineStatus and removed params isOnline renamed to updateOnlineStatus and removes params updateOnlineStatus default to true Improved the window.navigator.onLine check Adds tests for updateOnlineStatus Removes debug Fixes isTouchDevice test File cleanup Simplifies mock for window.navigator.onLine --- src/core/Core.js | 13 ++++--- src/core/Core.test.js | 84 +++++++++++++++++++++--------------------- src/core/Utils.test.js | 21 ++++++++--- 3 files changed, 65 insertions(+), 53 deletions(-) diff --git a/src/core/Core.js b/src/core/Core.js index 68ad030d6..bfe3e8fb9 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -575,14 +575,17 @@ class Uppy { // show informer if offline if (typeof window !== 'undefined') { - window.addEventListener('online', () => this.isOnline(true)) - window.addEventListener('offline', () => this.isOnline(false)) - setTimeout(() => this.isOnline(), 3000) + window.addEventListener('online', () => this.updateOnlineStatus()) + window.addEventListener('offline', () => this.updateOnlineStatus()) + setTimeout(() => this.updateOnlineStatus(), 3000) } } - isOnline (status) { - const online = status || window.navigator.onLine + updateOnlineStatus () { + const online = + typeof window.navigator.onLine !== 'undefined' + ? window.navigator.onLine + : true if (!online) { this.emit('is-offline') this.info('No internet connection', 'error', 0) diff --git a/src/core/Core.test.js b/src/core/Core.test.js index a031ab283..e2ba5cce6 100644 --- a/src/core/Core.test.js +++ b/src/core/Core.test.js @@ -7,23 +7,6 @@ import InvalidPlugin from '../../test/mocks/invalidPlugin' import InvalidPluginWithoutId from '../../test/mocks/invalidPluginWithoutId' import InvalidPluginWithoutType from '../../test/mocks/invalidPluginWithoutType' -/* -const RealDate = Date - -function mockDate (isoDate) { - global.Date = class extends RealDate { - constructor () { - super() - return new RealDate(isoDate) - } - } -} - -afterEach(() => { - global.Date = RealDate -}) -*/ - const sampleImageDataURI = 'data:image/jpeg;base64,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' @@ -719,36 +702,51 @@ describe('src/Core', () => { describe('actions', () => {}) - describe('isOnline', () => { - xit('should detect if the browser is online or not', () => {}) + describe('updateOnlineStatus', () => { + const RealNavigatorOnline = global.window.navigator.onLine - xit( - 'should emit the correct event when the online status is specified', - () => { - const onlineEventMock = jest.fn() - const offlineEventMock = jest.fn() - const backOnlineEventMock = jest.fn() - const core = new Core() - core.on('is-offline', offlineEventMock) - core.on('is-online', onlineEventMock) - core.on('back-online', backOnlineEventMock) + function mockNavigatorOnline (status) { + Object.defineProperty( + global.window.navigator, + 'onLine', + { + value: status, + writable: true + } + ) + } - core.isOnline(true) - expect(onlineEventMock.mock.calls.length).toEqual(1) - expect(offlineEventMock.mock.calls.length).toEqual(0) - expect(backOnlineEventMock.mock.calls.length).toEqual(0) + afterEach(() => { + global.window.navigator.onLine = RealNavigatorOnline + }) - core.isOnline(false) - expect(onlineEventMock.mock.calls.length).toEqual(1) - expect(offlineEventMock.mock.calls.length).toEqual(1) - expect(backOnlineEventMock.mock.calls.length).toEqual(0) + it('should emit the correct event based on whether there is a network connection', () => { + const onlineEventMock = jest.fn() + const offlineEventMock = jest.fn() + const backOnlineEventMock = jest.fn() + const core = new Core() + core.on('is-offline', offlineEventMock) + core.on('is-online', onlineEventMock) + core.on('back-online', backOnlineEventMock) - core.isOnline(true) - expect(onlineEventMock.mock.calls.length).toEqual(2) - expect(offlineEventMock.mock.calls.length).toEqual(1) - expect(backOnlineEventMock.mock.calls.length).toEqual(1) - } - ) + mockNavigatorOnline(true) + core.updateOnlineStatus() + expect(onlineEventMock.mock.calls.length).toEqual(1) + expect(offlineEventMock.mock.calls.length).toEqual(0) + expect(backOnlineEventMock.mock.calls.length).toEqual(0) + + mockNavigatorOnline(false) + core.updateOnlineStatus() + expect(onlineEventMock.mock.calls.length).toEqual(1) + expect(offlineEventMock.mock.calls.length).toEqual(1) + expect(backOnlineEventMock.mock.calls.length).toEqual(0) + + mockNavigatorOnline(true) + core.updateOnlineStatus() + expect(onlineEventMock.mock.calls.length).toEqual(2) + expect(offlineEventMock.mock.calls.length).toEqual(1) + expect(backOnlineEventMock.mock.calls.length).toEqual(1) + }) }) describe('info', () => { diff --git a/src/core/Utils.test.js b/src/core/Utils.test.js index fa7ac49ef..50c860051 100644 --- a/src/core/Utils.test.js +++ b/src/core/Utils.test.js @@ -127,13 +127,24 @@ describe('core/utils', () => { }) describe('isTouchDevice', () => { - it("should return true if it's a touch device", () => { - global.window.ontouchstart = () => {} - expect(utils.isTouchDevice()).toEqual(true) + const RealTouchStart = global.window.ontouchstart + const RealMaxTouchPoints = global.navigator.maxTouchPoints - delete global.window.ontouchstart - global.navigator.maxTouchPoints = () => {} + beforeEach(() => { + global.window.ontouchstart = true + global.navigator.maxTouchPoints = 1 + }) + + afterEach(() => { + global.navigator.maxTouchPoints = RealMaxTouchPoints + global.window.ontouchstart = RealTouchStart + }) + + xit("should return true if it's a touch device", () => { expect(utils.isTouchDevice()).toEqual(true) + delete global.window.ontouchstart + global.navigator.maxTouchPoints = false + expect(utils.isTouchDevice()).toEqual(false) }) }) From 1cdd617b8cd8c98e4d70245f0bd3eb02c9f122ec Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Sep 2017 10:33:52 -0400 Subject: [PATCH 17/32] return an array always, even with a single item --- src/core/Utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index 2857293ad..4d64e8b2a 100644 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -537,7 +537,7 @@ function findAllDOMElements (element) { } if (typeof element === 'object' && isDOMElement(element)) { - return element + return [element] } } From 4d0d62804d74461998031657136b0766b791213e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Mon, 11 Sep 2017 16:04:21 +0200 Subject: [PATCH 18/32] Add example using multiple Uppy instances with RestoreFiles --- examples/multiple-instances/.gitignore | 1 + examples/multiple-instances/aliasify.js | 7 + examples/multiple-instances/index.html | 31 + examples/multiple-instances/main.js | 32 + examples/multiple-instances/package-lock.json | 3048 +++++++++++++++++ examples/multiple-instances/package.json | 15 + examples/multiple-instances/readme.md | 13 + 7 files changed, 3147 insertions(+) create mode 100644 examples/multiple-instances/.gitignore create mode 100644 examples/multiple-instances/aliasify.js create mode 100644 examples/multiple-instances/index.html create mode 100644 examples/multiple-instances/main.js create mode 100644 examples/multiple-instances/package-lock.json create mode 100644 examples/multiple-instances/package.json create mode 100644 examples/multiple-instances/readme.md diff --git a/examples/multiple-instances/.gitignore b/examples/multiple-instances/.gitignore new file mode 100644 index 000000000..70a19130f --- /dev/null +++ b/examples/multiple-instances/.gitignore @@ -0,0 +1 @@ +uppy.min.css diff --git a/examples/multiple-instances/aliasify.js b/examples/multiple-instances/aliasify.js new file mode 100644 index 000000000..694ca67e1 --- /dev/null +++ b/examples/multiple-instances/aliasify.js @@ -0,0 +1,7 @@ +const path = require('path') + +module.exports = { + replacements: { + '^uppy/lib/(.*?)$': path.join(__dirname, '../../src/$1') + } +} diff --git a/examples/multiple-instances/index.html b/examples/multiple-instances/index.html new file mode 100644 index 000000000..a29319352 --- /dev/null +++ b/examples/multiple-instances/index.html @@ -0,0 +1,31 @@ + + + + + + Uppy example: Multiple instances + + + +
+
+

Instance A

+
+
+
+

Instance B

+
+
+
+ + + + + diff --git a/examples/multiple-instances/main.js b/examples/multiple-instances/main.js new file mode 100644 index 000000000..b4bda290b --- /dev/null +++ b/examples/multiple-instances/main.js @@ -0,0 +1,32 @@ +const Uppy = require('uppy/lib/core') +const Dashboard = require('uppy/lib/plugins/Dashboard') +const RestoreFiles = require('uppy/lib/plugins/RestoreFiles') + +// Initialise two Uppy instances with the RestoreFiles plugin, +// but with different `id`s. +const a = Uppy({ + id: 'a', + debug: true +}) + .use(Dashboard, { + target: '#a', + inline: true, + maxWidth: 400 + }) + .use(RestoreFiles, { serviceWorker: false }) + .run() + +const b = Uppy({ + id: 'b', + debug: true +}) + .use(Dashboard, { + target: '#b', + inline: true, + maxWidth: 400 + }) + .use(RestoreFiles, { serviceWorker: false }) + .run() + +window.a = a +window.b = b diff --git a/examples/multiple-instances/package-lock.json b/examples/multiple-instances/package-lock.json new file mode 100644 index 000000000..933e0532e --- /dev/null +++ b/examples/multiple-instances/package-lock.json @@ -0,0 +1,3048 @@ +{ + "name": "uppy-multiple-instances-example", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "JSONStream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", + "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "dev": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, + "acorn": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "dev": true + }, + "aliasify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aliasify/-/aliasify-2.1.0.tgz", + "integrity": "sha1-fDCCW5RQueYYW6J1M+r24gZ9S0I=", + "dev": true, + "requires": { + "browserify-transform-tools": "1.7.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "asn1.js": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", + "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "astw": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", + "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.0", + "debug": "2.6.8", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.7" + } + }, + "babel-generator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "dev": true, + "requires": { + "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-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "6.26.0", + "babel-runtime": "6.26.0", + "core-js": "2.5.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "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": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "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": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } + }, + "babelify": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "dev": true, + "requires": { + "babel-core": "6.26.0", + "object-assign": "4.1.1" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "binary-extensions": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", + "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "bole": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bole/-/bole-2.0.0.tgz", + "integrity": "sha1-2KocaQRnv7T+Ebh0rLLoOH44JhU=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "individual": "3.0.0", + "json-stringify-safe": "5.0.1" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz", + "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "combine-source-map": "0.7.2", + "defined": "1.0.0", + "through2": "2.0.3", + "umd": "3.0.1" + } + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserify": { + "version": "14.4.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.4.0.tgz", + "integrity": "sha1-CJo0Y69Y0OSNjNQHCz90ZU1avKk=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "assert": "1.4.1", + "browser-pack": "6.0.2", + "browser-resolve": "1.11.2", + "browserify-zlib": "0.1.4", + "buffer": "5.0.7", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.11.1", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.1.7", + "duplexer2": "0.1.4", + "events": "1.1.1", + "glob": "7.1.2", + "has": "1.0.1", + "htmlescape": "1.1.1", + "https-browserify": "1.0.0", + "inherits": "2.0.3", + "insert-module-globals": "7.0.1", + "labeled-stream-splicer": "2.0.0", + "module-deps": "4.1.1", + "os-browserify": "0.1.2", + "parents": "1.0.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.3", + "resolve": "1.4.0", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "1.0.3", + "subarg": "1.0.0", + "syntax-error": "1.3.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4", + "xtend": "4.0.1" + } + }, + "browserify-aes": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz", + "integrity": "sha512-WYCMOT/PtGTlpOKFht0YJFYcPy6pLCR98CtWfzK13zoynLlBMvAdEMSRGmgnJCw2M2j/5qxBkinZQFobieM8dQ==", + "dev": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.0.8", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.5" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-transform-tools": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/browserify-transform-tools/-/browserify-transform-tools-1.7.0.tgz", + "integrity": "sha1-g+J3Ih9jJZvtLn6yooOpcKUB9MQ=", + "dev": true, + "requires": { + "falafel": "2.1.0", + "through": "2.3.8" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "0.2.9" + } + }, + "budo": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/budo/-/budo-10.0.4.tgz", + "integrity": "sha512-fJcz4EGwMno+e2xrD7QwclvZ77InghizqG8GGqMIYzanMUuWTOSrio+SUKpQRxLoFiSLiP+lceFcNbPseeew9A==", + "dev": true, + "requires": { + "bole": "2.0.0", + "browserify": "14.4.0", + "chokidar": "1.7.0", + "connect-pushstate": "1.1.0", + "escape-html": "1.0.3", + "events": "1.1.1", + "garnish": "5.2.0", + "get-ports": "1.0.3", + "inject-lr-script": "2.1.0", + "internal-ip": "1.2.0", + "micromatch": "2.3.11", + "on-finished": "2.3.0", + "on-headers": "1.0.1", + "once": "1.4.0", + "opn": "3.0.3", + "path-is-absolute": "1.0.1", + "pem": "1.10.0", + "reload-css": "1.0.2", + "resolve": "1.4.0", + "serve-static": "1.12.4", + "simple-html-index": "1.5.0", + "stacked": "1.1.1", + "stdout-stream": "1.4.0", + "strip-ansi": "3.0.1", + "subarg": "1.0.0", + "term-color": "1.0.1", + "url-trim": "1.0.0", + "watchify-middleware": "1.6.0", + "ws": "1.1.4", + "xtend": "4.0.1" + } + }, + "buffer": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.7.tgz", + "integrity": "sha512-NeeHXWh5pCbPQCt2/6rLvXqapZfVsqw/YgRgaHpT3H9Uzgs+S0lSg5SQzouIuDvcmlQRqBe8hOO2scKCu3cxrg==", + "dev": true, + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cached-path-relative": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", + "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "combine-source-map": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", + "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "dev": true, + "requires": { + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" + }, + "dependencies": { + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "connect-pushstate": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/connect-pushstate/-/connect-pushstate-1.1.0.tgz", + "integrity": "sha1-vKsiQnHEOWBKD7D2FMCl9WPojiQ=", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "dev": true + }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.8" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.8" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "crypto-browserify": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", + "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debounce": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.0.2.tgz", + "integrity": "sha1-UDzGdNjX9zcJlmT7dd29NrlibcY=", + "dev": true + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "detective": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.5.0.tgz", + "integrity": "sha1-blqMaybmx6JUsca210kNmOyR7dE=", + "dev": true, + "requires": { + "acorn": "4.0.13", + "defined": "1.0.0" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.0", + "randombytes": "2.0.5" + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz", + "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE=", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "falafel": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz", + "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", + "dev": true, + "requires": { + "acorn": "5.1.2", + "foreach": "2.0.5", + "isarray": "0.0.1", + "object-keys": "1.0.11" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fresh": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", + "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "from2-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/from2-string/-/from2-string-1.1.0.tgz", + "integrity": "sha1-GCgrJ9CKJnyzAwzSuLSw8hKvdSo=", + "dev": true, + "requires": { + "from2": "2.3.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "garnish": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/garnish/-/garnish-5.2.0.tgz", + "integrity": "sha1-vtQ2WTguSxmOM8eTiXvnxwHmVXc=", + "dev": true, + "requires": { + "chalk": "0.5.1", + "minimist": "1.2.0", + "pad-left": "2.1.0", + "pad-right": "0.2.2", + "prettier-bytes": "1.0.4", + "pretty-ms": "2.1.0", + "right-now": "1.0.0", + "split2": "0.2.1", + "stdout-stream": "1.4.0", + "url-trim": "1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "dev": true + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "1.1.0", + "escape-string-regexp": "1.0.5", + "has-ansi": "0.1.0", + "strip-ansi": "0.3.0", + "supports-color": "0.2.0" + } + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + } + } + }, + "get-ports": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-ports/-/get-ports-1.0.3.tgz", + "integrity": "sha1-9AvVgKyn7A77e5bL/L6wPviUteg=", + "dev": true, + "requires": { + "map-limit": "0.0.1" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.3.1" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "individual": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/individual/-/individual-3.0.0.tgz", + "integrity": "sha1-58pPhfiVewGHNPKFdQ3CLsL5hi0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inject-lr-script": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/inject-lr-script/-/inject-lr-script-2.1.0.tgz", + "integrity": "sha1-5htehMEYczkGy+oB7D10Zpijn2U=", + "dev": true, + "requires": { + "resp-modifier": "6.0.2" + } + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "insert-module-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", + "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "combine-source-map": "0.7.2", + "concat-stream": "1.5.2", + "is-buffer": "1.1.5", + "lexical-scope": "1.2.0", + "process": "0.11.10", + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "internal-ip": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", + "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=", + "dev": true, + "requires": { + "meow": "3.7.0" + } + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.10.0" + } + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + }, + "labeled-stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", + "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "isarray": "0.0.1", + "stream-splicer": "2.0.0" + } + }, + "lexical-scope": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", + "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "dev": true, + "requires": { + "astw": "2.2.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "map-limit": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz", + "integrity": "sha1-63lhAxwPDo0AG/LVb6toXViCLzg=", + "dev": true, + "requires": { + "once": "1.3.3" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + } + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "dev": true, + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "1.1.5" + } + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "miller-rabin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", + "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "module-deps": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", + "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "defined": "1.0.0", + "detective": "4.5.0", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.3", + "resolve": "1.4.0", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "opn": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/opn/-/opn-3.0.3.tgz", + "integrity": "sha1-ttmec5n3jWXDuq/+8fsojpuFJDo=", + "dev": true, + "requires": { + "object-assign": "4.1.1" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true + }, + "os-browserify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", + "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "outpipe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", + "integrity": "sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=", + "dev": true, + "requires": { + "shell-quote": "1.6.1" + } + }, + "pad-left": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-2.1.0.tgz", + "integrity": "sha1-FuajstRKjhOMsIOMx8tAOk/J6ZQ=", + "dev": true, + "requires": { + "repeat-string": "1.6.1" + } + }, + "pad-right": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", + "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", + "dev": true, + "requires": { + "repeat-string": "1.6.1" + } + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.9.1", + "browserify-aes": "1.0.8", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parse-ms": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", + "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", + "dev": true + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.8" + } + }, + "pem": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/pem/-/pem-1.10.0.tgz", + "integrity": "sha1-tc7WLVI4bCSTy7UTE7pQTikdOeo=", + "dev": true, + "requires": { + "md5": "2.2.1", + "os-tmpdir": "1.0.2", + "which": "1.3.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "plur": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", + "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "prettier-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prettier-bytes/-/prettier-bytes-1.0.4.tgz", + "integrity": "sha1-mUsCqkb2mcULYle1+qp/4lV+YtY=", + "dev": true + }, + "pretty-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", + "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", + "dev": true, + "requires": { + "is-finite": "1.0.2", + "parse-ms": "1.0.1", + "plur": "1.0.0" + } + }, + "private": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", + "dev": true + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "reload-css": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reload-css/-/reload-css-1.0.2.tgz", + "integrity": "sha1-avsRFi4jFP7M2tbcX96CH9cxgzE=", + "dev": true, + "requires": { + "query-string": "4.3.4" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resp-modifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", + "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", + "dev": true, + "requires": { + "debug": "2.6.8", + "minimatch": "3.0.4" + } + }, + "right-now": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/right-now/-/right-now-1.0.0.tgz", + "integrity": "sha1-bolgne69fc2vja7Mmuo5z1haCRg=", + "dev": true + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true, + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "send": { + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz", + "integrity": "sha1-mF+qPihLAnPHkzZKNcZze9k5Bbk=", + "dev": true, + "requires": { + "debug": "2.6.8", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.0", + "fresh": "0.5.0", + "http-errors": "1.6.2", + "mime": "1.3.4", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + } + }, + "serve-static": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz", + "integrity": "sha1-m2qpjutyU8Tu3Ewfb9vKYJkBqWE=", + "dev": true, + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.15.4" + } + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + }, + "sha.js": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", + "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.8" + } + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-html-index": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/simple-html-index/-/simple-html-index-1.5.0.tgz", + "integrity": "sha1-LJPurrrAAdihNfwAIr1K3o9YmW8=", + "dev": true, + "requires": { + "from2-string": "1.1.0" + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "dev": true, + "requires": { + "through2": "0.6.5" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "stacked": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stacked/-/stacked-1.1.1.tgz", + "integrity": "sha1-LH+jjMfjejQRp3zY55LeRI+faXU=", + "dev": true + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "stdout-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "syntax-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", + "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "term-color": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/term-color/-/term-color-1.0.1.tgz", + "integrity": "sha1-OOGSVTpHPjXkFgT/UZmEa/gRejo=", + "dev": true, + "requires": { + "ansi-styles": "2.0.1", + "supports-color": "1.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.0.1.tgz", + "integrity": "sha1-sDP1f5Pi0oreuLwRE4+hPaD9IKM=", + "dev": true + }, + "supports-color": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.3.1.tgz", + "integrity": "sha1-FXWN8J2P87SswwdTn6vicJXhBC0=", + "dev": true + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "0.11.10" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", + "dev": true + }, + "umd": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", + "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-trim": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-trim/-/url-trim-1.0.0.tgz", + "integrity": "sha1-QAV+LxZLiOXaynJp2kfm0d2Detw=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "watchify": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.9.0.tgz", + "integrity": "sha1-8HX9LoqGrN6Eztum5cKgvt1SPZ4=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "browserify": "14.4.0", + "chokidar": "1.7.0", + "defined": "1.0.0", + "outpipe": "1.1.1", + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "watchify-middleware": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchify-middleware/-/watchify-middleware-1.6.0.tgz", + "integrity": "sha1-bbbijwJ53hyhIJrk8afwY3RYd8Q=", + "dev": true, + "requires": { + "concat-stream": "1.5.2", + "debounce": "1.0.2", + "events": "1.1.1", + "object-assign": "4.1.1", + "strip-ansi": "3.0.1", + "watchify": "3.9.0" + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.4.tgz", + "integrity": "sha1-V/QNA2gy5fUFVmKjl8Tedu1mv2E=", + "dev": true, + "requires": { + "options": "0.0.6", + "ultron": "1.0.2" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } +} diff --git a/examples/multiple-instances/package.json b/examples/multiple-instances/package.json new file mode 100644 index 000000000..72c7d8254 --- /dev/null +++ b/examples/multiple-instances/package.json @@ -0,0 +1,15 @@ +{ + "private": true, + "name": "uppy-multiple-instances-example", + "scripts": { + "css": "cp ../../dist/uppy.min.css .", + "start": "npm run css && budo main.js:bundle.js -- -t babelify -g aliasify" + }, + "aliasify": "./aliasify.js", + "dependencies": {}, + "devDependencies": { + "aliasify": "^2.1.0", + "babelify": "^7.3.0", + "budo": "^10.0.4" + } +} diff --git a/examples/multiple-instances/readme.md b/examples/multiple-instances/readme.md new file mode 100644 index 000000000..9df1cdb5a --- /dev/null +++ b/examples/multiple-instances/readme.md @@ -0,0 +1,13 @@ +# Multiple Instances + +This example uses Uppy with the RestoreFiles plugin. +It has two instances on the same page, side-by-side, but with different `id`s so their stored files don't interfere with each other. + +## Run it + +Move into this directory, then: + +```bash +npm install +npm start +``` From 91ec5dbdd6825ed4f2d62928901dbcd710471649 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Sep 2017 14:09:44 -0400 Subject: [PATCH 19/32] refactor: openModal, closeModal, isModalOpen --- src/plugins/Dashboard/Dashboard.js | 2 +- src/plugins/Dashboard/index.js | 70 +++++++++++++----------------- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/plugins/Dashboard/Dashboard.js b/src/plugins/Dashboard/Dashboard.js index 857da16b4..61e1483e7 100644 --- a/src/plugins/Dashboard/Dashboard.js +++ b/src/plugins/Dashboard/Dashboard.js @@ -69,7 +69,7 @@ module.exports = function Dashboard (props) { type="button" aria-label="${props.i18n('closeModal')}" title="${props.i18n('closeModal')}" - onclick=${props.hide}>${closeIcon()} + onclick=${props.closeModal}>${closeIcon()}
diff --git a/src/plugins/Dashboard/index.js b/src/plugins/Dashboard/index.js index 0c36f8a0f..94fc468b4 100644 --- a/src/plugins/Dashboard/index.js +++ b/src/plugins/Dashboard/index.js @@ -66,8 +66,9 @@ module.exports = class DashboardUI extends Plugin { this.translator = new Translator({locale: this.locale}) this.containerWidth = this.translator.translate.bind(this.translator) - this.hide = this.hide.bind(this) - this.show = this.show.bind(this) + this.closeModal = this.closeModal.bind(this) + this.openModal = this.openModal.bind(this) + this.isModalOpen = this.isModalOpen.bind(this) this.addTarget = this.addTarget.bind(this) this.actions = this.actions.bind(this) @@ -143,25 +144,7 @@ module.exports = class DashboardUI extends Plugin { })}) } - isOpen () { - return !this.core.getState().modal.isHidden || false - } - - hide () { - const modal = this.core.getState().modal - - this.core.setState({ - modal: Object.assign({}, modal, { - isHidden: true - }) - }) - - document.body.classList.remove('is-UppyDashboard-open') - - window.scrollTo(0, this.savedDocumentScrollPosition) - } - - show () { + openModal () { const modal = this.core.getState().modal this.core.setState({ @@ -186,26 +169,41 @@ module.exports = class DashboardUI extends Plugin { setTimeout(this.updateDashboardElWidth, 500) } + closeModal () { + const modal = this.core.getState().modal + + this.core.setState({ + modal: Object.assign({}, modal, { + isHidden: true + }) + }) + + document.body.classList.remove('is-UppyDashboard-open') + + window.scrollTo(0, this.savedDocumentScrollPosition) + } + + isModalOpen () { + return !this.core.getState().modal.isHidden || false + } + // Close the Modal on esc key press handleEscapeKeyPress (event) { if (event.keyCode === 27) { - this.hide() + this.closeModal() } } handleClickOutside () { - if (this.opts.closeModalOnClickOutside) this.hide() + if (this.opts.closeModalOnClickOutside) this.closeModal() } initEvents () { // Modal open button const showModalTrigger = findAllDOMElements(this.opts.trigger) + console.log(showModalTrigger) if (!this.opts.inline && showModalTrigger) { - if (Array.isArray(showModalTrigger)) { - showModalTrigger.forEach(trigger => trigger.addEventListener('click', this.show)) - } else { - showModalTrigger.addEventListener('click', this.show) - } + showModalTrigger.forEach(trigger => trigger.addEventListener('click', this.openModal)) } if (!this.opts.inline && !showModalTrigger) { @@ -223,11 +221,7 @@ module.exports = class DashboardUI extends Plugin { removeEvents () { const showModalTrigger = findAllDOMElements(this.opts.trigger) if (!this.opts.inline && showModalTrigger) { - if (Array.isArray(showModalTrigger)) { - showModalTrigger.forEach(trigger => trigger.removeEventListener('click', this.show)) - } else { - showModalTrigger.removeEventListener('click', this.show) - } + showModalTrigger.forEach(trigger => trigger.removeEventListener('click', this.openModal)) } this.removeDragDropListener() @@ -354,12 +348,6 @@ module.exports = class DashboardUI extends Plugin { this.core.emit('dashboard:file-card') } - // const info = (text, type, duration) => { - // this.core.info(text, type, duration) - // } - - const resumableUploads = this.core.state.capabilities.resumableUploads || false - return Dashboard({ state: state, modal: state.modal, @@ -373,7 +361,7 @@ module.exports = class DashboardUI extends Plugin { autoProceed: this.core.opts.autoProceed, hideUploadButton: this.opts.hideUploadButton, id: this.id, - hide: this.hide, + closeModal: this.closeModal, handleClickOutside: this.handleClickOutside, showProgressDetails: this.opts.showProgressDetails, inline: this.opts.inline, @@ -389,7 +377,7 @@ module.exports = class DashboardUI extends Plugin { info: this.core.info, note: this.opts.note, metaFields: state.metaFields, - resumableUploads: resumableUploads, + resumableUploads: this.core.state.capabilities.resumableUploads || false, startUpload: startUpload, pauseUpload: pauseUpload, cancelUpload: cancelUpload, From be9ef1b07622c0a8e02ec56ebedb53a0c490c5f4 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Sep 2017 14:10:01 -0400 Subject: [PATCH 20/32] docs for openModal, closeModal, isModalOpen --- website/src/docs/dashboard.md | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/website/src/docs/dashboard.md b/website/src/docs/dashboard.md index f6b9c0dca..7433985ae 100644 --- a/website/src/docs/dashboard.md +++ b/website/src/docs/dashboard.md @@ -21,12 +21,14 @@ Dashboard is a universal UI plugin for Uppy: uppy.use(Dashboard, { target: 'body', getMetaFromForm: true, + trigger: '#uppy-select-files', inline: false, width: 750, height: 550, + showProgressDetails: false, + hideUploadButton: false, note: false, - disableStatusBar: false, - disableInformer: false, + closeModalOnClickOutside: false, locale: { strings: { selectToUpload: 'Select files to upload', @@ -60,7 +62,7 @@ By default Dashboard will be rendered as a modal, which is opened via clicking o ### `trigger: '#uppy-select-files'` -String with a CSS selector for a button that will trigger opening Dashboard modal. +String with a CSS selector for a button that will trigger opening Dashboard modal. Multiple buttons or links can be used, if it’s a class selector (`.uppy-choose`, for example). ### `width: 750` @@ -88,4 +90,29 @@ See [general plugin options](/docs/plugins). ### `locale` -See [general plugin options](/docs/plugins). \ No newline at end of file +See [general plugin options](/docs/plugins). + +## Methods + +### `openModal()` + +Shows the Dashboard modal. Use it like this: + +`uppy.getPlugin('Dashboard').openModal()` + +### `closeModal()` + +Hides the Dashboard modal. Use it like this: + +`uppy.getPlugin('Dashboard').closeModal()` + +### `isModalOpen()` + +Returns `true` if the Dashboard modal is open, `false` otherwise. + +```js +const dashboard = uppy.getPlugin('Dashboard') +if ( dashboard.isModalOpen() ) { + dashboard.closeModal() +} +``` \ No newline at end of file From bf0cae6a4299ed41f95972615c989631c1dc1b52 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Sep 2017 14:24:24 -0400 Subject: [PATCH 21/32] changelog --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a768b0cce..302d43cf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,7 +105,13 @@ Theme: React and Retry - [ ] core: retry or show error when upload can’t start / fails (offline, wrong endpoint) — now it just sits there; add error in file progress state, UI, question mark button (@arturi @goto-bus-stop) - [ ] core: improve and merge in the React PR (@arturi @goto-bus-stop) - [ ] goldenretriver: add “ghost” files (@arturi @goto-bus-stop) -- [ ] dashboard: expose/document show/hide/isOpen API (@arturi) +- [ ] core: remove unused bootstrap styles (#329 / @arturi) +- [x] core: experiment with yo-yo --> preact and picodom (#297 / @arturi) +- [x] dashboard: fix FileItem source icon position and copy (@arturi) +- [x] dashboard: expose and document the show/hide/isOpen API (@arturi) +- [x] dashboard: allow multiple `triggers` of the same class `.open-uppy` (@arturi) +- [x] core: Handle sync returns and throws in possibly-async function options (#315 / @goto-bus-stop) +- [x] core: switch to Jest tests, add more tests for Core and Utils (@richardwillars) ## 0.18.1 From 504a6977acc0f4d0416a908ae9d8d0a0e990ee05 Mon Sep 17 00:00:00 2001 From: Richard Willars Date: Tue, 12 Sep 2017 09:09:25 +0100 Subject: [PATCH 22/32] Adds tests for info messages (and fixes hideInfo method) --- src/core/Core.js | 2 +- src/core/Core.test.js | 85 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/core/Core.js b/src/core/Core.js index 7613bf076..55d73262b 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -743,7 +743,7 @@ class Uppy { } hideInfo () { - const newInfo = Object.assign({}, this.core.state.info, { + const newInfo = Object.assign({}, this.state.info, { isHidden: true }) this.setState({ diff --git a/src/core/Core.test.js b/src/core/Core.test.js index a031ab283..53002daef 100644 --- a/src/core/Core.test.js +++ b/src/core/Core.test.js @@ -752,9 +752,90 @@ describe('src/Core', () => { }) describe('info', () => { - xit('should set an info message to be displayed', () => {}) + it('should set a string based message to be displayed infinitely', () => { + const infoVisibleEvent = jest.fn() + const core = new Core() + core.run() + core.on('core:info-visible', infoVisibleEvent) - xit('should hide an info message', () => {}) + core.info('This is the message', 'info', 0) + expect(core.state.info).toEqual({ + isHidden: false, + type: 'info', + message: 'This is the message', + details: null + }) + expect(infoVisibleEvent.mock.calls.length).toEqual(1) + expect(typeof core.infoTimeoutID).toEqual('undefined') + }) + + it('should set a object based message to be displayed infinitely', () => { + const infoVisibleEvent = jest.fn() + const core = new Core() + core.run() + core.on('core:info-visible', infoVisibleEvent) + + core.info({ + message: 'This is the message', + details: { + foo: 'bar' + } + }, 'warning', 0) + expect(core.state.info).toEqual({ + isHidden: false, + type: 'warning', + message: 'This is the message', + details: { + foo: 'bar' + } + }) + expect(infoVisibleEvent.mock.calls.length).toEqual(1) + expect(typeof core.infoTimeoutID).toEqual('undefined') + }) + + it('should set an info message to be displayed for a period of time before hiding', (done) => { + const infoVisibleEvent = jest.fn() + const infoHiddenEvent = jest.fn() + const core = new Core() + core.run() + core.on('core:info-visible', infoVisibleEvent) + core.on('core:info-hidden', infoHiddenEvent) + + core.info('This is the message', 'info', 100) + expect(typeof core.infoTimeoutID).toEqual('number') + expect(infoHiddenEvent.mock.calls.length).toEqual(0) + setTimeout(() => { + expect(infoHiddenEvent.mock.calls.length).toEqual(1) + expect(core.state.info).toEqual({ + isHidden: true, + type: 'info', + message: 'This is the message', + details: null + }) + done() + }, 110) + }) + + it('should hide an info message', () => { + const infoVisibleEvent = jest.fn() + const infoHiddenEvent = jest.fn() + const core = new Core() + core.run() + core.on('core:info-visible', infoVisibleEvent) + core.on('core:info-hidden', infoHiddenEvent) + + core.info('This is the message', 'info', 0) + expect(typeof core.infoTimeoutID).toEqual('undefined') + expect(infoHiddenEvent.mock.calls.length).toEqual(0) + core.hideInfo() + expect(infoHiddenEvent.mock.calls.length).toEqual(1) + expect(core.state.info).toEqual({ + isHidden: true, + type: 'info', + message: 'This is the message', + details: null + }) + }) }) describe('createUpload', () => { From 979be0454086d6d1034516a0226bc088f1e0773c Mon Sep 17 00:00:00 2001 From: Richard Willars Date: Tue, 12 Sep 2017 10:10:21 +0100 Subject: [PATCH 23/32] Remove upload test --- src/core/Core.test.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/core/Core.test.js b/src/core/Core.test.js index 53002daef..c2bbffce0 100644 --- a/src/core/Core.test.js +++ b/src/core/Core.test.js @@ -843,6 +843,31 @@ describe('src/Core', () => { }) describe('removeUpload', () => { - xit('should remove all files from the specified upload', () => {}) + it('should remove all files from the specified upload', () => { + // this uploader will run once the upload has started + const uploader = () => { + return Promise.resolve().then(() => { + const uploadId = Object.keys(core.state.currentUploads)[0] + expect(typeof core.state.currentUploads[uploadId]).toEqual('object') + expect(core.state.currentUploads[uploadId].fileIDs.length).toEqual(1) + core.removeUpload(uploadId) + expect(typeof core.state.currentUploads[uploadId]).toEqual('undefined') + }) + } + + const core = new Core() + core.run() + core.addUploader(uploader) + return core + .addFile({ + source: 'jest', + name: 'foo.jpg', + type: 'image/jpg', + data: utils.dataURItoFile(sampleImageDataURI, {}) + }) + .then(() => { + return core.upload(true) + }) + }) }) }) From abbaed88cd964f1a8c3ce898e31ccadb675051c4 Mon Sep 17 00:00:00 2001 From: Richard Willars Date: Tue, 12 Sep 2017 10:50:12 +0100 Subject: [PATCH 24/32] Test for createUpload --- src/core/Core.test.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/Core.test.js b/src/core/Core.test.js index c2bbffce0..f3eb1a17c 100644 --- a/src/core/Core.test.js +++ b/src/core/Core.test.js @@ -839,7 +839,25 @@ describe('src/Core', () => { }) describe('createUpload', () => { - xit('should assign the specified files to a new upload', () => {}) + it('should assign the specified files to a new upload', () => { + const core = new Core() + core.run() + return core.addFile({ + source: 'jest', + name: 'foo.jpg', + type: 'image/jpg', + data: utils.dataURItoFile(sampleImageDataURI, {}) + }).then(() => { + core.createUpload(Object.keys(core.state.files)) + const uploadId = Object.keys(core.state.currentUploads)[0] + const currentUploadsState = {} + currentUploadsState[uploadId] = { + fileIDs: Object.keys(core.state.files), + step: 0 + } + expect(core.state.currentUploads).toEqual(currentUploadsState) + }) + }) }) describe('removeUpload', () => { From 050ecbfa1e726790d90598c065492e7ae10aafc6 Mon Sep 17 00:00:00 2001 From: Richard Willars Date: Tue, 12 Sep 2017 15:48:03 +0100 Subject: [PATCH 25/32] Adds tests for checkRestrictions --- src/core/Core.test.js | 61 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/src/core/Core.test.js b/src/core/Core.test.js index f3eb1a17c..b5dcf68d3 100644 --- a/src/core/Core.test.js +++ b/src/core/Core.test.js @@ -708,13 +708,68 @@ describe('src/Core', () => { }) describe('checkRestrictions', () => { + it('should enforce the maxNumberOfFiles rule', () => { + const core = new Core({ + autoProceed: false, + restrictions: { + maxNumberOfFiles: 1 + } + }) + + // add 2 files + core.addFile({ + source: 'jest', + name: 'foo1.jpg', + type: 'image/jpg', + data: utils.dataURItoFile(sampleImageDataURI, {}) + }) + expect(core.addFile({ + source: 'jest', + name: 'foo2.jpg', + type: 'image/jpg', + data: utils.dataURItoFile(sampleImageDataURI, {}) + })).rejects.toMatch('File not allowed').then(() => { + expect(core.state.info.message).toEqual('You can only upload 1 file') + }) + }) + xit('should enforce the minNumberOfFiles rule', () => {}) - xit('should enforce the maxNumberOfFiles rule', () => {}) + it('should enfore the allowedFileTypes rule', () => { + const core = new Core({ + autoProceed: false, + restrictions: { + allowedFileTypes: ['image/gif', 'image/png'] + } + }) - xit('should enfore the allowedFileTypes rule', () => {}) + expect(core.addFile({ + source: 'jest', + name: 'foo2.jpg', + type: 'image/jpg', + data: utils.dataURItoFile(sampleImageDataURI, {}) + })).rejects.toMatch('File not allowed').then(() => { + expect(core.state.info.message).toEqual('You can only upload: image/gif, image/png') + }) + }) - xit('should enforce the maxFileSize rule', () => {}) + it('should enforce the maxFileSize rule', () => { + const core = new Core({ + autoProceed: false, + restrictions: { + maxFileSize: 1234 + } + }) + + expect(core.addFile({ + source: 'jest', + name: 'foo.jpg', + type: 'image/jpg', + data: utils.dataURItoFile(sampleImageDataURI, {}) + })).rejects.toMatch('File not allowed').then(() => { + expect(core.state.info.message).toEqual('This file exceeds maximum allowed size of 1.2 KB') + }) + }) }) describe('actions', () => {}) From 99efda8bcc964244561f89d0c6456be0ce593453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Wed, 13 Sep 2017 17:25:42 +0200 Subject: [PATCH 26/32] restore: Store blobs in a single IndexedDB store --- src/plugins/RestoreFiles/IndexedDBStore.js | 54 +++++++++++++++------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/plugins/RestoreFiles/IndexedDBStore.js b/src/plugins/RestoreFiles/IndexedDBStore.js index 0564e4d0a..36b4537d4 100644 --- a/src/plugins/RestoreFiles/IndexedDBStore.js +++ b/src/plugins/RestoreFiles/IndexedDBStore.js @@ -3,14 +3,16 @@ const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexe const isSupported = !!indexedDB const DB_NAME = 'uppy-blobs' -const DB_VERSION = 1 +const STORE_NAME = 'files' // maybe have a thumbnail store in the future +const DB_VERSION = 2 -function connect (dbName, name) { +function connect (dbName) { const request = indexedDB.open(dbName, DB_VERSION) return new Promise((resolve, reject) => { request.onupgradeneeded = (event) => { const db = event.target.result - const store = db.createObjectStore(name, { keyPath: 'id' }) + const store = db.createObjectStore(STORE_NAME, { keyPath: 'id' }) + store.createIndex('store', 'store', { unique: false }) store.transaction.oncomplete = () => { resolve(db) } @@ -41,7 +43,11 @@ class IndexedDBStore { }, opts) this.name = this.opts.storeName - this.ready = connect(this.opts.dbName, this.opts.storeName) + this.ready = connect(this.opts.dbName) + } + + key (fileID) { + return `${this.name}!${fileID}` } /** @@ -49,13 +55,18 @@ class IndexedDBStore { */ list () { return this.ready.then((db) => { - const transaction = db.transaction([this.name], 'readonly') - const request = transaction.objectStore(this.name).getAll() + const transaction = db.transaction([STORE_NAME], 'readonly') + const store = transaction.objectStore(STORE_NAME) + const request = store.index('store') + .getAll(IDBKeyRange.only(this.name)) return waitForRequest(request) }).then((files) => { const result = {} files.forEach((file) => { - result[file.id] = file + result[file.fileID] = { + id: file.fileID, + data: file.data + } }) return result }) @@ -66,10 +77,14 @@ class IndexedDBStore { */ get (fileID) { return this.ready.then((db) => { - const transaction = db.transaction([this.name], 'readonly') - const request = transaction.objectStore(this.name).get(fileID) + const transaction = db.transaction([STORE_NAME], 'readonly') + const request = transaction.objectStore(STORE_NAME) + .get(this.key(fileID)) return waitForRequest(request) - }).then((result) => result.data) + }).then((result) => ({ + id: result.data.fileID, + data: result.data.data + })) } /** @@ -79,8 +94,10 @@ class IndexedDBStore { */ getSize () { return this.ready.then((db) => { - const transaction = db.transaction([this.name], 'readonly') - const request = transaction.objectStore(this.name).openCursor() + const transaction = db.transaction([STORE_NAME], 'readonly') + const store = transaction.objectStore(STORE_NAME) + const request = store.index('store') + .openCursor(IDBKeyRange.only(this.name)) return new Promise((resolve, reject) => { let size = 0 request.onsuccess = (event) => { @@ -112,9 +129,11 @@ class IndexedDBStore { } return this.ready }).then((db) => { - const transaction = db.transaction([this.name], 'readwrite') - const request = transaction.objectStore(this.name).add({ - id: file.id, + const transaction = db.transaction([STORE_NAME], 'readwrite') + const request = transaction.objectStore(STORE_NAME).add({ + id: this.key(file.id), + fileID: file.id, + store: this.name, data: file.data }) return waitForRequest(request) @@ -126,8 +145,9 @@ class IndexedDBStore { */ delete (fileID) { return this.ready.then((db) => { - const transaction = db.transaction([this.name], 'readwrite') - const request = transaction.objectStore(this.name).delete(fileID) + const transaction = db.transaction([STORE_NAME], 'readwrite') + const request = transaction.objectStore(STORE_NAME) + .delete(this.key(fileID)) return waitForRequest(request) }) } From 0eb2448a3d61069a8ea6c81680c12797620fb1e0 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Wed, 13 Sep 2017 18:50:41 -0400 Subject: [PATCH 27/32] Fix calculateTotalProgress - NaN --- src/core/Core.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/core/Core.js b/src/core/Core.js index 96c0c6a10..d1dd86eca 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -72,6 +72,7 @@ class Uppy { this.initSocket = this.initSocket.bind(this) this.log = this.log.bind(this) this.info = this.info.bind(this) + this.hideInfo = this.hideInfo.bind(this) this.addFile = this.addFile.bind(this) this.removeFile = this.removeFile.bind(this) this.calculateProgress = this.calculateProgress.bind(this) @@ -423,7 +424,7 @@ class Uppy { progressAll = progressAll + files[file].progress.percentage }) - const totalProgress = Math.floor((progressAll * 100 / progressMax).toFixed(2)) + const totalProgress = progressMax === 0 ? 0 : Math.floor((progressAll * 100 / progressMax).toFixed(2)) this.setState({ totalProgress: totalProgress @@ -734,15 +735,7 @@ class Uppy { } // hide the informer after `duration` milliseconds - this.infoTimeoutID = setTimeout(() => { - const newInformer = Object.assign({}, this.state.info, { - isHidden: true - }) - this.setState({ - info: newInformer - }) - this.emit('core:info-hidden') - }, duration) + this.infoTimeoutID = setTimeout(this.hideInfo, duration) } hideInfo () { From 4e808ca3d26f06499c58bb77abbf1c3c2b510b4d Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Thu, 14 Sep 2017 12:01:19 -0400 Subject: [PATCH 28/32] add aria-hidden to all icons for accessibility, remove console.log --- src/plugins/Dashboard/icons.js | 32 +++++++++++++-------------- src/plugins/Dashboard/index.js | 1 - src/plugins/DragDrop/index.js | 2 +- src/plugins/Dropbox/icons.js | 12 +++++----- src/plugins/GoogleDrive/index.js | 2 +- src/plugins/Instagram/index.js | 2 +- src/plugins/StatusBar/StatusBar.js | 8 +++---- src/plugins/Webcam/CameraIcon.js | 2 +- src/plugins/Webcam/RecordStartIcon.js | 2 +- src/plugins/Webcam/RecordStopIcon.js | 2 +- src/plugins/Webcam/WebcamIcon.js | 2 +- 11 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/plugins/Dashboard/icons.js b/src/plugins/Dashboard/icons.js index d97e4e86e..ecf041fc3 100644 --- a/src/plugins/Dashboard/icons.js +++ b/src/plugins/Dashboard/icons.js @@ -3,26 +3,26 @@ const html = require('yo-yo') // https://css-tricks.com/creating-svg-icon-system-react/ function defaultTabIcon () { - return html` + return html`` } function iconCopy () { - return html` + return html`` } function iconResume () { - return html` + return html`` } function iconPause () { - return html` + return html`
- + Upload complete・${totalProgress}% @@ -170,13 +170,13 @@ const pauseResumeButtons = (props) => { return html`